@teselagen/ui 0.7.33-beta.5 → 0.7.33

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.
Files changed (119) hide show
  1. package/AdvancedOptions.js +33 -0
  2. package/AssignDefaultsModeContext.js +22 -0
  3. package/CellDragHandle.js +132 -0
  4. package/ColumnFilterMenu.js +62 -0
  5. package/Columns.js +979 -0
  6. package/DataTable/utils/queryParams.d.ts +18 -9
  7. package/DisabledLoadingComponent.js +15 -0
  8. package/DisplayOptions.js +199 -0
  9. package/DropdownButton.js +36 -0
  10. package/DropdownCell.js +61 -0
  11. package/EditableCell.js +44 -0
  12. package/FillWindow.css +6 -0
  13. package/FillWindow.js +69 -0
  14. package/FilterAndSortMenu.js +391 -0
  15. package/FormSeparator.js +9 -0
  16. package/LoadingDots.js +14 -0
  17. package/MatchHeaders.js +234 -0
  18. package/PagingTool.js +225 -0
  19. package/RenderCell.js +191 -0
  20. package/SearchBar.js +69 -0
  21. package/SimpleStepViz.js +22 -0
  22. package/SortableColumns.js +100 -0
  23. package/TableFormTrackerContext.js +10 -0
  24. package/Tag.js +112 -0
  25. package/ThComponent.js +44 -0
  26. package/TimelineEvent.js +31 -0
  27. package/UploadCsvWizard.css +4 -0
  28. package/UploadCsvWizard.js +719 -0
  29. package/Uploader.js +1278 -0
  30. package/adHoc.js +10 -0
  31. package/autoTooltip.js +201 -0
  32. package/basicHandleActionsWithFullState.js +14 -0
  33. package/browserUtils.js +3 -0
  34. package/combineReducersWithFullState.js +14 -0
  35. package/commandControls.js +82 -0
  36. package/commandUtils.js +112 -0
  37. package/constants.js +1 -0
  38. package/convertSchema.js +69 -0
  39. package/customIcons.js +361 -0
  40. package/dataTableEnhancer.js +41 -0
  41. package/defaultFormatters.js +32 -0
  42. package/defaultValidators.js +40 -0
  43. package/determineBlackOrWhiteTextColor.js +4 -0
  44. package/editCellHelper.js +44 -0
  45. package/formatPasteData.js +16 -0
  46. package/getAllRows.js +11 -0
  47. package/getCellCopyText.js +7 -0
  48. package/getCellInfo.js +36 -0
  49. package/getCellVal.js +20 -0
  50. package/getDayjsFormatter.js +35 -0
  51. package/getFieldPathToField.js +7 -0
  52. package/getIdOrCodeOrIndex.js +9 -0
  53. package/getLastSelectedEntity.js +11 -0
  54. package/getNewEntToSelect.js +25 -0
  55. package/getNewName.js +31 -0
  56. package/getRowCopyText.js +28 -0
  57. package/getTableConfigFromStorage.js +5 -0
  58. package/getTextFromEl.js +28 -0
  59. package/getVals.js +8 -0
  60. package/handleCopyColumn.js +21 -0
  61. package/handleCopyHelper.js +15 -0
  62. package/handleCopyRows.js +23 -0
  63. package/handleCopyTable.js +16 -0
  64. package/handlerHelpers.js +24 -0
  65. package/hotkeyUtils.js +131 -0
  66. package/index.cjs.js +970 -826
  67. package/index.d.ts +0 -1
  68. package/index.es.js +970 -826
  69. package/index.js +196 -0
  70. package/isBeingCalledExcessively.js +31 -0
  71. package/isBottomRightCornerOfRectangle.js +20 -0
  72. package/isEntityClean.js +15 -0
  73. package/isTruthy.js +12 -0
  74. package/isValueEmpty.js +3 -0
  75. package/itemUpload.js +84 -0
  76. package/menuUtils.js +433 -0
  77. package/package.json +1 -2
  78. package/popoverOverflowModifiers.js +11 -0
  79. package/primarySelectedValue.js +1 -0
  80. package/pureNoFunc.js +31 -0
  81. package/queryParams.js +1058 -0
  82. package/removeCleanRows.js +22 -0
  83. package/renderOnDoc.js +32 -0
  84. package/rerenderOnWindowResize.js +26 -0
  85. package/rowClick.js +181 -0
  86. package/selection.js +8 -0
  87. package/showAppSpinner.js +12 -0
  88. package/showDialogOnDocBody.js +33 -0
  89. package/showProgressToast.js +22 -0
  90. package/sortify.js +73 -0
  91. package/src/DataTable/index.js +1 -1
  92. package/src/DataTable/utils/filterLocalEntitiesToHasura.js +14 -0
  93. package/src/DataTable/utils/filterLocalEntitiesToHasura.test.js +49 -0
  94. package/src/DataTable/utils/queryParams.js +12 -9
  95. package/src/DataTable/utils/tableQueryParamsToHasuraClauses.js +146 -143
  96. package/style.css +29 -0
  97. package/tagUtils.js +45 -0
  98. package/tgFormValues.js +35 -0
  99. package/tg_modalState.js +47 -0
  100. package/throwFormError.js +16 -0
  101. package/toastr.js +148 -0
  102. package/tryToMatchSchemas.js +264 -0
  103. package/typeToCommonType.js +6 -0
  104. package/useDeepEqualMemo.js +15 -0
  105. package/useDialog.js +63 -0
  106. package/useStableReference.js +9 -0
  107. package/useTableEntities.js +38 -0
  108. package/useTraceUpdate.js +19 -0
  109. package/utils.js +37 -0
  110. package/validateTableWideErrors.js +160 -0
  111. package/viewColumn.js +97 -0
  112. package/withField.js +20 -0
  113. package/withFields.js +11 -0
  114. package/withLocalStorage.js +11 -0
  115. package/withSelectTableRecords.js +43 -0
  116. package/withSelectedEntities.js +65 -0
  117. package/withStore.js +10 -0
  118. package/withTableParams.js +301 -0
  119. package/wrapDialog.js +116 -0
