@teselagen/ui 0.4.14 → 0.4.15

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.d.ts +1 -1
  2. package/AssignDefaultsModeContext.d.ts +1 -1
  3. package/AsyncValidateFieldSpinner/index.d.ts +1 -1
  4. package/BlueprintError/index.d.ts +1 -1
  5. package/BounceLoader/index.d.ts +1 -1
  6. package/CollapsibleCard/index.d.ts +1 -1
  7. package/DNALoader/index.d.ts +1 -1
  8. package/DataTable/CellDragHandle.d.ts +1 -1
  9. package/DataTable/ColumnFilterMenu.d.ts +14 -0
  10. package/DataTable/DisabledLoadingComponent.d.ts +1 -1
  11. package/DataTable/DisplayOptions.d.ts +2 -2
  12. package/DataTable/DropdownCell.d.ts +8 -0
  13. package/DataTable/EditabelCell.d.ts +10 -0
  14. package/DataTable/FilterAndSortMenu.d.ts +2 -2
  15. package/DataTable/SearchBar.d.ts +1 -1
  16. package/DataTable/SortableColumns.d.ts +2 -2
  17. package/DataTable/TableFormTrackerContext.d.ts +1 -1
  18. package/DataTable/defaultProps.d.ts +1 -1
  19. package/DataTable/index.d.ts +0 -5
  20. package/DataTable/utils/computePresets.d.ts +1 -1
  21. package/DataTable/utils/formatPasteData.d.ts +5 -0
  22. package/DataTable/utils/getAllRows.d.ts +1 -0
  23. package/DataTable/utils/getCellCopyText.d.ts +1 -0
  24. package/DataTable/utils/getCellInfo.d.ts +17 -0
  25. package/DataTable/utils/getFieldPathToField.d.ts +1 -0
  26. package/DataTable/utils/getIdOrCodeOrIndex.d.ts +1 -2
  27. package/DataTable/utils/getLastSelectedEntity.d.ts +1 -0
  28. package/DataTable/utils/getNewEntToSelect.d.ts +6 -0
  29. package/DataTable/utils/getRowCopyText.d.ts +3 -0
  30. package/DataTable/utils/handleCopyColumn.d.ts +1 -0
  31. package/DataTable/utils/handleCopyHelper.d.ts +1 -0
  32. package/DataTable/utils/handleCopyRows.d.ts +5 -0
  33. package/DataTable/utils/index.d.ts +21 -0
  34. package/DataTable/utils/isBottomRightCornerOfRectangle.d.ts +8 -0
  35. package/DataTable/utils/isEntityClean.d.ts +1 -0
  36. package/DataTable/utils/removeCleanRows.d.ts +4 -0
  37. package/DataTable/utils/rowClick.d.ts +10 -2
  38. package/DataTable/utils/utils.d.ts +5 -0
  39. package/DataTable/viewColumn.d.ts +2 -2
  40. package/DialogFooter/index.d.ts +1 -1
  41. package/DropdownButton.d.ts +1 -1
  42. package/FillWindow.d.ts +1 -1
  43. package/FormComponents/LoadingDots.d.ts +1 -1
  44. package/FormComponents/Uploader.d.ts +29 -1
  45. package/FormComponents/index.d.ts +34 -34
  46. package/FormComponents/itemUpload.d.ts +1 -1
  47. package/HotkeysDialog/index.d.ts +1 -1
  48. package/InfoHelper/index.d.ts +1 -1
  49. package/IntentText/index.d.ts +1 -1
  50. package/MatchHeaders.d.ts +1 -1
  51. package/MenuBar/index.d.ts +4 -4
  52. package/PromptUnsavedChanges/index.d.ts +1 -1
  53. package/README.md +18 -0
  54. package/ResizableDraggableDialog/index.d.ts +2 -2
  55. package/ScrollToTop/index.d.ts +1 -1
  56. package/SimpleStepViz.d.ts +1 -1
  57. package/Tag.d.ts +1 -1
  58. package/TagSelect/index.d.ts +1 -1
  59. package/TgSelect/index.d.ts +2 -2
  60. package/TgSuggest/index.d.ts +3 -3
  61. package/Timeline/TimelineEvent.d.ts +1 -1
  62. package/Timeline/index.d.ts +2 -2
  63. package/UploadCsvWizard.d.ts +1 -1
  64. package/customIcons.d.ts +19 -19
  65. package/enhancers/withField.d.ts +1 -1
  66. package/enhancers/withFields.d.ts +1 -1
  67. package/enhancers/withLocalStorage.d.ts +1 -1
  68. package/index.cjs.js +14026 -12765
  69. package/index.d.ts +60 -60
  70. package/index.es.js +13844 -12583
  71. package/package.json +7 -4
  72. package/showConfirmationDialog/index.d.ts +2 -2
  73. package/src/DataTable/CellDragHandle.js +6 -7
  74. package/src/DataTable/ColumnFilterMenu.js +60 -0
  75. package/src/DataTable/DropdownCell.js +61 -0
  76. package/src/DataTable/EditabelCell.js +55 -0
  77. package/src/DataTable/PagingTool.js +1 -1
  78. package/src/DataTable/SortableColumns.js +53 -18
  79. package/src/DataTable/dataTableEnhancer.js +1 -1
  80. package/src/DataTable/index.js +385 -759
  81. package/src/DataTable/utils/formatPasteData.js +16 -0
  82. package/src/DataTable/utils/getAllRows.js +11 -0
  83. package/src/DataTable/utils/getCellCopyText.js +7 -0
  84. package/src/DataTable/utils/getCellInfo.js +36 -0
  85. package/src/DataTable/utils/getFieldPathToField.js +7 -0
  86. package/src/DataTable/utils/getIdOrCodeOrIndex.js +1 -1
  87. package/src/DataTable/utils/getLastSelectedEntity.js +11 -0
  88. package/src/DataTable/utils/getNewEntToSelect.js +25 -0
  89. package/src/DataTable/utils/getRowCopyText.js +28 -0
  90. package/src/DataTable/utils/handleCopyColumn.js +21 -0
  91. package/src/DataTable/utils/handleCopyHelper.js +15 -0
  92. package/src/DataTable/utils/handleCopyRows.js +23 -0
  93. package/src/DataTable/utils/index.js +51 -0
  94. package/src/DataTable/utils/isBottomRightCornerOfRectangle.js +20 -0
  95. package/src/DataTable/utils/isEntityClean.js +15 -0
  96. package/src/DataTable/utils/removeCleanRows.js +22 -0
  97. package/src/DataTable/utils/rowClick.js +7 -4
  98. package/src/DataTable/utils/selection.js +1 -1
  99. package/src/DataTable/utils/utils.js +37 -0
  100. package/src/DataTable/validateTableWideErrors.js +1 -1
  101. package/src/FillWindow.js +2 -3
  102. package/src/FormComponents/Uploader.js +400 -400
  103. package/src/FormComponents/tryToMatchSchemas.js +0 -6
  104. package/src/UploadCsvWizard.js +312 -371
  105. package/src/index.js +3 -3
  106. package/src/showDialogOnDocBody.js +5 -9
  107. package/src/useDialog.js +7 -4
  108. package/src/utils/renderOnDoc.js +8 -5
  109. package/style.css +7 -7
  110. package/useDialog.d.ts +2 -2
  111. package/utils/adHoc.d.ts +1 -1
  112. package/utils/commandControls.d.ts +5 -5
  113. package/utils/hotkeyUtils.d.ts +1 -1
  114. package/utils/menuUtils.d.ts +7 -7
  115. package/utils/renderOnDoc.d.ts +1 -1
  116. package/utils/tagUtils.d.ts +1 -1
  117. package/utils/tgFormValues.d.ts +1 -1
  118. package/utils/withStore.d.ts +1 -1
  119. package/wrapDialog.d.ts +1 -1
