@teselagen/ui 0.7.33-beta.2 → 0.7.33-beta.3

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 (115) hide show
  1. package/package.json +1 -1
  2. package/src/style.css +10 -26
  3. package/AdvancedOptions.js +0 -33
  4. package/AssignDefaultsModeContext.js +0 -22
  5. package/CellDragHandle.js +0 -132
  6. package/ColumnFilterMenu.js +0 -62
  7. package/Columns.js +0 -979
  8. package/DisabledLoadingComponent.js +0 -15
  9. package/DisplayOptions.js +0 -199
  10. package/DropdownButton.js +0 -36
  11. package/DropdownCell.js +0 -61
  12. package/EditableCell.js +0 -44
  13. package/FillWindow.css +0 -6
  14. package/FillWindow.js +0 -69
  15. package/FilterAndSortMenu.js +0 -388
  16. package/FormSeparator.js +0 -9
  17. package/LoadingDots.js +0 -14
  18. package/MatchHeaders.js +0 -234
  19. package/PagingTool.js +0 -225
  20. package/RenderCell.js +0 -191
  21. package/SearchBar.js +0 -69
  22. package/SimpleStepViz.js +0 -22
  23. package/SortableColumns.js +0 -100
  24. package/TableFormTrackerContext.js +0 -10
  25. package/Tag.js +0 -112
  26. package/ThComponent.js +0 -44
  27. package/TimelineEvent.js +0 -31
  28. package/UploadCsvWizard.css +0 -4
  29. package/UploadCsvWizard.js +0 -719
  30. package/Uploader.js +0 -1278
  31. package/adHoc.js +0 -10
  32. package/autoTooltip.js +0 -201
  33. package/basicHandleActionsWithFullState.js +0 -14
  34. package/browserUtils.js +0 -3
  35. package/combineReducersWithFullState.js +0 -14
  36. package/commandControls.js +0 -82
  37. package/commandUtils.js +0 -112
  38. package/constants.js +0 -1
  39. package/convertSchema.js +0 -69
  40. package/customIcons.js +0 -361
  41. package/dataTableEnhancer.js +0 -41
  42. package/defaultFormatters.js +0 -32
  43. package/defaultValidators.js +0 -40
  44. package/determineBlackOrWhiteTextColor.js +0 -4
  45. package/editCellHelper.js +0 -44
  46. package/filterLocalEntitiesToHasura.js +0 -216
  47. package/formatPasteData.js +0 -16
  48. package/getAllRows.js +0 -11
  49. package/getCellCopyText.js +0 -7
  50. package/getCellInfo.js +0 -36
  51. package/getCellVal.js +0 -20
  52. package/getDayjsFormatter.js +0 -35
  53. package/getFieldPathToField.js +0 -7
  54. package/getIdOrCodeOrIndex.js +0 -9
  55. package/getLastSelectedEntity.js +0 -11
  56. package/getNewEntToSelect.js +0 -25
  57. package/getNewName.js +0 -31
  58. package/getRowCopyText.js +0 -28
  59. package/getTableConfigFromStorage.js +0 -5
  60. package/getTextFromEl.js +0 -28
  61. package/getVals.js +0 -8
  62. package/handleCopyColumn.js +0 -21
  63. package/handleCopyHelper.js +0 -15
  64. package/handleCopyRows.js +0 -23
  65. package/handleCopyTable.js +0 -16
  66. package/handlerHelpers.js +0 -24
  67. package/hotkeyUtils.js +0 -131
  68. package/index.js +0 -1
  69. package/initializeHasuraWhereAndFilter.js +0 -27
  70. package/isBeingCalledExcessively.js +0 -24
  71. package/isBottomRightCornerOfRectangle.js +0 -20
  72. package/isEntityClean.js +0 -15
  73. package/isTruthy.js +0 -12
  74. package/isValueEmpty.js +0 -3
  75. package/itemUpload.js +0 -84
  76. package/menuUtils.js +0 -433
  77. package/popoverOverflowModifiers.js +0 -11
  78. package/primarySelectedValue.js +0 -1
  79. package/pureNoFunc.js +0 -31
  80. package/queryParams.js +0 -336
  81. package/removeCleanRows.js +0 -22
  82. package/renderOnDoc.js +0 -32
  83. package/rerenderOnWindowResize.js +0 -26
  84. package/rowClick.js +0 -181
  85. package/selection.js +0 -8
  86. package/showAppSpinner.js +0 -12
  87. package/showDialogOnDocBody.js +0 -33
  88. package/showProgressToast.js +0 -22
  89. package/simplifyHasuraWhere.js +0 -80
  90. package/sortify.js +0 -73
  91. package/style.css +0 -29
  92. package/tableQueryParamsToHasuraClauses.js +0 -113
  93. package/tagUtils.js +0 -45
  94. package/tgFormValues.js +0 -35
  95. package/tg_modalState.js +0 -47
  96. package/throwFormError.js +0 -16
  97. package/toastr.js +0 -148
  98. package/tryToMatchSchemas.js +0 -264
  99. package/typeToCommonType.js +0 -6
  100. package/useDeepEqualMemo.js +0 -15
  101. package/useDialog.js +0 -63
  102. package/useStableReference.js +0 -9
  103. package/useTableEntities.js +0 -38
  104. package/useTraceUpdate.js +0 -19
  105. package/utils.js +0 -37
  106. package/validateTableWideErrors.js +0 -160
  107. package/viewColumn.js +0 -97
  108. package/withField.js +0 -20
  109. package/withFields.js +0 -11
  110. package/withLocalStorage.js +0 -11
  111. package/withSelectTableRecords.js +0 -43
  112. package/withSelectedEntities.js +0 -65
  113. package/withStore.js +0 -10
  114. package/withTableParams.js +0 -288
  115. package/wrapDialog.js +0 -116
