@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,54 @@
1
+ .tg-hotkeys-dialog .bp3-tab-list {
2
+ /* border-top: 1px solid #ddd; */
3
+ display: flex;
4
+ justify-content: center;
5
+ padding-left: 10px;
6
+ margin-top: 5px;
7
+ }
8
+
9
+ .tg-hotkeys-dialog table {
10
+ table-layout: fixed;
11
+ margin: 0 5px 5px;
12
+ width: calc(100% - 10px);
13
+ border-spacing: 0;
14
+ }
15
+
16
+ .tg-hotkeys-dialog .bp3-tab-panel {
17
+ margin-top: 5px;
18
+ padding: 10px;
19
+ }
20
+ .tg-hotkeys-dialog thead,
21
+ .tg-hotkeys-dialog tbody tr {
22
+ display: table;
23
+ width: 100%;
24
+ table-layout: fixed; /* even columns width , fix width of table too*/
25
+ }
26
+
27
+ .tg-hotkeys-dialog .tg-table-wrapper tbody {
28
+ display: block;
29
+ max-height: 55vh;
30
+ overflow-y: auto;
31
+ }
32
+
33
+ .tg-hotkeys-dialog th {
34
+ width: 50%;
35
+ font-weight: bold;
36
+ color: black;
37
+ border-bottom: 3px solid #ddd;
38
+ }
39
+
40
+ .tg-hotkeys-dialog tr:nth-child(2n) td {
41
+ background-color: #f8f8f8;
42
+ }
43
+ .bp3-dark .tg-hotkeys-dialog tr:nth-child(2n) td {
44
+ background-color: #3e4b6d;
45
+ }
46
+
47
+ .tg-hotkeys-dialog td,
48
+ .tg-hotkeys-dialog th {
49
+ padding: 8px 12px;
50
+ }
51
+
52
+ .tg-hotkeys-dialog td:first-child {
53
+ border-right: 1px solid lightgrey;
54
+ }
@@ -0,0 +1,83 @@
1
+ import React, { Component } from "react";
2
+ import { Popover, Button, Tooltip, Icon } from "@blueprintjs/core";
3
+ import classnames from "classnames";
4
+ import "./style.css";
5
+ import { popoverOverflowModifiers } from "..";
6
+
7
+ export default class InfoHelper extends Component {
8
+ render() {
9
+ const {
10
+ className,
11
+ content,
12
+ children,
13
+ icon = "info-sign",
14
+ isPopover,
15
+ isButton,
16
+ size,
17
+ isInline,
18
+ clickable,
19
+ color,
20
+ noMarginTop,
21
+ popoverProps = {},
22
+ disabled,
23
+ displayToSide,
24
+ style,
25
+ ...rest
26
+ } = this.props;
27
+ const IconToUse = isButton ? Button : Icon;
28
+ const iconProps = {
29
+ icon,
30
+ color,
31
+ disabled
32
+ };
33
+ if (!isButton) iconProps.iconSize = size;
34
+
35
+ const IconInner = <IconToUse {...iconProps} {...rest} />;
36
+ let toReturn;
37
+ const toolTipOrPopoverProps = {
38
+ disabled:
39
+ disabled ||
40
+ (!isPopover &&
41
+ window.Cypress &&
42
+ !window.Cypress.allowInfoHelperTooltips),
43
+ popoverClassName: "tg-info-helper-popover bp3-tooltip",
44
+ content: content || children,
45
+ modifiers: popoverOverflowModifiers,
46
+ ...popoverProps
47
+ };
48
+ if (displayToSide) {
49
+ toReturn = (
50
+ <React.Fragment>
51
+ {IconInner}
52
+ <span style={{ paddingLeft: 5, fontStyle: "italic" }}>
53
+ {content || children}
54
+ </span>
55
+ </React.Fragment>
56
+ );
57
+ } else if (isPopover) {
58
+ toReturn = <Popover {...toolTipOrPopoverProps} target={IconInner} />;
59
+ } else {
60
+ toReturn = <Tooltip {...toolTipOrPopoverProps} target={IconInner} />;
61
+ }
62
+ const El = isInline ? "span" : "div";
63
+ return (
64
+ <El
65
+ style={{
66
+ ...(clickable ? { cursor: "pointer" } : {}),
67
+ ...(isInline ? {} : { display: "flex" }),
68
+ ...style
69
+ }}
70
+ className={classnames(
71
+ "info-helper-wrapper",
72
+ {
73
+ "info-helper-wrapper-noMarginTop": noMarginTop,
74
+ "info-helper-clickable": isPopover
75
+ },
76
+ className
77
+ )}
78
+ >
79
+ {toReturn}
80
+ </El>
81
+ );
82
+ }
83
+ }
@@ -0,0 +1,7 @@
1
+ .bp3-popover.tg-info-helper-popover .bp3-popover-content {
2
+ max-width: 340px;
3
+ }
4
+
5
+ .info-helper-clickable .bp3-popover-target {
6
+ cursor: pointer;
7
+ }
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import { Classes } from "@blueprintjs/core";
3
+ import classNames from "classnames";
4
+
5
+ const intentToClass = {
6
+ danger: Classes.INTENT_DANGER,
7
+ warning: Classes.INTENT_WARNING,
8
+ success: Classes.INTENT_SUCCESS,
9
+ primary: Classes.INTENT_PRIMARY
10
+ };
11
+
12
+ export default function IntentText({ intent, text, children }) {
13
+ return (
14
+ <div className={classNames(Classes.FORM_GROUP, intentToClass[intent])}>
15
+ <div className={Classes.FORM_HELPER_TEXT}>{text || children}</div>
16
+ </div>
17
+ );
18
+ }
@@ -0,0 +1,74 @@
1
+ import React from "react";
2
+ import DNALoader from "../DNALoader";
3
+ import "./style.css";
4
+ import { BounceLoader } from "@teselagen/bounce-loader";
5
+
6
+ export default class Loading extends React.Component {
7
+ state = {
8
+ longerThan200MS: false
9
+ };
10
+
11
+ componentDidMount() {
12
+ this.timeoutId = setTimeout(() => {
13
+ this.setState({
14
+ longerThan200MS: true
15
+ });
16
+ }, 200);
17
+ }
18
+
19
+ componentWillUnmount() {
20
+ clearTimeout(this.timeoutId);
21
+ }
22
+
23
+ render() {
24
+ const {
25
+ loading,
26
+ style: userStyle,
27
+ className,
28
+ containerStyle = {},
29
+ children,
30
+ displayInstantly = false,
31
+ bounce = false,
32
+ withTimeout,
33
+ inDialog,
34
+ centeredInPage
35
+ } = this.props;
36
+ const { longerThan200MS } = this.state;
37
+ const style = {
38
+ ...userStyle,
39
+ ...(inDialog && { minHeight: 120 })
40
+ };
41
+ const LoaderComp = bounce || inDialog ? BounceLoader : DNALoader;
42
+ if (loading || !children) {
43
+ if (
44
+ !displayInstantly &&
45
+ !longerThan200MS &&
46
+ ((!bounce && !inDialog) || withTimeout)
47
+ ) {
48
+ return <div />;
49
+ }
50
+ return (
51
+ <div
52
+ className="tg-loader-container tg-flex justify-center align-center"
53
+ style={{
54
+ width: "100%",
55
+ ...containerStyle,
56
+ ...(centeredInPage && {
57
+ width: undefined,
58
+ zIndex: 20,
59
+ height: 10,
60
+ position: "fixed",
61
+ top: "50%",
62
+ left: "50%",
63
+ transform: "translate(-50%, 0)"
64
+ })
65
+ }}
66
+ >
67
+ <LoaderComp style={style} className={className} />
68
+ </div>
69
+ );
70
+ } else {
71
+ return children || null;
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,4 @@
1
+ .tg-loader-container {
2
+ height: 100%;
3
+ align-self: center;
4
+ }
@@ -0,0 +1,223 @@
1
+ import React from "react";
2
+ import { Callout, Card, Intent } from "@blueprintjs/core";
3
+ import immer, { setAutoFreeze } from "immer";
4
+ import { flatMap, forEach } from "lodash";
5
+ import { ReactSelectField } from "./FormComponents";
6
+ import showConfirmationDialog from "./showConfirmationDialog";
7
+ import { startCase } from "lodash";
8
+ import { typeToCommonType } from "./typeToCommonType";
9
+ import { camelCase } from "lodash";
10
+
11
+ setAutoFreeze(false);
12
+ export function MatchHeaders({
13
+ onMultiFileUploadSubmit,
14
+ doAllFilesHaveSameHeaders,
15
+ csvValidationIssue,
16
+ searchResults,
17
+ matchedHeaders,
18
+ userSchema,
19
+ reduxFormEntitiesArray,
20
+ changeForm,
21
+ datatableFormName,
22
+ datatableFormNames: _datatableFormNames,
23
+ setFilesWIssues,
24
+ filesWIssues,
25
+ fileIndex,
26
+ }) {
27
+ const datatableFormNames = _datatableFormNames || [datatableFormName];
28
+ const flippedMatchedHeaders = {};
29
+
30
+ forEach(matchedHeaders, (v, k) => {
31
+ if (v) flippedMatchedHeaders[v] = k;
32
+ });
33
+ return (
34
+ <div style={{ maxWidth: 500 }}>
35
+ {!onMultiFileUploadSubmit && (
36
+ <Callout style={{ width: "fit-content" }} intent="warning">
37
+ {csvValidationIssue}
38
+ </Callout>
39
+ )}
40
+ <br></br>
41
+ <tr
42
+ style={{
43
+ display: "flex",
44
+ minHeight: 50,
45
+ alignItems: "center",
46
+ justifyContent: "space-between",
47
+ }}
48
+ >
49
+ <td
50
+ style={{
51
+ width: 200,
52
+ marginLeft: 20,
53
+ display: "flex",
54
+ fontWeight: "bold",
55
+ }}
56
+ >
57
+ Accepted Headers
58
+ </td>
59
+ <td
60
+ style={{
61
+ width: 200,
62
+ marginLeft: 20,
63
+ display: "flex",
64
+ fontWeight: "bold",
65
+ }}
66
+ >
67
+ Your Headers
68
+ </td>
69
+ <td
70
+ style={{
71
+ fontWeight: "bold",
72
+ marginLeft: 30,
73
+ }}
74
+ >
75
+ Data Preview
76
+ </td>
77
+ </tr>
78
+ {searchResults.map(({ path, displayName, type }, i) => {
79
+ const userMatchedHeader = matchedHeaders[path];
80
+ const opts = flatMap(userSchema.fields, ({ path: pathInner }) => {
81
+ if (
82
+ pathInner !== userMatchedHeader &&
83
+ flippedMatchedHeaders[pathInner]
84
+ ) {
85
+ return [];
86
+ }
87
+ return {
88
+ value: pathInner,
89
+ label: pathInner,
90
+ };
91
+ }).sort((a, b) => {
92
+ const ra = searchResults[i].matches
93
+ .map((m) => m.item.path)
94
+ .indexOf(a.value);
95
+ const rb = searchResults[i].matches
96
+ .map((m) => m.item.path)
97
+ .indexOf(b.value);
98
+ if (!ra) return -1;
99
+ if (!rb) return 1;
100
+ return rb - ra;
101
+ });
102
+ return (
103
+ <Card style={{ padding: 2 }} key={i}>
104
+ <table>
105
+ <tbody>
106
+ <tr
107
+ style={{
108
+ display: "flex",
109
+ minHeight: 50,
110
+ alignItems: "center",
111
+ justifyContent: "space-between",
112
+ }}
113
+ >
114
+ <td
115
+ style={{
116
+ width: 200,
117
+ display: "flex",
118
+ }}
119
+ >
120
+ <div
121
+ style={{
122
+ paddingTop: 2,
123
+ marginLeft: 15,
124
+ fontSize: 15,
125
+ }}
126
+ >
127
+ <span
128
+ data-tip={`Column Type: ${
129
+ typeToCommonType[type || "string"] || type
130
+ }`}
131
+ >
132
+ {displayName || startCase(camelCase(path))}
133
+ </span>
134
+ </div>
135
+ </td>
136
+ <td style={{ width: 200 }}>
137
+ <ReactSelectField
138
+ noMarginBottom
139
+ tooltipError
140
+ beforeOnChange={async () => {
141
+ const clearEntities = () => {
142
+ datatableFormNames.forEach((name) => {
143
+ changeForm(name, "reduxFormEntities", null);
144
+ });
145
+ };
146
+ if (reduxFormEntitiesArray.some((r) => r?.isDirty)) {
147
+ //when the column mapping changes, update the column in reduxFormEntities (if reduxFormEntities exists)
148
+ const doAction = await showConfirmationDialog({
149
+ text: "Are you sure you want to edit the columm mapping? This will clear any changes you've already made to the table data",
150
+ intent: Intent.DANGER,
151
+ confirmButtonText: "Yes",
152
+ cancelButtonText: "No",
153
+ // canEscapeKeyCancel: true //this is false by default
154
+ });
155
+ if (doAction) {
156
+ clearEntities();
157
+ } else {
158
+ return { stopEarly: true };
159
+ }
160
+ } else {
161
+ clearEntities();
162
+ return { stopEarly: false };
163
+ }
164
+ }}
165
+ onChange={(val) => {
166
+ setFilesWIssues(
167
+ immer(filesWIssues, (files) => {
168
+ files.forEach((f, i) => {
169
+ const isCurrentFile = fileIndex === i;
170
+ if (isCurrentFile || doAllFilesHaveSameHeaders) {
171
+ f.matchedHeaders[path] = val;
172
+ }
173
+ });
174
+ })
175
+ );
176
+ }}
177
+ name={path}
178
+ // isRequired={!allowEmpty && defaultValue === undefined}
179
+ defaultValue={userMatchedHeader}
180
+ options={opts}
181
+ ></ReactSelectField>
182
+ </td>
183
+ <td
184
+ style={{
185
+ marginTop: 10,
186
+ marginBottom: 10,
187
+ marginLeft: 20,
188
+ fontSize: 10 /* color: Colors.RED1 */,
189
+ }}
190
+ >
191
+ {userMatchedHeader &&
192
+ [
193
+ // { [userMatchedHeader]: "Preview:" },
194
+ ...(userSchema.userData?.slice(0, 3) || []),
195
+ // { [userMatchedHeader]: "..." }
196
+ ].map((row, i) => {
197
+ return (
198
+ <div
199
+ style={{
200
+ maxWidth: 70,
201
+ overflow: "hidden",
202
+ textOverflow: "ellipsis",
203
+ whiteSpace: "nowrap",
204
+ }}
205
+ key={i}
206
+ >
207
+ {row?.[userMatchedHeader] || ""}
208
+ </div>
209
+ );
210
+ })}
211
+ {/* {!allowEmpty &&
212
+ defaultValue === undefined &&
213
+ "(Required)"} */}
214
+ </td>
215
+ </tr>
216
+ </tbody>
217
+ </table>
218
+ </Card>
219
+ );
220
+ })}
221
+ </div>
222
+ );
223
+ }