@teselagen/ui 0.7.32 → 0.7.33-beta.2

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 (254) hide show
  1. package/AdvancedOptions.js +33 -0
  2. package/AssignDefaultsModeContext.js +22 -0
  3. package/DataTable/utils/filterLocalEntitiesToHasura.d.ts +5 -0
  4. package/DataTable/utils/initializeHasuraWhereAndFilter.d.ts +2 -0
  5. package/DataTable/utils/queryParams.d.ts +8 -12
  6. package/DataTable/utils/simplifyHasuraWhere.d.ts +1 -0
  7. package/DataTable/utils/tableQueryParamsToHasuraClauses.d.ts +14 -0
  8. package/DropdownButton.js +36 -0
  9. package/FillWindow.css +6 -0
  10. package/FillWindow.js +69 -0
  11. package/{src/DataTable/FilterAndSortMenu.js → FilterAndSortMenu.js} +27 -30
  12. package/MatchHeaders.js +234 -0
  13. package/SimpleStepViz.js +22 -0
  14. package/Tag.js +112 -0
  15. package/UploadCsvWizard.css +4 -0
  16. package/UploadCsvWizard.js +719 -0
  17. package/autoTooltip.js +201 -0
  18. package/constants.js +1 -0
  19. package/customIcons.js +361 -0
  20. package/filterLocalEntitiesToHasura.js +216 -0
  21. package/index.cjs.js +695 -967
  22. package/index.d.ts +1 -0
  23. package/index.es.js +695 -967
  24. package/initializeHasuraWhereAndFilter.js +27 -0
  25. package/{src/utils/isBeingCalledExcessively.js → isBeingCalledExcessively.js} +0 -1
  26. package/package.json +1 -1
  27. package/queryParams.js +336 -0
  28. package/rerenderOnWindowResize.js +26 -0
  29. package/showAppSpinner.js +12 -0
  30. package/showDialogOnDocBody.js +33 -0
  31. package/simplifyHasuraWhere.js +80 -0
  32. package/src/CellDragHandle.js +132 -0
  33. package/src/ColumnFilterMenu.js +62 -0
  34. package/src/Columns.js +979 -0
  35. package/src/DisabledLoadingComponent.js +15 -0
  36. package/src/DisplayOptions.js +199 -0
  37. package/src/DropdownCell.js +61 -0
  38. package/src/EditableCell.js +44 -0
  39. package/src/FilterAndSortMenu.js +388 -0
  40. package/src/FormSeparator.js +9 -0
  41. package/src/LoadingDots.js +14 -0
  42. package/src/PagingTool.js +225 -0
  43. package/src/RenderCell.js +191 -0
  44. package/src/SearchBar.js +69 -0
  45. package/src/SortableColumns.js +100 -0
  46. package/src/TableFormTrackerContext.js +10 -0
  47. package/src/ThComponent.js +44 -0
  48. package/src/TimelineEvent.js +31 -0
  49. package/src/Uploader.js +1278 -0
  50. package/src/adHoc.js +10 -0
  51. package/src/basicHandleActionsWithFullState.js +14 -0
  52. package/src/browserUtils.js +3 -0
  53. package/src/combineReducersWithFullState.js +14 -0
  54. package/src/commandControls.js +82 -0
  55. package/src/commandUtils.js +112 -0
  56. package/src/convertSchema.js +69 -0
  57. package/src/dataTableEnhancer.js +41 -0
  58. package/src/defaultFormatters.js +32 -0
  59. package/src/defaultValidators.js +40 -0
  60. package/src/determineBlackOrWhiteTextColor.js +4 -0
  61. package/src/editCellHelper.js +44 -0
  62. package/src/filterLocalEntitiesToHasura.js +216 -0
  63. package/src/formatPasteData.js +16 -0
  64. package/src/getAllRows.js +11 -0
  65. package/src/getCellCopyText.js +7 -0
  66. package/src/getCellInfo.js +36 -0
  67. package/src/getCellVal.js +20 -0
  68. package/src/getDayjsFormatter.js +35 -0
  69. package/src/getFieldPathToField.js +7 -0
  70. package/src/getIdOrCodeOrIndex.js +9 -0
  71. package/src/getLastSelectedEntity.js +11 -0
  72. package/src/getNewEntToSelect.js +25 -0
  73. package/src/getNewName.js +31 -0
  74. package/src/getRowCopyText.js +28 -0
  75. package/src/getTableConfigFromStorage.js +5 -0
  76. package/src/getTextFromEl.js +28 -0
  77. package/src/getVals.js +8 -0
  78. package/src/handleCopyColumn.js +21 -0
  79. package/src/handleCopyHelper.js +15 -0
  80. package/src/handleCopyRows.js +23 -0
  81. package/src/handleCopyTable.js +16 -0
  82. package/src/handlerHelpers.js +24 -0
  83. package/src/hotkeyUtils.js +131 -0
  84. package/src/index.js +1 -87
  85. package/src/initializeHasuraWhereAndFilter.js +27 -0
  86. package/src/isBeingCalledExcessively.js +24 -0
  87. package/src/isBottomRightCornerOfRectangle.js +20 -0
  88. package/src/isEntityClean.js +15 -0
  89. package/src/isTruthy.js +12 -0
  90. package/src/isValueEmpty.js +3 -0
  91. package/src/itemUpload.js +84 -0
  92. package/src/menuUtils.js +433 -0
  93. package/src/popoverOverflowModifiers.js +11 -0
  94. package/src/primarySelectedValue.js +1 -0
  95. package/src/pureNoFunc.js +31 -0
  96. package/src/queryParams.js +336 -0
  97. package/src/removeCleanRows.js +22 -0
  98. package/src/renderOnDoc.js +32 -0
  99. package/src/rowClick.js +181 -0
  100. package/src/selection.js +8 -0
  101. package/src/showProgressToast.js +22 -0
  102. package/src/simplifyHasuraWhere.js +80 -0
  103. package/src/sortify.js +73 -0
  104. package/src/style.css +24 -260
  105. package/src/tableQueryParamsToHasuraClauses.js +113 -0
  106. package/src/{DataTable/utils/withTableParams.js → withTableParams.js} +1 -14
  107. package/tableQueryParamsToHasuraClauses.js +113 -0
  108. package/tagUtils.js +45 -0
  109. package/tgFormValues.js +35 -0
  110. package/tg_modalState.js +47 -0
  111. package/throwFormError.js +16 -0
  112. package/toastr.js +148 -0
  113. package/tryToMatchSchemas.js +264 -0
  114. package/typeToCommonType.js +6 -0
  115. package/useDeepEqualMemo.js +15 -0
  116. package/useDialog.js +63 -0
  117. package/useStableReference.js +9 -0
  118. package/useTableEntities.js +38 -0
  119. package/useTraceUpdate.js +19 -0
  120. package/utils.js +37 -0
  121. package/validateTableWideErrors.js +160 -0
  122. package/viewColumn.js +97 -0
  123. package/withField.js +20 -0
  124. package/withFields.js +11 -0
  125. package/withLocalStorage.js +11 -0
  126. package/withSelectTableRecords.js +43 -0
  127. package/withSelectedEntities.js +65 -0
  128. package/withStore.js +10 -0
  129. package/withTableParams.js +288 -0
  130. package/wrapDialog.js +116 -0
  131. package/src/AdvancedOptions.spec.js +0 -26
  132. package/src/AsyncValidateFieldSpinner/index.js +0 -12
  133. package/src/BlueprintError/index.js +0 -14
  134. package/src/BounceLoader/index.js +0 -16
  135. package/src/BounceLoader/style.css +0 -45
  136. package/src/CollapsibleCard/index.js +0 -68
  137. package/src/CollapsibleCard/style.css +0 -23
  138. package/src/DNALoader/index.js +0 -20
  139. package/src/DNALoader/style.css +0 -251
  140. package/src/DataTable/index.js +0 -3213
  141. package/src/DataTable/style.css +0 -608
  142. package/src/DataTable/utils/index.js +0 -55
  143. package/src/DataTable/utils/queryParams.js +0 -1058
  144. package/src/DialogFooter/index.js +0 -86
  145. package/src/DialogFooter/style.css +0 -9
  146. package/src/FormComponents/index.js +0 -1266
  147. package/src/FormComponents/style.css +0 -275
  148. package/src/FormComponents/utils.js +0 -6
  149. package/src/HotkeysDialog/index.js +0 -79
  150. package/src/HotkeysDialog/style.css +0 -54
  151. package/src/InfoHelper/index.js +0 -78
  152. package/src/InfoHelper/style.css +0 -7
  153. package/src/IntentText/index.js +0 -18
  154. package/src/Loading/index.js +0 -70
  155. package/src/Loading/style.css +0 -4
  156. package/src/MenuBar/index.js +0 -423
  157. package/src/MenuBar/style.css +0 -45
  158. package/src/PromptUnsavedChanges/index.js +0 -38
  159. package/src/ResizableDraggableDialog/index.js +0 -141
  160. package/src/ResizableDraggableDialog/style.css +0 -42
  161. package/src/ScrollToTop/index.js +0 -72
  162. package/src/TagSelect/index.js +0 -69
  163. package/src/TagSelect/style.css +0 -13
  164. package/src/TgHtmlSelect/index.js +0 -20
  165. package/src/TgSelect/index.js +0 -537
  166. package/src/TgSelect/style.css +0 -61
  167. package/src/TgSuggest/index.js +0 -124
  168. package/src/Timeline/index.js +0 -15
  169. package/src/enhancers/withDialog/index.js +0 -196
  170. package/src/showConfirmationDialog/index.js +0 -148
  171. /package/{src/DataTable/CellDragHandle.js → CellDragHandle.js} +0 -0
  172. /package/{src/DataTable/ColumnFilterMenu.js → ColumnFilterMenu.js} +0 -0
  173. /package/{src/DataTable/Columns.js → Columns.js} +0 -0
  174. /package/{src/DataTable/DisabledLoadingComponent.js → DisabledLoadingComponent.js} +0 -0
  175. /package/{src/DataTable/DisplayOptions.js → DisplayOptions.js} +0 -0
  176. /package/{src/DataTable/DropdownCell.js → DropdownCell.js} +0 -0
  177. /package/{src/DataTable/EditableCell.js → EditableCell.js} +0 -0
  178. /package/{src/FormComponents/FormSeparator.js → FormSeparator.js} +0 -0
  179. /package/{src/FormComponents/LoadingDots.js → LoadingDots.js} +0 -0
  180. /package/{src/DataTable/PagingTool.js → PagingTool.js} +0 -0
  181. /package/{src/DataTable/RenderCell.js → RenderCell.js} +0 -0
  182. /package/{src/DataTable/SearchBar.js → SearchBar.js} +0 -0
  183. /package/{src/DataTable/SortableColumns.js → SortableColumns.js} +0 -0
  184. /package/{src/DataTable/TableFormTrackerContext.js → TableFormTrackerContext.js} +0 -0
  185. /package/{src/DataTable/ThComponent.js → ThComponent.js} +0 -0
  186. /package/{src/Timeline/TimelineEvent.js → TimelineEvent.js} +0 -0
  187. /package/{src/FormComponents/Uploader.js → Uploader.js} +0 -0
  188. /package/{src/utils/adHoc.js → adHoc.js} +0 -0
  189. /package/{src/utils/basicHandleActionsWithFullState.js → basicHandleActionsWithFullState.js} +0 -0
  190. /package/{src/utils/browserUtils.js → browserUtils.js} +0 -0
  191. /package/{src/utils/combineReducersWithFullState.js → combineReducersWithFullState.js} +0 -0
  192. /package/{src/utils/commandControls.js → commandControls.js} +0 -0
  193. /package/{src/utils/commandUtils.js → commandUtils.js} +0 -0
  194. /package/{src/DataTable/utils/convertSchema.js → convertSchema.js} +0 -0
  195. /package/{src/DataTable/dataTableEnhancer.js → dataTableEnhancer.js} +0 -0
  196. /package/{src/DataTable/defaultFormatters.js → defaultFormatters.js} +0 -0
  197. /package/{src/DataTable/defaultValidators.js → defaultValidators.js} +0 -0
  198. /package/{src/utils/determineBlackOrWhiteTextColor.js → determineBlackOrWhiteTextColor.js} +0 -0
  199. /package/{src/DataTable/editCellHelper.js → editCellHelper.js} +0 -0
  200. /package/{src/DataTable/utils/formatPasteData.js → formatPasteData.js} +0 -0
  201. /package/{src/DataTable/utils/getAllRows.js → getAllRows.js} +0 -0
  202. /package/{src/DataTable/utils/getCellCopyText.js → getCellCopyText.js} +0 -0
  203. /package/{src/DataTable/utils/getCellInfo.js → getCellInfo.js} +0 -0
  204. /package/{src/DataTable/getCellVal.js → getCellVal.js} +0 -0
  205. /package/{src/utils/getDayjsFormatter.js → getDayjsFormatter.js} +0 -0
  206. /package/{src/DataTable/utils/getFieldPathToField.js → getFieldPathToField.js} +0 -0
  207. /package/{src/DataTable/utils/getIdOrCodeOrIndex.js → getIdOrCodeOrIndex.js} +0 -0
  208. /package/{src/DataTable/utils/getLastSelectedEntity.js → getLastSelectedEntity.js} +0 -0
  209. /package/{src/DataTable/utils/getNewEntToSelect.js → getNewEntToSelect.js} +0 -0
  210. /package/{src/FormComponents/getNewName.js → getNewName.js} +0 -0
  211. /package/{src/DataTable/utils/getRowCopyText.js → getRowCopyText.js} +0 -0
  212. /package/{src/DataTable/utils/getTableConfigFromStorage.js → getTableConfigFromStorage.js} +0 -0
  213. /package/{src/utils/getTextFromEl.js → getTextFromEl.js} +0 -0
  214. /package/{src/DataTable/getVals.js → getVals.js} +0 -0
  215. /package/{src/DataTable/utils/handleCopyColumn.js → handleCopyColumn.js} +0 -0
  216. /package/{src/DataTable/utils/handleCopyHelper.js → handleCopyHelper.js} +0 -0
  217. /package/{src/DataTable/utils/handleCopyRows.js → handleCopyRows.js} +0 -0
  218. /package/{src/DataTable/utils/handleCopyTable.js → handleCopyTable.js} +0 -0
  219. /package/{src/utils/handlerHelpers.js → handlerHelpers.js} +0 -0
  220. /package/{src/utils/hotkeyUtils.js → hotkeyUtils.js} +0 -0
  221. /package/{src/utils/hooks/index.js → index.js} +0 -0
  222. /package/{src/DataTable/utils/isBottomRightCornerOfRectangle.js → isBottomRightCornerOfRectangle.js} +0 -0
  223. /package/{src/DataTable/utils/isEntityClean.js → isEntityClean.js} +0 -0
  224. /package/{src/DataTable/isTruthy.js → isTruthy.js} +0 -0
  225. /package/{src/DataTable/isValueEmpty.js → isValueEmpty.js} +0 -0
  226. /package/{src/FormComponents/itemUpload.js → itemUpload.js} +0 -0
  227. /package/{src/utils/menuUtils.js → menuUtils.js} +0 -0
  228. /package/{src/utils/popoverOverflowModifiers.js → popoverOverflowModifiers.js} +0 -0
  229. /package/{src/DataTable/utils/primarySelectedValue.js → primarySelectedValue.js} +0 -0
  230. /package/{src/utils/pureNoFunc.js → pureNoFunc.js} +0 -0
  231. /package/{src/DataTable/utils/removeCleanRows.js → removeCleanRows.js} +0 -0
  232. /package/{src/utils/renderOnDoc.js → renderOnDoc.js} +0 -0
  233. /package/{src/DataTable/utils/rowClick.js → rowClick.js} +0 -0
  234. /package/{src/DataTable/utils/selection.js → selection.js} +0 -0
  235. /package/{src/utils/showProgressToast.js → showProgressToast.js} +0 -0
  236. /package/{src/FormComponents/sortify.js → sortify.js} +0 -0
  237. /package/src/{utils/tagUtils.js → tagUtils.js} +0 -0
  238. /package/src/{utils/tgFormValues.js → tgFormValues.js} +0 -0
  239. /package/src/{enhancers/withDialog/tg_modalState.js → tg_modalState.js} +0 -0
  240. /package/src/{FormComponents/tryToMatchSchemas.js → tryToMatchSchemas.js} +0 -0
  241. /package/src/{utils/hooks/useDeepEqualMemo.js → useDeepEqualMemo.js} +0 -0
  242. /package/src/{utils/hooks/useStableReference.js → useStableReference.js} +0 -0
  243. /package/src/{DataTable/utils/useTableEntities.js → useTableEntities.js} +0 -0
  244. /package/src/{utils/useTraceUpdate.js → useTraceUpdate.js} +0 -0
  245. /package/src/{DataTable/utils/utils.js → utils.js} +0 -0
  246. /package/src/{DataTable/validateTableWideErrors.js → validateTableWideErrors.js} +0 -0
  247. /package/src/{DataTable/viewColumn.js → viewColumn.js} +0 -0
  248. /package/src/{enhancers/withField.js → withField.js} +0 -0
  249. /package/src/{enhancers/withFields.js → withFields.js} +0 -0
  250. /package/src/{enhancers/withLocalStorage.js → withLocalStorage.js} +0 -0
  251. /package/src/{utils/withSelectTableRecords.js → withSelectTableRecords.js} +0 -0
  252. /package/src/{DataTable/utils/withSelectedEntities.js → withSelectedEntities.js} +0 -0
  253. /package/src/{utils/withStore.js → withStore.js} +0 -0
  254. /package/{src/Timeline/style.css → style.css} +0 -0