@@ -1,4 +1,4 @@
1
- import React, { useRef, useState } from "react";
1
+ import React, { useRef, useState, useEffect } from "react";
2
2
  import { reduxForm, change, formValueSelector, destroy } from "redux-form";
3
3
  import { Callout, Icon, Intent, Tab, Tabs } from "@blueprintjs/core";
4
4
  import immer from "immer";
@@ -12,10 +12,11 @@ import { tgFormValueSelector } from "./utils/tgFormValues";
12
12
  import { some } from "lodash-es";
13
13
  import { times } from "lodash-es";
14
14
  import DialogFooter from "./DialogFooter";
15
- import DataTable, { removeCleanRows } from "./DataTable";
15
+ import DataTable from "./DataTable";
16
+ import { removeCleanRows } from "./DataTable/utils";
16
17
  import wrapDialog from "./wrapDialog";
17
18
  import { omit } from "lodash-es";
18
- import { connect } from "react-redux";
19
+ import { useDispatch, useSelector } from "react-redux";
19
20
  import { MatchHeaders } from "./MatchHeaders";
20
21
  import { isEmpty } from "lodash-es";
21
22
  import { addSpecialPropToAsyncErrs } from "./FormComponents/tryToMatchSchemas";
@@ -35,64 +36,62 @@ const UploadCsvWizardDialog = compose(
35
36
  reduxForm({
36
37
  form: "UploadCsvWizardDialog"
37
38
  }),
38
- connect(
39
- (state, props) => {
40
- if (props.filesWIssues.length > 0) {
41
- const reduxFormEntitiesArray = [];
42
- const finishedFiles = props.filesWIssues.map((f, i) => {
43
- const { reduxFormEntities, reduxFormCellValidation } =
44
- formValueSelector(`editableCellTable-${i}`)(
45
- state,
46
- "reduxFormEntities",
47
- "reduxFormCellValidation"
48
- );
49
- reduxFormEntitiesArray.push(reduxFormEntities);
50
- const { entsToUse, validationToUse } = removeCleanRows(
51
- reduxFormEntities,
52
- reduxFormCellValidation
53
- );
54
- return (
55
- entsToUse &&
56
- entsToUse.length &&
57
- !some(validationToUse, v => v) &&
58
- entsToUse
59
- );
60
- });
61
- return {
62
- reduxFormEntitiesArray,
63
- finishedFiles
64
- };
65
- }
66
- },
67
- { changeForm: change, destroyForms: destroy }
68
- ),
69
39
  observer
70
40
  )(function UploadCsvWizardDialogOuter({
71
- validateAgainstSchema,
72
- reduxFormEntitiesArray,
73
- filesWIssues: _filesWIssues,
74
- finishedFiles,
75
- onUploadWizardFinish,
76
- doAllFilesHaveSameHeaders,
77
- destroyForms,
78
41
  csvValidationIssue,
42
+ doAllFilesHaveSameHeaders,
43
+ filesWIssues: _filesWIssues,
44
+ flippedMatchedHeaders,
79
45
  ignoredHeadersMsg,
80
- searchResults,
81
46
  matchedHeaders,
47
+ onUploadWizardFinish,
48
+ searchResults,
82
49
  userSchema,
83
- flippedMatchedHeaders,
84
- changeForm
50
+ validateAgainstSchema
85
51
  }) {
52
+ const dispatch = useDispatch();
86
53
  // will unmount state hook
87
- React.useEffect(() => {
54
+ useEffect(() => {
88
55
  return () => {
89
- destroyForms(
90
- "editableCellTable",
91
- ...times(_filesWIssues.length, i => `editableCellTable-${i}`)
56
+ dispatch(
57
+ destroy(
58
+ "editableCellTable",
59
+ ...times(_filesWIssues.length, i => `editableCellTable-${i}`)
60
+ )
92
61
  );
93
62
  };
94
- // eslint-disable-next-line react-hooks/exhaustive-deps
95
- }, []);
63
+ }, [_filesWIssues.length, dispatch]);
64
+
65
+ const changeForm = (...args) => dispatch(change(...args));
66
+ const { reduxFormEntitiesArray, finishedFiles } = useSelector(state => {
67
+ if (_filesWIssues.length > 0) {
68
+ const reduxFormEntitiesArray = [];
69
+ const finishedFiles = _filesWIssues.map((f, i) => {
70
+ const { reduxFormEntities, reduxFormCellValidation } =
71
+ formValueSelector(`editableCellTable-${i}`)(
72
+ state,
73
+ "reduxFormEntities",
74
+ "reduxFormCellValidation"
75
+ );
76
+ reduxFormEntitiesArray.push(reduxFormEntities);
77
+ const { entsToUse, validationToUse } = removeCleanRows(
78
+ reduxFormEntities,
79
+ reduxFormCellValidation
80
+ );
81
+ return (
82
+ entsToUse &&
83
+ entsToUse.length &&
84
+ !some(validationToUse, v => v) &&
85
+ entsToUse
86
+ );
87
+ });
88
+ return {
89
+ reduxFormEntitiesArray,
90
+ finishedFiles
91
+ };
92
+ }
93
+ });
94
+
96
95
  const [hasSubmittedOuter, setSubmittedOuter] = useState();
97
96
  const [steps, setSteps] = useState(getInitialSteps(true));
98
97
 
@@ -118,7 +117,6 @@ const UploadCsvWizardDialog = compose(
118
117
  >
119
118
  {filesWIssues.map((f, i) => {
120
119
  const isGood = finishedFiles[i];
121
-
122
120
  const isThisTheLastBadFile = finishedFiles.every((ff, j) => {
123
121
  if (i === j) {
124
122
  return true;
@@ -135,108 +133,98 @@ const UploadCsvWizardDialog = compose(
135
133
  <Icon
136
134
  intent={isGood ? "success" : "warning"}
137
135
  icon={isGood ? "tick-circle" : "warning-sign"}
138
- ></Icon>{" "}
136
+ />{" "}
139
137
  {f.file.name}
140
138
  </div>
141
139
  }
142
140
  panel={
143
141
  <UploadCsvWizardDialogInner
144
- {...{
145
- isThisTheLastBadFile,
146
- onBackClick:
147
- doAllFilesHaveSameHeaders &&
148
- (() => {
149
- setSubmittedOuter(false);
150
- setSteps(getInitialSteps(true));
151
- }),
152
- onMultiFileUploadSubmit: async () => {
153
- let nextUnfinishedFile;
154
- //find the next unfinished file
155
- for (
156
- let j = (i + 1) % finishedFiles.length;
157
- j < finishedFiles.length;
158
- j++
159
- ) {
160
- if (j === i) {
161
- break;
162
- } else if (!finishedFiles[j]) {
163
- nextUnfinishedFile = j;
164
- break;
165
- } else if (j === finishedFiles.length - 1) {
166
- j = -1;
167
- }
142
+ isThisTheLastBadFile={isThisTheLastBadFile}
143
+ onBackClick={
144
+ doAllFilesHaveSameHeaders &&
145
+ (() => {
146
+ setSubmittedOuter(false);
147
+ setSteps(getInitialSteps(true));
148
+ })
149
+ }
150
+ onMultiFileUploadSubmit={async () => {
151
+ let nextUnfinishedFile;
152
+ //find the next unfinished file
153
+ for (
154
+ let j = (i + 1) % finishedFiles.length;
155
+ j < finishedFiles.length;
156
+ j++
157
+ ) {
158
+ if (j === i) {
159
+ break;
160
+ } else if (!finishedFiles[j]) {
161
+ nextUnfinishedFile = j;
162
+ break;
163
+ } else if (j === finishedFiles.length - 1) {
164
+ j = -1;
168
165
  }
169
-
170
- if (nextUnfinishedFile !== undefined) {
171
- //do async validation here if needed
172
-
173
- const currentEnts =
174
- reduxFormEntitiesArray[focusedTab];
175
-
166
+ }
167
+ if (nextUnfinishedFile !== undefined) {
168
+ //do async validation here if needed
169
+ const currentEnts = reduxFormEntitiesArray[focusedTab];
170
+ if (
171
+ await asyncValidateHelper(
172
+ validateAgainstSchema,
173
+ currentEnts,
174
+ changeForm,
175
+ `editableCellTable-${focusedTab}`
176
+ )
177
+ )
178
+ return;
179
+ setFocusedTab(nextUnfinishedFile);
180
+ } else {
181
+ //do async validation here if needed
182
+ for (const [i, ents] of finishedFiles.entries()) {
176
183
  if (
177
184
  await asyncValidateHelper(
178
185
  validateAgainstSchema,
179
- currentEnts,
186
+ ents,
180
187
  changeForm,
181
- `editableCellTable-${focusedTab}`
188
+ `editableCellTable-${i}`
182
189
  )
183
190
  )
184
191
  return;
185
-
186
- setFocusedTab(nextUnfinishedFile);
187
- } else {
188
- //do async validation here if needed
189
-
190
- for (const [i, ents] of finishedFiles.entries()) {
191
- if (
192
- await asyncValidateHelper(
193
- validateAgainstSchema,
194
- ents,
195
- changeForm,
196
- `editableCellTable-${i}`
197
- )
198
- )
199
- return;
200
- }
201
-
202
- //we are done
203
- onUploadWizardFinish({
204
- res: finishedFiles.map(ents => {
205
- return maybeStripIdFromEntities(
206
- ents,
207
- f.validateAgainstSchema
208
- );
209
- })
210
- });
211
192
  }
212
- },
213
- validateAgainstSchema,
214
- reduxFormEntitiesArray,
215
- filesWIssues,
216
- finishedFiles,
217
- onUploadWizardFinish,
218
- doAllFilesHaveSameHeaders,
219
- destroyForms,
220
- setFilesWIssues,
221
- csvValidationIssue,
222
- ignoredHeadersMsg,
223
- searchResults,
224
- matchedHeaders,
225
- userSchema,
226
- flippedMatchedHeaders,
227
- // reduxFormEntities,
228
- changeForm,
229
- fileIndex: i,
230
- form: `correctCSVHeadersForm-${i}`,
231
- datatableFormName: `editableCellTable-${i}`,
232
- ...f,
233
- ...(doAllFilesHaveSameHeaders && {
234
- csvValidationIssue: false
235
- })
193
+ //we are done
194
+ onUploadWizardFinish({
195
+ res: finishedFiles.map(ents => {
196
+ return maybeStripIdFromEntities(
197
+ ents,
198
+ f.validateAgainstSchema
199
+ );
200
+ })
201
+ });
202
+ }
236
203
  }}
204
+ validateAgainstSchema={validateAgainstSchema}
205
+ reduxFormEntitiesArray={reduxFormEntitiesArray}
206
+ filesWIssues={filesWIssues}
207
+ finishedFiles={finishedFiles}
208
+ onUploadWizardFinish={onUploadWizardFinish}
209
+ doAllFilesHaveSameHeaders={doAllFilesHaveSameHeaders}
210
+ setFilesWIssues={setFilesWIssues}
211
+ csvValidationIssue={csvValidationIssue}
212
+ ignoredHeadersMsg={ignoredHeadersMsg}
213
+ searchResults={searchResults}
214
+ matchedHeader={matchedHeaders}
215
+ userSchema={userSchema}
216
+ flippedMatchedHeaders={flippedMatchedHeaders}
217
+ changeForm={changeForm}
218
+ fileIndex={i}
219
+ form={`correctCSVHeadersForm-${i}`}
220
+ datatableFormName={`editableCellTable-${i}`}
221
+ {...f}
222
+ {...(doAllFilesHaveSameHeaders && {
223
+ csvValidationIssue: false
224
+ })}
237
225
  />
238
226
  }
239
- ></Tab>
227
+ />
240
228
  );
241
229
  })}
242
230
  </Tabs>
@@ -248,34 +236,27 @@ const UploadCsvWizardDialog = compose(
248
236
  comp = (
249
237
  <>
250
238
  {doAllFilesHaveSameHeaders && (
251
- <SimpleStepViz
252
- style={{ marginTop: 8 }}
253
- steps={steps}
254
- ></SimpleStepViz>
239
+ <SimpleStepViz style={{ marginTop: 8 }} steps={steps} />
255
240
  )}
256
241
 
257
242
  {!hasSubmittedOuter && (
258
243
  <MatchHeaders
259
- {...{
260
- doAllFilesHaveSameHeaders,
261
- datatableFormNames: filesWIssues.map((f, i) => {
262
- return `editableCellTable-${i}`;
263
- }),
264
- reduxFormEntitiesArray,
265
- // onMultiFileUploadSubmit,
266
- csvValidationIssue,
267
- ignoredHeadersMsg,
268
- searchResults,
269
- matchedHeaders,
270
- userSchema,
271
- flippedMatchedHeaders,
272
- // reduxFormEntities,
273
- changeForm,
274
- setFilesWIssues,
275
- filesWIssues,
276
- fileIndex: 0,
277
- ...filesWIssues[0]
278
- }}
244
+ doAllFilesHaveSameHeaders={doAllFilesHaveSameHeaders}
245
+ datatableFormNames={filesWIssues.map((f, i) => {
246
+ return `editableCellTable-${i}`;
247
+ })}
248
+ reduxFormEntitiesArray={reduxFormEntitiesArray}
249
+ csvValidationIssue={csvValidationIssue}
250
+ ignoredHeadersMsg={ignoredHeadersMsg}
251
+ searchResults={searchResults}
252
+ matchedHeaders={matchedHeaders}
253
+ userSchema={userSchema}
254
+ flippedMatchedHeaders={flippedMatchedHeaders}
255
+ changeForm={changeForm}
256
+ setFilesWIssues={setFilesWIssues}
257
+ filesWIssues={filesWIssues}
258
+ fileIndex={0}
259
+ {...filesWIssues[0]}
279
260
  />
280
261
  )}
281
262
  {hasSubmittedOuter && tabs}
@@ -287,230 +268,200 @@ const UploadCsvWizardDialog = compose(
287
268
  setSteps(getInitialSteps(false));
288
269
  }}
289
270
  text="Review and Edit Data"
290
- ></DialogFooter>
271
+ />
291
272
  )}
292
273
  </>
293
274
  );
294
275
  }
295
- return (
296
- <div
297
- style={{
298
- padding: 10
299
- }}
300
- >
301
- {comp}
302
- </div>
303
- );
276
+ return <div style={{ padding: 10 }}>{comp}</div>;
304
277
  } else {
305
278
  return (
306
279
  <UploadCsvWizardDialogInner
307
280
  form="correctCSVHeadersForm"
308
- {...{
309
- validateAgainstSchema,
310
- userSchema,
311
- searchResults,
312
- onUploadWizardFinish,
313
- csvValidationIssue,
314
- ignoredHeadersMsg,
315
- matchedHeaders,
316
- //fromRedux:
317
- changeForm,
318
- setFilesWIssues,
319
- // doAllFilesHaveSameHeaders,
320
- filesWIssues,
321
- flippedMatchedHeaders,
322
- // reduxFormEntities,
323
- // datatableFormNames
324
- fileIndex: 0,
325
- ...filesWIssues[0]
326
- }}
281
+ validateAgainstSchema={validateAgainstSchema}
282
+ userSchema={userSchema}
283
+ searchResults={searchResults}
284
+ onUploadWizardFinish={onUploadWizardFinish}
285
+ csvValidationIssue={csvValidationIssue}
286
+ ignoredHeadersMsg={ignoredHeadersMsg}
287
+ matchedHeaders={matchedHeaders}
288
+ changeForm={changeForm}
289
+ setFilesWIssues={setFilesWIssues}
290
+ filesWIssues={filesWIssues}
291
+ flippedMatchedHeaders={flippedMatchedHeaders}
292
+ fileIndex={0}
293
+ {...filesWIssues[0]}
327
294
  />
328
295
  );
329
296
  }
330
297
  });
331
298
 
332
- const UploadCsvWizardDialogInner = compose(
333
- reduxForm(),
334
- connect((state, props) => {
335
- return formValueSelector(props.datatableFormName || "editableCellTable")(
336
- state,
337
- "reduxFormEntities",
338
- "reduxFormCellValidation"
339
- );
340
- })
341
- )(function UploadCsvWizardDialogInner({
342
- validateAgainstSchema,
343
- userSchema,
344
- searchResults,
345
- onUploadWizardFinish,
346
- csvValidationIssue,
347
- ignoredHeadersMsg,
348
- matchedHeaders,
349
- //fromRedux:
350
- handleSubmit,
351
- fileIndex,
352
- reduxFormEntities,
353
- onBackClick,
354
- reduxFormCellValidation,
355
- changeForm,
356
- setFilesWIssues,
357
- doAllFilesHaveSameHeaders,
358
- filesWIssues,
359
- datatableFormName = "editableCellTable",
360
- onMultiFileUploadSubmit,
361
- isThisTheLastBadFile,
362
- submitting
363
- }) {
364
- const [hasSubmitted, setSubmitted] = useState(!csvValidationIssue);
365
- const [steps, setSteps] = useState(getInitialSteps(csvValidationIssue));
299
+ const UploadCsvWizardDialogInner = reduxForm()(
300
+ function UploadCsvWizardDialogInner({
301
+ validateAgainstSchema,
302
+ userSchema,
303
+ searchResults,
304
+ onUploadWizardFinish,
305
+ csvValidationIssue,
306
+ ignoredHeadersMsg,
307
+ matchedHeaders,
308
+ handleSubmit,
309
+ fileIndex,
310
+ onBackClick,
311
+ changeForm,
312
+ setFilesWIssues,
313
+ doAllFilesHaveSameHeaders,
314
+ filesWIssues,
315
+ datatableFormName = "editableCellTable",
316
+ onMultiFileUploadSubmit,
317
+ isThisTheLastBadFile,
318
+ submitting
319
+ }) {
320
+ const [hasSubmitted, setSubmitted] = useState(!csvValidationIssue);
321
+ const [steps, setSteps] = useState(getInitialSteps(csvValidationIssue));
366
322
 
367
- let inner;
368
- if (hasSubmitted) {
369
- inner = (
370
- <PreviewCsvData
371
- {...{
372
- datatableFormName,
373
- showDoesDataLookCorrectMsg: true,
374
- initialEntities: reduxFormEntities || null,
375
- matchedHeaders,
376
- validateAgainstSchema,
377
- userSchema
378
- }}
379
- ></PreviewCsvData>
323
+ const { reduxFormEntities, reduxFormCellValidation } = useSelector(state =>
324
+ formValueSelector(datatableFormName)(
325
+ state,
326
+ "reduxFormEntities",
327
+ "reduxFormCellValidation"
328
+ )
380
329
  );
381
- } else {
382
- inner = (
383
- <MatchHeaders
384
- {...{
385
- onMultiFileUploadSubmit,
386
- csvValidationIssue,
387
- ignoredHeadersMsg,
388
- searchResults,
389
- matchedHeaders,
390
- userSchema,
391
- reduxFormEntitiesArray: [reduxFormEntities],
392
- changeForm,
393
- datatableFormName,
394
- setFilesWIssues,
395
- filesWIssues,
396
- fileIndex
397
- }}
398
- ></MatchHeaders>
330
+
331
+ let inner;
332
+ if (hasSubmitted) {
333
+ inner = (
334
+ <PreviewCsvData
335
+ datatableFormName={datatableFormName}
336
+ showDoesDataLookCorrectMsg
337
+ initialEntities={reduxFormEntities || null}
338
+ matchedHeaders={matchedHeaders}
339
+ validateAgainstSchema={validateAgainstSchema}
340
+ userSchema={userSchema}
341
+ />
342
+ );
343
+ } else {
344
+ inner = (
345
+ <MatchHeaders
346
+ onMultiFileUploadSubmit={onMultiFileUploadSubmit}
347
+ csvValidationIssue={csvValidationIssue}
348
+ ignoredHeadersMsg={ignoredHeadersMsg}
349
+ searchResults={searchResults}
350
+ matchedHeaders={matchedHeaders}
351
+ userSchema={userSchema}
352
+ reduxFormEntitiesArray={[reduxFormEntities]}
353
+ changeForm={changeForm}
354
+ datatableFormName={datatableFormName}
355
+ setFilesWIssues={setFilesWIssues}
356
+ filesWIssues={filesWIssues}
357
+ fileIndex={fileIndex}
358
+ />
359
+ );
360
+ }
361
+ const { entsToUse, validationToUse } = removeCleanRows(
362
+ reduxFormEntities,
363
+ reduxFormCellValidation
399
364
  );
400
- }
401
- const { entsToUse, validationToUse } = removeCleanRows(
402
- reduxFormEntities,
403
- reduxFormCellValidation
404
- );
405
365
 
406
- return (
407
- <div>
408
- {!doAllFilesHaveSameHeaders && (
409
- <SimpleStepViz style={{ marginTop: 8 }} steps={steps}></SimpleStepViz>
410
- )}
411
- <div className="bp3-dialog-body">{inner}</div>
412
- <DialogFooter
413
- text={
414
- !hasSubmitted
415
- ? "Review and Edit Data"
416
- : onMultiFileUploadSubmit
417
- ? isThisTheLastBadFile
418
- ? "Finalize Files"
419
- : "Next File"
420
- : "Add File"
421
- }
422
- submitting={submitting}
423
- disabled={
424
- hasSubmitted && (!entsToUse?.length || some(validationToUse, v => v))
425
- }
426
- intent={
427
- hasSubmitted && onMultiFileUploadSubmit && isThisTheLastBadFile
428
- ? Intent.SUCCESS
429
- : Intent.PRIMARY
430
- }
431
- noCancel={onMultiFileUploadSubmit}
432
- {...(hasSubmitted && {
433
- onBackClick:
434
- onBackClick ||
435
- (() => {
366
+ return (
367
+ <div>
368
+ {!doAllFilesHaveSameHeaders && (
369
+ <SimpleStepViz style={{ marginTop: 8 }} steps={steps} />
370
+ )}
371
+ <div className="bp3-dialog-body">{inner}</div>
372
+ <DialogFooter
373
+ text={
374
+ !hasSubmitted
375
+ ? "Review and Edit Data"
376
+ : onMultiFileUploadSubmit
377
+ ? isThisTheLastBadFile
378
+ ? "Finalize Files"
379
+ : "Next File"
380
+ : "Add File"
381
+ }
382
+ submitting={submitting}
383
+ disabled={
384
+ hasSubmitted &&
385
+ (!entsToUse?.length || some(validationToUse, v => v))
386
+ }
387
+ intent={
388
+ hasSubmitted && onMultiFileUploadSubmit && isThisTheLastBadFile
389
+ ? Intent.SUCCESS
390
+ : Intent.PRIMARY
391
+ }
392
+ noCancel={onMultiFileUploadSubmit}
393
+ {...(hasSubmitted && {
394
+ onBackClick:
395
+ onBackClick ||
396
+ (() => {
397
+ setSteps(
398
+ immer(steps, draft => {
399
+ draft[0].active = true;
400
+ draft[0].completed = false;
401
+ draft[1].active = false;
402
+ })
403
+ );
404
+ setSubmitted(false);
405
+ })
406
+ })}
407
+ onClick={handleSubmit(async function () {
408
+ if (!hasSubmitted) {
409
+ //step 1 submit
436
410
  setSteps(
437
411
  immer(steps, draft => {
438
- draft[0].active = true;
439
- draft[0].completed = false;
440
- draft[1].active = false;
412
+ draft[0].active = false;
413
+ draft[0].completed = true;
414
+ draft[1].active = true;
441
415
  })
442
416
  );
443
- setSubmitted(false);
444
- })
445
- })}
446
- onClick={handleSubmit(async function () {
447
- if (!hasSubmitted) {
448
- //step 1 submit
449
- setSteps(
450
- immer(steps, draft => {
451
- draft[0].active = false;
452
- draft[0].completed = true;
453
- draft[1].active = true;
454
- })
455
- );
456
- setSubmitted(true);
457
- } else {
458
- if (!onMultiFileUploadSubmit) {
459
- //do async validation here if needed
460
- if (
461
- await asyncValidateHelper(
462
- validateAgainstSchema,
463
- entsToUse,
464
- changeForm,
465
- `editableCellTable`
417
+ setSubmitted(true);
418
+ } else {
419
+ if (!onMultiFileUploadSubmit) {
420
+ //do async validation here if needed
421
+ if (
422
+ await asyncValidateHelper(
423
+ validateAgainstSchema,
424
+ entsToUse,
425
+ changeForm,
426
+ `editableCellTable`
427
+ )
466
428
  )
467
- )
468
- return;
429
+ return;
430
+ }
431
+ //step 2 submit
432
+ const payload = maybeStripIdFromEntities(
433
+ entsToUse,
434
+ validateAgainstSchema
435
+ );
436
+ return onMultiFileUploadSubmit
437
+ ? await onMultiFileUploadSubmit()
438
+ : onUploadWizardFinish({ res: [payload] });
469
439
  }
470
- //step 2 submit
471
- const payload = maybeStripIdFromEntities(
472
- entsToUse,
473
- validateAgainstSchema
474
- );
475
- return onMultiFileUploadSubmit
476
- ? await onMultiFileUploadSubmit()
477
- : onUploadWizardFinish({ res: [payload] });
478
- }
479
- })}
480
- style={{ alignSelf: "end" }}
481
- ></DialogFooter>
482
- </div>
483
- );
484
- });
440
+ })}
441
+ style={{ alignSelf: "end" }}
442
+ />
443
+ </div>
444
+ );
445
+ }
446
+ );
485
447
 
486
448
  export default UploadCsvWizardDialog;
487
449
 
488
450
  const exampleData = { userData: times(5).map(() => ({ _isClean: true })) };
489
- export const PreviewCsvData = observer(function (props) {
451
+
452
+ export const PreviewCsvData = observer(props => {
490
453
  const {
491
454
  matchedHeaders,
492
455
  isEditingExistingFile,
493
456
  showDoesDataLookCorrectMsg,
494
457
  headerMessage,
495
458
  datatableFormName,
496
- // onlyShowRowsWErrors,
497
459
  validateAgainstSchema,
498
460
  userSchema = exampleData,
499
461
  initialEntities
500
462
  } = props;
501
463
  const rerenderKey = useRef(0);
502
464
  rerenderKey.current = rerenderKey.current + 1;
503
- // const useExampleData = userSchema === exampleData;
504
- // const [loading, setLoading] = useState(true);
505
- // useEffect(() => {
506
- // // simulate layout change outside of React lifecycle
507
- // setTimeout(() => {
508
- // setLoading(false);
509
- // }, 400);
510
- // }, []);
511
-
512
- // const [val, forceUpdate] = useForceUpdate();
513
-
514
465
  const data =
515
466
  userSchema.userData &&
516
467
  userSchema.userData.length &&
@@ -575,7 +526,7 @@ export const PreviewCsvData = observer(function (props) {
575
526
  <validateAgainstSchema.HeaderComp
576
527
  {...props}
577
528
  // {...{ forceUpdate }}
578
- ></validateAgainstSchema.HeaderComp>
529
+ />
579
530
  )}
580
531
  </div>
581
532
  <DataTable
@@ -591,7 +542,7 @@ export const PreviewCsvData = observer(function (props) {
591
542
  initialEntities={(initialEntities ? initialEntities : data) || []}
592
543
  entities={(initialEntities ? initialEntities : data) || []}
593
544
  schema={validateAgainstSchema}
594
- ></DataTable>
545
+ />
595
546
  </div>
596
547
  );
597
548
  });
@@ -608,14 +559,12 @@ export const SimpleInsertDataDialog = compose(
608
559
  "reduxFormEntities",
609
560
  "reduxFormCellValidation"
610
561
  ),
611
- connect(undefined, { changeForm: change }),
612
562
  observer
613
563
  )(function SimpleInsertDataDialog({
614
564
  onSimpleInsertDialogFinish,
615
565
  reduxFormEntities,
616
566
  reduxFormCellValidation,
617
567
  validateAgainstSchema,
618
- changeForm,
619
568
  submitting,
620
569
  isEditingExistingFile,
621
570
  matchedHeaders,
@@ -625,11 +574,14 @@ export const SimpleInsertDataDialog = compose(
625
574
  userSchema,
626
575
  initialEntities
627
576
  }) {
577
+ const dispatch = useDispatch();
628
578
  const { entsToUse, validationToUse } = removeCleanRows(
629
579
  reduxFormEntities,
630
580
  reduxFormCellValidation
631
581
  );
632
582
 
583
+ const changeForm = (...args) => dispatch(change(...args));
584
+
633
585
  return (
634
586
  <>
635
587
  <div className="bp3-dialog-body">
@@ -642,20 +594,17 @@ export const SimpleInsertDataDialog = compose(
642
594
  label="File Name:"
643
595
  defaultValue={"manual_data_entry"}
644
596
  name="fileName"
645
- ></InputField>
597
+ />
646
598
  <PreviewCsvData
647
- {...{
648
- matchedHeaders,
649
- isEditingExistingFile,
650
- showDoesDataLookCorrectMsg,
651
- headerMessage,
652
- // onlyShowRowsWErrors,
653
- validateAgainstSchema,
654
- userSchema,
655
- initialEntities,
656
- datatableFormName: "simpleInsertEditableTable"
657
- }}
658
- ></PreviewCsvData>
599
+ matchedHeaders={matchedHeaders}
600
+ isEditingExistingFile={isEditingExistingFile}
601
+ showDoesDataLookCorrectMsg={showDoesDataLookCorrectMsg}
602
+ headerMessage={headerMessage}
603
+ validateAgainstSchema={validateAgainstSchema}
604
+ userSchema={userSchema}
605
+ initialEntities={initialEntities}
606
+ datatableFormName={"simpleInsertEditableTable"}
607
+ />
659
608
  </div>
660
609
  <DialogFooter
661
610
  submitting={submitting}
@@ -681,7 +630,7 @@ export const SimpleInsertDataDialog = compose(
681
630
  })}
682
631
  disabled={!entsToUse?.length || some(validationToUse, e => e)}
683
632
  text={isEditingExistingFile ? "Edit Data" : "Add File"}
684
- ></DialogFooter>
633
+ />
685
634
  </>
686
635
  );
687
636
  });
@@ -715,11 +664,3 @@ function maybeStripIdFromEntities(ents, validateAgainstSchema) {
715
664
  }
716
665
  return toRet?.map(e => omit(e, ["_isClean"]));
717
666
  }
718
-
719
- //create your forceUpdate hook
720
- // function useForceUpdate() {
721
- // const [val, setValue] = useState(0); // integer state
722
- // return [val, () => setValue(value => value + 1)]; // update state to force render
723
- // // A function that increment 👆🏻 the previous state like here
724
- // // is better than directly setting `setValue(value + 1)`
725
- // }