@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.
Files changed (76) hide show
  1. package/DataTable/Columns.d.ts +1 -0
  2. package/DataTable/DisplayOptions.d.ts +14 -14
  3. package/DataTable/EditabelCell.d.ts +3 -5
  4. package/DataTable/FilterAndSortMenu.d.ts +9 -9
  5. package/DataTable/PagingTool.d.ts +25 -2
  6. package/DataTable/SearchBar.d.ts +2 -2
  7. package/DataTable/SortableColumns.d.ts +6 -9
  8. package/DataTable/ThComponent.d.ts +9 -0
  9. package/DataTable/index.d.ts +0 -5
  10. package/DataTable/utils/getIdOrCodeOrIndex.d.ts +1 -2
  11. package/DataTable/utils/handleCopyTable.d.ts +1 -0
  12. package/DataTable/utils/index.d.ts +4 -2
  13. package/DataTable/utils/primarySelectedValue.d.ts +1 -0
  14. package/DataTable/utils/queryParams.d.ts +6 -0
  15. package/DataTable/utils/removeCleanRows.d.ts +1 -1
  16. package/DataTable/utils/rowClick.d.ts +24 -3
  17. package/DataTable/utils/useDeepEqualMemo.d.ts +1 -0
  18. package/DataTable/utils/useTableParams.d.ts +49 -0
  19. package/FormComponents/Uploader.d.ts +34 -1
  20. package/FormComponents/index.d.ts +111 -45
  21. package/MatchHeaders.d.ts +9 -10
  22. package/SimpleStepViz.d.ts +2 -1
  23. package/TgSuggest/index.d.ts +1 -21
  24. package/UploadCsvWizard.d.ts +1 -1
  25. package/index.cjs.js +41038 -45265
  26. package/index.d.ts +3 -2
  27. package/index.es.js +44524 -48751
  28. package/package.json +2 -8
  29. package/src/DataTable/CellDragHandle.js +70 -69
  30. package/src/DataTable/ColumnFilterMenu.js +18 -18
  31. package/src/DataTable/Columns.js +1066 -0
  32. package/src/DataTable/DisplayOptions.js +173 -192
  33. package/src/DataTable/EditabelCell.js +6 -16
  34. package/src/DataTable/FilterAndSortMenu.js +213 -234
  35. package/src/DataTable/PagingTool.js +47 -56
  36. package/src/DataTable/SearchBar.js +3 -3
  37. package/src/DataTable/SortableColumns.js +44 -39
  38. package/src/DataTable/ThComponent.js +44 -0
  39. package/src/DataTable/dataTableEnhancer.js +35 -294
  40. package/src/DataTable/index.js +2933 -3601
  41. package/src/DataTable/utils/getIdOrCodeOrIndex.js +1 -1
  42. package/src/DataTable/utils/handleCopyTable.js +16 -0
  43. package/src/DataTable/utils/index.js +7 -3
  44. package/src/DataTable/utils/primarySelectedValue.js +1 -0
  45. package/src/DataTable/utils/queryParams.js +42 -13
  46. package/src/DataTable/utils/removeCleanRows.js +3 -3
  47. package/src/DataTable/utils/rowClick.js +34 -9
  48. package/src/DataTable/utils/selection.js +1 -1
  49. package/src/DataTable/utils/useDeepEqualMemo.js +10 -0
  50. package/src/DataTable/utils/useTableParams.js +361 -0
  51. package/src/DataTable/utils/withTableParams.js +30 -87
  52. package/src/DataTable/validateTableWideErrors.js +1 -1
  53. package/src/DialogFooter/index.js +3 -3
  54. package/src/FillWindow.js +2 -3
  55. package/src/FormComponents/Uploader.js +825 -784
  56. package/src/FormComponents/index.js +441 -603
  57. package/src/FormComponents/tryToMatchSchemas.js +1 -6
  58. package/src/MatchHeaders.js +27 -22
  59. package/src/SimpleStepViz.js +19 -23
  60. package/src/TgSuggest/index.js +94 -106
  61. package/src/UploadCsvWizard.js +570 -577
  62. package/src/index.js +4 -3
  63. package/src/showDialogOnDocBody.js +5 -9
  64. package/src/useDialog.js +25 -26
  65. package/src/utils/commandControls.js +2 -2
  66. package/src/utils/handlerHelpers.js +19 -25
  67. package/src/utils/popoverOverflowModifiers.js +1 -1
  68. package/src/utils/renderOnDoc.js +8 -5
  69. package/src/utils/tagUtils.js +3 -3
  70. package/src/utils/useTraceUpdate.js +19 -0
  71. package/src/wrapDialog.js +0 -2
  72. package/style.css +251 -251
  73. package/useDialog.d.ts +2 -6
  74. package/utils/renderOnDoc.d.ts +1 -1
  75. package/utils/tagUtils.d.ts +5 -1
  76. package/utils/useTraceUpdate.d.ts +1 -0
