@teselagen/ui 0.0.9 → 0.0.12

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 (126) hide show
  1. package/README.md +7 -0
  2. package/cypress.config.ts +6 -0
  3. package/index.html +12 -0
  4. package/package.json +2 -2
  5. package/project.json +74 -0
  6. package/src/AdvancedOptions.js +33 -0
  7. package/src/AdvancedOptions.spec.js +24 -0
  8. package/src/AssignDefaultsModeContext.js +21 -0
  9. package/src/AsyncValidateFieldSpinner/index.js +12 -0
  10. package/src/BlueprintError/index.js +14 -0
  11. package/src/BounceLoader/index.js +16 -0
  12. package/src/BounceLoader/style.css +45 -0
  13. package/src/CollapsibleCard/index.js +92 -0
  14. package/src/CollapsibleCard/style.css +21 -0
  15. package/src/DNALoader/index.js +20 -0
  16. package/src/DNALoader/style.css +251 -0
  17. package/src/DataTable/CellDragHandle.js +130 -0
  18. package/src/DataTable/DisabledLoadingComponent.js +15 -0
  19. package/src/DataTable/DisplayOptions.js +218 -0
  20. package/src/DataTable/FilterAndSortMenu.js +397 -0
  21. package/src/DataTable/PagingTool.js +232 -0
  22. package/src/DataTable/SearchBar.js +57 -0
  23. package/src/DataTable/SortableColumns.js +53 -0
  24. package/src/DataTable/TableFormTrackerContext.js +10 -0
  25. package/src/DataTable/dataTableEnhancer.js +291 -0
  26. package/src/DataTable/defaultFormatters.js +32 -0
  27. package/src/DataTable/defaultProps.js +45 -0
  28. package/src/DataTable/defaultValidators.js +40 -0
  29. package/src/DataTable/editCellHelper.js +44 -0
  30. package/src/DataTable/getCellVal.js +20 -0
  31. package/src/DataTable/getVals.js +8 -0
  32. package/src/DataTable/index.js +3537 -0
  33. package/src/DataTable/isTruthy.js +12 -0
  34. package/src/DataTable/isValueEmpty.js +3 -0
  35. package/src/DataTable/style.css +600 -0
  36. package/src/DataTable/utils/computePresets.js +42 -0
  37. package/src/DataTable/utils/convertSchema.js +69 -0
  38. package/src/DataTable/utils/getIdOrCodeOrIndex.js +9 -0
  39. package/src/DataTable/utils/getTableConfigFromStorage.js +5 -0
  40. package/src/DataTable/utils/queryParams.js +1032 -0
  41. package/src/DataTable/utils/rowClick.js +156 -0
  42. package/src/DataTable/utils/selection.js +8 -0
  43. package/src/DataTable/utils/withSelectedEntities.js +65 -0
  44. package/src/DataTable/utils/withTableParams.js +328 -0
  45. package/src/DataTable/validateTableWideErrors.js +135 -0
  46. package/src/DataTable/viewColumn.js +37 -0
  47. package/src/DialogFooter/index.js +79 -0
  48. package/src/DialogFooter/style.css +9 -0
  49. package/src/DropdownButton.js +36 -0
  50. package/src/FillWindow.css +6 -0
  51. package/src/FillWindow.js +69 -0
  52. package/src/FormComponents/Uploader.js +1197 -0
  53. package/src/FormComponents/getNewName.js +31 -0
  54. package/src/FormComponents/index.js +1384 -0
  55. package/src/FormComponents/itemUpload.js +84 -0
  56. package/src/FormComponents/sortify.js +73 -0
  57. package/src/FormComponents/style.css +247 -0
  58. package/src/FormComponents/tryToMatchSchemas.js +222 -0
  59. package/src/FormComponents/utils.js +6 -0
  60. package/src/HotkeysDialog/index.js +79 -0
  61. package/src/HotkeysDialog/style.css +54 -0
  62. package/src/InfoHelper/index.js +83 -0
  63. package/src/InfoHelper/style.css +7 -0
  64. package/src/IntentText/index.js +18 -0
  65. package/src/Loading/index.js +74 -0
  66. package/src/Loading/style.css +4 -0
  67. package/src/MatchHeaders.js +223 -0
  68. package/src/MenuBar/index.js +416 -0
  69. package/src/MenuBar/style.css +45 -0
  70. package/src/PromptUnsavedChanges/index.js +40 -0
  71. package/src/ResizableDraggableDialog/index.js +138 -0
  72. package/src/ResizableDraggableDialog/style.css +42 -0
  73. package/src/ScrollToTop/index.js +72 -0
  74. package/src/SimpleStepViz.js +26 -0
  75. package/src/TgSelect/index.js +465 -0
  76. package/src/TgSelect/style.css +34 -0
  77. package/src/TgSuggest/index.js +121 -0
  78. package/src/Timeline/TimelineEvent.js +31 -0
  79. package/src/Timeline/index.js +22 -0
  80. package/src/Timeline/style.css +29 -0
  81. package/src/UploadCsvWizard.css +4 -0
  82. package/src/UploadCsvWizard.js +731 -0
  83. package/src/autoTooltip.js +89 -0
  84. package/src/constants.js +1 -0
  85. package/src/customIcons.js +361 -0
  86. package/src/enhancers/withDialog/index.js +196 -0
  87. package/src/enhancers/withDialog/tg_modalState.js +46 -0
  88. package/src/enhancers/withField.js +20 -0
  89. package/src/enhancers/withFields.js +11 -0
  90. package/src/enhancers/withLocalStorage.js +11 -0
  91. package/src/index.js +76 -0
  92. package/src/rerenderOnWindowResize.js +27 -0
  93. package/src/showAppSpinner.js +12 -0
  94. package/src/showConfirmationDialog/index.js +116 -0
  95. package/src/showDialogOnDocBody.js +37 -0
  96. package/src/style.css +214 -0
  97. package/src/toastr.js +92 -0
  98. package/src/typeToCommonType.js +6 -0
  99. package/src/useDialog.js +64 -0
  100. package/src/utils/S3Download.js +14 -0
  101. package/src/utils/adHoc.js +10 -0
  102. package/src/utils/basicHandleActionsWithFullState.js +14 -0
  103. package/src/utils/combineReducersWithFullState.js +14 -0
  104. package/src/utils/commandControls.js +83 -0
  105. package/src/utils/commandUtils.js +112 -0
  106. package/src/utils/determineBlackOrWhiteTextColor.js +4 -0
  107. package/src/utils/getDayjsFormatter.js +35 -0
  108. package/src/utils/getTextFromEl.js +28 -0
  109. package/src/utils/handlerHelpers.js +30 -0
  110. package/src/utils/hotkeyUtils.js +129 -0
  111. package/src/utils/menuUtils.js +402 -0
  112. package/src/utils/popoverOverflowModifiers.js +11 -0
  113. package/src/utils/pureNoFunc.js +31 -0
  114. package/src/utils/renderOnDoc.js +29 -0
  115. package/src/utils/showProgressToast.js +22 -0
  116. package/src/utils/tagUtils.js +45 -0
  117. package/src/utils/tgFormValues.js +32 -0
  118. package/src/utils/withSelectTableRecords.js +38 -0
  119. package/src/utils/withStore.js +10 -0
  120. package/src/wrapDialog.js +112 -0
  121. package/tsconfig.json +4 -0
  122. package/vite.config.ts +7 -0
  123. package/index.js +0 -80652
  124. package/index.mjs +0 -80636
  125. package/index.umd.js +0 -80649
  126. package/style.css +0 -10421