package/src/adHoc.js ADDED
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { compose } from "recompose";
3
+
4
+ //adHoc allows you to add dynamic HOCs to a component
5
+ export default func => WrappedComponent => props => {
6
+ const calledFunc = func(props);
7
+ const composeArgs = Array.isArray(calledFunc) ? calledFunc : [calledFunc];
8
+ const ComposedAndWrapped = compose(...composeArgs)(WrappedComponent);
9
+ return <ComposedAndWrapped {...props} />;
10
+ };
@@ -0,0 +1,14 @@
1
+ export default function basicHandleActionsWithFullState(
2
+ handlers,
3
+ defaultState
4
+ ) {
5
+ return (state = defaultState, action, fullState) => {
6
+ const { type } = action;
7
+ const handler = handlers[type];
8
+ if (handler) {
9
+ return handler(state, action, fullState);
10
+ } else {
11
+ return state;
12
+ }
13
+ };
14
+ }
@@ -0,0 +1,3 @@
1
+ export const isSafari = /^((?!chrome|android).)*safari/i.test(
2
+ navigator.userAgent
3
+ );
@@ -0,0 +1,14 @@
1
+ export default function combineReducers(reducers = {}) {
2
+ const reducerKeys = Object.keys(reducers);
3
+ return function combination(state = {}, action, fullState) {
4
+ let hasChanged = false;
5
+ const nextState = {};
6
+ fullState = fullState || state;
7
+ for (let i = 0; i < reducerKeys.length; i++) {
8
+ const key = reducerKeys[i];
9
+ nextState[key] = reducers[key](state[key], action, fullState);
10
+ hasChanged = hasChanged || nextState[key] !== state[key];
11
+ }
12
+ return hasChanged ? nextState : state;
13
+ };
14
+ }
@@ -0,0 +1,82 @@
1
+ import React from "react";
2
+ import { Tooltip, Checkbox, Button, Switch } from "@blueprintjs/core";
3
+
4
+ export const withCommand =
5
+ mappings =>
6
+ WrappedComponent =>
7
+ ({ cmd, cmdOptions = {}, ...props }) => {
8
+ const mappedProps = {};
9
+ Object.keys(mappings).forEach(k => {
10
+ mappedProps[k] =
11
+ mappings[k] === "execute"
12
+ ? event => cmd.execute({ event })
13
+ : typeof mappings[k] === "function"
14
+ ? mappings[k](cmd, props)
15
+ : cmd[mappings[k]];
16
+ });
17
+
18
+ let out = <WrappedComponent {...mappedProps} {...props} />;
19
+ const tooltip =
20
+ cmd.tooltip || (typeof cmd.isDisabled === "string" && cmd.isDisabled);
21
+ if (tooltip && !cmdOptions.ignoreTooltip) {
22
+ out = <Tooltip content={tooltip}>{out}</Tooltip>;
23
+ }
24
+
25
+ return cmd.isHidden && !cmdOptions.ignoreHidden ? null : out;
26
+ };
27
+
28
+ export const CmdCheckbox = withCommand({
29
+ onChange: "execute",
30
+ label: (cmd, props) =>
31
+ props.name ||
32
+ (props.prefix && (
33
+ <React.Fragment>
34
+ {props.prefix}
35
+ {cmd.name}
36
+ </React.Fragment>
37
+ )) ||
38
+ cmd.name,
39
+ disabled: "isDisabled",
40
+ checked: "isActive"
41
+ })(Checkbox);
42
+
43
+ export const CmdSwitch = withCommand({
44
+ onChange: "execute",
45
+ label: (cmd, props) =>
46
+ props.name ||
47
+ (props.prefix && (
48
+ <React.Fragment>
49
+ {props.prefix}
50
+ {cmd.name}
51
+ </React.Fragment>
52
+ )) ||
53
+ cmd.name,
54
+ disabled: "isDisabled",
55
+ checked: "isActive"
56
+ })(Switch);
57
+
58
+ const Div = ({ onChange, children }) => {
59
+ return <div onClick={onChange}>{children}</div>;
60
+ };
61
+
62
+ export const CmdDiv = withCommand({
63
+ onChange: "execute",
64
+ children: (cmd, props) =>
65
+ props.name ||
66
+ (props.prefix && (
67
+ <React.Fragment>
68
+ {props.prefix}
69
+ {cmd.name}
70
+ </React.Fragment>
71
+ )) ||
72
+ cmd.name,
73
+ disabled: "isDisabled",
74
+ checked: "isActive"
75
+ })(Div);
76
+
77
+ export const CmdButton = withCommand({
78
+ onClick: "execute",
79
+ text: cmd => (cmd.isActive === false && cmd.inactiveName) || cmd.name,
80
+ icon: "icon",
81
+ disabled: "isDisabled"
82
+ })(Button);
@@ -0,0 +1,112 @@
1
+ import { startCase } from "lodash-es";
2
+
3
+ // Generic factory function to create command objects.
4
+ // TODO add documentation
5
+ export function genericCommandFactory(config) {
6
+ const out = {};
7
+ // eslint-disable-next-line no-unused-vars
8
+ for (const cmdId in config.commandDefs) {
9
+ const def = config.commandDefs[cmdId];
10
+ const command = { id: cmdId };
11
+ command.execute = (...execArgs) => {
12
+ config.handleReturn(
13
+ cmdId,
14
+ def.handler &&
15
+ def.handler.apply(command, config.getArguments(cmdId, execArgs))
16
+ );
17
+ };
18
+
19
+ const properties = [
20
+ "icon",
21
+ "name",
22
+ "component",
23
+ "shortName",
24
+ "description",
25
+ "hotkey",
26
+ "hotkeyProps",
27
+ "isDisabled",
28
+ "submenu",
29
+ "isActive",
30
+ "isHidden",
31
+ "tooltip",
32
+ "inactiveIcon",
33
+ "inactiveName"
34
+ ];
35
+
36
+ properties.forEach(prop => {
37
+ if (def[prop] !== undefined) {
38
+ if (typeof def[prop] === "function") {
39
+ Object.defineProperty(command, prop, {
40
+ get: () => {
41
+ return def[prop].apply(command, config.getArguments(cmdId, []));
42
+ }
43
+ });
44
+ } else {
45
+ command[prop] = def[prop];
46
+ }
47
+ }
48
+ });
49
+
50
+ // If no name was specified in the definition, let's try to give some
51
+ // auto-generated names
52
+ if (!def.name) {
53
+ command.name = startCase(cmdId);
54
+ if (def.toggle && cmdId.startsWith("toggle")) {
55
+ command.name = startCase(cmdId.replace("toggle", def.toggle[0] || ""));
56
+ command.inactiveName = startCase(
57
+ cmdId.replace("toggle", def.toggle[1] || "")
58
+ );
59
+ command.shortName = startCase(cmdId.replace("toggle", ""));
60
+ }
61
+ }
62
+
63
+ out[cmdId] = command;
64
+ }
65
+
66
+ return out;
67
+ }
68
+
69
+ // Extract hotkey props from the given commands or command defs, returning
70
+ // a mapping of command ids to hotkey prop objects
71
+ export function getCommandHotkeys(commandsOrDefs) {
72
+ const hotkeyDefs = {};
73
+ Object.keys(commandsOrDefs).forEach(cmdId => {
74
+ if (commandsOrDefs[cmdId].hotkey) {
75
+ hotkeyDefs[cmdId] = {
76
+ combo: commandsOrDefs[cmdId].hotkey,
77
+ label: commandsOrDefs[cmdId].name || startCase(cmdId),
78
+ ...commandsOrDefs[cmdId].hotkeyProps
79
+ };
80
+ }
81
+ });
82
+
83
+ return hotkeyDefs;
84
+ }
85
+
86
+ // Extract handler functions from the given commands, returning a mapping of
87
+ // command ids to handlers (directly - no checks added).
88
+ export function getCommandHandlers(commands) {
89
+ const handlers = {};
90
+ Object.keys(commands).forEach(cmdId => {
91
+ handlers[cmdId] = commands[cmdId].execute;
92
+ });
93
+
94
+ return handlers;
95
+ }
96
+
97
+ // Get hotkey handler functions for the given commands, returning a mapping of
98
+ // command ids to hotkey handlers.
99
+ export function getCommandHotkeyHandlers(commands) {
100
+ const handlers = {};
101
+ Object.keys(commands).forEach(cmdId => {
102
+ if (commands[cmdId].hotkey) {
103
+ handlers[cmdId] = event => {
104
+ if (!commands[cmdId].isDisabled && !commands[cmdId].isHidden) {
105
+ commands[cmdId].execute({ event, viaHotkey: true });
106
+ }
107
+ };
108
+ }
109
+ });
110
+
111
+ return handlers;
112
+ }
@@ -0,0 +1,69 @@
1
+ import { camelCase } from "lodash-es";
2
+ import { startCase, keyBy, map } from "lodash-es";
3
+
4
+ function convertSchema(schema) {
5
+ let schemaToUse = schema;
6
+ if (!schemaToUse.fields && Array.isArray(schema)) {
7
+ schemaToUse = {
8
+ fields: schema
9
+ };
10
+ }
11
+ schemaToUse = {
12
+ ...schemaToUse
13
+ };
14
+ schemaToUse.fields = schemaToUse.fields.map((field, i) => {
15
+ let fieldToUse = field;
16
+ if (typeof field === "string") {
17
+ fieldToUse = {
18
+ displayName: startCase(camelCase(field)),
19
+ path: field,
20
+ type: "string"
21
+ };
22
+ } else if (!field.type) {
23
+ fieldToUse = {
24
+ ...field,
25
+ type: "string"
26
+ };
27
+ }
28
+ if (!fieldToUse.displayName) {
29
+ fieldToUse = {
30
+ ...fieldToUse,
31
+ displayName: startCase(camelCase(fieldToUse.path))
32
+ };
33
+ }
34
+ // paths are needed for column resizing
35
+ if (!fieldToUse.path) {
36
+ fieldToUse = {
37
+ ...fieldToUse,
38
+ filterDisabled: true,
39
+ sortDisabled: true,
40
+ path: "fake-path" + i
41
+ };
42
+ }
43
+ return fieldToUse;
44
+ });
45
+ return schemaToUse;
46
+ }
47
+
48
+ export function mergeSchemas(_originalSchema, _overrideSchema) {
49
+ const originalSchema = convertSchema(_originalSchema);
50
+ const overrideSchema = convertSchema(_overrideSchema);
51
+
52
+ const overridesByKey = keyBy(overrideSchema.fields, "path");
53
+ return {
54
+ ...originalSchema,
55
+ ...overrideSchema,
56
+ fields: originalSchema.fields
57
+ .map(f => {
58
+ const override = overridesByKey[f.path];
59
+ if (override) {
60
+ delete overridesByKey[f.path];
61
+ return override;
62
+ }
63
+ return f;
64
+ })
65
+ .concat(map(overridesByKey))
66
+ };
67
+ }
68
+
69
+ export default convertSchema;
@@ -0,0 +1,41 @@
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
+ import { branch, compose, withProps } from "recompose";
9
+ import { withRouter } from "react-router-dom";
10
+
11
+ /*
12
+ Right now DataTable is doing the same as withTableParams, so the logic is being
13
+ run twice. We need to refactor this to make it more DRY.
14
+ We could do two possible refactorings:
15
+ - remove withTableParams and just give all the appropiate props to DataTable. This would
16
+ make the component simpler.
17
+ - remove the logic from DataTable and just use withTableParams and a new hook called
18
+ useTableParams. This would be more flexible in the case we want to be able to use
19
+ pagination in a different component.
20
+ We should avoid having the component handle all the different
21
+ cases of input because of the next reasons:
22
+ 1. It makes the component more complex and harder to understand.
23
+ 2. It makes the component harder to test.
24
+ 3. It makes the component harder to reuse.
25
+ 4. Maintaining the the logic in the component is harder.
26
+ Keeping the logic and uses simple makes maintaining easier.
27
+
28
+ In my opinion, reduxForm could be replaced here with regular redux or even just be taken down.
29
+ Could be a major simplification, but this needs to be analized with lims for better
30
+ understanding if it's possible.
31
+ */
32
+ export default compose(
33
+ // form prop is needed for redux-form, but we are giving this prop as
34
+ // formName, so we need to rename it. Previously it was done in the withTableParams, but now
35
+ // it doesn't have it by default.
36
+ withProps(({ formName }) => ({ form: formName })),
37
+ // the formName is passed via withTableParams and is often user overridden
38
+ branch(props => !props.noForm, reduxForm({})),
39
+ // don't use withRouter if noRouter is passed!
40
+ branch(props => !props.noRouter, withRouter)
41
+ );
@@ -0,0 +1,32 @@
1
+ import { toNumber } from "lodash-es";
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,40 @@
1
+ import { isNumber } from "lodash-es";
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,4 @@
1
+ /* Copyright (C) 2018 TeselaGen Biotechnology, Inc. */
2
+ import Color from "color";
3
+
4
+ export default c => (Color(c).isLight() ? "#000000" : "#FFFFFF");
@@ -0,0 +1,44 @@
1
+ import { set } from "lodash-es";
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,216 @@
1
+ import {
2
+ isEmpty,
3
+ every,
4
+ some,
5
+ isEqual,
6
+ isString,
7
+ isNull,
8
+ isArray,
9
+ includes,
10
+ isObject,
11
+ has,
12
+ orderBy
13
+ } from "lodash-es";
14
+
15
+ export function filterLocalEntitiesToHasura(
16
+ records,
17
+ { where, order_by, limit, offset, isInfinite } = {}
18
+ ) {
19
+ let filteredRecords = [...records];
20
+
21
+ // Apply where clause if it exists
22
+ if (where) {
23
+ filteredRecords = applyWhereClause(filteredRecords, where);
24
+ }
25
+
26
+ // Apply order_by if it exists
27
+ if (order_by) {
28
+ filteredRecords = applyOrderBy(filteredRecords, order_by);
29
+ }
30
+
31
+ // Store the complete filtered and ordered records for pagination info
32
+ const allFilteredRecords = [...filteredRecords];
33
+
34
+ // Apply limit and offset
35
+ if (!isInfinite && offset !== undefined) {
36
+ filteredRecords = filteredRecords.slice(offset);
37
+ }
38
+
39
+ if (!isInfinite && limit !== undefined) {
40
+ filteredRecords = filteredRecords.slice(0, limit);
41
+ }
42
+
43
+ // For consistency, always return an object with entities, entitiesAcrossPages, and entityCount
44
+ return {
45
+ entities: filteredRecords,
46
+ entitiesAcrossPages: allFilteredRecords,
47
+ entityCount: allFilteredRecords.length
48
+ };
49
+ }
50
+
51
+ function applyWhereClause(records, where) {
52
+ function applyFilter(record, filter) {
53
+ if (isEmpty(filter)) {
54
+ return true; // No filter, all records pass
55
+ }
56
+
57
+ for (const key in filter) {
58
+ if (key === "_and") {
59
+ if (!every(filter[key], subFilter => applyFilter(record, subFilter))) {
60
+ return false;
61
+ }
62
+ } else if (key === "_or") {
63
+ if (!some(filter[key], subFilter => applyFilter(record, subFilter))) {
64
+ return false;
65
+ }
66
+ } else if (key === "_not") {
67
+ if (applyFilter(record, filter[key])) {
68
+ return false;
69
+ }
70
+ } else {
71
+ const value = record[key];
72
+ const conditions = filter[key];
73
+
74
+ for (const operator in conditions) {
75
+ const conditionValue = conditions[operator];
76
+
77
+ // Handle range conditions (_gt/_lt or _gte/_lte combinations)
78
+ if (operator === "_gt" && conditions._lt) {
79
+ if (!(value > conditionValue && value < conditions._lt))
80
+ return false;
81
+ continue;
82
+ }
83
+ if (operator === "_gte" && conditions._lte) {
84
+ if (!(value >= conditionValue && value <= conditions._lte))
85
+ return false;
86
+ continue;
87
+ }
88
+
89
+ switch (operator) {
90
+ case "_eq":
91
+ if (!isEqual(value, conditionValue)) return false;
92
+ break;
93
+ case "_neq":
94
+ if (isEqual(value, conditionValue)) return false;
95
+ break;
96
+ case "_gt":
97
+ if (!(value > conditionValue)) return false;
98
+ break;
99
+ case "_gte":
100
+ if (!(value >= conditionValue)) return false;
101
+ break;
102
+ case "_lt":
103
+ if (!(value < conditionValue)) return false;
104
+ break;
105
+ case "_lte":
106
+ if (!(value <= conditionValue)) return false;
107
+ break;
108
+ case "_like":
109
+ if (
110
+ !isString(value) ||
111
+ !new RegExp(conditionValue.replace(/%/g, ".*")).test(value)
112
+ )
113
+ return false;
114
+ break;
115
+ case "_ilike":
116
+ if (
117
+ !isString(value) ||
118
+ !new RegExp(conditionValue.replace(/%/g, ".*"), "i").test(value)
119
+ )
120
+ return false;
121
+ break;
122
+ case "_nlike":
123
+ if (
124
+ !isString(value) ||
125
+ new RegExp(conditionValue.replace(/%/g, ".*")).test(value)
126
+ )
127
+ return false;
128
+ break;
129
+ case "_nilike":
130
+ if (
131
+ !isString(value) ||
132
+ new RegExp(conditionValue.replace(/%/g, ".*"), "i").test(value)
133
+ )
134
+ return false;
135
+ break;
136
+ case "_starts_with":
137
+ if (!isString(value) || !value.startsWith(conditionValue))
138
+ return false;
139
+ break;
140
+ case "_ends_with":
141
+ if (!isString(value) || !value.endsWith(conditionValue))
142
+ return false;
143
+ break;
144
+ case "_is_null":
145
+ if (
146
+ (conditionValue && !isNull(value)) ||
147
+ (!conditionValue && isNull(value))
148
+ )
149
+ return false;
150
+ break;
151
+ case "_contains":
152
+ if (
153
+ !isArray(value) ||
154
+ !every(conditionValue, item => includes(value, item))
155
+ )
156
+ return false;
157
+ break;
158
+ case "_contained_in":
159
+ if (
160
+ !isArray(value) ||
161
+ !every(value, item => includes(conditionValue, item))
162
+ )
163
+ return false;
164
+ break;
165
+ case "_has_key":
166
+ if (!isObject(value) || !has(value, conditionValue)) return false;
167
+ break;
168
+ case "_has_keys_any":
169
+ if (
170
+ !isObject(value) ||
171
+ !some(conditionValue, item => has(value, item))
172
+ )
173
+ return false;
174
+ break;
175
+ case "_has_keys_all":
176
+ if (
177
+ !isObject(value) ||
178
+ !every(conditionValue, item => has(value, item))
179
+ )
180
+ return false;
181
+ break;
182
+ case "_similar":
183
+ if (
184
+ !isString(value) ||
185
+ !new RegExp(conditionValue.replace(/%/g, ".*")).test(value)
186
+ )
187
+ return false;
188
+ break;
189
+ default:
190
+ if (operator.startsWith("_")) {
191
+ console.warn(`Unsupported operator: ${operator}`);
192
+ return false;
193
+ } else {
194
+ console.warn(`Unsupported operator: ${operator}`);
195
+ return false;
196
+ }
197
+ }
198
+ }
199
+ }
200
+ }
201
+
202
+ return true;
203
+ }
204
+
205
+ return records.filter(record => applyFilter(record, where));
206
+ }
207
+
208
+ function applyOrderBy(records, order_by) {
209
+ const keys = Object.keys(order_by);
210
+ if (keys.length > 0) {
211
+ const field = keys[0];
212
+ const direction = order_by[field] === "asc" ? "asc" : "desc";
213
+ return orderBy(records, [field], [direction]);
214
+ }
215
+ return records;
216
+ }