@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.
- package/README.md +7 -0
- package/cypress.config.ts +6 -0
- package/index.html +12 -0
- package/package.json +2 -2
- package/project.json +74 -0
- package/src/AdvancedOptions.js +33 -0
- package/src/AdvancedOptions.spec.js +24 -0
- package/src/AssignDefaultsModeContext.js +21 -0
- package/src/AsyncValidateFieldSpinner/index.js +12 -0
- package/src/BlueprintError/index.js +14 -0
- package/src/BounceLoader/index.js +16 -0
- package/src/BounceLoader/style.css +45 -0
- package/src/CollapsibleCard/index.js +92 -0
- package/src/CollapsibleCard/style.css +21 -0
- package/src/DNALoader/index.js +20 -0
- package/src/DNALoader/style.css +251 -0
- package/src/DataTable/CellDragHandle.js +130 -0
- package/src/DataTable/DisabledLoadingComponent.js +15 -0
- package/src/DataTable/DisplayOptions.js +218 -0
- package/src/DataTable/FilterAndSortMenu.js +397 -0
- package/src/DataTable/PagingTool.js +232 -0
- package/src/DataTable/SearchBar.js +57 -0
- package/src/DataTable/SortableColumns.js +53 -0
- package/src/DataTable/TableFormTrackerContext.js +10 -0
- package/src/DataTable/dataTableEnhancer.js +291 -0
- package/src/DataTable/defaultFormatters.js +32 -0
- package/src/DataTable/defaultProps.js +45 -0
- package/src/DataTable/defaultValidators.js +40 -0
- package/src/DataTable/editCellHelper.js +44 -0
- package/src/DataTable/getCellVal.js +20 -0
- package/src/DataTable/getVals.js +8 -0
- package/src/DataTable/index.js +3537 -0
- package/src/DataTable/isTruthy.js +12 -0
- package/src/DataTable/isValueEmpty.js +3 -0
- package/src/DataTable/style.css +600 -0
- package/src/DataTable/utils/computePresets.js +42 -0
- package/src/DataTable/utils/convertSchema.js +69 -0
- package/src/DataTable/utils/getIdOrCodeOrIndex.js +9 -0
- package/src/DataTable/utils/getTableConfigFromStorage.js +5 -0
- package/src/DataTable/utils/queryParams.js +1032 -0
- package/src/DataTable/utils/rowClick.js +156 -0
- package/src/DataTable/utils/selection.js +8 -0
- package/src/DataTable/utils/withSelectedEntities.js +65 -0
- package/src/DataTable/utils/withTableParams.js +328 -0
- package/src/DataTable/validateTableWideErrors.js +135 -0
- package/src/DataTable/viewColumn.js +37 -0
- package/src/DialogFooter/index.js +79 -0
- package/src/DialogFooter/style.css +9 -0
- package/src/DropdownButton.js +36 -0
- package/src/FillWindow.css +6 -0
- package/src/FillWindow.js +69 -0
- package/src/FormComponents/Uploader.js +1197 -0
- package/src/FormComponents/getNewName.js +31 -0
- package/src/FormComponents/index.js +1384 -0
- package/src/FormComponents/itemUpload.js +84 -0
- package/src/FormComponents/sortify.js +73 -0
- package/src/FormComponents/style.css +247 -0
- package/src/FormComponents/tryToMatchSchemas.js +222 -0
- package/src/FormComponents/utils.js +6 -0
- package/src/HotkeysDialog/index.js +79 -0
- package/src/HotkeysDialog/style.css +54 -0
- package/src/InfoHelper/index.js +83 -0
- package/src/InfoHelper/style.css +7 -0
- package/src/IntentText/index.js +18 -0
- package/src/Loading/index.js +74 -0
- package/src/Loading/style.css +4 -0
- package/src/MatchHeaders.js +223 -0
- package/src/MenuBar/index.js +416 -0
- package/src/MenuBar/style.css +45 -0
- package/src/PromptUnsavedChanges/index.js +40 -0
- package/src/ResizableDraggableDialog/index.js +138 -0
- package/src/ResizableDraggableDialog/style.css +42 -0
- package/src/ScrollToTop/index.js +72 -0
- package/src/SimpleStepViz.js +26 -0
- package/src/TgSelect/index.js +465 -0
- package/src/TgSelect/style.css +34 -0
- package/src/TgSuggest/index.js +121 -0
- package/src/Timeline/TimelineEvent.js +31 -0
- package/src/Timeline/index.js +22 -0
- package/src/Timeline/style.css +29 -0
- package/src/UploadCsvWizard.css +4 -0
- package/src/UploadCsvWizard.js +731 -0
- package/src/autoTooltip.js +89 -0
- package/src/constants.js +1 -0
- package/src/customIcons.js +361 -0
- package/src/enhancers/withDialog/index.js +196 -0
- package/src/enhancers/withDialog/tg_modalState.js +46 -0
- package/src/enhancers/withField.js +20 -0
- package/src/enhancers/withFields.js +11 -0
- package/src/enhancers/withLocalStorage.js +11 -0
- package/src/index.js +76 -0
- package/src/rerenderOnWindowResize.js +27 -0
- package/src/showAppSpinner.js +12 -0
- package/src/showConfirmationDialog/index.js +116 -0
- package/src/showDialogOnDocBody.js +37 -0
- package/src/style.css +214 -0
- package/src/toastr.js +92 -0
- package/src/typeToCommonType.js +6 -0
- package/src/useDialog.js +64 -0
- package/src/utils/S3Download.js +14 -0
- package/src/utils/adHoc.js +10 -0
- package/src/utils/basicHandleActionsWithFullState.js +14 -0
- package/src/utils/combineReducersWithFullState.js +14 -0
- package/src/utils/commandControls.js +83 -0
- package/src/utils/commandUtils.js +112 -0
- package/src/utils/determineBlackOrWhiteTextColor.js +4 -0
- package/src/utils/getDayjsFormatter.js +35 -0
- package/src/utils/getTextFromEl.js +28 -0
- package/src/utils/handlerHelpers.js +30 -0
- package/src/utils/hotkeyUtils.js +129 -0
- package/src/utils/menuUtils.js +402 -0
- package/src/utils/popoverOverflowModifiers.js +11 -0
- package/src/utils/pureNoFunc.js +31 -0
- package/src/utils/renderOnDoc.js +29 -0
- package/src/utils/showProgressToast.js +22 -0
- package/src/utils/tagUtils.js +45 -0
- package/src/utils/tgFormValues.js +32 -0
- package/src/utils/withSelectTableRecords.js +38 -0
- package/src/utils/withStore.js +10 -0
- package/src/wrapDialog.js +112 -0
- package/tsconfig.json +4 -0
- package/vite.config.ts +7 -0
- package/index.js +0 -80652
- package/index.mjs +0 -80636
- package/index.umd.js +0 -80649
- 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
|
+
};
|