@@ -0,0 +1,53 @@
1
+ import React, { Component } from "react";
2
+ import { SortableContainer } from "react-sortable-hoc";
3
+
4
+ function CustomTheadComponent(props) {
5
+ const headerColumns = props.children.props.children;
6
+ return (
7
+ <div className={"rt-thead " + props.className} style={props.style}>
8
+ <div className="rt-tr">
9
+ {headerColumns.map(column => {
10
+ // if a column is marked as immovable just return regular column
11
+ if (column.props.immovable === "true") return column;
12
+ // keeps track of hidden columns here so columnIndex might not equal i
13
+ return column;
14
+ })}
15
+ </div>
16
+ </div>
17
+ );
18
+ }
19
+
20
+ const SortableCustomTheadComponent = SortableContainer(CustomTheadComponent);
21
+
22
+ class SortableColumns extends Component {
23
+ shouldCancelStart = e => {
24
+ const className = e.target.className;
25
+ // if its an svg then it's a blueprint icon
26
+ return (
27
+ e.target instanceof SVGElement || className.indexOf("rt-resizer") > -1
28
+ );
29
+ };
30
+
31
+ onSortEnd = ({ oldIndex, newIndex }) => {
32
+ this.props.moveColumn({
33
+ oldIndex,
34
+ newIndex
35
+ });
36
+ };
37
+
38
+ render() {
39
+ return (
40
+ <SortableCustomTheadComponent
41
+ {...this.props}
42
+ lockAxis="x"
43
+ axis="x"
44
+ distance={10}
45
+ helperClass="above-dialog"
46
+ shouldCancelStart={this.shouldCancelStart}
47
+ onSortEnd={this.onSortEnd}
48
+ />
49
+ );
50
+ }
51
+ }
52
+
53
+ 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;
@@ -0,0 +1,291 @@
1
+ /**
2
+ * @param {options} options
3
+ * @typedef {object} options
4
+ * @property {boolean} isPlural Are we searching for 1 thing or many?
5
+ * @property {string} queryName What the props come back on ( by default = modelName + 'Query')
6
+ */
7
+ import { reduxForm } from "redux-form";
8
+
9
+ import { arrayMove } from "react-sortable-hoc";
10
+ import { toArray, keyBy, get } from "lodash";
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";
15
+ import pureNoFunc from "../utils/pureNoFunc";
16
+ import tgFormValues from "../utils/tgFormValues";
17
+ import getTableConfigFromStorage from "./utils/getTableConfigFromStorage";
18
+
19
+ export default compose(
20
+ //connect to withTableParams here in the dataTable component so that, in the case that the table is not manually connected,
21
+ withTableParams({
22
+ isLocalCall: true
23
+ }),
24
+ withState("showForcedHiddenColumns", "setShowForcedHidden", false),
25
+ withProps(ownProps => {
26
+ let propsToUse = ownProps;
27
+ if (!ownProps.isTableParamsConnected) {
28
+ //this is the case where we're hooking up to withTableParams locally, so we need to take the tableParams off the props
29
+ propsToUse = {
30
+ ...ownProps,
31
+ ...ownProps.tableParams
32
+ };
33
+ }
34
+
35
+ const {
36
+ schema,
37
+ withDisplayOptions,
38
+ syncDisplayOptionsToDb,
39
+ formName,
40
+ tableConfigurations,
41
+ deleteTableConfiguration,
42
+ upsertTableConfiguration,
43
+ upsertFieldOption,
44
+ currentUser,
45
+ isViewable,
46
+ isOpenable,
47
+ entities = [],
48
+ cellRenderer = {},
49
+ showForcedHiddenColumns,
50
+ isSimple,
51
+ isInfinite,
52
+ compact = true,
53
+ extraCompact
54
+ } = propsToUse;
55
+ let schemaToUse = convertSchema(schema);
56
+ let fieldOptsByPath = {};
57
+ let tableConfig = {};
58
+ let resetDefaultVisibility;
59
+ let updateColumnVisibility;
60
+ let persistPageSize;
61
+ let moveColumnPersist;
62
+ let resizePersist;
63
+ let updateTableDisplayDensity;
64
+ let compactToUse = !!compact;
65
+ let extraCompactToUse = !!extraCompact;
66
+
67
+ if (isViewable) {
68
+ schemaToUse.fields = [viewColumn, ...schemaToUse.fields];
69
+ }
70
+ if (isOpenable) {
71
+ schemaToUse.fields = [openColumn, ...schemaToUse.fields];
72
+ }
73
+ // this must come before handling orderings.
74
+ schemaToUse.fields = schemaToUse.fields.map(field => {
75
+ if (field.placementPath) {
76
+ return {
77
+ ...field,
78
+ sortDisabled:
79
+ field.sortDisabled ||
80
+ (typeof field.path === "string" && field.path.includes(".")),
81
+ path: field.placementPath
82
+ };
83
+ } else {
84
+ return field;
85
+ }
86
+ });
87
+ const hasOptionForForcedHidden =
88
+ withDisplayOptions && (isSimple || isInfinite);
89
+ if (withDisplayOptions) {
90
+ if (syncDisplayOptionsToDb) {
91
+ tableConfig = tableConfigurations && tableConfigurations[0];
92
+ } else {
93
+ tableConfig = getTableConfigFromStorage(formName);
94
+ }
95
+ if (!tableConfig) {
96
+ tableConfig = {
97
+ fieldOptions: []
98
+ };
99
+ }
100
+ if (tableConfig.density) {
101
+ compactToUse = tableConfig.density === "compact";
102
+ }
103
+ if (tableConfig.density) {
104
+ extraCompactToUse = tableConfig.density === "extraCompact";
105
+ }
106
+ const columnOrderings = tableConfig.columnOrderings;
107
+ fieldOptsByPath = keyBy(tableConfig.fieldOptions, "path");
108
+ schemaToUse = {
109
+ ...schemaToUse,
110
+ fields: schemaToUse.fields.map(field => {
111
+ const fieldOpt = fieldOptsByPath[field.path];
112
+ let noValsForField = false;
113
+ // only add this hidden column ability if no paging
114
+ if (!showForcedHiddenColumns && hasOptionForForcedHidden) {
115
+ noValsForField = entities.every(e => {
116
+ const val = get(e, field.path);
117
+ return field.render
118
+ ? !field.render(val, e)
119
+ : cellRenderer[field.path]
120
+ ? !cellRenderer[field.path](val, e)
121
+ : !val;
122
+ });
123
+ }
124
+ if (noValsForField) {
125
+ return {
126
+ ...field,
127
+ isHidden: true,
128
+ isForcedHidden: true
129
+ };
130
+ } else if (fieldOpt) {
131
+ return {
132
+ ...field,
133
+ isHidden: fieldOpt.isHidden
134
+ };
135
+ } else {
136
+ return field;
137
+ }
138
+ })
139
+ };
140
+
141
+ if (columnOrderings) {
142
+ const fieldsWithOrders = [];
143
+ const fieldsWithoutOrder = [];
144
+ // if a new field has been added since the orderings were set then we want
145
+ // it to be at the end instead of the beginning
146
+ schemaToUse.fields.forEach(field => {
147
+ if (columnOrderings.indexOf(field.path) > -1) {
148
+ fieldsWithOrders.push(field);
149
+ } else {
150
+ fieldsWithoutOrder.push(field);
151
+ }
152
+ });
153
+ schemaToUse.fields = fieldsWithOrders
154
+ .sort(({ path: path1 }, { path: path2 }) => {
155
+ return (
156
+ columnOrderings.indexOf(path1) - columnOrderings.indexOf(path2)
157
+ );
158
+ })
159
+ .concat(fieldsWithoutOrder);
160
+ tableConfig.columnOrderings = schemaToUse.fields.map(f => f.path);
161
+ }
162
+
163
+ if (syncDisplayOptionsToDb) {
164
+ //sync up to db
165
+ let tableConfigurationId;
166
+ resetDefaultVisibility = function() {
167
+ tableConfigurationId = tableConfig.id;
168
+
169
+ if (tableConfigurationId) {
170
+ deleteTableConfiguration(tableConfigurationId);
171
+ }
172
+ };
173
+ updateColumnVisibility = function({ shouldShow, path }) {
174
+ if (tableConfigurationId) {
175
+ const existingFieldOpt = fieldOptsByPath[path] || {};
176
+ upsertFieldOption({
177
+ id: existingFieldOpt.id,
178
+ path,
179
+ isHidden: !shouldShow,
180
+ tableConfigurationId
181
+ });
182
+ } else {
183
+ upsertTableConfiguration({
184
+ userId: currentUser.user.id,
185
+ formName,
186
+ fieldOptions: [
187
+ {
188
+ path,
189
+ isHidden: !shouldShow
190
+ }
191
+ ]
192
+ });
193
+ }
194
+ };
195
+ } else {
196
+ const syncStorage = () => {
197
+ window.localStorage.setItem(formName, JSON.stringify(tableConfig));
198
+ };
199
+
200
+ //sync display options with localstorage
201
+ resetDefaultVisibility = function() {
202
+ window.localStorage.removeItem(formName);
203
+ };
204
+ updateColumnVisibility = function({ path, paths, shouldShow }) {
205
+ const newFieldOpts = {
206
+ ...fieldOptsByPath
207
+ };
208
+ const pathsToUse = paths ? paths : [path];
209
+ pathsToUse.forEach(path => {
210
+ newFieldOpts[path] = { path, isHidden: !shouldShow };
211
+ });
212
+ tableConfig.fieldOptions = toArray(newFieldOpts);
213
+ syncStorage();
214
+ };
215
+ updateTableDisplayDensity = function(density) {
216
+ tableConfig.density = density;
217
+ syncStorage();
218
+ };
219
+ persistPageSize = function(pageSize) {
220
+ tableConfig.userSetPageSize = pageSize;
221
+ syncStorage();
222
+ };
223
+ moveColumnPersist = function({ oldIndex, newIndex }) {
224
+ // we might already have an array of the fields [path1, path2, ..etc]
225
+ const columnOrderings =
226
+ tableConfig.columnOrderings ||
227
+ schemaToUse.fields.map(({ path }) => path); // columnOrderings is [path1, path2, ..etc]
228
+
229
+ tableConfig.columnOrderings = arrayMove(
230
+ columnOrderings,
231
+ oldIndex,
232
+ newIndex
233
+ );
234
+ syncStorage();
235
+ };
236
+ resizePersist = function(newResized) {
237
+ tableConfig.resized = newResized;
238
+ syncStorage();
239
+ };
240
+ }
241
+ }
242
+ const resized = tableConfig.resized;
243
+ return {
244
+ ...propsToUse,
245
+ schema: schemaToUse,
246
+ compact: compactToUse,
247
+ extraCompact: extraCompactToUse,
248
+ resized,
249
+ resetDefaultVisibility,
250
+ updateColumnVisibility,
251
+ persistPageSize,
252
+ updateTableDisplayDensity,
253
+ resizePersist,
254
+ moveColumnPersist,
255
+ hasOptionForForcedHidden
256
+ };
257
+ }),
258
+ branch(props => !props.noForm, reduxForm({})), //the formName is passed via withTableParams and is often user overridden
259
+ tgFormValues(
260
+ "localStorageForceUpdate",
261
+ "reduxFormQueryParams",
262
+ "reduxFormSearchInput",
263
+ "onlyShowRowsWErrors",
264
+ "reduxFormSelectedEntityIdMap",
265
+ "reduxFormExpandedEntityIdMap",
266
+ "reduxFormSelectedCells",
267
+ "reduxFormEditingCell",
268
+ "reduxFormEditingCellSelectAll",
269
+ "reduxFormCellIdToEditValue",
270
+ "reduxFormEntities",
271
+ "reduxFormCellValidation",
272
+ "reduxFormEntitiesUndoRedoStack"
273
+ ),
274
+ withProps(props => {
275
+ const entities = props.reduxFormEntities || props.entities;
276
+ return {
277
+ _origEntities: props.entities,
278
+ entities
279
+ };
280
+ }),
281
+ // withFields({
282
+ // names: [
283
+ // "localStorageForceUpdate",
284
+ // "reduxFormQueryParams",
285
+ // "reduxFormSearchInput",
286
+ // "reduxFormSelectedEntityIdMap",
287
+ // "reduxFormExpandedEntityIdMap"
288
+ // ]
289
+ // }),
290
+ branch(props => !props.alwaysRerender, pureNoFunc)
291
+ );
@@ -0,0 +1,32 @@
1
+ import { toNumber } from "lodash";
2
+ import { getVals } from "./getVals";
3
+ import { isValueEmpty } from "./isValueEmpty";
4
+ import { isTruthy } from "./isTruthy";
5
+
6
+ export const defaultFormatters = {
7
+ boolean: newVal => {
8
+ return isTruthy(newVal);
9
+ },
10
+ dropdown: (newVal, field) => {
11
+ const valsMap = {};
12
+ getVals(field.values).forEach(v => {
13
+ valsMap[v.toLowerCase().trim()] = v;
14
+ });
15
+ return valsMap[newVal?.toLowerCase().trim()] || newVal;
16
+ },
17
+ dropdownMulti: (newVal, field) => {
18
+ const valsMap = {};
19
+ getVals(field.values).forEach(v => {
20
+ valsMap[v.toLowerCase().trim()] = v;
21
+ });
22
+ if (!newVal) return;
23
+ return newVal
24
+ .split(",")
25
+ .map(v => valsMap[v.toLowerCase().trim()] || v)
26
+ .join(",");
27
+ },
28
+ number: newVal => {
29
+ if (isValueEmpty(newVal)) return newVal;
30
+ return toNumber(newVal);
31
+ }
32
+ };
@@ -0,0 +1,45 @@
1
+ import { noop } from "lodash";
2
+
3
+ // eslint-disable-next-line import/no-anonymous-default-export
4
+ export default {
5
+ //NOTE: DO NOT SET DEFAULTS HERE FOR PROPS THAT GET COMPUTED AS PART OF PRESET GROUPS IN computePresets
6
+ addFilters: noop,
7
+ className: "",
8
+ clearFilters: noop,
9
+ contextMenu: noop,
10
+ disabled: false,
11
+ entities: [],
12
+ extraClasses: "",
13
+ filters: [],
14
+ isCopyable: true,
15
+ isEntityDisabled: noop,
16
+ isLoading: false,
17
+ isSimple: false,
18
+ isSingleSelect: false,
19
+ maxHeight: 600,
20
+ noHeader: false,
21
+ noSelect: false,
22
+ noUserSelect: false,
23
+ onDeselect: noop,
24
+ onMultiRowSelect: noop,
25
+ onRowClick: noop,
26
+ onRowSelect: noop,
27
+ onSingleRowSelect: noop,
28
+ page: 1,
29
+ pageSize: 10,
30
+ reduxFormExpandedEntityIdMap: {},
31
+ reduxFormSearchInput: "",
32
+ reduxFormSelectedEntityIdMap: {},
33
+ removeSingleFilter: noop,
34
+ resized: [],
35
+ resizePersist: noop,
36
+ setFilter: noop,
37
+ setOrder: noop,
38
+ setPage: noop,
39
+ setPageSize: noop,
40
+ setSearchTerm: noop,
41
+ showCount: false,
42
+ style: {},
43
+ withCheckboxes: false,
44
+ withSort: true
45
+ };
@@ -0,0 +1,40 @@
1
+ import { isNumber } from "lodash";
2
+ import { getVals } from "./getVals";
3
+ import { isValueEmpty } from "./isValueEmpty";
4
+
5
+ export const defaultValidators = {
6
+ dropdown: (newVal, field) => {
7
+ const err = "Please choose one of the accepted values";
8
+ if (!newVal) {
9
+ if (field.isRequired) return err;
10
+ } else if (!getVals(field.values).includes(newVal)) {
11
+ return err;
12
+ }
13
+ },
14
+ dropdownMulti: (newVal, field) => {
15
+ const err = "Please choose one of the accepted values";
16
+ if (!newVal) {
17
+ if (field.isRequired) return err;
18
+ } else {
19
+ let err;
20
+ newVal.split(",").some(v => {
21
+ if (!getVals(field.values).includes(v)) {
22
+ err = `${v} is not an accepted value`;
23
+ return true;
24
+ }
25
+ return false;
26
+ });
27
+ return err;
28
+ }
29
+ },
30
+ number: (newVal, field) => {
31
+ if (isValueEmpty(newVal) && !field.isRequired) return;
32
+ if (isNaN(newVal) || !isNumber(newVal)) {
33
+ return "Must be a number";
34
+ }
35
+ },
36
+ string: (newVal, field) => {
37
+ if (!field.isRequired) return false;
38
+ if (!newVal) return "Please enter a value here";
39
+ }
40
+ };
@@ -0,0 +1,44 @@
1
+ import { set } from "lodash";
2
+ import { defaultValidators } from "./defaultValidators";
3
+ import { defaultFormatters } from "./defaultFormatters";
4
+
5
+ //(mutative) responsible for formatting and then validating the
6
+
7
+ export const editCellHelper = ({
8
+ entity,
9
+ path,
10
+ schema,
11
+ columnSchema,
12
+ newVal
13
+ }) => {
14
+ let nv = newVal;
15
+
16
+ const colSchema =
17
+ columnSchema || schema?.fields?.find(({ path: p }) => p === path) || {};
18
+ path = path || colSchema.path;
19
+ const { format, validate, type } = colSchema;
20
+ let error;
21
+ if (nv === undefined && colSchema.defaultValue !== undefined)
22
+ nv = colSchema.defaultValue;
23
+
24
+ if (format) {
25
+ nv = format(nv, colSchema);
26
+ }
27
+ if (defaultFormatters[type]) {
28
+ nv = defaultFormatters[type](nv, colSchema);
29
+ }
30
+ if (validate) {
31
+ error = validate(nv, colSchema, entity);
32
+ }
33
+ if (!error) {
34
+ const validator =
35
+ defaultValidators[type] ||
36
+ type === "string" ||
37
+ (type === undefined && defaultValidators.string);
38
+ if (validator) {
39
+ error = validator(nv, colSchema);
40
+ }
41
+ }
42
+ set(entity, path, nv);
43
+ return { entity, error };
44
+ };
@@ -0,0 +1,20 @@
1
+ import { get } from "lodash";
2
+ import { isString } from "lodash";
3
+ import { isTruthy } from "./isTruthy";
4
+
5
+ export const getCellVal = (ent, path, col) => {
6
+ const isBool = col?.type === "boolean";
7
+ let selectedCellVal = get(ent, path, "");
8
+ if (isBool) {
9
+ if (isString(selectedCellVal)) {
10
+ selectedCellVal = selectedCellVal.toLowerCase();
11
+ }
12
+ selectedCellVal =
13
+ selectedCellVal === "true" ||
14
+ selectedCellVal === true ||
15
+ selectedCellVal === 1 ||
16
+ selectedCellVal === "yes";
17
+ selectedCellVal = isTruthy(selectedCellVal);
18
+ }
19
+ return selectedCellVal;
20
+ };
@@ -0,0 +1,8 @@
1
+ import { isFunction } from "lodash";
2
+
3
+ export function getVals(values) {
4
+ if (isFunction(values)) {
5
+ return values();
6
+ }
7
+ return values;
8
+ }