@teselagen/ui 0.5.21 → 0.5.23-beta.1
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/Columns.d.ts +1 -0
- package/DataTable/DisplayOptions.d.ts +14 -14
- package/DataTable/EditabelCell.d.ts +3 -5
- package/DataTable/FilterAndSortMenu.d.ts +9 -9
- package/DataTable/PagingTool.d.ts +25 -2
- package/DataTable/SearchBar.d.ts +2 -2
- package/DataTable/SortableColumns.d.ts +6 -9
- package/DataTable/ThComponent.d.ts +9 -0
- package/DataTable/index.d.ts +0 -5
- package/DataTable/utils/getIdOrCodeOrIndex.d.ts +1 -2
- package/DataTable/utils/handleCopyTable.d.ts +1 -0
- package/DataTable/utils/index.d.ts +4 -2
- package/DataTable/utils/primarySelectedValue.d.ts +1 -0
- package/DataTable/utils/queryParams.d.ts +6 -0
- package/DataTable/utils/removeCleanRows.d.ts +1 -1
- package/DataTable/utils/rowClick.d.ts +24 -3
- package/DataTable/utils/useDeepEqualMemo.d.ts +1 -0
- package/DataTable/utils/useTableParams.d.ts +49 -0
- package/FormComponents/Uploader.d.ts +34 -1
- package/FormComponents/index.d.ts +111 -45
- package/MatchHeaders.d.ts +9 -10
- package/SimpleStepViz.d.ts +2 -1
- package/TgSuggest/index.d.ts +1 -21
- package/UploadCsvWizard.d.ts +1 -1
- package/index.cjs.js +41038 -45265
- package/index.d.ts +3 -2
- package/index.es.js +44524 -48751
- package/package.json +2 -8
- package/src/DataTable/CellDragHandle.js +70 -69
- package/src/DataTable/ColumnFilterMenu.js +18 -18
- package/src/DataTable/Columns.js +1066 -0
- package/src/DataTable/DisplayOptions.js +173 -192
- package/src/DataTable/EditabelCell.js +6 -16
- package/src/DataTable/FilterAndSortMenu.js +213 -234
- package/src/DataTable/PagingTool.js +47 -56
- package/src/DataTable/SearchBar.js +3 -3
- package/src/DataTable/SortableColumns.js +44 -39
- package/src/DataTable/ThComponent.js +44 -0
- package/src/DataTable/dataTableEnhancer.js +35 -294
- package/src/DataTable/index.js +2933 -3601
- package/src/DataTable/utils/getIdOrCodeOrIndex.js +1 -1
- package/src/DataTable/utils/handleCopyTable.js +16 -0
- package/src/DataTable/utils/index.js +7 -3
- package/src/DataTable/utils/primarySelectedValue.js +1 -0
- package/src/DataTable/utils/queryParams.js +42 -13
- package/src/DataTable/utils/removeCleanRows.js +3 -3
- package/src/DataTable/utils/rowClick.js +34 -9
- package/src/DataTable/utils/selection.js +1 -1
- package/src/DataTable/utils/useDeepEqualMemo.js +10 -0
- package/src/DataTable/utils/useTableParams.js +361 -0
- package/src/DataTable/utils/withTableParams.js +30 -87
- package/src/DataTable/validateTableWideErrors.js +1 -1
- package/src/DialogFooter/index.js +3 -3
- package/src/FillWindow.js +2 -3
- package/src/FormComponents/Uploader.js +825 -784
- package/src/FormComponents/index.js +441 -603
- package/src/FormComponents/tryToMatchSchemas.js +1 -6
- package/src/MatchHeaders.js +27 -22
- package/src/SimpleStepViz.js +19 -23
- package/src/TgSuggest/index.js +94 -106
- package/src/UploadCsvWizard.js +570 -577
- package/src/index.js +4 -3
- package/src/showDialogOnDocBody.js +5 -9
- package/src/useDialog.js +25 -26
- package/src/utils/commandControls.js +2 -2
- package/src/utils/handlerHelpers.js +19 -25
- package/src/utils/popoverOverflowModifiers.js +1 -1
- package/src/utils/renderOnDoc.js +8 -5
- package/src/utils/tagUtils.js +3 -3
- package/src/utils/useTraceUpdate.js +19 -0
- package/src/wrapDialog.js +0 -2
- package/style.css +251 -251
- package/useDialog.d.ts +2 -6
- package/utils/renderOnDoc.d.ts +1 -1
- package/utils/tagUtils.d.ts +5 -1
- package/utils/useTraceUpdate.d.ts +1 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { getAllRows } from "./getAllRows";
|
|
2
|
+
import { handleCopyRows } from "./handleCopyRows";
|
|
3
|
+
|
|
4
|
+
export const handleCopyTable = (e, opts) => {
|
|
5
|
+
try {
|
|
6
|
+
const allRowEls = getAllRows(e);
|
|
7
|
+
if (!allRowEls) return;
|
|
8
|
+
handleCopyRows(allRowEls, {
|
|
9
|
+
...opts,
|
|
10
|
+
onFinishMsg: "Table Copied"
|
|
11
|
+
});
|
|
12
|
+
} catch (error) {
|
|
13
|
+
console.error(`error:`, error);
|
|
14
|
+
window.toastr.error("Error copying rows.");
|
|
15
|
+
}
|
|
16
|
+
};
|
|
@@ -2,7 +2,6 @@ import { isEntityClean } from "./isEntityClean";
|
|
|
2
2
|
import { getSelectedRowsFromEntities } from "./selection";
|
|
3
3
|
import { removeCleanRows } from "./removeCleanRows";
|
|
4
4
|
import { getIdOrCodeOrIndex } from "./getIdOrCodeOrIndex";
|
|
5
|
-
import computePresets from "./computePresets";
|
|
6
5
|
import { getRecordsFromIdMap } from "./withSelectedEntities";
|
|
7
6
|
import { formatPasteData } from "./formatPasteData";
|
|
8
7
|
import { getFieldPathToField } from "./getFieldPathToField";
|
|
@@ -23,9 +22,11 @@ import { handleCopyHelper } from "./handleCopyHelper";
|
|
|
23
22
|
import { handleCopyRows } from "./handleCopyRows";
|
|
24
23
|
import { handleCopyColumn } from "./handleCopyColumn";
|
|
25
24
|
import { isBottomRightCornerOfRectangle } from "./isBottomRightCornerOfRectangle";
|
|
25
|
+
import { handleCopyTable } from "./handleCopyTable";
|
|
26
|
+
import { PRIMARY_SELECTED_VAL } from "./primarySelectedValue";
|
|
27
|
+
import { useDeepEqualMemo } from "./useDeepEqualMemo";
|
|
26
28
|
|
|
27
29
|
export {
|
|
28
|
-
computePresets,
|
|
29
30
|
defaultParsePaste,
|
|
30
31
|
formatPasteData,
|
|
31
32
|
getAllRows,
|
|
@@ -44,8 +45,11 @@ export {
|
|
|
44
45
|
handleCopyColumn,
|
|
45
46
|
handleCopyHelper,
|
|
46
47
|
handleCopyRows,
|
|
48
|
+
handleCopyTable,
|
|
47
49
|
isBottomRightCornerOfRectangle,
|
|
48
50
|
isEntityClean,
|
|
51
|
+
PRIMARY_SELECTED_VAL,
|
|
49
52
|
removeCleanRows,
|
|
50
|
-
stripNumberAtEnd
|
|
53
|
+
stripNumberAtEnd,
|
|
54
|
+
useDeepEqualMemo
|
|
51
55
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const PRIMARY_SELECTED_VAL = "main_cell";
|
|
@@ -39,7 +39,7 @@ export function getMergedOpts(topLevel = {}, instanceLevel = {}) {
|
|
|
39
39
|
//filters look like this:
|
|
40
40
|
// {
|
|
41
41
|
// selectedFilter: 'textContains', //camel case
|
|
42
|
-
// filterOn: ccDisplayName, //camel case display name
|
|
42
|
+
// filterOn: ccDisplayName, //camel case display name if available and string, otherwise path
|
|
43
43
|
// filterValue: 'thomas',
|
|
44
44
|
// }
|
|
45
45
|
],
|
|
@@ -63,9 +63,27 @@ function safeParse(val) {
|
|
|
63
63
|
return val;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
*
|
|
69
|
+
* @param {object} field
|
|
70
|
+
* @returns the camelCase display name of the field, to be used for filters, sorting, etc
|
|
71
|
+
*/
|
|
72
|
+
export function getCCDisplayName(field) {
|
|
73
|
+
return camelCase(
|
|
74
|
+
typeof field.displayName === "string" ? field.displayName : field.path
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Takes a schema and returns an object with the fields mapped by their camelCased display name.
|
|
80
|
+
* If the displayName is not set or is a jsx element, the path is used instead.
|
|
81
|
+
* The same conversion must be done when using the result of this method
|
|
82
|
+
*/
|
|
66
83
|
function getFieldsMappedByCCDisplayName(schema) {
|
|
67
84
|
return schema.fields.reduce((acc, field) => {
|
|
68
|
-
|
|
85
|
+
const ccDisplayName = getCCDisplayName(field);
|
|
86
|
+
acc[ccDisplayName] = field;
|
|
69
87
|
return acc;
|
|
70
88
|
}, {});
|
|
71
89
|
}
|
|
@@ -75,14 +93,14 @@ function orderEntitiesLocal(orderArray, entities, schema, ownProps) {
|
|
|
75
93
|
const orderFuncs = [];
|
|
76
94
|
const ascOrDescArray = [];
|
|
77
95
|
orderArray.forEach(order => {
|
|
78
|
-
const ccDisplayName = order.replace(/^-/gi, "");
|
|
96
|
+
const ccDisplayName = order.replace(/^-/gi, ""); // "-updatedAt" => "updatedAt"
|
|
79
97
|
const ccFields = getFieldsMappedByCCDisplayName(schema);
|
|
80
98
|
const field = ccFields[ccDisplayName];
|
|
81
99
|
if (!field) {
|
|
82
100
|
throw new Error(
|
|
83
101
|
"Ruh roh, there should have been a column to sort on for " +
|
|
84
102
|
order +
|
|
85
|
-
"but none was found in " +
|
|
103
|
+
" but none was found in " +
|
|
86
104
|
schema.fields
|
|
87
105
|
);
|
|
88
106
|
}
|
|
@@ -234,14 +252,14 @@ function getFiltersFromSearchTerm(searchTerm, schema) {
|
|
|
234
252
|
isSearchTermFilter: true
|
|
235
253
|
};
|
|
236
254
|
schema.fields.forEach(field => {
|
|
237
|
-
const { type,
|
|
255
|
+
const { type, searchDisabled } = field;
|
|
238
256
|
if (searchDisabled || field.filterDisabled || type === "color") return;
|
|
239
|
-
const
|
|
257
|
+
const ccDisplayName = getCCDisplayName(field);
|
|
240
258
|
const filterValue = cleanFilterValue(searchTerm, type);
|
|
241
259
|
if (type === "string" || type === "lookup") {
|
|
242
260
|
searchTermFilters.push({
|
|
243
261
|
...sharedFields,
|
|
244
|
-
filterOn:
|
|
262
|
+
filterOn: ccDisplayName,
|
|
245
263
|
filterValue: searchTerm,
|
|
246
264
|
selectedFilter: "contains"
|
|
247
265
|
});
|
|
@@ -256,14 +274,14 @@ function getFiltersFromSearchTerm(searchTerm, schema) {
|
|
|
256
274
|
if ("true".replace(regex, "") !== "true") {
|
|
257
275
|
searchTermFilters.push({
|
|
258
276
|
...sharedFields,
|
|
259
|
-
filterOn:
|
|
277
|
+
filterOn: ccDisplayName,
|
|
260
278
|
filterValue: true,
|
|
261
279
|
selectedFilter: "true"
|
|
262
280
|
});
|
|
263
281
|
} else if ("false".replace(regex, "") !== "false") {
|
|
264
282
|
searchTermFilters.push({
|
|
265
283
|
...sharedFields,
|
|
266
|
-
filterOn:
|
|
284
|
+
filterOn: ccDisplayName,
|
|
267
285
|
filterValue: false,
|
|
268
286
|
selectedFilter: "false"
|
|
269
287
|
});
|
|
@@ -278,7 +296,7 @@ function getFiltersFromSearchTerm(searchTerm, schema) {
|
|
|
278
296
|
}
|
|
279
297
|
searchTermFilters.push({
|
|
280
298
|
...sharedFields,
|
|
281
|
-
filterOn:
|
|
299
|
+
filterOn: ccDisplayName,
|
|
282
300
|
filterValue: filterValue,
|
|
283
301
|
selectedFilter: "equalTo"
|
|
284
302
|
});
|
|
@@ -347,7 +365,13 @@ function getSubFilter(
|
|
|
347
365
|
if (!fieldVal?.toString) return false;
|
|
348
366
|
return (
|
|
349
367
|
arrayFilterValue
|
|
350
|
-
.map(val =>
|
|
368
|
+
.map(val => {
|
|
369
|
+
if (val) {
|
|
370
|
+
if (val.toString) return val.toString().toLowerCase();
|
|
371
|
+
return val.toLowerCase();
|
|
372
|
+
}
|
|
373
|
+
return undefined;
|
|
374
|
+
})
|
|
351
375
|
.indexOf(fieldVal.toString().toLowerCase()) > -1
|
|
352
376
|
);
|
|
353
377
|
};
|
|
@@ -359,7 +383,13 @@ function getSubFilter(
|
|
|
359
383
|
if (!fieldVal?.toString) return false;
|
|
360
384
|
return (
|
|
361
385
|
arrayFilterValue
|
|
362
|
-
.map(val =>
|
|
386
|
+
.map(val => {
|
|
387
|
+
if (val) {
|
|
388
|
+
if (val.toString) return val.toString().toLowerCase();
|
|
389
|
+
return val.toLowerCase();
|
|
390
|
+
}
|
|
391
|
+
return undefined;
|
|
392
|
+
})
|
|
363
393
|
.indexOf(fieldVal.toString().toLowerCase()) === -1
|
|
364
394
|
);
|
|
365
395
|
};
|
|
@@ -859,7 +889,6 @@ export function getQueryParams({
|
|
|
859
889
|
}));
|
|
860
890
|
});
|
|
861
891
|
};
|
|
862
|
-
|
|
863
892
|
const orFiltersObject = getQueries(orFilters, qb, ccFields);
|
|
864
893
|
let allOrFilters = flattenFilters(orFiltersObject);
|
|
865
894
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { isEntityClean } from "./isEntityClean";
|
|
2
2
|
import { getIdOrCodeOrIndex } from "./getIdOrCodeOrIndex";
|
|
3
3
|
|
|
4
|
-
export const removeCleanRows = (
|
|
4
|
+
export const removeCleanRows = (entities, cellValidation) => {
|
|
5
5
|
const toFilterOut = {};
|
|
6
|
-
const entsToUse = (
|
|
6
|
+
const entsToUse = (entities || []).filter(e => {
|
|
7
7
|
if (!(e._isClean || isEntityClean(e))) return true;
|
|
8
8
|
else {
|
|
9
9
|
toFilterOut[getIdOrCodeOrIndex(e)] = true;
|
|
@@ -12,7 +12,7 @@ export const removeCleanRows = (reduxFormEntities, reduxFormCellValidation) => {
|
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
const validationToUse = {};
|
|
15
|
-
Object.entries(
|
|
15
|
+
Object.entries(cellValidation || {}).forEach(([k, v]) => {
|
|
16
16
|
const [rowId] = k.split(":");
|
|
17
17
|
if (!toFilterOut[rowId]) {
|
|
18
18
|
validationToUse[k] = v;
|
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
import { isEmpty, forEach, range } from "lodash-es";
|
|
2
2
|
import { getSelectedRowsFromEntities } from "./selection";
|
|
3
|
-
import getIdOrCodeOrIndex from "./getIdOrCodeOrIndex";
|
|
3
|
+
import { getIdOrCodeOrIndex } from "./getIdOrCodeOrIndex";
|
|
4
4
|
import { getRecordsFromIdMap } from "./withSelectedEntities";
|
|
5
5
|
|
|
6
|
-
export default function rowClick(
|
|
7
|
-
|
|
6
|
+
export default function rowClick(
|
|
7
|
+
e,
|
|
8
|
+
rowInfo,
|
|
9
|
+
entities,
|
|
10
|
+
{
|
|
8
11
|
reduxFormSelectedEntityIdMap,
|
|
9
12
|
isSingleSelect,
|
|
10
13
|
noSelect,
|
|
11
14
|
onRowClick,
|
|
12
15
|
isEntityDisabled,
|
|
13
|
-
withCheckboxes
|
|
14
|
-
|
|
16
|
+
withCheckboxes,
|
|
17
|
+
onDeselect,
|
|
18
|
+
onSingleRowSelect,
|
|
19
|
+
onMultiRowSelect,
|
|
20
|
+
noDeselectAll,
|
|
21
|
+
onRowSelect,
|
|
22
|
+
change
|
|
23
|
+
}
|
|
24
|
+
) {
|
|
15
25
|
const entity = rowInfo.original;
|
|
16
26
|
onRowClick(e, entity, rowInfo);
|
|
17
27
|
if (noSelect || isEntityDisabled(entity)) return;
|
|
@@ -101,7 +111,19 @@ export default function rowClick(e, rowInfo, entities, props) {
|
|
|
101
111
|
}
|
|
102
112
|
}
|
|
103
113
|
|
|
104
|
-
finalizeSelection({
|
|
114
|
+
finalizeSelection({
|
|
115
|
+
idMap: newIdMap,
|
|
116
|
+
entities,
|
|
117
|
+
props: {
|
|
118
|
+
onDeselect,
|
|
119
|
+
onSingleRowSelect,
|
|
120
|
+
onMultiRowSelect,
|
|
121
|
+
noDeselectAll,
|
|
122
|
+
onRowSelect,
|
|
123
|
+
noSelect,
|
|
124
|
+
change
|
|
125
|
+
}
|
|
126
|
+
});
|
|
105
127
|
}
|
|
106
128
|
|
|
107
129
|
export function changeSelectedEntities({ idMap, entities = [], change }) {
|
|
@@ -124,8 +146,10 @@ export function changeSelectedEntities({ idMap, entities = [], change }) {
|
|
|
124
146
|
change("reduxFormSelectedEntityIdMap", newIdMap);
|
|
125
147
|
}
|
|
126
148
|
|
|
127
|
-
export function finalizeSelection({
|
|
128
|
-
|
|
149
|
+
export function finalizeSelection({
|
|
150
|
+
idMap,
|
|
151
|
+
entities,
|
|
152
|
+
props: {
|
|
129
153
|
onDeselect,
|
|
130
154
|
onSingleRowSelect,
|
|
131
155
|
onMultiRowSelect,
|
|
@@ -133,7 +157,8 @@ export function finalizeSelection({ idMap, entities, props }) {
|
|
|
133
157
|
onRowSelect,
|
|
134
158
|
noSelect,
|
|
135
159
|
change
|
|
136
|
-
}
|
|
160
|
+
}
|
|
161
|
+
}) {
|
|
137
162
|
if (noSelect) return;
|
|
138
163
|
if (
|
|
139
164
|
noDeselectAll &&
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import { useContext, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { change } from "redux-form";
|
|
3
|
+
import { useDispatch, useSelector } from "react-redux";
|
|
4
|
+
import { isFunction, keyBy, get } from "lodash-es";
|
|
5
|
+
import TableFormTrackerContext from "../TableFormTrackerContext";
|
|
6
|
+
import { viewColumn, openColumn } from "./viewColumn";
|
|
7
|
+
import convertSchema from "./convertSchema";
|
|
8
|
+
import { getRecordsFromIdMap } from "./withSelectedEntities";
|
|
9
|
+
import {
|
|
10
|
+
makeDataTableHandlers,
|
|
11
|
+
getQueryParams,
|
|
12
|
+
setCurrentParamsOnUrl,
|
|
13
|
+
getCurrentParamsFromUrl,
|
|
14
|
+
getCCDisplayName
|
|
15
|
+
} from "./queryParams";
|
|
16
|
+
import getTableConfigFromStorage from "./getTableConfigFromStorage";
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
NOTE:
|
|
20
|
+
This haven't been tested yet. It is the first version of what we should replace withTableParams
|
|
21
|
+
and also the first bit of the DataTable.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Note all these options can be passed at Design Time or at Runtime (like reduxForm())
|
|
26
|
+
*
|
|
27
|
+
* @export
|
|
28
|
+
*
|
|
29
|
+
* @param {compOrOpts} compOrOpts
|
|
30
|
+
* @typedef {object} compOrOpts
|
|
31
|
+
* @property {*string} formName - required unique identifier for the table
|
|
32
|
+
* @property {Object | Function} schema - The data table schema or a function returning it. The function wll be called with props as the argument.
|
|
33
|
+
* @property {boolean} urlConnected - whether the table should connect to/update the URL
|
|
34
|
+
* @property {boolean} withSelectedEntities - whether or not to pass the selected entities
|
|
35
|
+
* @property {boolean} isCodeModel - whether the model is keyed by code instead of id in the db
|
|
36
|
+
* @property {object} defaults - tableParam defaults such as pageSize, filter, etc
|
|
37
|
+
* @property {boolean} noOrderError - won't console an error if an order is not found on schema
|
|
38
|
+
*/
|
|
39
|
+
export default function useTableParams(
|
|
40
|
+
props // This should be the same as the spread above
|
|
41
|
+
) {
|
|
42
|
+
const {
|
|
43
|
+
formName,
|
|
44
|
+
isTableParamsConnected,
|
|
45
|
+
urlConnected,
|
|
46
|
+
onlyOneFilter,
|
|
47
|
+
defaults = {},
|
|
48
|
+
// WE NEED THIS HOOK TO BE WRAPPED IN A WITHROUTER OR MOVE TO REACT-ROUTER-DOM 5
|
|
49
|
+
// BEST SOLUTION IS TO ASSUME IT IS GOING TO BE RECEIVED
|
|
50
|
+
history,
|
|
51
|
+
withSelectedEntities,
|
|
52
|
+
tableParams: _tableParams,
|
|
53
|
+
schema: __schema,
|
|
54
|
+
noForm,
|
|
55
|
+
orderByFirstColumn,
|
|
56
|
+
withDisplayOptions,
|
|
57
|
+
syncDisplayOptionsToDb,
|
|
58
|
+
tableConfigurations,
|
|
59
|
+
isViewable,
|
|
60
|
+
isOpenable,
|
|
61
|
+
showEmptyColumnsByDefault,
|
|
62
|
+
isSimple,
|
|
63
|
+
entities: _origEntities = [],
|
|
64
|
+
cellRenderer,
|
|
65
|
+
additionalFilter,
|
|
66
|
+
additionalOrFilter,
|
|
67
|
+
doNotCoercePageSize,
|
|
68
|
+
isLocalCall
|
|
69
|
+
} = props;
|
|
70
|
+
const isInfinite = props.isInfinite || isSimple || !props.withPaging;
|
|
71
|
+
const additionalFilterToUse =
|
|
72
|
+
typeof additionalFilter === "function"
|
|
73
|
+
? additionalFilter.bind(this, props)
|
|
74
|
+
: () => additionalFilter;
|
|
75
|
+
|
|
76
|
+
const additionalOrFilterToUse =
|
|
77
|
+
typeof additionalOrFilter === "function"
|
|
78
|
+
? additionalOrFilter.bind(this, props)
|
|
79
|
+
: () => additionalOrFilter;
|
|
80
|
+
|
|
81
|
+
let _schema;
|
|
82
|
+
if (isFunction(__schema)) _schema = __schema(props);
|
|
83
|
+
else _schema = __schema;
|
|
84
|
+
const convertedSchema = convertSchema(_schema);
|
|
85
|
+
|
|
86
|
+
if (isLocalCall) {
|
|
87
|
+
if (!noForm && (!formName || formName === "tgDataTable")) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
"Please pass a unique 'formName' prop to the locally connected <DataTable/> component with schema: ",
|
|
90
|
+
_schema
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
if (orderByFirstColumn && !defaults?.order?.length) {
|
|
94
|
+
const r = [getCCDisplayName(convertedSchema.fields[0])];
|
|
95
|
+
defaults.order = r;
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
//in user instantiated withTableParams() call
|
|
99
|
+
if (!formName || formName === "tgDataTable") {
|
|
100
|
+
throw new Error(
|
|
101
|
+
"Please pass a unique 'formName' prop to the withTableParams() with schema: ",
|
|
102
|
+
_schema
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const [showForcedHiddenColumns, setShowForcedHidden] = useState(() => {
|
|
108
|
+
if (showEmptyColumnsByDefault) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const [tableConfig, setTableConfig] = useState({ fieldOptions: [] });
|
|
115
|
+
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
let newTableConfig = {};
|
|
118
|
+
if (withDisplayOptions) {
|
|
119
|
+
if (syncDisplayOptionsToDb) {
|
|
120
|
+
newTableConfig = tableConfigurations && tableConfigurations[0];
|
|
121
|
+
} else {
|
|
122
|
+
newTableConfig = getTableConfigFromStorage(formName);
|
|
123
|
+
}
|
|
124
|
+
if (!newTableConfig) {
|
|
125
|
+
newTableConfig = {
|
|
126
|
+
fieldOptions: []
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
setTableConfig(newTableConfig);
|
|
131
|
+
}, [
|
|
132
|
+
formName,
|
|
133
|
+
syncDisplayOptionsToDb,
|
|
134
|
+
tableConfigurations,
|
|
135
|
+
withDisplayOptions
|
|
136
|
+
]);
|
|
137
|
+
|
|
138
|
+
// make user set page size persist
|
|
139
|
+
const userSetPageSize =
|
|
140
|
+
tableConfig?.userSetPageSize && parseInt(tableConfig.userSetPageSize, 10);
|
|
141
|
+
if (!syncDisplayOptionsToDb && userSetPageSize) {
|
|
142
|
+
defaults.pageSize = userSetPageSize;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const {
|
|
146
|
+
reduxFormSearchInput = "",
|
|
147
|
+
onlyShowRowsWErrors,
|
|
148
|
+
reduxFormCellValidation,
|
|
149
|
+
reduxFormEntities,
|
|
150
|
+
reduxFormSelectedCells = {},
|
|
151
|
+
reduxFormSelectedEntityIdMap = {},
|
|
152
|
+
reduxFormQueryParams = {}
|
|
153
|
+
} = useSelector(state => {
|
|
154
|
+
if (!state.form[formName]) return {};
|
|
155
|
+
return state.form[formName].values || {};
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const entities = reduxFormEntities || _origEntities;
|
|
159
|
+
|
|
160
|
+
const { schema } = useMemo(() => {
|
|
161
|
+
const schema = convertSchema(_schema);
|
|
162
|
+
if (isViewable) {
|
|
163
|
+
schema.fields = [viewColumn, ...schema.fields];
|
|
164
|
+
}
|
|
165
|
+
if (isOpenable) {
|
|
166
|
+
schema.fields = [openColumn, ...schema.fields];
|
|
167
|
+
}
|
|
168
|
+
// this must come before handling orderings.
|
|
169
|
+
schema.fields = schema.fields.map(field => {
|
|
170
|
+
if (field.placementPath) {
|
|
171
|
+
return {
|
|
172
|
+
...field,
|
|
173
|
+
sortDisabled:
|
|
174
|
+
field.sortDisabled ||
|
|
175
|
+
(typeof field.path === "string" && field.path.includes(".")),
|
|
176
|
+
path: field.placementPath
|
|
177
|
+
};
|
|
178
|
+
} else {
|
|
179
|
+
return field;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
if (withDisplayOptions) {
|
|
184
|
+
const fieldOptsByPath = keyBy(tableConfig.fieldOptions, "path");
|
|
185
|
+
schema.fields = schema.fields.map(field => {
|
|
186
|
+
const fieldOpt = fieldOptsByPath[field.path];
|
|
187
|
+
let noValsForField = false;
|
|
188
|
+
// only add this hidden column ability if no paging
|
|
189
|
+
if (
|
|
190
|
+
!showForcedHiddenColumns &&
|
|
191
|
+
withDisplayOptions &&
|
|
192
|
+
(isSimple || isInfinite)
|
|
193
|
+
) {
|
|
194
|
+
noValsForField = entities.every(e => {
|
|
195
|
+
const val = get(e, field.path);
|
|
196
|
+
return field.render
|
|
197
|
+
? !field.render(val, e)
|
|
198
|
+
: cellRenderer[field.path]
|
|
199
|
+
? !cellRenderer[field.path](val, e)
|
|
200
|
+
: !val;
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
if (noValsForField) {
|
|
204
|
+
return {
|
|
205
|
+
...field,
|
|
206
|
+
isHidden: true,
|
|
207
|
+
isForcedHidden: true
|
|
208
|
+
};
|
|
209
|
+
} else if (fieldOpt) {
|
|
210
|
+
return {
|
|
211
|
+
...field,
|
|
212
|
+
isHidden: fieldOpt.isHidden
|
|
213
|
+
};
|
|
214
|
+
} else {
|
|
215
|
+
return field;
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
const columnOrderings = tableConfig.columnOrderings;
|
|
220
|
+
if (columnOrderings) {
|
|
221
|
+
const fieldsWithOrders = [];
|
|
222
|
+
const fieldsWithoutOrder = [];
|
|
223
|
+
// if a new field has been added since the orderings were set then we want
|
|
224
|
+
// it to be at the end instead of the beginning
|
|
225
|
+
schema.fields.forEach(field => {
|
|
226
|
+
if (columnOrderings.indexOf(field.path) > -1) {
|
|
227
|
+
fieldsWithOrders.push(field);
|
|
228
|
+
} else {
|
|
229
|
+
fieldsWithoutOrder.push(field);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
schema.fields = fieldsWithOrders
|
|
233
|
+
.sort(({ path: path1 }, { path: path2 }) => {
|
|
234
|
+
return (
|
|
235
|
+
columnOrderings.indexOf(path1) - columnOrderings.indexOf(path2)
|
|
236
|
+
);
|
|
237
|
+
})
|
|
238
|
+
.concat(fieldsWithoutOrder);
|
|
239
|
+
setTableConfig(prev => ({
|
|
240
|
+
...prev,
|
|
241
|
+
columnOrderings: schema.fields.map(f => f.path)
|
|
242
|
+
}));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return { schema };
|
|
246
|
+
}, [
|
|
247
|
+
_schema,
|
|
248
|
+
cellRenderer,
|
|
249
|
+
entities,
|
|
250
|
+
isInfinite,
|
|
251
|
+
isOpenable,
|
|
252
|
+
isSimple,
|
|
253
|
+
isViewable,
|
|
254
|
+
showForcedHiddenColumns,
|
|
255
|
+
tableConfig,
|
|
256
|
+
withDisplayOptions
|
|
257
|
+
]);
|
|
258
|
+
|
|
259
|
+
const selectedEntities = withSelectedEntities
|
|
260
|
+
? getRecordsFromIdMap(reduxFormSelectedEntityIdMap)
|
|
261
|
+
: undefined;
|
|
262
|
+
|
|
263
|
+
const currentParams = urlConnected
|
|
264
|
+
? getCurrentParamsFromUrl(history.location) //important to use history location and not ownProps.location because for some reason the location path lags one render behind!!
|
|
265
|
+
: reduxFormQueryParams;
|
|
266
|
+
|
|
267
|
+
currentParams.searchTerm = reduxFormSearchInput;
|
|
268
|
+
|
|
269
|
+
props = {
|
|
270
|
+
...props,
|
|
271
|
+
...getQueryParams({
|
|
272
|
+
doNotCoercePageSize,
|
|
273
|
+
currentParams,
|
|
274
|
+
entities: props.entities, // for local table
|
|
275
|
+
urlConnected,
|
|
276
|
+
defaults: props.defaults,
|
|
277
|
+
schema: convertedSchema,
|
|
278
|
+
isInfinite,
|
|
279
|
+
isLocalCall,
|
|
280
|
+
additionalFilter: additionalFilterToUse,
|
|
281
|
+
additionalOrFilter: additionalOrFilterToUse,
|
|
282
|
+
noOrderError: props.noOrderError,
|
|
283
|
+
isCodeModel: props.isCodeModel,
|
|
284
|
+
ownProps: props
|
|
285
|
+
})
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const dispatch = useDispatch();
|
|
289
|
+
let tableParams;
|
|
290
|
+
if (!isTableParamsConnected) {
|
|
291
|
+
const updateSearch = val => {
|
|
292
|
+
setTimeout(() => {
|
|
293
|
+
dispatch(change(formName, "reduxFormSearchInput", val || ""));
|
|
294
|
+
});
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
let setNewParams;
|
|
298
|
+
if (urlConnected) {
|
|
299
|
+
setNewParams = newParams => {
|
|
300
|
+
setCurrentParamsOnUrl(newParams, history.replace);
|
|
301
|
+
dispatch(change(formName, "reduxFormQueryParams", newParams)); //we always will update the redux params as a workaround for withRouter not always working if inside a redux-connected container https://github.com/ReactTraining/react-router/issues/5037
|
|
302
|
+
};
|
|
303
|
+
} else {
|
|
304
|
+
setNewParams = function (newParams) {
|
|
305
|
+
dispatch(change(formName, "reduxFormQueryParams", newParams));
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const bindThese = makeDataTableHandlers({
|
|
310
|
+
setNewParams,
|
|
311
|
+
updateSearch,
|
|
312
|
+
defaults,
|
|
313
|
+
onlyOneFilter
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const boundDispatchProps = {};
|
|
317
|
+
//bind currentParams to actions
|
|
318
|
+
Object.keys(bindThese).forEach(function (key) {
|
|
319
|
+
const action = bindThese[key];
|
|
320
|
+
boundDispatchProps[key] = function (...args) {
|
|
321
|
+
action(...args, currentParams);
|
|
322
|
+
};
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
const changeFormValue = (...args) => dispatch(change(formName, ...args));
|
|
326
|
+
|
|
327
|
+
tableParams = {
|
|
328
|
+
changeFormValue,
|
|
329
|
+
selectedEntities,
|
|
330
|
+
..._tableParams,
|
|
331
|
+
...props,
|
|
332
|
+
...boundDispatchProps,
|
|
333
|
+
form: formName, //this will override the default redux form name
|
|
334
|
+
isTableParamsConnected: true //let the table know not to do local sorting/filtering etc.
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const formTracker = useContext(TableFormTrackerContext);
|
|
339
|
+
useEffect(() => {
|
|
340
|
+
if (formTracker.isActive && !formTracker.formNames.includes(formName)) {
|
|
341
|
+
formTracker.pushFormName(formName);
|
|
342
|
+
}
|
|
343
|
+
}, [formTracker, formName]);
|
|
344
|
+
|
|
345
|
+
return {
|
|
346
|
+
...props,
|
|
347
|
+
selectedEntities,
|
|
348
|
+
tableParams,
|
|
349
|
+
currentParams,
|
|
350
|
+
schema,
|
|
351
|
+
entities,
|
|
352
|
+
reduxFormSearchInput,
|
|
353
|
+
onlyShowRowsWErrors,
|
|
354
|
+
reduxFormCellValidation,
|
|
355
|
+
reduxFormSelectedCells,
|
|
356
|
+
reduxFormSelectedEntityIdMap,
|
|
357
|
+
reduxFormQueryParams,
|
|
358
|
+
showForcedHiddenColumns,
|
|
359
|
+
setShowForcedHidden
|
|
360
|
+
};
|
|
361
|
+
}
|