@teselagen/ui 0.10.5 → 0.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DataTable/DisplayOptions.d.ts +2 -1
- package/DataTable/DraggableColumnOptions.d.ts +7 -0
- package/DataTable/SortableColumns.d.ts +2 -1
- package/DataTable/ThComponent.d.ts +2 -1
- package/DataTable/dragNoticeEl.d.ts +1 -0
- package/DataTable/viewColumn.d.ts +0 -2
- package/index.cjs.js +1647 -1514
- package/index.es.js +546 -413
- package/package.json +1 -1
- package/src/DataTable/Columns.js +12 -4
- package/src/DataTable/DisplayOptions.js +27 -122
- package/src/DataTable/DraggableColumnOptions.js +176 -0
- package/src/DataTable/SortableColumns.js +38 -26
- package/src/DataTable/ThComponent.js +22 -9
- package/src/DataTable/dragNoticeEl.js +13 -0
- package/src/DataTable/index.js +65 -129
- package/src/DataTable/style.css +13 -0
- package/src/DataTable/utils/queryParams.js +6 -1
- package/src/DataTable/utils/tableQueryParamsToHasuraClauses.js +179 -147
- package/src/DataTable/utils/withTableParams.js +2 -3
- package/src/DataTable/viewColumn.js +0 -1
- package/src/TgSelect/index.js +1 -0
- package/ui.css +13 -0
package/package.json
CHANGED
package/src/DataTable/Columns.js
CHANGED
|
@@ -9,7 +9,8 @@ import {
|
|
|
9
9
|
noop,
|
|
10
10
|
cloneDeep,
|
|
11
11
|
get,
|
|
12
|
-
padStart
|
|
12
|
+
padStart,
|
|
13
|
+
flatMap
|
|
13
14
|
} from "lodash-es";
|
|
14
15
|
import dayjs from "dayjs";
|
|
15
16
|
import localizedFormat from "dayjs/plugin/localizedFormat";
|
|
@@ -38,6 +39,7 @@ import { change as _change } from "redux-form";
|
|
|
38
39
|
import { RenderCell } from "./RenderCell";
|
|
39
40
|
import { getCCDisplayName } from "./utils/tableQueryParamsToHasuraClauses";
|
|
40
41
|
import { showContextMenu } from "../utils/menuUtils";
|
|
42
|
+
import { dragNoticeEl } from "./dragNoticeEl";
|
|
41
43
|
|
|
42
44
|
dayjs.extend(localizedFormat);
|
|
43
45
|
|
|
@@ -177,6 +179,7 @@ const RenderColumnHeader = ({
|
|
|
177
179
|
e.persist();
|
|
178
180
|
showContextMenu(
|
|
179
181
|
[
|
|
182
|
+
dragNoticeEl,
|
|
180
183
|
{
|
|
181
184
|
text: "Hide Column",
|
|
182
185
|
disabled: onlyOneVisibleColumn,
|
|
@@ -917,7 +920,10 @@ export const useColumns = ({
|
|
|
917
920
|
});
|
|
918
921
|
}
|
|
919
922
|
|
|
920
|
-
const tableColumns = columns
|
|
923
|
+
const tableColumns = flatMap(columns, column => {
|
|
924
|
+
if (column.isHidden) {
|
|
925
|
+
return [];
|
|
926
|
+
}
|
|
921
927
|
const tableColumn = {
|
|
922
928
|
...column,
|
|
923
929
|
Header: RenderColumnHeader({
|
|
@@ -950,8 +956,10 @@ export const useColumns = ({
|
|
|
950
956
|
getHeaderProps: () => ({
|
|
951
957
|
// needs to be a string because it is getting passed
|
|
952
958
|
// to the dom
|
|
953
|
-
immovable:
|
|
954
|
-
|
|
959
|
+
immovable:
|
|
960
|
+
column.type === "action" || column.immovable ? "true" : "false",
|
|
961
|
+
columnindex: column.columnIndex,
|
|
962
|
+
path: column.path
|
|
955
963
|
})
|
|
956
964
|
};
|
|
957
965
|
const noEllipsis = column.noEllipsis;
|
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
Button,
|
|
5
|
-
Checkbox,
|
|
6
|
-
Menu,
|
|
7
|
-
MenuItem,
|
|
8
|
-
Classes,
|
|
9
|
-
InputGroup,
|
|
10
|
-
Popover,
|
|
11
|
-
Switch
|
|
12
|
-
} from "@blueprintjs/core";
|
|
13
|
-
import { getCCDisplayName } from "./utils/tableQueryParamsToHasuraClauses";
|
|
2
|
+
import { noop } from "lodash-es";
|
|
3
|
+
import { Button, Menu, Classes, Popover, Switch } from "@blueprintjs/core";
|
|
14
4
|
import InfoHelper from "../InfoHelper";
|
|
5
|
+
import DraggableColumnOptions from "./DraggableColumnOptions";
|
|
6
|
+
import { dragNoticeEl } from "./dragNoticeEl";
|
|
15
7
|
|
|
16
8
|
const DisplayOptions = ({
|
|
17
9
|
compact,
|
|
@@ -22,13 +14,13 @@ const DisplayOptions = ({
|
|
|
22
14
|
resetDefaultVisibility = noop,
|
|
23
15
|
updateColumnVisibility = noop,
|
|
24
16
|
updateTableDisplayDensity,
|
|
17
|
+
moveColumnPersist = noop,
|
|
25
18
|
showForcedHiddenColumns,
|
|
26
19
|
setShowForcedHidden,
|
|
27
20
|
hasOptionForForcedHidden,
|
|
28
21
|
schema
|
|
29
22
|
}) => {
|
|
30
23
|
const [isOpen, setIsOpen] = useState(false);
|
|
31
|
-
const [searchTerms, setSearchTerms] = useState({});
|
|
32
24
|
|
|
33
25
|
const changeTableDensity = e => {
|
|
34
26
|
updateTableDisplayDensity(e.target.value);
|
|
@@ -41,99 +33,13 @@ const DisplayOptions = ({
|
|
|
41
33
|
return null; //don't show antyhing!
|
|
42
34
|
}
|
|
43
35
|
const { fields } = schema;
|
|
44
|
-
const fieldGroups = {};
|
|
45
|
-
const mainFields = [];
|
|
46
|
-
|
|
47
|
-
fields.forEach(field => {
|
|
48
|
-
if (field.hideInMenu) return;
|
|
49
|
-
if (!field.fieldGroup) return mainFields.push(field);
|
|
50
|
-
if (!fieldGroups[field.fieldGroup]) fieldGroups[field.fieldGroup] = [];
|
|
51
|
-
fieldGroups[field.fieldGroup].push(field);
|
|
52
|
-
});
|
|
53
36
|
|
|
54
37
|
let numVisible = 0;
|
|
55
38
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<Checkbox
|
|
62
|
-
name={`${path}-${i}`}
|
|
63
|
-
key={path || i}
|
|
64
|
-
onChange={() => {
|
|
65
|
-
if (numVisible <= 1 && !isHidden) {
|
|
66
|
-
return window.toastr.warning(
|
|
67
|
-
"We have to display at least one column :)"
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
updateColumnVisibility({ shouldShow: isHidden, path });
|
|
71
|
-
}}
|
|
72
|
-
checked={!isHidden}
|
|
73
|
-
label={
|
|
74
|
-
<span style={{ display: "flex", marginTop: -17 }}>
|
|
75
|
-
{displayName}
|
|
76
|
-
{subFrag && (
|
|
77
|
-
<InfoHelper
|
|
78
|
-
icon="warning-sign"
|
|
79
|
-
intent="warning"
|
|
80
|
-
style={{ marginLeft: 5 }}
|
|
81
|
-
>
|
|
82
|
-
Viewing this column may cause the table to load slower
|
|
83
|
-
</InfoHelper>
|
|
84
|
-
)}
|
|
85
|
-
</span>
|
|
86
|
-
}
|
|
87
|
-
/>
|
|
88
|
-
);
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
let fieldGroupMenu;
|
|
92
|
-
if (!isEmpty(fieldGroups)) {
|
|
93
|
-
fieldGroupMenu = map(fieldGroups, (groupFields, groupName) => {
|
|
94
|
-
const searchTerm = searchTerms[groupName] || "";
|
|
95
|
-
const anyVisible = groupFields.some(
|
|
96
|
-
field => !field.isHidden && !field.isForcedHidden
|
|
97
|
-
);
|
|
98
|
-
const anyNotForcedHidden = groupFields.some(
|
|
99
|
-
field => !field.isForcedHidden
|
|
100
|
-
);
|
|
101
|
-
if (!anyNotForcedHidden) return;
|
|
102
|
-
return (
|
|
103
|
-
<MenuItem key={groupName} text={groupName}>
|
|
104
|
-
<InputGroup
|
|
105
|
-
leftIcon="search"
|
|
106
|
-
value={searchTerm}
|
|
107
|
-
onChange={e => {
|
|
108
|
-
setSearchTerms(prev => ({
|
|
109
|
-
...prev,
|
|
110
|
-
[groupName]: e.target.value
|
|
111
|
-
}));
|
|
112
|
-
}}
|
|
113
|
-
/>
|
|
114
|
-
<Button
|
|
115
|
-
className={Classes.MINIMAL}
|
|
116
|
-
text={(anyVisible ? "Hide" : "Show") + " All"}
|
|
117
|
-
style={{ margin: "10px 0" }}
|
|
118
|
-
onClick={() => {
|
|
119
|
-
updateColumnVisibility({
|
|
120
|
-
shouldShow: !anyVisible,
|
|
121
|
-
paths: groupFields.map(field => field.path)
|
|
122
|
-
});
|
|
123
|
-
}}
|
|
124
|
-
/>
|
|
125
|
-
{groupFields
|
|
126
|
-
.filter(
|
|
127
|
-
field =>
|
|
128
|
-
startCase(getCCDisplayName(field)) // We have to use startCase with the camelCase here because the displayName is not always a string
|
|
129
|
-
.toLowerCase()
|
|
130
|
-
.indexOf(searchTerm.toLowerCase()) > -1
|
|
131
|
-
)
|
|
132
|
-
.map(getFieldCheckbox)}
|
|
133
|
-
</MenuItem>
|
|
134
|
-
);
|
|
135
|
-
});
|
|
136
|
-
}
|
|
39
|
+
// Count number of visible fields
|
|
40
|
+
fields.forEach(field => {
|
|
41
|
+
if (!field.isHidden && field.type !== "action") numVisible++;
|
|
42
|
+
});
|
|
137
43
|
|
|
138
44
|
return (
|
|
139
45
|
<Popover
|
|
@@ -170,7 +76,7 @@ const DisplayOptions = ({
|
|
|
170
76
|
<h5
|
|
171
77
|
style={{
|
|
172
78
|
fontWeight: "bold",
|
|
173
|
-
marginBottom:
|
|
79
|
+
marginBottom: 0,
|
|
174
80
|
marginTop: 10,
|
|
175
81
|
display: "flex"
|
|
176
82
|
}}
|
|
@@ -183,10 +89,16 @@ const DisplayOptions = ({
|
|
|
183
89
|
</InfoHelper>
|
|
184
90
|
)}
|
|
185
91
|
</h5>
|
|
186
|
-
|
|
187
|
-
|
|
92
|
+
{dragNoticeEl}
|
|
93
|
+
|
|
94
|
+
<div style={{ maxHeight: 360, overflowY: "auto", padding: 2 }}>
|
|
95
|
+
<DraggableColumnOptions
|
|
96
|
+
fields={fields}
|
|
97
|
+
onVisibilityChange={updateColumnVisibility}
|
|
98
|
+
moveColumnPersist={moveColumnPersist}
|
|
99
|
+
numVisible={numVisible}
|
|
100
|
+
/>
|
|
188
101
|
</div>
|
|
189
|
-
<div>{fieldGroupMenu}</div>
|
|
190
102
|
{hasOptionForForcedHidden && (
|
|
191
103
|
<div style={{ marginTop: 15 }}>
|
|
192
104
|
<Switch
|
|
@@ -196,22 +108,15 @@ const DisplayOptions = ({
|
|
|
196
108
|
/>
|
|
197
109
|
</div>
|
|
198
110
|
)}
|
|
199
|
-
<
|
|
200
|
-
style={{
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
111
|
+
<Button
|
|
112
|
+
style={{ marginTop: 5 }}
|
|
113
|
+
onClick={resetDefaultVisibility}
|
|
114
|
+
title="Display Options"
|
|
115
|
+
icon="reset"
|
|
116
|
+
minimal
|
|
205
117
|
>
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
title="Display Options"
|
|
209
|
-
icon="reset"
|
|
210
|
-
minimal
|
|
211
|
-
>
|
|
212
|
-
Reset Column Visibilites
|
|
213
|
-
</Button>
|
|
214
|
-
</div>
|
|
118
|
+
Reset Column Visibilites
|
|
119
|
+
</Button>
|
|
215
120
|
</div>
|
|
216
121
|
</Menu>
|
|
217
122
|
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
|
+
import { DndContext, MouseSensor, useSensor, useSensors } from "@dnd-kit/core";
|
|
3
|
+
import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
|
|
4
|
+
import {
|
|
5
|
+
SortableContext,
|
|
6
|
+
verticalListSortingStrategy,
|
|
7
|
+
useSortable,
|
|
8
|
+
arrayMove
|
|
9
|
+
} from "@dnd-kit/sortable";
|
|
10
|
+
import { CSS } from "@dnd-kit/utilities";
|
|
11
|
+
import { Checkbox, Classes } from "@blueprintjs/core";
|
|
12
|
+
import InfoHelper from "../InfoHelper";
|
|
13
|
+
|
|
14
|
+
const DraggableColumnOption = ({
|
|
15
|
+
field,
|
|
16
|
+
index,
|
|
17
|
+
onVisibilityChange,
|
|
18
|
+
numVisible
|
|
19
|
+
}) => {
|
|
20
|
+
const { displayName, isHidden, path, subFrag, immovable, type } = field;
|
|
21
|
+
|
|
22
|
+
const { attributes, listeners, setNodeRef, transform, transition } =
|
|
23
|
+
useSortable({
|
|
24
|
+
id: path,
|
|
25
|
+
disabled: immovable === "true"
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (type === "action") {
|
|
29
|
+
return null; // Skip action columns
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const style = {
|
|
33
|
+
transform: CSS.Transform.toString(transform),
|
|
34
|
+
transition,
|
|
35
|
+
cursor: "grab",
|
|
36
|
+
marginBottom: 5
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div
|
|
41
|
+
ref={setNodeRef}
|
|
42
|
+
style={style}
|
|
43
|
+
className="SortableItem"
|
|
44
|
+
data-path={path}
|
|
45
|
+
{...attributes}
|
|
46
|
+
{...listeners}
|
|
47
|
+
>
|
|
48
|
+
<Checkbox
|
|
49
|
+
name={`${path}-${index}`}
|
|
50
|
+
key={index}
|
|
51
|
+
onChange={() => {
|
|
52
|
+
if (numVisible <= 1 && !isHidden) {
|
|
53
|
+
return window.toastr.warning(
|
|
54
|
+
"We have to display at least one column :)"
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
onVisibilityChange({ shouldShow: isHidden, path });
|
|
58
|
+
}}
|
|
59
|
+
checked={!isHidden}
|
|
60
|
+
label={
|
|
61
|
+
<span style={{ display: "flex", marginTop: -17 }}>
|
|
62
|
+
{displayName}{" "}
|
|
63
|
+
{field.fieldGroup && (
|
|
64
|
+
<span
|
|
65
|
+
style={{ fontSize: 10, marginLeft: 5, marginTop: 2 }}
|
|
66
|
+
className={Classes.TEXT_MUTED}
|
|
67
|
+
>
|
|
68
|
+
({field.fieldGroup})
|
|
69
|
+
</span>
|
|
70
|
+
)}
|
|
71
|
+
{subFrag && (
|
|
72
|
+
<InfoHelper
|
|
73
|
+
icon="warning-sign"
|
|
74
|
+
intent="warning"
|
|
75
|
+
style={{ marginLeft: 5 }}
|
|
76
|
+
>
|
|
77
|
+
Viewing this column may cause the table to load slower
|
|
78
|
+
</InfoHelper>
|
|
79
|
+
)}
|
|
80
|
+
</span>
|
|
81
|
+
}
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const DraggableColumnOptions = ({
|
|
88
|
+
fields,
|
|
89
|
+
onVisibilityChange,
|
|
90
|
+
moveColumnPersist,
|
|
91
|
+
numVisible
|
|
92
|
+
}) => {
|
|
93
|
+
const [sortedFields, setSortedFields] = useState(fields);
|
|
94
|
+
|
|
95
|
+
// Update sorted fields when external fields change
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
setSortedFields(fields);
|
|
98
|
+
}, [fields]);
|
|
99
|
+
|
|
100
|
+
const mouseSensor = useSensor(MouseSensor, {
|
|
101
|
+
activationConstraint: {
|
|
102
|
+
distance: 5
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const sensors = useSensors(mouseSensor);
|
|
107
|
+
|
|
108
|
+
const handleDragStart = event => {
|
|
109
|
+
// Add a class to the body to indicate dragging state
|
|
110
|
+
document.body.classList.add("column-dragging");
|
|
111
|
+
|
|
112
|
+
// Add a class to the active drag item
|
|
113
|
+
const { active } = event;
|
|
114
|
+
if (active) {
|
|
115
|
+
const activeNode = document.querySelector(`[data-path="${active.id}"]`);
|
|
116
|
+
if (activeNode) {
|
|
117
|
+
activeNode.classList.add("dragging");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const handleDragEnd = event => {
|
|
123
|
+
// Remove the dragging class
|
|
124
|
+
document.body.classList.remove("column-dragging");
|
|
125
|
+
|
|
126
|
+
// Remove the class from the active drag item
|
|
127
|
+
const draggingItem = document.querySelector(".SortableItem.dragging");
|
|
128
|
+
if (draggingItem) {
|
|
129
|
+
draggingItem.classList.remove("dragging");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const { active, over } = event;
|
|
133
|
+
|
|
134
|
+
if (!over || !active || active.id === over.id) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const oldIndex = sortedFields.findIndex(f => f.path === active.id);
|
|
139
|
+
const newIndex = sortedFields.findIndex(f => f.path === over.id);
|
|
140
|
+
|
|
141
|
+
// Update the local state immediately for a smooth UI
|
|
142
|
+
const newSortedFields = arrayMove(sortedFields, oldIndex, newIndex);
|
|
143
|
+
setSortedFields(newSortedFields);
|
|
144
|
+
|
|
145
|
+
// Notify parent component to persist the change
|
|
146
|
+
moveColumnPersist({ oldIndex, newIndex });
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<DndContext
|
|
151
|
+
sensors={sensors}
|
|
152
|
+
modifiers={[restrictToVerticalAxis]}
|
|
153
|
+
onDragStart={handleDragStart}
|
|
154
|
+
onDragEnd={handleDragEnd}
|
|
155
|
+
>
|
|
156
|
+
<SortableContext
|
|
157
|
+
items={sortedFields.map(field => field.path)}
|
|
158
|
+
strategy={verticalListSortingStrategy}
|
|
159
|
+
>
|
|
160
|
+
<div>
|
|
161
|
+
{sortedFields.map((field, index) => (
|
|
162
|
+
<DraggableColumnOption
|
|
163
|
+
key={field.path || index}
|
|
164
|
+
field={field}
|
|
165
|
+
index={index}
|
|
166
|
+
onVisibilityChange={onVisibilityChange}
|
|
167
|
+
numVisible={numVisible}
|
|
168
|
+
/>
|
|
169
|
+
))}
|
|
170
|
+
</div>
|
|
171
|
+
</SortableContext>
|
|
172
|
+
</DndContext>
|
|
173
|
+
);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export default DraggableColumnOptions;
|
|
@@ -1,21 +1,34 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
2
|
import { MouseSensor, useSensor, useSensors, DndContext } from "@dnd-kit/core";
|
|
3
3
|
import {
|
|
4
4
|
SortableContext,
|
|
5
|
-
horizontalListSortingStrategy
|
|
5
|
+
horizontalListSortingStrategy,
|
|
6
|
+
arrayMove as dndArrayMove
|
|
6
7
|
} from "@dnd-kit/sortable";
|
|
7
8
|
import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
|
|
8
9
|
|
|
9
10
|
const CustomTheadComponent = ({
|
|
10
11
|
children: _children,
|
|
11
12
|
className,
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
moveColumn,
|
|
14
|
+
sortedItemsFull,
|
|
14
15
|
style
|
|
15
16
|
}) => {
|
|
16
17
|
// We need to do this because react table gives the children wrapped
|
|
17
18
|
// in another component
|
|
18
19
|
const children = _children.props.children;
|
|
20
|
+
const [sortedItems, setSortedItems] = useState(() =>
|
|
21
|
+
children.map(c => {
|
|
22
|
+
// Use the path as the ID for sorting instead of the index
|
|
23
|
+
return c.props.path || c.key.split("-")[1];
|
|
24
|
+
})
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// Update local state when children change
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
setSortedItems(children.map(c => c.props.path || c.key.split("-")[1]));
|
|
30
|
+
}, [children]);
|
|
31
|
+
|
|
19
32
|
const mouseSensor = useSensor(MouseSensor, {
|
|
20
33
|
activationConstraint: {
|
|
21
34
|
distance: 10
|
|
@@ -34,15 +47,21 @@ const CustomTheadComponent = ({
|
|
|
34
47
|
return;
|
|
35
48
|
}
|
|
36
49
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
50
|
+
// Update local state immediately for smooth UI
|
|
51
|
+
// Use path ID directly instead of parsing as integer
|
|
52
|
+
const oldPath = active.id;
|
|
53
|
+
const newPath = over.id;
|
|
54
|
+
const oldIndex = sortedItemsFull.indexOf(oldPath);
|
|
55
|
+
const newIndex = sortedItemsFull.indexOf(newPath);
|
|
56
|
+
const newSortedItems = dndArrayMove(sortedItemsFull, oldIndex, newIndex);
|
|
57
|
+
setSortedItems(newSortedItems);
|
|
58
|
+
|
|
59
|
+
// Pass to parent for persistence
|
|
60
|
+
moveColumn({ oldIndex, newIndex });
|
|
41
61
|
};
|
|
42
62
|
|
|
43
63
|
return (
|
|
44
64
|
<DndContext
|
|
45
|
-
onDragStart={onSortStart}
|
|
46
65
|
onDragEnd={handleDragEnd}
|
|
47
66
|
modifiers={[restrictToHorizontalAxis]}
|
|
48
67
|
sensors={sensors}
|
|
@@ -50,7 +69,7 @@ const CustomTheadComponent = ({
|
|
|
50
69
|
<div className={"rt-thead " + className} style={style}>
|
|
51
70
|
<div className="rt-tr">
|
|
52
71
|
<SortableContext
|
|
53
|
-
items={
|
|
72
|
+
items={sortedItems}
|
|
54
73
|
strategy={horizontalListSortingStrategy}
|
|
55
74
|
>
|
|
56
75
|
{children}
|
|
@@ -61,7 +80,13 @@ const CustomTheadComponent = ({
|
|
|
61
80
|
);
|
|
62
81
|
};
|
|
63
82
|
|
|
64
|
-
const SortableColumns = ({
|
|
83
|
+
const SortableColumns = ({
|
|
84
|
+
className,
|
|
85
|
+
style,
|
|
86
|
+
children,
|
|
87
|
+
moveColumn,
|
|
88
|
+
sortedItemsFull
|
|
89
|
+
}) => {
|
|
65
90
|
const shouldCancelStart = e => {
|
|
66
91
|
const className = e.target.className;
|
|
67
92
|
// if its an svg then it's a blueprint icon
|
|
@@ -70,25 +95,12 @@ const SortableColumns = ({ className, style, children, moveColumn }) => {
|
|
|
70
95
|
);
|
|
71
96
|
};
|
|
72
97
|
|
|
73
|
-
const onSortEnd = (...args) => {
|
|
74
|
-
const { oldIndex, newIndex } = args[0];
|
|
75
|
-
document.body.classList.remove("drag-active");
|
|
76
|
-
moveColumn({
|
|
77
|
-
oldIndex,
|
|
78
|
-
newIndex
|
|
79
|
-
});
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
const onSortStart = () => {
|
|
83
|
-
document.body.classList.add("drag-active");
|
|
84
|
-
};
|
|
85
|
-
|
|
86
98
|
return (
|
|
87
99
|
<CustomTheadComponent
|
|
88
100
|
className={className}
|
|
89
101
|
style={style}
|
|
90
|
-
|
|
91
|
-
|
|
102
|
+
sortedItemsFull={sortedItemsFull}
|
|
103
|
+
moveColumn={moveColumn}
|
|
92
104
|
helperClass="above-dialog"
|
|
93
105
|
shouldCancelStart={shouldCancelStart}
|
|
94
106
|
>
|
|
@@ -9,19 +9,31 @@ export const ThComponent = ({
|
|
|
9
9
|
className,
|
|
10
10
|
children,
|
|
11
11
|
style,
|
|
12
|
+
path,
|
|
12
13
|
columnindex,
|
|
13
14
|
...rest
|
|
14
15
|
}) => {
|
|
15
|
-
const index = columnindex
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
const index = columnindex ? path : -1;
|
|
17
|
+
const disabled = !path || immovable === "true" || immovable === true;
|
|
18
|
+
const {
|
|
19
|
+
attributes,
|
|
20
|
+
listeners,
|
|
21
|
+
setNodeRef,
|
|
22
|
+
transform,
|
|
23
|
+
transition,
|
|
24
|
+
isDragging: _isDragging
|
|
25
|
+
} = useSortable({
|
|
26
|
+
id: path,
|
|
27
|
+
disabled
|
|
28
|
+
});
|
|
29
|
+
const isDragging = _isDragging && !disabled;
|
|
30
|
+
if (transform) {
|
|
31
|
+
transform.scaleX = 1; // Prevent column header from shrinking/expanding during drag (looks bad)
|
|
32
|
+
}
|
|
22
33
|
const sortStyles = {
|
|
23
34
|
transform: CSS.Transform.toString(transform),
|
|
24
|
-
transition
|
|
35
|
+
transition,
|
|
36
|
+
zIndex: isDragging ? 999 : undefined
|
|
25
37
|
};
|
|
26
38
|
|
|
27
39
|
return (
|
|
@@ -30,11 +42,12 @@ export const ThComponent = ({
|
|
|
30
42
|
ref={setNodeRef}
|
|
31
43
|
{...attributes}
|
|
32
44
|
{...listeners}
|
|
33
|
-
className={classNames("rt-th", className)}
|
|
45
|
+
className={classNames("rt-th", className, { "th-dragging": isDragging })}
|
|
34
46
|
onClick={e => toggleSort && toggleSort(e)}
|
|
35
47
|
role="columnheader"
|
|
36
48
|
tabIndex="-1" // Resolves eslint issues without implementing keyboard navigation incorrectly
|
|
37
49
|
columnindex={columnindex}
|
|
50
|
+
path={path}
|
|
38
51
|
index={index}
|
|
39
52
|
{...rest}
|
|
40
53
|
>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Classes, Icon } from "@blueprintjs/core";
|
|
2
|
+
|
|
3
|
+
export const dragNoticeEl = (
|
|
4
|
+
<div
|
|
5
|
+
className={Classes.TEXT_MUTED}
|
|
6
|
+
style={{
|
|
7
|
+
padding: 10,
|
|
8
|
+
fontSize: "12px"
|
|
9
|
+
}}
|
|
10
|
+
>
|
|
11
|
+
<Icon icon="info-sign" size={12} /> Drag columns to reorder them
|
|
12
|
+
</div>
|
|
13
|
+
);
|