@teselagen/ui 0.7.33-beta.6 → 0.7.34

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 (114) hide show
  1. package/AdvancedOptions.js +33 -0
  2. package/AssignDefaultsModeContext.js +22 -0
  3. package/CellDragHandle.js +132 -0
  4. package/ColumnFilterMenu.js +62 -0
  5. package/Columns.js +979 -0
  6. package/DataTable/utils/queryParams.d.ts +14 -7
  7. package/DisabledLoadingComponent.js +15 -0
  8. package/DisplayOptions.js +199 -0
  9. package/DropdownButton.js +36 -0
  10. package/DropdownCell.js +61 -0
  11. package/EditableCell.js +44 -0
  12. package/FillWindow.css +6 -0
  13. package/FillWindow.js +69 -0
  14. package/FilterAndSortMenu.js +391 -0
  15. package/FormSeparator.js +9 -0
  16. package/LoadingDots.js +14 -0
  17. package/MatchHeaders.js +234 -0
  18. package/PagingTool.js +225 -0
  19. package/RenderCell.js +191 -0
  20. package/SearchBar.js +69 -0
  21. package/SimpleStepViz.js +22 -0
  22. package/SortableColumns.js +100 -0
  23. package/TableFormTrackerContext.js +10 -0
  24. package/Tag.js +112 -0
  25. package/ThComponent.js +44 -0
  26. package/TimelineEvent.js +31 -0
  27. package/UploadCsvWizard.css +4 -0
  28. package/UploadCsvWizard.js +719 -0
  29. package/Uploader.js +1278 -0
  30. package/adHoc.js +10 -0
  31. package/autoTooltip.js +201 -0
  32. package/basicHandleActionsWithFullState.js +14 -0
  33. package/browserUtils.js +3 -0
  34. package/combineReducersWithFullState.js +14 -0
  35. package/commandControls.js +82 -0
  36. package/commandUtils.js +112 -0
  37. package/constants.js +1 -0
  38. package/convertSchema.js +69 -0
  39. package/customIcons.js +361 -0
  40. package/dataTableEnhancer.js +41 -0
  41. package/defaultFormatters.js +32 -0
  42. package/defaultValidators.js +40 -0
  43. package/determineBlackOrWhiteTextColor.js +4 -0
  44. package/editCellHelper.js +44 -0
  45. package/formatPasteData.js +16 -0
  46. package/getAllRows.js +11 -0
  47. package/getCellCopyText.js +7 -0
  48. package/getCellInfo.js +36 -0
  49. package/getCellVal.js +20 -0
  50. package/getDayjsFormatter.js +35 -0
  51. package/getFieldPathToField.js +7 -0
  52. package/getIdOrCodeOrIndex.js +9 -0
  53. package/getLastSelectedEntity.js +11 -0
  54. package/getNewEntToSelect.js +25 -0
  55. package/getNewName.js +31 -0
  56. package/getRowCopyText.js +28 -0
  57. package/getTableConfigFromStorage.js +5 -0
  58. package/getTextFromEl.js +28 -0
  59. package/getVals.js +8 -0
  60. package/handleCopyColumn.js +21 -0
  61. package/handleCopyHelper.js +15 -0
  62. package/handleCopyRows.js +23 -0
  63. package/handleCopyTable.js +16 -0
  64. package/handlerHelpers.js +24 -0
  65. package/hotkeyUtils.js +131 -0
  66. package/index.cjs.js +972 -837
  67. package/index.d.ts +0 -1
  68. package/index.es.js +972 -837
  69. package/index.js +1 -0
  70. package/isBeingCalledExcessively.js +31 -0
  71. package/isBottomRightCornerOfRectangle.js +20 -0
  72. package/isEntityClean.js +15 -0
  73. package/isTruthy.js +12 -0
  74. package/isValueEmpty.js +3 -0
  75. package/itemUpload.js +84 -0
  76. package/menuUtils.js +433 -0
  77. package/package.json +1 -2
  78. package/popoverOverflowModifiers.js +11 -0
  79. package/primarySelectedValue.js +1 -0
  80. package/pureNoFunc.js +31 -0
  81. package/queryParams.js +1058 -0
  82. package/removeCleanRows.js +22 -0
  83. package/renderOnDoc.js +32 -0
  84. package/rerenderOnWindowResize.js +26 -0
  85. package/rowClick.js +181 -0
  86. package/selection.js +8 -0
  87. package/showAppSpinner.js +12 -0
  88. package/showDialogOnDocBody.js +33 -0
  89. package/showProgressToast.js +22 -0
  90. package/sortify.js +73 -0
  91. package/style.css +13 -0
  92. package/tagUtils.js +45 -0
  93. package/tgFormValues.js +35 -0
  94. package/tg_modalState.js +47 -0
  95. package/throwFormError.js +16 -0
  96. package/toastr.js +148 -0
  97. package/tryToMatchSchemas.js +264 -0
  98. package/typeToCommonType.js +6 -0
  99. package/useDeepEqualMemo.js +15 -0
  100. package/useDialog.js +63 -0
  101. package/useStableReference.js +9 -0
  102. package/useTableEntities.js +38 -0
  103. package/useTraceUpdate.js +19 -0
  104. package/utils.js +37 -0
  105. package/validateTableWideErrors.js +160 -0
  106. package/viewColumn.js +97 -0
  107. package/withField.js +20 -0
  108. package/withFields.js +11 -0
  109. package/withLocalStorage.js +11 -0
  110. package/withSelectTableRecords.js +43 -0
  111. package/withSelectedEntities.js +65 -0
  112. package/withStore.js +10 -0
  113. package/withTableParams.js +301 -0
  114. package/wrapDialog.js +116 -0