@@ -1,4 +1,4 @@
1
- import React, { Component } from "react";
1
+ import React from "react";
2
2
  import { MouseSensor, useSensor, useSensors, DndContext } from "@dnd-kit/core";
3
3
  import {
4
4
  SortableContext,
@@ -6,8 +6,16 @@ import {
6
6
  } from "@dnd-kit/sortable";
7
7
  import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
8
8
 
9
- function CustomTheadComponent(props) {
10
- const headerColumns = props.children.props.children;
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;
11
19
  const mouseSensor = useSensor(MouseSensor, {
12
20
  activationConstraint: {
13
21
  distance: 10
@@ -15,7 +23,7 @@ function CustomTheadComponent(props) {
15
23
  });
16
24
 
17
25
  const sensors = useSensors(mouseSensor);
18
- function handleDragEnd(event) {
26
+ const handleDragEnd = event => {
19
27
  const { active, over } = event;
20
28
 
21
29
  if (!over || !active) {
@@ -25,40 +33,36 @@ function CustomTheadComponent(props) {
25
33
  if (active.id === over.id) {
26
34
  return;
27
35
  }
28
- props.onSortEnd({
36
+
37
+ onSortEnd({
29
38
  oldIndex: parseInt(active.id),
30
39
  newIndex: parseInt(over.id)
31
40
  });
32
- }
41
+ };
33
42
 
34
43
  return (
35
44
  <DndContext
36
- onDragStart={props.onSortStart}
45
+ onDragStart={onSortStart}
37
46
  onDragEnd={handleDragEnd}
38
47
  modifiers={[restrictToHorizontalAxis]}
39
48
  sensors={sensors}
40
49
  >
41
- <SortableContext
42
- items={headerColumns.map((_item, index) => `${index}`)}
43
- strategy={horizontalListSortingStrategy}
44
- >
45
- <div className={"rt-thead " + props.className} style={props.style}>
46
- <div className="rt-tr">
47
- {headerColumns.map(column => {
48
- // if a column is marked as immovable just return regular column
49
- if (column.props.immovable === "true") return column;
50
- // keeps track of hidden columns here so columnIndex might not equal i
51
- return column;
52
- })}
53
- </div>
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>
54
58
  </div>
55
- </SortableContext>
59
+ </div>
56
60
  </DndContext>
57
61
  );
58
- }
62
+ };
59
63
 
60
- class SortableColumns extends Component {
61
- shouldCancelStart = e => {
64
+ const SortableColumns = ({ className, style, children, moveColumn }) => {
65
+ const shouldCancelStart = e => {
62
66
  const className = e.target.className;
63
67
  // if its an svg then it's a blueprint icon
64
68
  return (
@@ -66,30 +70,31 @@ class SortableColumns extends Component {
66
70
  );
67
71
  };
68
72
 
69
- onSortEnd = (...args) => {
73
+ const onSortEnd = (...args) => {
70
74
  const { oldIndex, newIndex } = args[0];
71
75
  document.body.classList.remove("drag-active");
72
- this.props.moveColumn({
76
+ moveColumn({
73
77
  oldIndex,
74
78
  newIndex
75
79
  });
76
80
  };
77
81
 
78
- onSortStart = () => {
82
+ const onSortStart = () => {
79
83
  document.body.classList.add("drag-active");
80
84
  };
81
85
 
82
- render() {
83
- return (
84
- <CustomTheadComponent
85
- {...this.props}
86
- onSortStart={this.onSortStart}
87
- onSortEnd={this.onSortEnd}
88
- helperClass="above-dialog"
89
- shouldCancelStart={this.shouldCancelStart}
90
- />
91
- );
92
- }
93
- }
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
+ };
94
99
 
95
100
  export default SortableColumns;
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import { useSortable } from "@dnd-kit/sortable";
3
+ import { CSS } from "@dnd-kit/utilities";
4
+ import classNames from "classnames";
5
+
6
+ export const ThComponent = ({
7
+ toggleSort,
8
+ immovable,
9
+ className,
10
+ children,
11
+ style,
12
+ columnindex,
13
+ ...rest
14
+ }) => {
15
+ const index = columnindex ?? -1;
16
+ const { attributes, listeners, setNodeRef, transform, transition } =
17
+ useSortable({
18
+ id: `${index}`,
19
+ disabled: immovable === "true"
20
+ });
21
+
22
+ const sortStyles = {
23
+ transform: CSS.Transform.toString(transform),
24
+ transition
25
+ };
26
+
27
+ return (
28
+ <div
29
+ style={{ ...sortStyles, ...style }}
30
+ ref={setNodeRef}
31
+ {...attributes}
32
+ {...listeners}
33
+ className={classNames("rt-th", className)}
34
+ onClick={e => toggleSort && toggleSort(e)}
35
+ role="columnheader"
36
+ tabIndex="-1" // Resolves eslint issues without implementing keyboard navigation incorrectly
37
+ columnindex={columnindex}
38
+ index={index}
39
+ {...rest}
40
+ >
41
+ {children}
42
+ </div>
43
+ );
44
+ };
@@ -5,300 +5,41 @@
5
5
  * @property {string} queryName What the props come back on ( by default = modelName + 'Query')
6
6
  */
7
7
  import { reduxForm } from "redux-form";
8
-
9
- import { arrayMove } from "@dnd-kit/sortable";
10
- import { toArray, keyBy, get } from "lodash-es";
11
- import { withProps, withState, branch, compose } from "recompose";
12
- import withTableParams from "../DataTable/utils/withTableParams";
13
- import convertSchema from "../DataTable/utils/convertSchema";
14
- import { viewColumn, openColumn } from "../DataTable/viewColumn";
8
+ import { branch, compose, withProps } from "recompose";
15
9
  import pureNoFunc from "../utils/pureNoFunc";
16
- import tgFormValues from "../utils/tgFormValues";
17
- import getTableConfigFromStorage from "./utils/getTableConfigFromStorage";
18
-
10
+ import { withRouter } from "react-router-dom";
11
+
12
+ /*
13
+ Right now DataTable is doing the same as withTableParams, so the logic is being
14
+ run twice. We need to refactor this to make it more DRY.
15
+ We could do two possible refactorings:
16
+ - remove withTableParams and just give all the appropiate props to DataTable. This would
17
+ make the component simpler.
18
+ - remove the logic from DataTable and just use withTableParams and a new hook called
19
+ useTableParams. This would be more flexible in the case we want to be able to use
20
+ pagination in a different component.
21
+ We should avoid having the component handle all the different
22
+ cases of input because of the next reasons:
23
+ 1. It makes the component more complex and harder to understand.
24
+ 2. It makes the component harder to test.
25
+ 3. It makes the component harder to reuse.
26
+ 4. Maintaining the the logic in the component is harder.
27
+ Keeping the logic and uses simple makes maintaining easier.
28
+
29
+ In my opinion, reduxForm could be replaced here with regular redux or even just be taken down.
30
+ Could be a major simplification, but this needs to be analized with lims for better
31
+ understanding if it's possible.
32
+ */
19
33
  export default compose(
20
- // maybe we need this in some cases?
21
- // tgFormValues("reduxFormEntities"),
22
- // withProps(props => {
23
- // const entities = props.reduxFormEntities || props.entities;
24
- // return {
25
- // _origEntities: props.entities,
26
- // entities
27
- // };
28
- // }),
29
- //connect to withTableParams here in the dataTable component so that, in the case that the table is not manually connected,
30
- withTableParams({
31
- isLocalCall: true
32
- }),
33
- branch(
34
- props => props.showEmptyColumnsByDefault,
35
- withState("showForcedHiddenColumns", "setShowForcedHidden", true),
36
- withState("showForcedHiddenColumns", "setShowForcedHidden", false)
37
- ),
38
- withProps(ownProps => {
39
- let propsToUse = ownProps;
40
- if (!ownProps.isTableParamsConnected) {
41
- //this is the case where we're hooking up to withTableParams locally, so we need to take the tableParams off the props
42
- propsToUse = {
43
- ...ownProps,
44
- ...ownProps.tableParams
45
- };
46
- }
47
-
48
- const {
49
- schema,
50
- withDisplayOptions,
51
- syncDisplayOptionsToDb,
52
- formName,
53
- tableConfigurations,
54
- deleteTableConfiguration,
55
- upsertTableConfiguration,
56
- upsertFieldOption,
57
- currentUser,
58
- isViewable,
59
- isOpenable,
60
- entities = [],
61
- cellRenderer = {},
62
- showForcedHiddenColumns,
63
- isSimple,
64
- isInfinite,
65
- compact = true,
66
- extraCompact
67
- } = propsToUse;
68
- let schemaToUse = convertSchema(schema);
69
- let fieldOptsByPath = {};
70
- let tableConfig = {};
71
- let resetDefaultVisibility;
72
- let updateColumnVisibility;
73
- let persistPageSize;
74
- let moveColumnPersist;
75
- let resizePersist;
76
- let updateTableDisplayDensity;
77
- let compactToUse = !!compact;
78
- let extraCompactToUse = !!extraCompact;
79
-
80
- if (isViewable) {
81
- schemaToUse.fields = [viewColumn, ...schemaToUse.fields];
82
- }
83
- if (isOpenable) {
84
- schemaToUse.fields = [openColumn, ...schemaToUse.fields];
85
- }
86
- // this must come before handling orderings.
87
- schemaToUse.fields = schemaToUse.fields.map(field => {
88
- if (field.placementPath) {
89
- return {
90
- ...field,
91
- sortDisabled:
92
- field.sortDisabled ||
93
- (typeof field.path === "string" && field.path.includes(".")),
94
- path: field.placementPath
95
- };
96
- } else {
97
- return field;
98
- }
99
- });
100
- const hasOptionForForcedHidden =
101
- withDisplayOptions && (isSimple || isInfinite);
102
- if (withDisplayOptions) {
103
- if (syncDisplayOptionsToDb) {
104
- tableConfig = tableConfigurations && tableConfigurations[0];
105
- } else {
106
- tableConfig = getTableConfigFromStorage(formName);
107
- }
108
- if (!tableConfig) {
109
- tableConfig = {
110
- fieldOptions: []
111
- };
112
- }
113
- if (tableConfig.density) {
114
- compactToUse = tableConfig.density === "compact";
115
- }
116
- if (tableConfig.density) {
117
- extraCompactToUse = tableConfig.density === "extraCompact";
118
- }
119
- const columnOrderings = tableConfig.columnOrderings;
120
- fieldOptsByPath = keyBy(tableConfig.fieldOptions, "path");
121
- schemaToUse = {
122
- ...schemaToUse,
123
- fields: schemaToUse.fields.map(field => {
124
- const fieldOpt = fieldOptsByPath[field.path];
125
- let noValsForField = false;
126
- // only add this hidden column ability if no paging
127
- if (!showForcedHiddenColumns && hasOptionForForcedHidden) {
128
- noValsForField = entities.every(e => {
129
- const val = get(e, field.path);
130
- return field.render
131
- ? !field.render(val, e)
132
- : cellRenderer[field.path]
133
- ? !cellRenderer[field.path](val, e)
134
- : !val;
135
- });
136
- }
137
- if (noValsForField) {
138
- return {
139
- ...field,
140
- isHidden: true,
141
- isForcedHidden: true
142
- };
143
- } else if (fieldOpt) {
144
- return {
145
- ...field,
146
- isHidden: fieldOpt.isHidden
147
- };
148
- } else {
149
- return field;
150
- }
151
- })
152
- };
153
-
154
- if (columnOrderings) {
155
- const fieldsWithOrders = [];
156
- const fieldsWithoutOrder = [];
157
- // if a new field has been added since the orderings were set then we want
158
- // it to be at the end instead of the beginning
159
- schemaToUse.fields.forEach(field => {
160
- if (columnOrderings.indexOf(field.path) > -1) {
161
- fieldsWithOrders.push(field);
162
- } else {
163
- fieldsWithoutOrder.push(field);
164
- }
165
- });
166
- schemaToUse.fields = fieldsWithOrders
167
- .sort(({ path: path1 }, { path: path2 }) => {
168
- return (
169
- columnOrderings.indexOf(path1) - columnOrderings.indexOf(path2)
170
- );
171
- })
172
- .concat(fieldsWithoutOrder);
173
- tableConfig.columnOrderings = schemaToUse.fields.map(f => f.path);
174
- }
175
-
176
- if (syncDisplayOptionsToDb) {
177
- //sync up to db
178
- let tableConfigurationId;
179
- resetDefaultVisibility = function () {
180
- tableConfigurationId = tableConfig.id;
181
-
182
- if (tableConfigurationId) {
183
- deleteTableConfiguration(tableConfigurationId);
184
- }
185
- };
186
- updateColumnVisibility = function ({ shouldShow, path }) {
187
- if (tableConfigurationId) {
188
- const existingFieldOpt = fieldOptsByPath[path] || {};
189
- upsertFieldOption({
190
- id: existingFieldOpt.id,
191
- path,
192
- isHidden: !shouldShow,
193
- tableConfigurationId
194
- });
195
- } else {
196
- upsertTableConfiguration({
197
- userId: currentUser.user.id,
198
- formName,
199
- fieldOptions: [
200
- {
201
- path,
202
- isHidden: !shouldShow
203
- }
204
- ]
205
- });
206
- }
207
- };
208
- } else {
209
- const syncStorage = () => {
210
- window.localStorage.setItem(formName, JSON.stringify(tableConfig));
211
- };
212
-
213
- //sync display options with localstorage
214
- resetDefaultVisibility = function () {
215
- window.localStorage.removeItem(formName);
216
- };
217
- updateColumnVisibility = function ({ path, paths, shouldShow }) {
218
- const newFieldOpts = {
219
- ...fieldOptsByPath
220
- };
221
- const pathsToUse = paths ? paths : [path];
222
- pathsToUse.forEach(path => {
223
- newFieldOpts[path] = { path, isHidden: !shouldShow };
224
- });
225
- tableConfig.fieldOptions = toArray(newFieldOpts);
226
- syncStorage();
227
- };
228
- updateTableDisplayDensity = function (density) {
229
- tableConfig.density = density;
230
- syncStorage();
231
- };
232
- persistPageSize = function (pageSize) {
233
- tableConfig.userSetPageSize = pageSize;
234
- syncStorage();
235
- };
236
- moveColumnPersist = function ({ oldIndex, newIndex }) {
237
- // we might already have an array of the fields [path1, path2, ..etc]
238
- const columnOrderings =
239
- tableConfig.columnOrderings ||
240
- schemaToUse.fields.map(({ path }) => path); // columnOrderings is [path1, path2, ..etc]
241
-
242
- tableConfig.columnOrderings = arrayMove(
243
- columnOrderings,
244
- oldIndex,
245
- newIndex
246
- );
247
- syncStorage();
248
- };
249
- resizePersist = function (newResized) {
250
- tableConfig.resized = newResized;
251
- syncStorage();
252
- };
253
- }
254
- }
255
- const resized = tableConfig.resized;
256
- return {
257
- ...propsToUse,
258
- schema: schemaToUse,
259
- compact: compactToUse,
260
- extraCompact: extraCompactToUse,
261
- resized,
262
- resetDefaultVisibility,
263
- updateColumnVisibility,
264
- persistPageSize,
265
- updateTableDisplayDensity,
266
- resizePersist,
267
- moveColumnPersist,
268
- hasOptionForForcedHidden
269
- };
270
- }),
271
- branch(props => !props.noForm, reduxForm({})), //the formName is passed via withTableParams and is often user overridden
272
- tgFormValues(
273
- "localStorageForceUpdate",
274
- "reduxFormQueryParams",
275
- "reduxFormSearchInput",
276
- "onlyShowRowsWErrors",
277
- "reduxFormSelectedEntityIdMap",
278
- "reduxFormExpandedEntityIdMap",
279
- "reduxFormSelectedCells",
280
- "reduxFormEditingCell",
281
- "reduxFormEditingCellSelectAll",
282
- "reduxFormCellIdToEditValue",
283
- "reduxFormEntities",
284
- "reduxFormCellValidation",
285
- "reduxFormEntitiesUndoRedoStack"
286
- ),
287
- withProps(props => {
288
- const entities = props.reduxFormEntities || props.entities;
289
- return {
290
- _origEntities: props.entities,
291
- entities
292
- };
293
- }),
294
- // withFields({
295
- // names: [
296
- // "localStorageForceUpdate",
297
- // "reduxFormQueryParams",
298
- // "reduxFormSearchInput",
299
- // "reduxFormSelectedEntityIdMap",
300
- // "reduxFormExpandedEntityIdMap"
301
- // ]
302
- // }),
303
- branch(props => !props.alwaysRerender, pureNoFunc)
34
+ // Function to make sure we don't rerender unless there are changes
35
+ // in the params
36
+ branch(props => !props.alwaysRerender, pureNoFunc),
37
+ // form prop is needed for redux-form, but we are giving this prop as
38
+ // formName, so we need to rename it. Previously it was done in the withTableParams, but now
39
+ // it doesn't have it by default.
40
+ withProps(({ formName }) => ({ form: formName })),
41
+ // the formName is passed via withTableParams and is often user overridden
42
+ branch(props => !props.noForm, reduxForm({})),
43
+ // don't use withRouter if noRouter is passed!
44
+ branch(props => !props.noRouter, withRouter)
304
45
  );