@@ -1,388 +0,0 @@
1
- import React, { useState } from "react";
2
- import { DateInput, DateRangeInput } from "@blueprintjs/datetime";
3
- import { camelCase, startCase } from "lodash-es";
4
- import classNames from "classnames";
5
- import {
6
- Menu,
7
- Intent,
8
- MenuDivider,
9
- InputGroup,
10
- Classes,
11
- NumericInput,
12
- MenuItem
13
- } from "@blueprintjs/core";
14
- import dayjs from "dayjs";
15
-
16
- import getDayjsFormatter from "../utils/getDayjsFormatter";
17
- import { onEnterHelper } from "../utils/handlerHelpers";
18
- import DialogFooter from "../DialogFooter";
19
- import TgSelect from "../TgSelect";
20
- import "@teselagen/react-table/react-table.css";
21
- import "./style.css";
22
- import "../toastr";
23
-
24
- const filterTypesDictionary = {
25
- none: "",
26
- startsWith: "text",
27
- endsWith: "text",
28
- contains: "text",
29
- notContains: "text",
30
- isExactly: "text",
31
- isEmpty: "text",
32
- notEmpty: "text",
33
- inList: "list",
34
- notInList: "list",
35
- true: "boolean",
36
- false: "boolean",
37
- dateIs: "date",
38
- notBetween: "dateRange",
39
- isBetween: "dateRange",
40
- isBefore: "date",
41
- isAfter: "date",
42
- greaterThan: "number",
43
- lessThan: "number",
44
- inRange: "numberRange",
45
- outsideRange: "numberRange",
46
- equalTo: "number",
47
- regex: "text"
48
- };
49
-
50
- const isInvalidFilterValue = value => {
51
- if (Array.isArray(value) && value.length) {
52
- return value.some(item => isInvalidFilterValue(item));
53
- }
54
- return value === "" || value === undefined || value.length === 0;
55
- };
56
-
57
- const FilterAndSortMenu = ({
58
- dataType,
59
- togglePopover,
60
- filterOn,
61
- addFilters,
62
- removeSingleFilter,
63
- currentFilter
64
- }) => {
65
- const [selectedFilter, setSelectedFilter] = useState(
66
- currentFilter?.selectedFilter ?? camelCase(getFilterMenuItems(dataType)[0])
67
- );
68
- const [filterValue, setFilterValue] = useState(
69
- currentFilter?.filterValue ?? ""
70
- );
71
-
72
- const handleFilterChange = selectedFilter => {
73
- if (
74
- filterValue &&
75
- !Array.isArray(filterValue) &&
76
- filterTypesDictionary[selectedFilter] === "list"
77
- ) {
78
- setFilterValue(filterValue?.split(" ") || []);
79
- } else if (
80
- filterTypesDictionary[selectedFilter] === "text" &&
81
- Array.isArray(filterValue)
82
- ) {
83
- setFilterValue(filterValue.join(" "));
84
- }
85
- setSelectedFilter(camelCase(selectedFilter));
86
- };
87
-
88
- const handleFilterValueChange = filterValue => setFilterValue(filterValue);
89
-
90
- const handleFilterSubmit = () => {
91
- const ccSelectedFilter = camelCase(selectedFilter);
92
- let filterValToUse = filterValue;
93
- if (ccSelectedFilter === "true" || ccSelectedFilter === "false") {
94
- //manually set the filterValue because none is set when type=boolean
95
- filterValToUse = ccSelectedFilter;
96
- } else if (ccSelectedFilter === "notEmpty") {
97
- // manually set filter value (nothing is selected by user)
98
- filterValToUse = true;
99
- } else if (ccSelectedFilter === "isEmpty") {
100
- // manually set filter value (nothing is selected by user)
101
- filterValToUse = false;
102
- } else if (
103
- ccSelectedFilter === "inList" ||
104
- ccSelectedFilter === "notInList"
105
- ) {
106
- if (dataType === "number") {
107
- filterValToUse =
108
- filterValue &&
109
- filterValue.map(val => parseFloat(val.replaceAll(",", "")));
110
- }
111
- }
112
-
113
- if (isInvalidFilterValue(filterValToUse)) {
114
- togglePopover();
115
- return removeSingleFilter(filterOn);
116
- }
117
- addFilters([
118
- {
119
- filterOn,
120
- selectedFilter: ccSelectedFilter,
121
- filterValue: filterValToUse
122
- }
123
- ]);
124
- togglePopover();
125
- };
126
-
127
- const filterMenuItems = getFilterMenuItems(dataType);
128
- const ccSelectedFilter = camelCase(selectedFilter);
129
- const requiresValue = ccSelectedFilter && ccSelectedFilter !== "none";
130
-
131
- return (
132
- <Menu className="data-table-header-menu">
133
- <div className="custom-menu-item">
134
- <div className={classNames(Classes.SELECT, Classes.FILL)}>
135
- <select
136
- onChange={function (e) {
137
- const ccSelectedFilter = camelCase(e.target.value);
138
- handleFilterChange(ccSelectedFilter);
139
- }}
140
- value={ccSelectedFilter}
141
- >
142
- {filterMenuItems.map(function (menuItem, index) {
143
- return (
144
- <option key={index} value={camelCase(menuItem)}>
145
- {menuItem}
146
- </option>
147
- );
148
- })}
149
- </select>
150
- </div>
151
- </div>
152
- <div className="custom-menu-item">
153
- <FilterInput
154
- dataType={dataType}
155
- requiresValue={requiresValue}
156
- handleFilterSubmit={handleFilterSubmit}
157
- filterValue={filterValue}
158
- handleFilterValueChange={handleFilterValueChange}
159
- filterSubType={camelCase(selectedFilter)}
160
- filterType={filterTypesDictionary[camelCase(selectedFilter)]}
161
- />
162
- </div>
163
- <MenuDivider />
164
- <DialogFooter
165
- secondaryClassName={Classes.POPOVER_DISMISS}
166
- onClick={() => {
167
- handleFilterSubmit();
168
- }}
169
- intent={Intent.SUCCESS}
170
- text="Filter"
171
- secondaryText="Clear"
172
- secondaryIntent={Intent.DANGER}
173
- secondaryAction={() => {
174
- if (currentFilter) removeSingleFilter(currentFilter.filterOn);
175
- }}
176
- />
177
- </Menu>
178
- );
179
- };
180
-
181
- export default FilterAndSortMenu;
182
-
183
- const dateMinMaxHelpers = {
184
- minDate: dayjs().subtract(25, "years").toDate(),
185
- maxDate: dayjs().add(25, "years").toDate()
186
- };
187
-
188
- const renderCreateNewOption = (query, active, handleClick) => (
189
- <MenuItem
190
- icon="add"
191
- text={query}
192
- active={active}
193
- onClick={handleClick}
194
- shouldDismissPopover={false}
195
- />
196
- );
197
-
198
- const FilterInput = ({
199
- handleFilterValueChange,
200
- handleFilterSubmit,
201
- filterValue,
202
- filterSubType,
203
- filterType
204
- }) => {
205
- //Options: Text, Single number (before, after, equals), 2 numbers (range),
206
- //Single Date (before, after, on), 2 dates (range)
207
- let inputGroup = <div />;
208
- switch (filterType) {
209
- case "text":
210
- inputGroup =
211
- filterSubType === "notEmpty" || filterSubType === "isEmpty" ? (
212
- <div />
213
- ) : (
214
- <div className="custom-menu-item">
215
- <InputGroup
216
- placeholder="Value"
217
- onChange={function (e) {
218
- handleFilterValueChange(e.target.value);
219
- }}
220
- autoFocus
221
- {...onEnterHelper(handleFilterSubmit)}
222
- value={filterValue}
223
- />
224
- </div>
225
- );
226
- break;
227
- case "list":
228
- inputGroup = (
229
- <div className="custom-menu-item">
230
- <TgSelect
231
- placeholder="Add item"
232
- renderCreateNewOption={renderCreateNewOption}
233
- noResults={null}
234
- multi={true}
235
- creatable={true}
236
- value={(filterValue || []).map(val => ({
237
- label: val,
238
- value: val
239
- }))}
240
- onChange={selectedOptions => {
241
- selectedOptions.some(opt => opt.value === "")
242
- ? handleFilterSubmit()
243
- : handleFilterValueChange(
244
- selectedOptions.map(opt => opt.value)
245
- );
246
- }}
247
- options={[]}
248
- />
249
- </div>
250
- );
251
- break;
252
- case "number":
253
- inputGroup = (
254
- <div className="custom-menu-item">
255
- <NumericInput
256
- placeholder="Value"
257
- onValueChange={function (numVal) {
258
- handleFilterValueChange(isNaN(numVal) ? 0 : numVal);
259
- }}
260
- autoFocus
261
- {...onEnterHelper(handleFilterSubmit)}
262
- value={filterValue}
263
- />
264
- </div>
265
- );
266
- break;
267
- case "numberRange":
268
- inputGroup = (
269
- <div className="custom-menu-item">
270
- <NumericInput
271
- placeholder="Low"
272
- onValueChange={function (numVal) {
273
- handleFilterValueChange([
274
- isNaN(numVal) ? 0 : numVal,
275
- filterValue[1]
276
- ]);
277
- }}
278
- {...onEnterHelper(handleFilterSubmit)}
279
- value={filterValue && filterValue[0]}
280
- />
281
- <NumericInput
282
- placeholder="High"
283
- onValueChange={function (numVal) {
284
- handleFilterValueChange([
285
- filterValue[0],
286
- isNaN(numVal) ? 0 : numVal
287
- ]);
288
- }}
289
- {...onEnterHelper(handleFilterSubmit)}
290
- value={filterValue && filterValue[1]}
291
- />
292
- </div>
293
- );
294
- break;
295
- case "date":
296
- inputGroup = (
297
- <div className="custom-menu-item">
298
- <DateInput
299
- value={filterValue ? dayjs(filterValue).toDate() : undefined}
300
- {...getDayjsFormatter("L")}
301
- {...dateMinMaxHelpers}
302
- onChange={selectedDates => {
303
- handleFilterValueChange(selectedDates);
304
- }}
305
- />
306
- </div>
307
- );
308
- break;
309
- case "dateRange":
310
- // eslint-disable-next-line no-case-declarations
311
- let filterValueToUse;
312
- if (Array.isArray(filterValue)) {
313
- filterValueToUse = filterValue;
314
- } else {
315
- filterValueToUse =
316
- filterValue && filterValue.split && filterValue.split(";");
317
- }
318
- inputGroup = (
319
- <div className="custom-menu-item">
320
- <DateRangeInput
321
- value={
322
- filterValueToUse && filterValueToUse[0] && filterValueToUse[1]
323
- ? [new Date(filterValueToUse[0]), new Date(filterValueToUse[1])]
324
- : undefined
325
- }
326
- popoverProps={{
327
- captureDismiss: true
328
- }}
329
- formatDate={date => (date == null ? "" : date.toLocaleDateString())}
330
- parseDate={str => new Date(Date.parse(str))}
331
- placeholder="JS Date"
332
- {...dateMinMaxHelpers}
333
- onChange={selectedDates => {
334
- if (selectedDates[0] && selectedDates[1]) {
335
- handleFilterValueChange(selectedDates);
336
- }
337
- }}
338
- />
339
- </div>
340
- );
341
- break;
342
- default:
343
- // to do
344
- }
345
- return inputGroup;
346
- };
347
-
348
- function getFilterMenuItems(dataType) {
349
- let filterMenuItems = [];
350
- if (dataType === "string") {
351
- filterMenuItems = [
352
- "contains",
353
- "notContains",
354
- "startsWith",
355
- "endsWith",
356
- "isExactly",
357
- "regex",
358
- "inList",
359
- "notInList",
360
- "isEmpty",
361
- "notEmpty"
362
- ];
363
- } else if (dataType === "lookup") {
364
- filterMenuItems = [
365
- "contains",
366
- "notContains",
367
- "startsWith",
368
- "endsWith",
369
- "isExactly",
370
- "regex"
371
- ];
372
- } else if (dataType === "boolean") {
373
- filterMenuItems = ["true", "false"];
374
- } else if (dataType === "number" || dataType === "integer") {
375
- filterMenuItems = [
376
- "greaterThan",
377
- "lessThan",
378
- "inRange",
379
- "outsideRange",
380
- "equalTo",
381
- "inList",
382
- "notInList"
383
- ];
384
- } else if (dataType === "timestamp") {
385
- filterMenuItems = ["isBetween", "notBetween", "isBefore", "isAfter"];
386
- }
387
- return filterMenuItems.map(item => startCase(item));
388
- }
package/FormSeparator.js DELETED
@@ -1,9 +0,0 @@
1
- import React from "react";
2
- import "./style.css";
3
- export const FormSeparator = ({ label = "or" } = {}) => {
4
- return (
5
- <div className="form-separator">
6
- <p style={{ opacity: 0.8 }}>{label}</p>
7
- </div>
8
- );
9
- };
package/LoadingDots.js DELETED
@@ -1,14 +0,0 @@
1
- import React, { useEffect, useState } from "react";
2
-
3
- export const LoadingDots = () => {
4
- const [dots, setDots] = useState("");
5
- useEffect(() => {
6
- const interval = setInterval(() => {
7
- setDots(dots => {
8
- return dots.length === 3 ? "" : dots + ".";
9
- });
10
- }, 500);
11
- return () => clearInterval(interval);
12
- }, []);
13
- return <span>{dots}</span>;
14
- };
package/MatchHeaders.js DELETED
@@ -1,234 +0,0 @@
1
- import React, { useMemo } from "react";
2
- import { Callout, Card, Intent } from "@blueprintjs/core";
3
- import immer, { setAutoFreeze } from "immer";
4
- import { flatMap, forEach } from "lodash-es";
5
- import { ReactSelectField } from "./FormComponents";
6
- import showConfirmationDialog from "./showConfirmationDialog";
7
- import { startCase } from "lodash-es";
8
- import { typeToCommonType } from "./typeToCommonType";
9
- import { camelCase } from "lodash-es";
10
- import { change } from "redux-form";
11
- import { useDispatch } from "react-redux";
12
-
13
- setAutoFreeze(false);
14
- export const MatchHeaders = ({
15
- csvValidationIssue,
16
- datatableFormName,
17
- datatableFormNames: _datatableFormNames,
18
- doAllFilesHaveSameHeaders,
19
- fileIndex,
20
- filesWIssues,
21
- ignoredHeadersMsg,
22
- matchedHeaders,
23
- onMultiFileUploadSubmit,
24
- reduxFormEntitiesArray,
25
- searchResults,
26
- setFilesWIssues,
27
- userSchema
28
- }) => {
29
- const datatableFormNames = _datatableFormNames || [datatableFormName];
30
- const dispatch = useDispatch();
31
- const flippedMatchedHeaders = useMemo(() => {
32
- const _flippedMatchedHeaders = {};
33
- forEach(matchedHeaders, (v, k) => {
34
- if (v) _flippedMatchedHeaders[v] = k;
35
- });
36
- return _flippedMatchedHeaders;
37
- }, [matchedHeaders]);
38
-
39
- return (
40
- <div style={{ maxWidth: 500 }}>
41
- {!onMultiFileUploadSubmit && (
42
- <Callout style={{ width: "fit-content" }} intent="warning">
43
- {csvValidationIssue}
44
- </Callout>
45
- )}
46
- {!onMultiFileUploadSubmit && ignoredHeadersMsg && (
47
- <Callout style={{ width: "fit-content" }} intent="warning">
48
- {ignoredHeadersMsg}
49
- </Callout>
50
- )}
51
- <br />
52
- <tr
53
- style={{
54
- display: "flex",
55
- minHeight: 50,
56
- alignItems: "center",
57
- justifyContent: "space-between"
58
- }}
59
- >
60
- <td
61
- style={{
62
- width: 200,
63
- marginLeft: 20,
64
- display: "flex",
65
- fontWeight: "bold"
66
- }}
67
- >
68
- Accepted Headers
69
- </td>
70
- <td
71
- style={{
72
- width: 200,
73
- marginLeft: 20,
74
- display: "flex",
75
- fontWeight: "bold"
76
- }}
77
- >
78
- Your Headers
79
- </td>
80
- <td
81
- style={{
82
- fontWeight: "bold",
83
- marginLeft: 30
84
- }}
85
- >
86
- Data Preview
87
- </td>
88
- </tr>
89
- {searchResults.map(({ path, displayName, type }, i) => {
90
- const userMatchedHeader = matchedHeaders[path];
91
- const opts = flatMap(userSchema.fields, ({ path: pathInner }) => {
92
- if (
93
- pathInner !== userMatchedHeader &&
94
- flippedMatchedHeaders[pathInner]
95
- ) {
96
- return [];
97
- }
98
- return {
99
- value: pathInner,
100
- label: pathInner
101
- };
102
- }).sort((a, b) => {
103
- const ra = searchResults[i].matches
104
- .map(m => m.item.path)
105
- .indexOf(a.value);
106
- const rb = searchResults[i].matches
107
- .map(m => m.item.path)
108
- .indexOf(b.value);
109
- if (!ra) return -1;
110
- if (!rb) return 1;
111
- return rb - ra;
112
- });
113
- return (
114
- <Card style={{ padding: 2 }} key={`field-${i}`}>
115
- <table>
116
- <tbody>
117
- <tr
118
- style={{
119
- display: "flex",
120
- minHeight: 50,
121
- alignItems: "center",
122
- justifyContent: "space-between"
123
- }}
124
- >
125
- <td
126
- style={{
127
- width: 200,
128
- display: "flex"
129
- }}
130
- >
131
- <div
132
- style={{
133
- paddingTop: 2,
134
- marginLeft: 15,
135
- fontSize: 15
136
- }}
137
- >
138
- <span
139
- data-tip={`Column Type: ${
140
- typeToCommonType[type || "string"] || type
141
- }`}
142
- >
143
- {displayName || startCase(camelCase(path))}
144
- </span>
145
- </div>
146
- </td>
147
- <td style={{ width: 200 }}>
148
- <ReactSelectField
149
- noMarginBottom
150
- tooltipError
151
- beforeOnChange={async () => {
152
- const clearEntities = () => {
153
- datatableFormNames.forEach(name => {
154
- dispatch(change(name, "reduxFormEntities", null));
155
- });
156
- };
157
- if (reduxFormEntitiesArray.some(r => r?.isDirty)) {
158
- //when the column mapping changes, update the column in reduxFormEntities (if reduxFormEntities exists)
159
- const doAction = await showConfirmationDialog({
160
- text: "Are you sure you want to edit the columm mapping? This will clear any changes you've already made to the table data",
161
- intent: Intent.DANGER,
162
- confirmButtonText: "Yes",
163
- cancelButtonText: "No"
164
- // canEscapeKeyCancel: true //this is false by default
165
- });
166
- if (doAction) {
167
- clearEntities();
168
- } else {
169
- return { stopEarly: true };
170
- }
171
- } else {
172
- clearEntities();
173
- return { stopEarly: false };
174
- }
175
- }}
176
- onChange={val => {
177
- setFilesWIssues(
178
- immer(filesWIssues, files => {
179
- files.forEach((f, i) => {
180
- const isCurrentFile = fileIndex === i;
181
- if (isCurrentFile || doAllFilesHaveSameHeaders) {
182
- f.matchedHeaders[path] = val;
183
- }
184
- });
185
- })
186
- );
187
- }}
188
- name={path}
189
- // isRequired={!allowEmpty && defaultValue === undefined}
190
- defaultValue={userMatchedHeader}
191
- options={opts}
192
- />
193
- </td>
194
- <td
195
- style={{
196
- marginTop: 10,
197
- marginBottom: 10,
198
- marginLeft: 20,
199
- fontSize: 10 /* color: Colors.RED1 */
200
- }}
201
- >
202
- {userMatchedHeader &&
203
- [
204
- // { [userMatchedHeader]: "Preview:" },
205
- ...(userSchema.userData?.slice(0, 3) || [])
206
- // { [userMatchedHeader]: "..." }
207
- ].map((row, i) => {
208
- return (
209
- <div
210
- style={{
211
- maxWidth: 70,
212
- overflow: "hidden",
213
- textOverflow: "ellipsis",
214
- whiteSpace: "nowrap"
215
- }}
216
- key={`userMatchedHeader-${i}`}
217
- >
218
- {row?.[userMatchedHeader] || ""}
219
- </div>
220
- );
221
- })}
222
- {/* {!allowEmpty &&
223
- defaultValue === undefined &&
224
- "(Required)"} */}
225
- </td>
226
- </tr>
227
- </tbody>
228
- </table>
229
- </Card>
230
- );
231
- })}
232
- </div>
233
- );
234
- };