@@ -0,0 +1,160 @@
1
+ import { getIdOrCodeOrIndex } from "./utils";
2
+ import { getCellVal } from "./getCellVal";
3
+ import { forEach, isArray } from "lodash-es";
4
+ import { startCase } from "lodash-es";
5
+ import { camelCase } from "lodash-es";
6
+
7
+ const uniqueMsg = "This value must be unique";
8
+ export function validateTableWideErrors({
9
+ entities,
10
+ schema,
11
+ optionalUserSchema,
12
+ newCellValidate
13
+ }) {
14
+ forEach(newCellValidate, (err, cellId) => {
15
+ if (err && err._isTableWideError) {
16
+ delete newCellValidate[cellId];
17
+ }
18
+ });
19
+ if (schema.tableWideValidation) {
20
+ const newErrs = schema.tableWideValidation({
21
+ entities
22
+ });
23
+ forEach(newErrs, (err, cellId) => {
24
+ newCellValidate[cellId] = {
25
+ message: err,
26
+ _isTableWideError: true
27
+ };
28
+ });
29
+ }
30
+ const displayNameMap = {};
31
+ const fieldUpperToPath = {};
32
+
33
+ forEach(schema.fields, f => {
34
+ fieldUpperToPath[f.path.toUpperCase()] = f.path;
35
+ displayNameMap[f.path] = f.displayName || startCase(camelCase(f.path));
36
+ });
37
+ function getDisplayName(path) {
38
+ return displayNameMap[path] || startCase(camelCase(path));
39
+ }
40
+
41
+ if (schema.requireAtLeastOneOf) {
42
+ //make sure at least one of the required fields is present
43
+ (isArray(schema.requireAtLeastOneOf[0])
44
+ ? schema.requireAtLeastOneOf
45
+ : [schema.requireAtLeastOneOf]
46
+ ).forEach(alo => {
47
+ entities.forEach(entity => {
48
+ if (!alo.some(path => getCellVal(entity, path))) {
49
+ alo.forEach(path => {
50
+ const cellId = `${getIdOrCodeOrIndex(entity)}:${path}`;
51
+ newCellValidate[cellId] = {
52
+ message: `At least one of these fields must be present - ${alo
53
+ .map(getDisplayName)
54
+ .join(", ")}`,
55
+ _isTableWideError: true
56
+ };
57
+ });
58
+ }
59
+ });
60
+ });
61
+ }
62
+ if (schema.requireExactlyOneOf) {
63
+ (isArray(schema.requireExactlyOneOf[0])
64
+ ? schema.requireExactlyOneOf
65
+ : [schema.requireExactlyOneOf]
66
+ ).forEach(reqs => {
67
+ entities.forEach(entity => {
68
+ const present = reqs.filter(path => getCellVal(entity, path));
69
+ if (present.length !== 1) {
70
+ reqs.forEach(path => {
71
+ const cellId = `${getIdOrCodeOrIndex(entity)}:${path}`;
72
+ const fields = reqs.map(getDisplayName).join(", ");
73
+ const err = {
74
+ message:
75
+ present.length === 0
76
+ ? `One of these fields is required - ${fields}`
77
+ : `Cannot have more than one of these fields - ${fields}`,
78
+ _isTableWideError: true
79
+ };
80
+ newCellValidate[cellId] = err;
81
+ });
82
+ }
83
+ });
84
+ });
85
+ }
86
+
87
+ const requireIfs = [];
88
+ schema.fields.forEach(col => {
89
+ const { path, requireIf } = col;
90
+ if (requireIf) {
91
+ const requireIfPath = fieldUpperToPath[requireIf.toUpperCase()];
92
+ requireIfs.push([requireIfPath, path]);
93
+ }
94
+ });
95
+ requireIfs.forEach(([requireIfPath, path]) => {
96
+ entities.forEach(entity => {
97
+ const requireIfVal = getCellVal(entity, requireIfPath);
98
+ const pathVal = getCellVal(entity, path);
99
+ if (requireIfVal && !pathVal) {
100
+ const cellId = `${getIdOrCodeOrIndex(entity)}:${path}`;
101
+ newCellValidate[cellId] = {
102
+ message: `This field is required if ${displayNameMap[requireIfPath]} is present`,
103
+ _isTableWideError: true
104
+ };
105
+ }
106
+ });
107
+ });
108
+ if (schema.requireAllOrNone) {
109
+ (isArray(schema.requireAllOrNone[0])
110
+ ? schema.requireAllOrNone
111
+ : [schema.requireAllOrNone]
112
+ ).forEach(reqs => {
113
+ entities.forEach(entity => {
114
+ const present = reqs.filter(path => getCellVal(entity, path));
115
+ if (present.length && present.length !== reqs.length) {
116
+ reqs.forEach(path => {
117
+ const cellId = `${getIdOrCodeOrIndex(entity)}:${path}`;
118
+ const fields = reqs.map(getDisplayName).join(", ");
119
+ const err = {
120
+ message: `Please specify either ALL of the following fields or NONE of them - ${fields}`,
121
+ _isTableWideError: true
122
+ };
123
+ newCellValidate[cellId] = err;
124
+ });
125
+ }
126
+ });
127
+ });
128
+ }
129
+
130
+ schema.fields.forEach(col => {
131
+ let { path, isUnique } = col;
132
+ if (isUnique) {
133
+ if (optionalUserSchema) {
134
+ path = col.matches[0].item.path;
135
+ }
136
+ const existingVals = {};
137
+ entities.forEach(entity => {
138
+ const val = getCellVal(entity, path, col);
139
+ if (!val) return;
140
+ const cellId = `${getIdOrCodeOrIndex(entity)}:${path}`;
141
+ if (existingVals[val]) {
142
+ newCellValidate[cellId] = {
143
+ message: uniqueMsg,
144
+ _isTableWideError: true
145
+ };
146
+ newCellValidate[existingVals[val]] = {
147
+ message: uniqueMsg,
148
+ _isTableWideError: true
149
+ };
150
+ } else {
151
+ if (newCellValidate[cellId] === uniqueMsg) {
152
+ delete newCellValidate[cellId];
153
+ }
154
+ existingVals[val] = cellId;
155
+ }
156
+ });
157
+ }
158
+ });
159
+ return newCellValidate;
160
+ }
package/viewColumn.js ADDED
@@ -0,0 +1,97 @@
1
+ import React from "react";
2
+ import { Icon, Button, Tooltip } from "@blueprintjs/core";
3
+ import { reduce } from "lodash-es";
4
+
5
+ export const viewColumn = {
6
+ width: 35,
7
+ noEllipsis: true,
8
+ hideInMenu: true,
9
+ immovable: true,
10
+ type: "action",
11
+ render: () => {
12
+ return <Icon className="dt-eyeIcon" icon="eye-open" />;
13
+ }
14
+ };
15
+
16
+ export const openColumn = ({ onDoubleClick, history }) => ({
17
+ ...viewColumn,
18
+ render: (val, record, rowInfo) => {
19
+ return (
20
+ <Tooltip content="Open">
21
+ <Button
22
+ onClick={e => {
23
+ e.stopPropagation();
24
+ onDoubleClick &&
25
+ onDoubleClick(rowInfo.original, rowInfo.index, history);
26
+ }}
27
+ minimal
28
+ small
29
+ className="dt-eyeIcon"
30
+ icon="document-open"
31
+ />
32
+ </Tooltip>
33
+ );
34
+ }
35
+ });
36
+
37
+ export const multiViewColumn = {
38
+ ...viewColumn,
39
+ columnHeader: ({ recordIdToIsVisibleMap, setRecordIdToIsVisibleMap }) => {
40
+ const allVisible = reduce(
41
+ recordIdToIsVisibleMap,
42
+ (acc, val) => acc && val,
43
+ true
44
+ );
45
+ return (
46
+ <Tooltip content={allVisible ? "Hide All" : "Show All"}>
47
+ <Button
48
+ className={`showHideAllButton-${allVisible ? "visible" : "hidden"}`}
49
+ minimal
50
+ onClick={() => {
51
+ setRecordIdToIsVisibleMap(
52
+ reduce(
53
+ recordIdToIsVisibleMap,
54
+ (acc, val, key) => {
55
+ acc[key] = !allVisible;
56
+ return acc;
57
+ },
58
+ {}
59
+ )
60
+ );
61
+ }}
62
+ icon={allVisible ? "eye-open" : "eye-off"}
63
+ />
64
+ </Tooltip>
65
+ );
66
+ },
67
+ render: (
68
+ val,
69
+ record,
70
+ row,
71
+ { recordIdToIsVisibleMap, setRecordIdToIsVisibleMap }
72
+ ) => {
73
+ if (!recordIdToIsVisibleMap) {
74
+ return null;
75
+ }
76
+ const isVisible = recordIdToIsVisibleMap[record.id];
77
+ return (
78
+ <Tooltip content={isVisible ? "Hide" : "Show"}>
79
+ <Button
80
+ onClick={e => {
81
+ e.stopPropagation();
82
+ e.preventDefault();
83
+ setRecordIdToIsVisibleMap(
84
+ Object.assign({}, recordIdToIsVisibleMap, {
85
+ [record.id]: !isVisible
86
+ })
87
+ );
88
+ }}
89
+ minimal
90
+ small
91
+ className={`showHideButton-${isVisible ? "visible" : "hidden"}-${record.id}`}
92
+ icon={isVisible ? "eye-open" : "eye-off"}
93
+ />
94
+ </Tooltip>
95
+ );
96
+ }
97
+ };
package/withField.js ADDED
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { Field } from "redux-form";
3
+ import { fieldRequired } from "../FormComponents/utils";
4
+
5
+ //simple enhancer that wraps a component in a redux <Field/> component
6
+ //all options are passed as props to <Field/>
7
+ export default function WithField(fieldProps) {
8
+ return function AddFieldHOC(Component) {
9
+ return function AddField({ isRequired, ...rest }) {
10
+ return (
11
+ <Field
12
+ {...(isRequired && { validate: fieldRequired })}
13
+ {...fieldProps}
14
+ {...rest}
15
+ component={Component}
16
+ />
17
+ );
18
+ };
19
+ };
20
+ }
package/withFields.js ADDED
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { Fields } from "redux-form";
3
+ //simple enhancer that wraps a component in a redux <Fields/> component
4
+ //all options are passed as props to <Fields/>
5
+ export default function WithFields(fieldsProps) {
6
+ return function AddFieldsHOC(Component) {
7
+ return function AddFields(props) {
8
+ return <Fields {...fieldsProps} {...props} component={Component} />;
9
+ };
10
+ };
11
+ }
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { Field } from "redux-form";
3
+ //simple enhancer that wraps a component in a redux <Field/> component
4
+ //all options are passed as props to <Field/>
5
+ export default function WithField(fieldProps) {
6
+ return function AddFieldHOC(Component) {
7
+ return function AddField(props) {
8
+ return <Field {...fieldProps} {...props} component={Component} />;
9
+ };
10
+ };
11
+ }
@@ -0,0 +1,43 @@
1
+ /* Copyright (C) 2018 TeselaGen Biotechnology, Inc. */
2
+ import { compose, withHandlers } from "recompose";
3
+ import { connect } from "react-redux";
4
+ import { change, initialize } from "redux-form";
5
+
6
+ export default function (_tableFormName, propName = "selectTableRecords") {
7
+ return compose(
8
+ connect(null, {
9
+ changeFormValue: change,
10
+ initializeForm: initialize
11
+ }),
12
+ withHandlers({
13
+ [propName]:
14
+ props =>
15
+ (_records = []) => {
16
+ let tableFormName = _tableFormName;
17
+ if (typeof _tableFormName === "function") {
18
+ tableFormName = _tableFormName(props);
19
+ }
20
+ // initialize if needed so that the values will stay
21
+ props.initializeForm(tableFormName, {}, true, {
22
+ keepDirty: true,
23
+ updateUnregisteredFields: true,
24
+ keepValues: true
25
+ });
26
+ const selectedEntityIdMap = {};
27
+ let records = _records;
28
+ if (_records && !Array.isArray(_records)) records = [records];
29
+ records.forEach(record => {
30
+ selectedEntityIdMap[record.id] = {
31
+ entity: record,
32
+ time: Date.now()
33
+ };
34
+ });
35
+ props.changeFormValue(
36
+ tableFormName,
37
+ "reduxFormSelectedEntityIdMap",
38
+ selectedEntityIdMap
39
+ );
40
+ }
41
+ })
42
+ );
43
+ }
@@ -0,0 +1,65 @@
1
+ import { formValueSelector } from "redux-form";
2
+ import { reduce } from "lodash-es";
3
+ import { connect } from "react-redux";
4
+ /**
5
+ * @param {*string} formName
6
+ * @param {*string} formName
7
+ * @param {*string} formName
8
+ * @param {*string} ...etc
9
+ * adds a new prop `${formName}SelectedEntities` eg sequenceTableSelectedEntities
10
+ */
11
+ export default function withSelectedEntities(...formNames) {
12
+ if (!formNames.length) {
13
+ throw new Error(
14
+ "You need to pass at least one arg to withSelectedEntities"
15
+ );
16
+ }
17
+ if (typeof formNames[0] === "string") {
18
+ //NEW WAY
19
+ return connect(state => {
20
+ return formNames.reduce((acc, formName) => {
21
+ acc[formName + "SelectedEntities"] = getRecordsFromReduxForm(
22
+ state,
23
+ formName
24
+ );
25
+ return acc;
26
+ }, {});
27
+ });
28
+ } else {
29
+ //OLD WAY:
30
+ const { formName, name } = formNames[0];
31
+ if (!formName) {
32
+ throw new Error(
33
+ "Please pass a {formName} option when using withSelectedEntities"
34
+ );
35
+ }
36
+ return connect(state => {
37
+ return {
38
+ [name || "selectedEntities"]: getRecordsFromReduxForm(state, formName)
39
+ };
40
+ });
41
+ }
42
+ }
43
+
44
+ export function getRecordsFromReduxForm(state, formName) {
45
+ const selector = formValueSelector(formName);
46
+ return getRecordsFromIdMap(selector(state, "reduxFormSelectedEntityIdMap"));
47
+ }
48
+
49
+ export function getRecordsFromIdMap(idMap = {}) {
50
+ return reduce(
51
+ idMap,
52
+ (acc, item) => {
53
+ if (item && item.entity) acc.push(item);
54
+ return acc;
55
+ },
56
+ []
57
+ )
58
+ .sort((a, b) => a.rowIndex - b.rowIndex)
59
+ .map(item => item.entity);
60
+ }
61
+
62
+ export function getSelectedEntities(storeOrState, formName) {
63
+ const state = storeOrState.getState ? storeOrState.getState() : storeOrState;
64
+ return getRecordsFromReduxForm(state, formName);
65
+ }
package/withStore.js ADDED
@@ -0,0 +1,10 @@
1
+ import { useStore } from "react-redux";
2
+ import React from "react";
3
+
4
+ const withStore = Component => {
5
+ return props => {
6
+ const store = useStore();
7
+ return <Component {...props} store={store} />;
8
+ };
9
+ };
10
+ export default withStore;