1
|
|
|
import React, { Fragment } from 'react';
|
2
|
|
|
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
|
3
|
|
|
|
4
|
|
|
import PageHeader from '../common/PageHeader';
|
5
|
|
|
import { Button, Card, CardBody, CardHeader, Row, Col } from 'reactstrap';
|
6
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
7
|
|
|
|
8
|
|
|
import FalconEditor from '../common/FalconEditor';
|
9
|
|
|
import { useState } from 'react';
|
10
|
|
|
|
11
|
|
|
const DragAndDropCode = `function DragAndDropExample() {
|
12
|
|
|
|
13
|
|
|
return (
|
14
|
|
|
<DragDropContext onDragEnd={onDragEnd} >
|
15
|
|
|
<Row>
|
16
|
|
|
<Col>
|
17
|
|
|
<h5>List 1</h5>
|
18
|
|
|
<Droppable droppableId="droppable">
|
19
|
|
|
{(provided, snapshot) => (
|
20
|
|
|
<div
|
21
|
|
|
ref={provided.innerRef}
|
22
|
|
|
style={getListStyle(snapshot.isDraggingOver)}>
|
23
|
|
|
{data.items.map((item, index) => (
|
24
|
|
|
<Draggable
|
25
|
|
|
key={item.id}
|
26
|
|
|
draggableId={item.id}
|
27
|
|
|
index={index}>
|
28
|
|
|
{(provided, snapshot) => (
|
29
|
|
|
<div
|
30
|
|
|
ref={provided.innerRef}
|
31
|
|
|
{...provided.draggableProps}
|
32
|
|
|
{...provided.dragHandleProps}
|
33
|
|
|
style={getItemStyle(
|
34
|
|
|
snapshot.isDragging,
|
35
|
|
|
provided.draggableProps.style
|
36
|
|
|
)}>
|
37
|
|
|
{item.content}
|
38
|
|
|
</div>
|
39
|
|
|
)}
|
40
|
|
|
</Draggable>
|
41
|
|
|
))}
|
42
|
|
|
{provided.placeholder}
|
43
|
|
|
</div>
|
44
|
|
|
)}
|
45
|
|
|
</Droppable>
|
46
|
|
|
</Col>
|
47
|
|
|
<Col>
|
48
|
|
|
<h5>List 2</h5>
|
49
|
|
|
<Droppable droppableId="droppable2">
|
50
|
|
|
{(provided, snapshot) => (
|
51
|
|
|
<div
|
52
|
|
|
ref={provided.innerRef}
|
53
|
|
|
style={getListStyle(snapshot.isDraggingOver)}>
|
54
|
|
|
{data.selected.map((item, index) => (
|
55
|
|
|
<Draggable
|
56
|
|
|
key={item.id}
|
57
|
|
|
draggableId={item.id}
|
58
|
|
|
index={index}>
|
59
|
|
|
{(provided, snapshot) => (
|
60
|
|
|
<div
|
61
|
|
|
ref={provided.innerRef}
|
62
|
|
|
{...provided.draggableProps}
|
63
|
|
|
{...provided.dragHandleProps}
|
64
|
|
|
style={getItemStyle(
|
65
|
|
|
snapshot.isDragging,
|
66
|
|
|
provided.draggableProps.style
|
67
|
|
|
)}>
|
68
|
|
|
{item.content}
|
69
|
|
|
</div>
|
70
|
|
|
)}
|
71
|
|
|
</Draggable>
|
72
|
|
|
))}
|
73
|
|
|
{provided.placeholder}
|
74
|
|
|
</div>
|
75
|
|
|
)}
|
76
|
|
|
</Droppable>
|
77
|
|
|
</Col>
|
78
|
|
|
</Row>
|
79
|
|
|
</DragDropContext>)
|
80
|
|
|
}`;
|
81
|
|
|
|
82
|
|
|
const getItems = (count, offset = 0) =>
|
83
|
|
|
Array.from({ length: count }, (v, k) => k).map(k => ({
|
84
|
|
|
id: `item-${k + offset}`,
|
85
|
|
|
content: `item ${k + offset}`
|
86
|
|
|
}));
|
87
|
|
|
|
88
|
|
|
// a little function to help us with reordering the result
|
89
|
|
|
const reorder = (list, startIndex, endIndex) => {
|
90
|
|
|
const result = Array.from(list);
|
91
|
|
|
const [removed] = result.splice(startIndex, 1);
|
92
|
|
|
result.splice(endIndex, 0, removed);
|
93
|
|
|
|
94
|
|
|
return result;
|
95
|
|
|
};
|
96
|
|
|
|
97
|
|
|
/**
|
98
|
|
|
* Moves an item from one list to another list.
|
99
|
|
|
*/
|
100
|
|
|
const move = (source, destination, droppableSource, droppableDestination) => {
|
101
|
|
|
const sourceClone = Array.from(source);
|
102
|
|
|
const destClone = Array.from(destination);
|
103
|
|
|
const [removed] = sourceClone.splice(droppableSource.index, 1);
|
104
|
|
|
|
105
|
|
|
destClone.splice(droppableDestination.index, 0, removed);
|
106
|
|
|
|
107
|
|
|
const result = {};
|
108
|
|
|
result[droppableSource.droppableId] = sourceClone;
|
109
|
|
|
result[droppableDestination.droppableId] = destClone;
|
110
|
|
|
|
111
|
|
|
return result;
|
112
|
|
|
};
|
113
|
|
|
|
114
|
|
|
const grid = 8;
|
115
|
|
|
|
116
|
|
|
const getItemStyle = (isDragging, draggableStyle) => ({
|
117
|
|
|
// some basic styles to make the items look a bit nicer
|
118
|
|
|
userSelect: 'none',
|
119
|
|
|
padding: grid * 2,
|
120
|
|
|
margin: `0 0 ${grid}px 0`,
|
121
|
|
|
|
122
|
|
|
// change background colour if dragging
|
123
|
|
|
background: isDragging ? 'lightgreen' : '#FFF',
|
124
|
|
|
|
125
|
|
|
// styles we need to apply on draggables
|
126
|
|
|
...draggableStyle
|
127
|
|
|
});
|
128
|
|
|
|
129
|
|
|
const getListStyle = isDraggingOver => ({
|
130
|
|
|
background: isDraggingOver ? 'lightblue' : 'lightgrey',
|
131
|
|
|
padding: grid,
|
132
|
|
|
width: 250
|
133
|
|
|
});
|
134
|
|
|
|
135
|
|
|
const ReactBootstrapTable2 = () => {
|
136
|
|
|
const [data, setData] = useState({ items: getItems(10), selected: getItems(5, 10) });
|
137
|
|
|
|
138
|
|
|
const id2List = {
|
139
|
|
|
droppable: 'items',
|
140
|
|
|
droppable2: 'selected'
|
141
|
|
|
};
|
142
|
|
|
|
143
|
|
|
const getList = id => data[id2List[id]];
|
144
|
|
|
|
145
|
|
|
const onDragEnd = result => {
|
146
|
|
|
const { source, destination } = result;
|
147
|
|
|
|
148
|
|
|
// dropped outside the list
|
149
|
|
|
if (!destination) {
|
150
|
|
|
return;
|
151
|
|
|
}
|
152
|
|
|
|
153
|
|
|
if (source.droppableId === destination.droppableId) {
|
154
|
|
|
const reorderData = reorder(getList(source.droppableId), source.index, destination.index);
|
155
|
|
|
|
156
|
|
|
setData({ items: reorderData, selected: data.selected });
|
157
|
|
|
|
158
|
|
|
if (source.droppableId === 'droppable2') {
|
159
|
|
|
setData({ ...data, selected: reorderData });
|
160
|
|
|
}
|
161
|
|
|
} else {
|
162
|
|
|
const result = move(getList(source.droppableId), getList(destination.droppableId), source, destination);
|
163
|
|
|
|
164
|
|
|
setData({
|
165
|
|
|
items: result.droppable,
|
166
|
|
|
selected: result.droppable2
|
167
|
|
|
});
|
168
|
|
|
}
|
169
|
|
|
};
|
170
|
|
|
|
171
|
|
|
return (
|
172
|
|
|
<Fragment>
|
173
|
|
|
<PageHeader
|
174
|
|
|
title="React Beautiful DnD"
|
175
|
|
|
description="Intuitive to use.
|
176
|
|
|
Compatible for Bootstrap 3 and 4.
|
177
|
|
|
Better than legacy react-bootstrap-table!!. It has Rich Functionality - Sortable, Row Selection, Cell Editor, Row Expand, Column Filter Pagination etc. Easy to Configurable and customizable table."
|
178
|
|
|
className="mb-3"
|
179
|
|
|
>
|
180
|
|
|
<Button
|
181
|
|
|
tag="a"
|
182
|
|
|
href="https://github.com/atlassian/react-beautiful-dnd"
|
183
|
|
|
target="_blank"
|
184
|
|
|
color="link"
|
185
|
|
|
size="sm"
|
186
|
|
|
className="pl-0"
|
187
|
|
|
>
|
188
|
|
|
React Beautiful DnD Documentation
|
189
|
|
|
<FontAwesomeIcon icon="chevron-right" className="ml-1 fs--2" />
|
190
|
|
|
</Button>
|
191
|
|
|
</PageHeader>
|
192
|
|
|
<Card>
|
193
|
|
|
<CardHeader className="bg-light">
|
194
|
|
|
<h4 className="mb-0">Example</h4>
|
195
|
|
|
</CardHeader>
|
196
|
|
|
<CardBody>
|
197
|
|
|
<Row>
|
198
|
|
|
<Col>
|
199
|
|
|
<FalconEditor
|
200
|
|
|
code={DragAndDropCode}
|
201
|
|
|
scope={{ DragDropContext, Droppable, Draggable, data, setData, onDragEnd, getListStyle, getItemStyle }}
|
202
|
|
|
language="jsx"
|
203
|
|
|
/>
|
204
|
|
|
{/* <PurchasesTable /> */}
|
205
|
|
|
</Col>
|
206
|
|
|
</Row>
|
207
|
|
|
</CardBody>
|
208
|
|
|
</Card>
|
209
|
|
|
</Fragment>
|
210
|
|
|
);
|
211
|
|
|
};
|
212
|
|
|
|
213
|
|
|
export default ReactBootstrapTable2;
|
214
|
|
|
|