package/PagingTool.js ADDED
@@ -0,0 +1,225 @@
1
+ import React, { useState, useEffect, useRef, useCallback } from "react";
2
+ import classNames from "classnames";
3
+ import { noop, get, toInteger } from "lodash-es";
4
+ import { Button, Classes } from "@blueprintjs/core";
5
+ import { onEnterOrBlurHelper } from "../utils/handlerHelpers";
6
+ import { defaultPageSizes } from "./utils/queryParams";
7
+ import { getIdOrCodeOrIndex } from "./utils";
8
+
9
+ function PagingInput({ disabled, onBlur, defaultPage }) {
10
+ const [page, setPage] = useState(defaultPage);
11
+ const defaultValue = useRef(defaultPage);
12
+
13
+ useEffect(() => {
14
+ if (page !== defaultPage && defaultValue.current !== defaultPage) {
15
+ setPage(defaultPage);
16
+ }
17
+ defaultValue.current = defaultPage;
18
+ }, [page, defaultPage]);
19
+
20
+ return (
21
+ <input
22
+ name="page"
23
+ style={{
24
+ marginLeft: 5,
25
+ width: page > 999 ? 65 : page > 99 ? 45 : 35,
26
+ marginRight: 8
27
+ }}
28
+ value={page}
29
+ disabled={disabled}
30
+ onChange={e => {
31
+ setPage(e.target.value);
32
+ }}
33
+ {...onEnterOrBlurHelper(onBlur)}
34
+ className={Classes.INPUT}
35
+ />
36
+ );
37
+ }
38
+
39
+ // Define the functional component and its props
40
+ const PagingTool = ({
41
+ controlled_hasNextPage,
42
+ controlled_onRefresh,
43
+ controlled_page,
44
+ controlled_setPage,
45
+ controlled_setPageSize,
46
+ controlled_total,
47
+ disabled: _disabled,
48
+ disableSetPageSize,
49
+ entities,
50
+ entityCount,
51
+ hideSetPageSize,
52
+ hideTotalPages,
53
+ keepSelectionOnPageChange,
54
+ onRefresh: _onRefresh,
55
+ page: _page,
56
+ pageSize,
57
+ pagingDisabled,
58
+ persistPageSize = noop,
59
+ scrollToTop,
60
+ setPage: _setPage,
61
+ setPageSize: _setPageSize,
62
+ setSelectedEntityIdMap
63
+ }) => {
64
+ const page = controlled_page || _page;
65
+ const total = controlled_total || entityCount;
66
+ const disabled = _disabled || pagingDisabled;
67
+ const onRefresh = controlled_onRefresh || _onRefresh;
68
+ const setPage = controlled_setPage || _setPage;
69
+ const setPageSize = controlled_setPageSize || _setPageSize;
70
+
71
+ const onPageChange = useCallback(() => {
72
+ const record = get(entities, "[0]");
73
+ if (
74
+ !keepSelectionOnPageChange &&
75
+ (!record || !getIdOrCodeOrIndex(record))
76
+ ) {
77
+ setSelectedEntityIdMap({});
78
+ }
79
+ scrollToTop();
80
+ }, [
81
+ entities,
82
+ keepSelectionOnPageChange,
83
+ scrollToTop,
84
+ setSelectedEntityIdMap
85
+ ]);
86
+ // Define local state
87
+ const [refetching, setRefetching] = useState(false);
88
+
89
+ // Initialize additional page sizes
90
+ useEffect(() => {
91
+ const additionalPageSize =
92
+ window.frontEndConfig && window.frontEndConfig.additionalPageSize
93
+ ? [toInteger(window.frontEndConfig.additionalPageSize)]
94
+ : [];
95
+ window.tgPageSizes = [...defaultPageSizes, ...additionalPageSize];
96
+ }, []);
97
+
98
+ // Define event handlers for the component
99
+ const onRefreshHandler = async () => {
100
+ setRefetching(true);
101
+ await onRefresh();
102
+ setRefetching(false);
103
+ };
104
+
105
+ const setPageHandler = page => {
106
+ setPage(page);
107
+ onPageChange(page);
108
+ };
109
+
110
+ const setPageSizeHandler = e => {
111
+ const newPageSize = parseInt(e.target.value, 10);
112
+ setPageSize(newPageSize);
113
+ persistPageSize(newPageSize);
114
+ };
115
+
116
+ const pageBackHandler = () => {
117
+ setPageHandler(parseInt(page, 10) - 1);
118
+ };
119
+
120
+ const pageForwardHandler = () => {
121
+ setPageHandler(parseInt(page, 10) + 1);
122
+ };
123
+
124
+ const pageInputBlurHandler = e => {
125
+ const lastPage = Math.ceil(total / pageSize);
126
+ const pageValue = parseInt(e.target.value, 10);
127
+ const selectedPage =
128
+ pageValue > lastPage
129
+ ? lastPage
130
+ : pageValue < 1 || isNaN(pageValue)
131
+ ? 1
132
+ : pageValue;
133
+ setPageHandler(selectedPage);
134
+ };
135
+
136
+ // Define rendering logic
137
+ const pageStart = (page - 1) * pageSize + 1;
138
+ if (pageStart < 0) throw new Error("We should never have page be <0");
139
+ const backEnabled = page - 1 > 0;
140
+ const forwardEnabled = page * pageSize < total;
141
+ const lastPage = Math.ceil(total / pageSize);
142
+ const options = [...(window.tgPageSizes || defaultPageSizes)];
143
+ if (!options.includes(pageSize)) {
144
+ options.push(pageSize);
145
+ }
146
+
147
+ return (
148
+ <div className="paging-toolbar-container">
149
+ {onRefresh && (
150
+ <Button
151
+ minimal
152
+ loading={refetching}
153
+ icon="refresh"
154
+ disabled={disabled}
155
+ onClick={onRefreshHandler}
156
+ />
157
+ )}
158
+ {!hideSetPageSize && (
159
+ <div
160
+ title="Set Page Size"
161
+ className={classNames(Classes.SELECT, Classes.MINIMAL)}
162
+ >
163
+ <select
164
+ name="page-size"
165
+ className="paging-page-size"
166
+ onChange={setPageSizeHandler}
167
+ disabled={disabled || disableSetPageSize}
168
+ value={pageSize}
169
+ >
170
+ {[
171
+ <option key="page-size-placeholder" disabled value="fake">
172
+ Size
173
+ </option>,
174
+ ...options.map(size => {
175
+ return (
176
+ <option key={size} value={size}>
177
+ {size}
178
+ </option>
179
+ );
180
+ })
181
+ ]}
182
+ </select>
183
+ </div>
184
+ )}
185
+ <Button
186
+ onClick={pageBackHandler}
187
+ disabled={!backEnabled || disabled}
188
+ minimal
189
+ className="paging-arrow-left"
190
+ icon="chevron-left"
191
+ />
192
+ <div>
193
+ {hideTotalPages ? (
194
+ page
195
+ ) : total ? (
196
+ <div>
197
+ <PagingInput
198
+ disabled={disabled}
199
+ onBlur={pageInputBlurHandler}
200
+ defaultPage={page}
201
+ lastPage={lastPage}
202
+ />
203
+ of {lastPage}
204
+ </div>
205
+ ) : (
206
+ "No Rows"
207
+ )}
208
+ </div>
209
+ <Button
210
+ style={{ marginLeft: 5 }}
211
+ disabled={
212
+ (controlled_hasNextPage === undefined
213
+ ? !forwardEnabled
214
+ : !controlled_hasNextPage) || disabled
215
+ }
216
+ icon="chevron-right"
217
+ minimal
218
+ className="paging-arrow-right"
219
+ onClick={pageForwardHandler}
220
+ />
221
+ </div>
222
+ );
223
+ };
224
+
225
+ export default PagingTool;
package/RenderCell.js ADDED
@@ -0,0 +1,191 @@
1
+ import React from "react";
2
+ import { useSelector } from "react-redux";
3
+ import { Checkbox, Icon } from "@blueprintjs/core";
4
+ import {
5
+ getIdOrCodeOrIndex,
6
+ isBottomRightCornerOfRectangle,
7
+ PRIMARY_SELECTED_VAL
8
+ } from "./utils";
9
+ import { DropdownCell } from "./DropdownCell";
10
+ import { EditableCell } from "./EditableCell";
11
+ import { getVals } from "./getVals";
12
+ import { CellDragHandle } from "./CellDragHandle";
13
+
14
+ export const RenderCell = ({
15
+ oldFunc,
16
+ getCopyTextForCell,
17
+ column,
18
+ isCellEditable,
19
+ isEntityDisabled,
20
+ finishCellEdit,
21
+ formName,
22
+ noEllipsis,
23
+ cancelCellEdit,
24
+ getCellHoverText,
25
+ selectedCells,
26
+ isSelectionARectangle,
27
+ startCellEdit,
28
+ tableRef,
29
+ onDragEnd,
30
+ args
31
+ }) => {
32
+ const editingCell = useSelector(
33
+ state => state.form?.[formName]?.values?.reduxFormEditingCell
34
+ );
35
+ const initialValue = useSelector(
36
+ state => state.form?.[formName]?.values?.reduxFormInitialValue
37
+ );
38
+
39
+ const [row] = args;
40
+ const rowId = getIdOrCodeOrIndex(row.original, row.index);
41
+ const cellId = `${rowId}:${row.column.path}`;
42
+ const isEditingCell = editingCell === cellId;
43
+ let val = oldFunc(...args);
44
+ const oldVal = val;
45
+ const text = getCopyTextForCell(val, row, column);
46
+ const dataTest = {
47
+ "data-test": "tgCell_" + column.path
48
+ };
49
+ const fullValue = row.original?.[row.column.path];
50
+
51
+ if (isEditingCell) {
52
+ if (column.type === "genericSelect") {
53
+ const GenericSelectComp = column.GenericSelectComp;
54
+
55
+ return (
56
+ <GenericSelectComp
57
+ rowId={rowId}
58
+ fullValue={fullValue}
59
+ initialValue={text}
60
+ {...dataTest}
61
+ finishEdit={(newVal, doNotStopEditing) => {
62
+ finishCellEdit(cellId, newVal, doNotStopEditing);
63
+ }}
64
+ dataTest={dataTest}
65
+ cancelEdit={cancelCellEdit}
66
+ />
67
+ );
68
+ }
69
+ if (column.type === "dropdown" || column.type === "dropdownMulti") {
70
+ return (
71
+ <DropdownCell
72
+ isMulti={dataTest.isMulti || column.type === "dropdownMulti"}
73
+ initialValue={dataTest.initialValue || text}
74
+ options={getVals(column.values)}
75
+ finishEdit={(newVal, doNotStopEditing) => {
76
+ finishCellEdit(cellId, newVal, doNotStopEditing);
77
+ }}
78
+ dataTest={dataTest}
79
+ cancelEdit={cancelCellEdit}
80
+ />
81
+ );
82
+ } else {
83
+ return (
84
+ <EditableCell
85
+ dataTest={dataTest}
86
+ cancelEdit={cancelCellEdit}
87
+ isNumeric={column.type === "number"}
88
+ initialValue={initialValue || text}
89
+ finishEdit={newVal => {
90
+ finishCellEdit(cellId, newVal);
91
+ }}
92
+ />
93
+ );
94
+ }
95
+ }
96
+
97
+ const isBool = column.type === "boolean";
98
+ if (isCellEditable && isBool) {
99
+ val = (
100
+ <Checkbox
101
+ disabled={isEntityDisabled(row.original)}
102
+ className="tg-cell-edit-boolean-checkbox"
103
+ checked={oldVal === "True"}
104
+ onChange={e => {
105
+ const checked = e.target.checked;
106
+ finishCellEdit(cellId, checked);
107
+ }}
108
+ />
109
+ );
110
+ noEllipsis = true;
111
+ }
112
+
113
+ //wrap the original tableColumn.Cell function in another div in order to add a title attribute
114
+ let title = text;
115
+ if (getCellHoverText) title = getCellHoverText(...args);
116
+ else if (column.getTitleAttr) title = column.getTitleAttr(...args);
117
+ const isSelectedCell = selectedCells?.[cellId];
118
+ const {
119
+ isRect,
120
+ selectionGrid,
121
+ lastRowIndex,
122
+ lastCellIndex,
123
+ entityMap,
124
+ pathToIndex
125
+ } = isSelectionARectangle();
126
+
127
+ return (
128
+ <>
129
+ <div
130
+ style={{
131
+ ...(!noEllipsis && {
132
+ textOverflow: "ellipsis",
133
+ overflow: "hidden"
134
+ })
135
+ }}
136
+ {...dataTest}
137
+ className="tg-cell-wrapper"
138
+ data-copy-text={text}
139
+ data-copy-json={JSON.stringify(
140
+ //tnw: eventually we'll parse these back out and use either the fullValue (for the generic selects) or the regular text vals for everything else
141
+ column.type === "genericSelect"
142
+ ? {
143
+ __strVal: fullValue,
144
+ __genSelCol: column.path
145
+ }
146
+ : { __strVal: text }
147
+ )}
148
+ title={title || undefined}
149
+ >
150
+ {val}
151
+ </div>
152
+ {isCellEditable &&
153
+ (column.type === "dropdown" ||
154
+ column.type === "dropdownMulti" ||
155
+ column.type === "genericSelect") && (
156
+ <Icon
157
+ icon="caret-down"
158
+ style={{
159
+ position: "absolute",
160
+ right: 5,
161
+ opacity: 0.3
162
+ }}
163
+ className="cell-edit-dropdown"
164
+ onClick={() => {
165
+ startCellEdit(cellId);
166
+ }}
167
+ />
168
+ )}
169
+
170
+ {isSelectedCell &&
171
+ (isRect
172
+ ? isBottomRightCornerOfRectangle({
173
+ cellId,
174
+ selectionGrid,
175
+ lastRowIndex,
176
+ lastCellIndex,
177
+ entityMap,
178
+ pathToIndex
179
+ })
180
+ : isSelectedCell === PRIMARY_SELECTED_VAL) && (
181
+ <CellDragHandle
182
+ key={cellId}
183
+ thisTable={tableRef.current.tableRef}
184
+ cellId={cellId}
185
+ isSelectionARectangle={isSelectionARectangle}
186
+ onDragEnd={onDragEnd}
187
+ />
188
+ )}
189
+ </>
190
+ );
191
+ };
package/SearchBar.js ADDED
@@ -0,0 +1,69 @@
1
+ import React, { useState } from "react";
2
+ import { Button, Classes, Spinner } from "@blueprintjs/core";
3
+ import classNames from "classnames";
4
+ import { onEnterHelper } from "../utils/handlerHelpers";
5
+ import { InputField } from "../FormComponents";
6
+
7
+ const SearchBar = ({
8
+ searchInput,
9
+ setSearchTerm,
10
+ loading,
11
+ searchMenuButton,
12
+ disabled,
13
+ autoFocusSearch,
14
+ noForm
15
+ }) => {
16
+ const [inputText, setInputText] = useState(searchInput);
17
+ if (noForm) {
18
+ console.error(
19
+ "The search bar requires the component to be wrapped in a form"
20
+ );
21
+ return;
22
+ }
23
+ let rightElement;
24
+ // need to always render searchMenuButton so it doesn't close
25
+ if (searchMenuButton) {
26
+ rightElement = (
27
+ <div style={{ display: "flex" }}>
28
+ {loading && <Spinner size="18" />}
29
+ {searchMenuButton}
30
+ </div>
31
+ );
32
+ } else {
33
+ rightElement = loading ? (
34
+ <Spinner size="18" />
35
+ ) : (
36
+ <Button
37
+ minimal
38
+ icon="search"
39
+ onClick={() => {
40
+ setSearchTerm(inputText);
41
+ }}
42
+ />
43
+ );
44
+ }
45
+ return (
46
+ <InputField
47
+ autoFocus={autoFocusSearch}
48
+ disabled={disabled}
49
+ loading={loading}
50
+ type="search"
51
+ defaultValue={searchInput}
52
+ value={inputText}
53
+ onChange={e => {
54
+ setInputText(e.target.value);
55
+ }}
56
+ className={classNames("datatable-search-input", Classes.ROUND)}
57
+ placeholder="Search..."
58
+ {...onEnterHelper(e => {
59
+ e.preventDefault();
60
+ e.stopPropagation();
61
+ setSearchTerm(e.target.value);
62
+ e.nativeEvent.stopImmediatePropagation();
63
+ })}
64
+ rightElement={rightElement}
65
+ />
66
+ );
67
+ };
68
+
69
+ export default SearchBar;
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { Icon } from "@blueprintjs/core";
3
+ import classNames from "classnames";
4
+
5
+ export default ({ steps, ...rest }) => (
6
+ <div style={{ display: "flex", justifyContent: "center" }}>
7
+ <ul className="bp3-breadcrumbs" {...rest}>
8
+ {steps.map(({ completed, active, text }, i) => (
9
+ <li key={i}>
10
+ <div
11
+ className={classNames("bp3-breadcrumb", {
12
+ "bp3-breadcrumb-current": active
13
+ })}
14
+ >
15
+ <Icon icon={completed ? "tick-circle" : undefined} />
16
+ {text}
17
+ </div>
18
+ </li>
19
+ ))}
20
+ </ul>
21
+ </div>
22
+ );
@@ -0,0 +1,100 @@
1
+ import React from "react";
2
+ import { MouseSensor, useSensor, useSensors, DndContext } from "@dnd-kit/core";
3
+ import {
4
+ SortableContext,
5
+ horizontalListSortingStrategy
6
+ } from "@dnd-kit/sortable";
7
+ import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
8
+
9
+ const CustomTheadComponent = ({
10
+ children: _children,
11
+ className,
12
+ onSortEnd,
13
+ onSortStart,
14
+ style
15
+ }) => {
16
+ // We need to do this because react table gives the children wrapped
17
+ // in another component
18
+ const children = _children.props.children;
19
+ const mouseSensor = useSensor(MouseSensor, {
20
+ activationConstraint: {
21
+ distance: 10
22
+ }
23
+ });
24
+
25
+ const sensors = useSensors(mouseSensor);
26
+ const handleDragEnd = event => {
27
+ const { active, over } = event;
28
+
29
+ if (!over || !active) {
30
+ return;
31
+ }
32
+
33
+ if (active.id === over.id) {
34
+ return;
35
+ }
36
+
37
+ onSortEnd({
38
+ oldIndex: parseInt(active.id),
39
+ newIndex: parseInt(over.id)
40
+ });
41
+ };
42
+
43
+ return (
44
+ <DndContext
45
+ onDragStart={onSortStart}
46
+ onDragEnd={handleDragEnd}
47
+ modifiers={[restrictToHorizontalAxis]}
48
+ sensors={sensors}
49
+ >
50
+ <div className={"rt-thead " + className} style={style}>
51
+ <div className="rt-tr">
52
+ <SortableContext
53
+ items={children.map((_, index) => `${index}`)}
54
+ strategy={horizontalListSortingStrategy}
55
+ >
56
+ {children}
57
+ </SortableContext>
58
+ </div>
59
+ </div>
60
+ </DndContext>
61
+ );
62
+ };
63
+
64
+ const SortableColumns = ({ className, style, children, moveColumn }) => {
65
+ const shouldCancelStart = e => {
66
+ const className = e.target.className;
67
+ // if its an svg then it's a blueprint icon
68
+ return (
69
+ e.target instanceof SVGElement || className.indexOf("rt-resizer") > -1
70
+ );
71
+ };
72
+
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
+ return (
87
+ <CustomTheadComponent
88
+ className={className}
89
+ style={style}
90
+ onSortStart={onSortStart}
91
+ onSortEnd={onSortEnd}
92
+ helperClass="above-dialog"
93
+ shouldCancelStart={shouldCancelStart}
94
+ >
95
+ {children}
96
+ </CustomTheadComponent>
97
+ );
98
+ };
99
+
100
+ export default SortableColumns;
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+
3
+ const TableFormTrackerContext = React.createContext({
4
+ formNames: [],
5
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
6
+ pushFormName: () => {},
7
+ isActive: false
8
+ });
9
+
10
+ export default TableFormTrackerContext;