fuse-importer 0.1.4-testing → 0.1.6-testing

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 (129) hide show
  1. package/lib/esm/Importer/ImporterWithContext.js +38 -7
  2. package/lib/esm/Importer/Matcher/EnumFieldsMatchers/EnumFieldMatcher/index.js +1 -1
  3. package/lib/esm/Importer/Matcher/EnumFieldsMatchers/index.js +4 -3
  4. package/lib/esm/Importer/Matcher/HeaderMatcher/index.js +14 -9
  5. package/lib/esm/Importer/PreviewFirstTime.js +1 -1
  6. package/lib/esm/Importer/Review/ReviewContextProvider.d.ts +6 -6
  7. package/lib/esm/Importer/Review/ReviewContextProvider.js +51 -223
  8. package/lib/esm/Importer/Review/ReviewWithContext.js +2 -2
  9. package/lib/esm/Importer/Stepper/StepperSubmitModal.d.ts +2 -1
  10. package/lib/esm/Importer/Stepper/StepperSubmitModal.js +4 -2
  11. package/lib/esm/Importer/Stepper/UnmatchedHeadersModal.js +1 -1
  12. package/lib/esm/Importer/Stepper/index.js +20 -69
  13. package/lib/esm/Importer/Uploader/DragAndDropImporter/ImporterDropzone.d.ts +2 -1
  14. package/lib/esm/Importer/Uploader/DragAndDropImporter/ImporterDropzone.js +14 -86
  15. package/lib/esm/Importer/Uploader/DragAndDropImporter/index.js +11 -3
  16. package/lib/esm/Importer/Uploader/HeadersPreview.js +1 -1
  17. package/lib/esm/Importer/common/Spreadsheet/DataSetContextProvider/index.d.ts +16 -0
  18. package/lib/esm/Importer/common/Spreadsheet/DataSetContextProvider/index.js +63 -0
  19. package/lib/esm/Importer/common/Spreadsheet/DuplicateDataContextProvider/index.d.ts +18 -0
  20. package/lib/esm/Importer/common/Spreadsheet/DuplicateDataContextProvider/index.js +101 -0
  21. package/lib/esm/Importer/common/Spreadsheet/FilteredDataContextProvider/index.d.ts +29 -0
  22. package/lib/esm/Importer/common/Spreadsheet/FilteredDataContextProvider/index.js +150 -0
  23. package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/filterMethods.d.ts +6 -4
  24. package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/filterMethods.js +37 -37
  25. package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/hashCalculators.d.ts +6 -0
  26. package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/hashCalculators.js +138 -0
  27. package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/index.d.ts +7 -29
  28. package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/index.js +11 -193
  29. package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/useBatchProcessing.d.ts +5 -0
  30. package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/useBatchProcessing.js +72 -0
  31. package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/useDataSetManipulation.d.ts +4 -0
  32. package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/useDataSetManipulation.js +46 -0
  33. package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/utils.js +2 -1
  34. package/lib/esm/Importer/common/Spreadsheet/ValidationContextProvider/index.d.ts +31 -0
  35. package/lib/esm/Importer/common/Spreadsheet/ValidationContextProvider/index.js +304 -0
  36. package/lib/esm/Importer/common/Spreadsheet/common/index.js +5 -4
  37. package/lib/esm/Importer/common/Spreadsheet/common/types.d.ts +2 -3
  38. package/lib/esm/Importer/common/Spreadsheet/components/FieldHeader.d.ts +0 -2
  39. package/lib/esm/Importer/common/Spreadsheet/components/FieldHeader.js +26 -11
  40. package/lib/esm/Importer/common/Spreadsheet/components/SpreadsheetData.js +21 -13
  41. package/lib/esm/Importer/common/Spreadsheet/components/SpreadsheetRowCheckboxes.js +35 -36
  42. package/lib/esm/Importer/common/Spreadsheet/components/SpreadsheetRowNumbers.js +3 -3
  43. package/lib/esm/Importer/common/Spreadsheet/components/fields/SpreadsheetInput.js +5 -1
  44. package/lib/esm/Importer/common/Spreadsheet/components/fields/index.js +44 -18
  45. package/lib/esm/Importer/common/Spreadsheet/components/inputs/index.js +1 -2
  46. package/lib/esm/Importer/common/Spreadsheet/index.d.ts +0 -1
  47. package/lib/esm/Importer/common/Spreadsheet/index.js +1 -84
  48. package/lib/esm/Importer/common/Spreadsheet/styles.d.ts +1 -2
  49. package/lib/esm/Importer/common/Spreadsheet/styles.js +13 -1
  50. package/lib/esm/Importer/common/Spreadsheet/transformation/index.d.ts +2 -1
  51. package/lib/esm/Importer/common/Spreadsheet/transformation/index.js +9 -5
  52. package/lib/esm/Importer/common/Spreadsheet/transformation/transformators.d.ts +8 -2
  53. package/lib/esm/Importer/common/Spreadsheet/transformation/transformators.js +4 -16
  54. package/lib/esm/Importer/common/Spreadsheet/useFieldSorting.d.ts +5 -0
  55. package/lib/esm/Importer/common/Spreadsheet/useFieldSorting.js +81 -0
  56. package/lib/esm/Importer/common/Spreadsheet/validation/index.d.ts +5 -3
  57. package/lib/esm/Importer/common/Spreadsheet/validation/index.js +13 -17
  58. package/lib/esm/Importer/common/Spreadsheet/validation/validators.d.ts +3 -2
  59. package/lib/esm/Importer/common/Spreadsheet/validation/validators.js +16 -7
  60. package/lib/esm/Importer/contexts/ImporterContextProvider.d.ts +4 -2
  61. package/lib/esm/Importer/contexts/ImporterContextProvider.js +121 -13
  62. package/lib/esm/Importer/data/index.d.ts +1 -0
  63. package/lib/esm/Importer/data/index.js +44 -5
  64. package/lib/esm/Importer/hooks/useExportDataToFile.d.ts +5 -0
  65. package/lib/esm/Importer/hooks/useExportDataToFile.js +54 -0
  66. package/lib/esm/Importer/hooks/useSubmitToServer.d.ts +7 -0
  67. package/lib/esm/Importer/hooks/useSubmitToServer.js +192 -0
  68. package/lib/esm/common/EventManagerContextProvider/index.d.ts +22 -0
  69. package/lib/esm/common/EventManagerContextProvider/index.js +38 -0
  70. package/lib/esm/common/FileUploadDropzone/ImporterDropzone.d.ts +16 -0
  71. package/lib/esm/common/FileUploadDropzone/ImporterDropzone.js +108 -0
  72. package/lib/esm/common/FileUploadDropzone/index.d.ts +1 -0
  73. package/lib/esm/common/FileUploadDropzone/index.js +1 -0
  74. package/lib/esm/common/Table/TableActions/CustomActions/CustomActions.js +55 -41
  75. package/lib/esm/common/Table/TableActions/DeleteSelectedRows.js +25 -16
  76. package/lib/esm/common/Table/TableActions/ExportData.js +5 -3
  77. package/lib/esm/common/Table/TableActions/FilterByErrors/FilterByErrors.js +38 -9
  78. package/lib/esm/common/Table/TableActions/RowFilters.js +53 -5
  79. package/lib/esm/common/Table/TableActions/SearchRows.js +3 -1
  80. package/lib/esm/common/Table/TableActions/TableActions.js +2 -1
  81. package/lib/esm/common/Table/TableActions/TableActions.styles.js +1 -1
  82. package/lib/esm/common/Table/TableActions/TransformedRecordsCount.d.ts +1 -0
  83. package/lib/esm/common/Table/TableActions/TransformedRecordsCount.js +25 -17
  84. package/lib/esm/common/Table/TableActions/ValidationProgress.d.ts +2 -0
  85. package/lib/esm/common/Table/TableActions/ValidationProgress.js +22 -0
  86. package/lib/esm/common/Table/TableView/TableRows/TableRow.d.ts +1 -1
  87. package/lib/esm/common/Table/TableView/TableRows/TableRow.js +2 -2
  88. package/lib/esm/common/Table/TableView/TableRows/index.js +21 -6
  89. package/lib/esm/common/Table/TableView/index.d.ts +1 -1
  90. package/lib/esm/common/Table/TableView/index.js +6 -15
  91. package/lib/esm/common/Table/TableView/types.d.ts +8 -9
  92. package/lib/esm/common/Table/index.d.ts +2 -1
  93. package/lib/esm/common/Table/index.js +2 -2
  94. package/lib/esm/common/Toast.js +3 -2
  95. package/lib/esm/common/TooltipProvider.d.ts +2 -0
  96. package/lib/esm/common/TooltipProvider.js +12 -9
  97. package/lib/esm/common/buttons.d.ts +5 -1
  98. package/lib/esm/common/buttons.js +13 -7
  99. package/lib/esm/common/columnsTransformations.js +1 -1
  100. package/lib/esm/common/datePatterns.d.ts +1 -0
  101. package/lib/esm/common/datePatterns.js +10 -0
  102. package/lib/esm/common/icons/index.d.ts +1 -0
  103. package/lib/esm/common/icons/index.js +1 -0
  104. package/lib/esm/common/index.d.ts +1 -0
  105. package/lib/esm/common/index.js +1 -0
  106. package/lib/esm/common/inputs/Autocomplete.js +1 -1
  107. package/lib/esm/locales/de.d.ts +1 -1
  108. package/lib/esm/locales/de.js +1 -1
  109. package/lib/esm/locales/en.d.ts +1 -1
  110. package/lib/esm/locales/en.js +4 -4
  111. package/lib/esm/locales/es.d.ts +1 -1
  112. package/lib/esm/locales/es.js +1 -1
  113. package/lib/esm/locales/fr.d.ts +1 -1
  114. package/lib/esm/locales/fr.js +1 -1
  115. package/lib/esm/types.d.ts +20 -5
  116. package/lib/main.js +2 -2
  117. package/package.json +6 -4
  118. package/lib/esm/Importer/Stepper/common/getEnumFieldValueMatchingsInitialValue.d.ts +0 -8
  119. package/lib/esm/Importer/Stepper/common/getEnumFieldValueMatchingsInitialValue.js +0 -36
  120. package/lib/esm/Importer/common/Spreadsheet/components/ValidationProgress.d.ts +0 -5
  121. package/lib/esm/Importer/common/Spreadsheet/components/ValidationProgress.js +0 -19
  122. package/lib/esm/Importer/common/Spreadsheet/components/inputs/EmailInput.d.ts +0 -3
  123. package/lib/esm/Importer/common/Spreadsheet/components/inputs/EmailInput.js +0 -14
  124. package/lib/esm/Importer/common/Spreadsheet/hooks.d.ts +0 -33
  125. package/lib/esm/Importer/common/Spreadsheet/hooks.js +0 -256
  126. package/lib/esm/common/Table/TableActions/FilterByErrors/functions.d.ts +0 -11
  127. package/lib/esm/common/Table/TableActions/FilterByErrors/functions.js +0 -35
  128. package/lib/esm/common/Table/TableActions/hooks.d.ts +0 -18
  129. package/lib/esm/common/Table/TableActions/hooks.js +0 -41
@@ -0,0 +1,81 @@
1
+ import { get } from "lodash";
2
+ import { DateTime } from "luxon";
3
+ import { useImporterContext } from "../../contexts/ImporterContextProvider";
4
+ export var useFieldSorting = function () {
5
+ var templateHeaders = useImporterContext().templateHeaders;
6
+ var getDefaultSortCompareFn = function (sortBy) {
7
+ return function (a, b) {
8
+ var aField = get(a, sortBy.field);
9
+ var bField = get(b, sortBy.field);
10
+ var fieldTypes = templateHeaders.reduce(function (acc, header) {
11
+ var type = header.column_type;
12
+ var pattern = header.pattern || null;
13
+ acc[header.internal_key] = { type: type, pattern: pattern };
14
+ return acc;
15
+ }, {});
16
+ var fieldType = fieldTypes[sortBy.field];
17
+ var isAEmpty = aField === undefined || aField === null || aField === "";
18
+ var isBEmpty = bField === undefined || bField === null || bField === "";
19
+ // sort empty values to the end
20
+ if (isAEmpty && isBEmpty) {
21
+ if (a._meta.rowIndex === b._meta.rowIndex)
22
+ return 0;
23
+ return a._meta.rowIndex < b._meta.rowIndex ? -1 : 1;
24
+ }
25
+ if (isAEmpty)
26
+ return 1;
27
+ if (isBEmpty)
28
+ return -1;
29
+ if (fieldType && fieldType.type === "boolean") {
30
+ var aString = aField ? "true" : "false";
31
+ var bString = bField ? "true" : "false";
32
+ if (aString === bString) {
33
+ if (a._meta.rowIndex === b._meta.rowIndex)
34
+ return 0;
35
+ return a._meta.rowIndex < b._meta.rowIndex ? -1 : 1;
36
+ }
37
+ if (aString === "true")
38
+ return sortBy.direction === "asc" ? -1 : 1;
39
+ if (bString === "true")
40
+ return sortBy.direction === "asc" ? 1 : -1;
41
+ }
42
+ else if (fieldType &&
43
+ (fieldType.type === "date" ||
44
+ fieldType.type === "datetime" ||
45
+ fieldType.type === "time")) {
46
+ var aDateTime = aField
47
+ ? DateTime.fromFormat(aField, fieldType.pattern)
48
+ : null;
49
+ var bDateTime = bField
50
+ ? DateTime.fromFormat(bField, fieldType.pattern)
51
+ : null;
52
+ // sort invalid date values to the end before empty values
53
+ if (aDateTime && !aDateTime.isValid)
54
+ return 1;
55
+ if (bDateTime && !bDateTime.isValid)
56
+ return -1;
57
+ if (aDateTime && bDateTime && aDateTime.equals(bDateTime)) {
58
+ if (a._meta.rowIndex === b._meta.rowIndex)
59
+ return 0;
60
+ return a._meta.rowIndex < b._meta.rowIndex ? -1 : 1;
61
+ }
62
+ if (sortBy.direction === "asc") {
63
+ return (aDateTime === null || aDateTime === void 0 ? void 0 : aDateTime.valueOf()) - (bDateTime === null || bDateTime === void 0 ? void 0 : bDateTime.valueOf());
64
+ }
65
+ return (bDateTime === null || bDateTime === void 0 ? void 0 : bDateTime.valueOf()) - (aDateTime === null || aDateTime === void 0 ? void 0 : aDateTime.valueOf());
66
+ }
67
+ else {
68
+ if (aField === bField) {
69
+ if (a._meta.rowIndex === b._meta.rowIndex)
70
+ return 0;
71
+ return a._meta.rowIndex < b._meta.rowIndex ? -1 : 1;
72
+ }
73
+ if (sortBy.direction === "asc") {
74
+ return aField > bField ? 1 : -1;
75
+ }
76
+ return aField < bField ? 1 : -1;
77
+ }
78
+ };
79
+ };
80
+ return { getDefaultSortCompareFn: getDefaultSortCompareFn };
81
+ };
@@ -1,4 +1,5 @@
1
- import { Field, FieldValidation, OnValidateRecord, Record, ValidationErrors } from "../../../../types";
1
+ import { MutableRefObject } from "react";
2
+ import { DuplicateValuesCollection, Field, FieldValidation, OnValidateRecord, Record, ValidationErrors } from "../../../../types";
2
3
  import { FieldValidator } from "./validators";
3
4
  type SelectedValidator = {
4
5
  validator: FieldValidation;
@@ -13,10 +14,11 @@ type ValidateRecordArgs = {
13
14
  validatorsCache?: SelectedFieldValidators[];
14
15
  record: Record;
15
16
  fields: Field[];
16
- data: Record[];
17
+ duplicateValues: MutableRefObject<DuplicateValuesCollection>;
18
+ backendErrors?: ValidationErrors;
17
19
  };
18
20
  export declare function selectValidatorsFor(fields: Field[]): SelectedFieldValidators[];
19
- export declare function validateRecord({ record, fields, data, onValidateRecord, validatorsCache, }: ValidateRecordArgs): Promise<{
21
+ export declare function validateRecord({ record, fields, onValidateRecord, validatorsCache, duplicateValues, backendErrors, }: ValidateRecordArgs): Promise<{
20
22
  errors?: ValidationErrors;
21
23
  warnings?: ValidationErrors;
22
24
  }>;
@@ -89,9 +89,9 @@ function safeCallOnValidateRecord(_a) {
89
89
  });
90
90
  }
91
91
  function safeCallValidator(_a) {
92
- var field = _a.field, record = _a.record, validator = _a.validator, validatorFunction = _a.validatorFunction, data = _a.data;
92
+ var field = _a.field, record = _a.record, validator = _a.validator, validatorFunction = _a.validatorFunction, duplicateValues = _a.duplicateValues;
93
93
  try {
94
- return validatorFunction(field, record[field.name], validator, data);
94
+ return validatorFunction(field, record[field.name], validator, duplicateValues);
95
95
  }
96
96
  catch (e) {
97
97
  console.error("Validator ".concat(validator === null || validator === void 0 ? void 0 : validator.validation_type, " for field ").concat(JSON.stringify(field), " and value ").concat(record[field.name], " failed."), e);
@@ -102,7 +102,7 @@ function mergeErrorsAndWarnings(currentErrors, errors) {
102
102
  return __assign(__assign({}, currentErrors), { errors: __assign(__assign({}, (currentErrors.errors || {})), errors), warnings: __assign({}, (currentErrors.warnings || {})) });
103
103
  }
104
104
  function runValidatorsFor(_a) {
105
- var record = _a.record, data = _a.data, validators = _a.validators;
105
+ var record = _a.record, validators = _a.validators, duplicateValues = _a.duplicateValues;
106
106
  return validators.reduce(function (currentErrors, _a) {
107
107
  var field = _a.field, validators = _a.validators;
108
108
  var errors = {};
@@ -115,8 +115,8 @@ function runValidatorsFor(_a) {
115
115
  field: field,
116
116
  record: record,
117
117
  validator: validator,
118
- data: data,
119
118
  validatorFunction: validatorFunction,
119
+ duplicateValues: duplicateValues,
120
120
  });
121
121
  if (error) {
122
122
  errors[field.name] = error;
@@ -159,29 +159,25 @@ export function selectValidatorsFor(fields) {
159
159
  });
160
160
  }
161
161
  export function validateRecord(_a) {
162
- var _b, _c;
163
- var record = _a.record, fields = _a.fields, data = _a.data, onValidateRecord = _a.onValidateRecord, validatorsCache = _a.validatorsCache;
162
+ var record = _a.record, fields = _a.fields, onValidateRecord = _a.onValidateRecord, validatorsCache = _a.validatorsCache, duplicateValues = _a.duplicateValues, backendErrors = _a.backendErrors;
164
163
  return __awaiter(this, void 0, void 0, function () {
165
- var isTouched, backendErrors, hasBackendErrors, validators, _d, validatorErrors, validatorWarnings, errors, warnings, _e, onValidateRecordErrors, onValidateRecordWarnings;
166
- return __generator(this, function (_f) {
167
- switch (_f.label) {
164
+ var validators, _b, validatorErrors, validatorWarnings, errors, warnings, _c, onValidateRecordErrors, onValidateRecordWarnings;
165
+ return __generator(this, function (_d) {
166
+ switch (_d.label) {
168
167
  case 0:
169
168
  if (isRecordEmpty(record, fields)) {
170
169
  //TODO: Check this logic because this can skip the validation of touched rows because all fields are empty
171
170
  return [2 /*return*/, { errors: {}, warnings: {} }];
172
171
  }
173
- isTouched = (_b = record._meta) === null || _b === void 0 ? void 0 : _b.touched;
174
- backendErrors = ((_c = record._meta) === null || _c === void 0 ? void 0 : _c.backendErrors) || {};
175
- hasBackendErrors = Object.keys(backendErrors).length > 0;
176
- if (!isTouched && hasBackendErrors) {
172
+ if (backendErrors) {
177
173
  return [2 /*return*/, { errors: backendErrors, warnings: {} }];
178
174
  }
179
175
  validators = validatorsCache !== null && validatorsCache !== void 0 ? validatorsCache : selectValidatorsFor(fields);
180
- _d = runValidatorsFor({
176
+ _b = runValidatorsFor({
181
177
  record: record,
182
- data: data,
183
178
  validators: validators,
184
- }), validatorErrors = _d.errors, validatorWarnings = _d.warnings;
179
+ duplicateValues: duplicateValues,
180
+ }), validatorErrors = _b.errors, validatorWarnings = _b.warnings;
185
181
  errors = ignoreNullOrUndefinedKeyValues(validatorErrors);
186
182
  warnings = ignoreNullOrUndefinedKeyValues(validatorWarnings);
187
183
  if (!!isNullOrUndefined(onValidateRecord)) return [3 /*break*/, 2];
@@ -190,7 +186,7 @@ export function validateRecord(_a) {
190
186
  record: record,
191
187
  })];
192
188
  case 1:
193
- _e = _f.sent(), onValidateRecordErrors = _e.errors, onValidateRecordWarnings = _e.warnings;
189
+ _c = _d.sent(), onValidateRecordErrors = _c.errors, onValidateRecordWarnings = _c.warnings;
194
190
  return [2 /*return*/, {
195
191
  errors: __assign(__assign({}, errors), onValidateRecordErrors),
196
192
  warnings: __assign(__assign({}, warnings), onValidateRecordWarnings),
@@ -1,5 +1,6 @@
1
- import { Field, FieldValidation, Record } from "../../../../types";
2
- export type FieldValidator = (field: Field, fieldValue: any, validation?: FieldValidation, data?: Record[], customErrorMessage?: string) => null | string;
1
+ import { DuplicateValuesCollection, Field, FieldValidation } from "../../../../types";
2
+ import { MutableRefObject } from "react";
3
+ export type FieldValidator = (field: Field, fieldValue: any, validation?: FieldValidation, duplicateValues?: MutableRefObject<DuplicateValuesCollection>, customErrorMessage?: string) => null | string;
3
4
  export type FieldValidations = Partial<{
4
5
  [key: string]: FieldValidator;
5
6
  }>;
@@ -85,7 +85,9 @@ export var fieldValidations = {
85
85
  if (!isNullOrUndefined(field.pattern) &&
86
86
  !isNullOrUndefined(fieldValue) &&
87
87
  !DateTime.fromFormat(fieldValue, field.pattern).isValid) {
88
- var randomDate = DateTime.fromISO("1990-01-15T14:35:55.150");
88
+ var randomDate = DateTime.fromISO("1990-01-15T14:35:55.150", {
89
+ zone: "utc",
90
+ });
89
91
  var transformedValue = randomDate === null || randomDate === void 0 ? void 0 : randomDate.toFormat(field.pattern);
90
92
  var defaultMessage = "".concat(field.label, " must match the pattern ").concat(field.pattern);
91
93
  return transformedValue
@@ -93,18 +95,25 @@ export var fieldValidations = {
93
95
  : defaultMessage;
94
96
  }
95
97
  },
96
- unique_case_sensitive: function (field, fieldValue, validator, data) {
98
+ unique_case_sensitive: function (field, fieldValue, validator, duplicateValues) {
97
99
  var _a;
98
- if (!isNullOrUndefined(fieldValue) && !isNullOrUndefined(data)) {
99
- var isDuplicated = data.filter(function (d) { return d[field.name] === fieldValue; }).length > 1;
100
+ if (!isNullOrUndefined(fieldValue) &&
101
+ !isNullOrUndefined(duplicateValues.current)) {
102
+ var isDuplicated = duplicateValues.current[field.name] &&
103
+ duplicateValues.current[field.name][fieldValue] &&
104
+ duplicateValues.current[field.name][fieldValue].length > 1;
100
105
  var message = (_a = validator.message) !== null && _a !== void 0 ? _a : "".concat(field.label, " must be unique case sensitive");
101
106
  return isDuplicated ? message : undefined;
102
107
  }
103
108
  },
104
- unique_case_insensitive: function (field, fieldValue, validator, data) {
109
+ unique_case_insensitive: function (field, fieldValue, validator, duplicateValues) {
105
110
  var _a;
106
- if (!isNullOrUndefined(fieldValue) && !isNullOrUndefined(data)) {
107
- var isDuplicated = data.filter(function (d) { var _a; return ((_a = d[field.name]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === fieldValue.toLowerCase(); }).length > 1;
111
+ if (!isNullOrUndefined(fieldValue) &&
112
+ !isNullOrUndefined(duplicateValues.current)) {
113
+ var isDuplicated = duplicateValues.current[field.name] &&
114
+ duplicateValues.current[field.name][fieldValue.toLowerCase()] &&
115
+ duplicateValues.current[field.name][fieldValue.toLowerCase()].length >
116
+ 1;
108
117
  var message = (_a = validator.message) !== null && _a !== void 0 ? _a : "".concat(field.label, " must be unique case insensitive");
109
118
  return isDuplicated ? message : undefined;
110
119
  }
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { ColumnMapping, CustomAction, FormatRecord, ImporterOptions, Integration, OnSubmit, OnValidateRecord, Record, TemplateHeader } from "../../types";
2
+ import { CustomAction, FormatRecord, ImporterOptions, Integration, OnSubmit, OnValidateRecord, Record, TemplateHeader } from "../../types";
3
3
  import { FuseApi } from "../common/FuseApi";
4
4
  export type HeaderMatchings = {
5
5
  [templateHeaderLabel: string]: string;
@@ -23,6 +23,7 @@ export type State = {
23
23
  initialRecords: Record[];
24
24
  enumFieldValueMatchings: EnumFieldValueMatchings;
25
25
  templateHeaders: TemplateHeader[];
26
+ userDynamicColumns: string[];
26
27
  templateHeaderMatchings: HeaderMatchings;
27
28
  uploadedDataHeaders: string[];
28
29
  matcherSubstep: number;
@@ -55,8 +56,9 @@ export type State = {
55
56
  isUsingManualImport: React.MutableRefObject<boolean>;
56
57
  resetImporterWhenUsingManualImport: () => void;
57
58
  manualDataImportSelected: () => void;
58
- columnMappingsAttributes: ColumnMapping[];
59
59
  customActions: CustomAction[];
60
+ headerMappingsLoaded: boolean;
61
+ valueMappingsLoaded: boolean;
60
62
  };
61
63
  export type Props = {
62
64
  templateSlug: string;
@@ -71,22 +71,51 @@ export var ImporterContextProvider = function (_a) {
71
71
  var _g = useState(null), uploadedData = _g[0], setUploadedData = _g[1];
72
72
  var _h = useState(null), organization = _h[0], setOrganization = _h[1];
73
73
  var _j = useState(null), previewFirstTime = _j[0], setPreviewFirstTime = _j[1];
74
- var _k = useState(null), columnMappingsAttributes = _k[0], setColumnMappingsAttributes = _k[1];
75
- var _l = useState(null), headersMappings = _l[0], setHeadersMappings = _l[1];
76
- var _m = useState({
74
+ var _k = useState(null), headersMappings = _k[0], setHeadersMappings = _k[1];
75
+ var _l = useState({
77
76
  theme: theme,
78
77
  logoURL: null,
79
- }), style = _m[0], setStyle = _m[1];
80
- var _o = useState(null), templateHeaderMatchings = _o[0], setTemplateHeaderMatchings = _o[1];
81
- var _p = useState(null), enumFieldValueMatchings = _p[0], setEnumFieldValueMatchings = _p[1];
82
- var _q = useState(null), uploadedDataEnumFieldValues = _q[0], setUploadedDataEnumFieldValues = _q[1];
83
- var _r = useState([]), selectedRows = _r[0], setSelectedRows = _r[1];
78
+ }), style = _l[0], setStyle = _l[1];
79
+ var _m = useState(null), templateHeaderMatchings = _m[0], setTemplateHeaderMatchings = _m[1];
80
+ var _o = useState(null), enumFieldValueMatchings = _o[0], setEnumFieldValueMatchings = _o[1];
81
+ var _p = useState(null), uploadedDataEnumFieldValues = _p[0], setUploadedDataEnumFieldValues = _p[1];
82
+ var _q = useState([]), selectedRows = _q[0], setSelectedRows = _q[1];
84
83
  var isUsingManualImport = useRef(false);
85
- var _s = useState(0), headerRowIndex = _s[0], setHeaderRowIndex = _s[1];
84
+ var _r = useState(0), headerRowIndex = _r[0], setHeaderRowIndex = _r[1];
85
+ var _s = useState(false), headerMappingsLoaded = _s[0], setHeaderMappingsLoaded = _s[1];
86
+ var _t = useState(false), valueMappingsLoaded = _t[0], setValueMappingsLoaded = _t[1];
86
87
  var fuseApi = useMemo(function () { return new FuseApi(options.env, apiToken); }, [
87
88
  options.env,
88
89
  apiToken,
89
90
  ]);
91
+ var fetchColumnMappings = function (userDynamicColumns) { return __awaiter(void 0, void 0, void 0, function () {
92
+ var mappings;
93
+ return __generator(this, function (_a) {
94
+ switch (_a.label) {
95
+ case 0: return [4 /*yield*/, fuseApi.post("/api/v1/importer/templates/".concat(templateSlug, "/column_mappings"), {
96
+ file_headers: uploadedDataHeaders,
97
+ dynamic_columns: userDynamicColumns,
98
+ })];
99
+ case 1:
100
+ mappings = (_a.sent()).data.mappings;
101
+ return [2 /*return*/, mappings];
102
+ }
103
+ });
104
+ }); };
105
+ var fetchValueMappings = function (_uploadedDataEnumFieldValues, userDynamicValues) { return __awaiter(void 0, void 0, void 0, function () {
106
+ var mappings;
107
+ return __generator(this, function (_a) {
108
+ switch (_a.label) {
109
+ case 0: return [4 /*yield*/, fuseApi.post("/api/v1/importer/templates/".concat(templateSlug, "/value_mappings"), {
110
+ file_values: _uploadedDataEnumFieldValues,
111
+ dynamic_values: userDynamicValues,
112
+ })];
113
+ case 1:
114
+ mappings = (_a.sent()).data.mappings;
115
+ return [2 /*return*/, mappings];
116
+ }
117
+ });
118
+ }); };
90
119
  var uploadedDataHeaders = useMemo(function () {
91
120
  var _a;
92
121
  if (!uploadedData)
@@ -101,6 +130,79 @@ export var ImporterContextProvider = function (_a) {
101
130
  return typeof ud === "number" ? ud.toString() : ud;
102
131
  });
103
132
  }, [uploadedData, headerRowIndex]);
133
+ var userDynamicColumns = dynamicColumns.map(function (value) { return value.label; });
134
+ // use the API to match selected headers to the template
135
+ var loadHeaderMappings = function () { return __awaiter(void 0, void 0, void 0, function () {
136
+ var mappings, e_1;
137
+ return __generator(this, function (_a) {
138
+ switch (_a.label) {
139
+ case 0:
140
+ setHeaderMappingsLoaded(false);
141
+ _a.label = 1;
142
+ case 1:
143
+ _a.trys.push([1, 3, , 4]);
144
+ return [4 /*yield*/, fetchColumnMappings(userDynamicColumns)];
145
+ case 2:
146
+ mappings = _a.sent();
147
+ setHeadersMappings(mappings);
148
+ return [3 /*break*/, 4];
149
+ case 3:
150
+ e_1 = _a.sent();
151
+ setHeadersMappings([]);
152
+ console.error("Error occurred while fetching header mappings", e_1);
153
+ return [3 /*break*/, 4];
154
+ case 4:
155
+ setHeaderMappingsLoaded(true);
156
+ return [2 /*return*/];
157
+ }
158
+ });
159
+ }); };
160
+ useEffect(function () {
161
+ (function () { return __awaiter(void 0, void 0, void 0, function () {
162
+ return __generator(this, function (_a) {
163
+ if (uploadedDataHeaders) {
164
+ loadHeaderMappings();
165
+ }
166
+ return [2 /*return*/];
167
+ });
168
+ }); })();
169
+ }, [uploadedDataHeaders]);
170
+ // Values mappings for enum columns
171
+ var loadValueMappings = function (_uploadedDataEnumFieldValues) { return __awaiter(void 0, void 0, void 0, function () {
172
+ var dynamicValues, mappings, e_2;
173
+ return __generator(this, function (_a) {
174
+ switch (_a.label) {
175
+ case 0:
176
+ setValueMappingsLoaded(false);
177
+ if (!(!!_uploadedDataEnumFieldValues &&
178
+ Object.keys(_uploadedDataEnumFieldValues).length > 0)) return [3 /*break*/, 4];
179
+ _a.label = 1;
180
+ case 1:
181
+ _a.trys.push([1, 3, , 4]);
182
+ dynamicValues = userDynamicColumns.reduce(function (acc, column) {
183
+ var _a;
184
+ var values = (_a = templateHeaders.find(function (header) { return header.label === column; })) === null || _a === void 0 ? void 0 : _a.values;
185
+ if (values) {
186
+ acc[column] = values;
187
+ }
188
+ return acc;
189
+ }, {});
190
+ return [4 /*yield*/, fetchValueMappings(_uploadedDataEnumFieldValues, dynamicValues)];
191
+ case 2:
192
+ mappings = _a.sent();
193
+ setEnumFieldValueMatchings(mappings);
194
+ return [3 /*break*/, 4];
195
+ case 3:
196
+ e_2 = _a.sent();
197
+ setEnumFieldValueMatchings({});
198
+ console.error("Error occurred while fetching value mappings", e_2);
199
+ return [3 /*break*/, 4];
200
+ case 4:
201
+ setValueMappingsLoaded(true);
202
+ return [2 /*return*/];
203
+ }
204
+ });
205
+ }); };
104
206
  useEffect(function () {
105
207
  var setHeadersFromDataset = function () {
106
208
  var _templateHeaderMatchings = {};
@@ -150,10 +252,11 @@ export var ImporterContextProvider = function (_a) {
150
252
  });
151
253
  });
152
254
  setUploadedDataEnumFieldValues(_uploadedDataEnumFieldValues);
255
+ loadValueMappings(_uploadedDataEnumFieldValues);
153
256
  }, [templateHeaderMatchings, uploadedDataHeaders]);
154
257
  useEffect(function () {
155
258
  (function () { return __awaiter(void 0, void 0, void 0, function () {
156
- var _a, organization_1, columns_1, importer_style_preferences, integrations_1, preview_first_time, column_mappings_attributes, error_1, errorMsg;
259
+ var _a, organization_1, columns_1, importer_style_preferences, integrations_1, preview_first_time, error_1, errorMsg;
157
260
  var _b, _c;
158
261
  return __generator(this, function (_d) {
159
262
  switch (_d.label) {
@@ -161,7 +264,7 @@ export var ImporterContextProvider = function (_a) {
161
264
  _d.trys.push([0, 2, , 3]);
162
265
  return [4 /*yield*/, fuseApi.get("/api/v1/importer/templates/".concat(templateSlug))];
163
266
  case 1:
164
- _a = (_d.sent()).data, organization_1 = _a.organization, columns_1 = _a.columns, importer_style_preferences = _a.importer_style_preferences, integrations_1 = _a.integrations, preview_first_time = _a.preview_first_time, column_mappings_attributes = _a.column_mappings_attributes;
267
+ _a = (_d.sent()).data, organization_1 = _a.organization, columns_1 = _a.columns, importer_style_preferences = _a.importer_style_preferences, integrations_1 = _a.integrations, preview_first_time = _a.preview_first_time;
165
268
  setOrganization(organization_1);
166
269
  setTemplateHeaders(function () {
167
270
  // user has created dynamic columns
@@ -178,7 +281,6 @@ export var ImporterContextProvider = function (_a) {
178
281
  });
179
282
  setIntegrations(integrations_1);
180
283
  setPreviewFirstTime(preview_first_time);
181
- setColumnMappingsAttributes(column_mappings_attributes);
182
284
  if (organization_1.plan && organization_1.plan.allow_style_customization) {
183
285
  setStyle(getCustomTheme(importer_style_preferences));
184
286
  }
@@ -197,6 +299,10 @@ export var ImporterContextProvider = function (_a) {
197
299
  var resetImport = function () {
198
300
  setUploadedData(null);
199
301
  setTemplateHeaderMatchings(null);
302
+ setHeadersMappings(null);
303
+ setEnumFieldValueMatchings(null);
304
+ setSelectedRows([]);
305
+ setHeaderRowIndex(0);
200
306
  };
201
307
  var resetImporterWhenUsingManualImport = function () {
202
308
  setCurrentStepIndex(0);
@@ -216,6 +322,7 @@ export var ImporterContextProvider = function (_a) {
216
322
  initialRecords: initialRecords,
217
323
  currentStepIndex: currentStepIndex,
218
324
  templateHeaders: templateHeaders,
325
+ userDynamicColumns: userDynamicColumns,
219
326
  enumFieldValueMatchings: enumFieldValueMatchings,
220
327
  templateHeaderMatchings: templateHeaderMatchings,
221
328
  uploadedDataEnumFieldValues: uploadedDataEnumFieldValues,
@@ -231,7 +338,6 @@ export var ImporterContextProvider = function (_a) {
231
338
  theme: style.theme,
232
339
  logoURL: style.logoURL,
233
340
  integrations: integrations,
234
- columnMappingsAttributes: columnMappingsAttributes,
235
341
  previewFirstTime: previewFirstTime,
236
342
  headerRowIndex: headerRowIndex,
237
343
  setHeaderRowIndex: setHeaderRowIndex,
@@ -253,6 +359,8 @@ export var ImporterContextProvider = function (_a) {
253
359
  resetImporterWhenUsingManualImport: resetImporterWhenUsingManualImport,
254
360
  manualDataImportSelected: manualDataImportSelected,
255
361
  customActions: customActions,
362
+ headerMappingsLoaded: headerMappingsLoaded,
363
+ valueMappingsLoaded: valueMappingsLoaded,
256
364
  };
257
365
  return (_jsx(ImporterContext.Provider, __assign({ value: value }, { children: children })));
258
366
  };
@@ -7,6 +7,7 @@ export declare const addEmptyRows: (data: Record[], fields: Field[]) => (Record
7
7
  };
8
8
  })[];
9
9
  export declare const addMeta: (record: any, index: number, uploadedRow?: any, transformedRow?: TransformedRecord) => Record;
10
+ export declare const calculatePossibleDateFormats: (fieldsWithDateTransformations: Field[], sample: Record[]) => string[];
10
11
  export declare const recordListToDataSet: (data: Record[], fields: Field[]) => RecordDataSet;
11
12
  type transformToRecordsArgs = {
12
13
  templateHeaderMatchings: HeaderMatchings;
@@ -18,13 +18,16 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
18
18
  }
19
19
  return to.concat(ar || Array.prototype.slice.call(from));
20
20
  };
21
+ import { datesDateTimesAndTimesTransformations } from "../../Importer/common/Spreadsheet/transformation/transformators";
21
22
  import { transformRecord } from "../../Importer/common/Spreadsheet/transformation";
22
23
  import { FieldTypes, } from "../../types";
23
24
  import { parseValue } from "../common/Spreadsheet/common";
25
+ import { DateTime } from "luxon";
26
+ import { allowedPatternValues } from "../../common/datePatterns";
27
+ import _ from "lodash";
24
28
  var MINIMUM_ROW_COUNT = 20;
25
29
  var getRowId = function (index) {
26
- var uniqueTimestamp = new Date().getTime();
27
- return "r".concat(index, "-").concat(uniqueTimestamp);
30
+ return index.toString();
28
31
  };
29
32
  export var addEmptyRows = function (data, fields) {
30
33
  var emptyRecord = fields.reduce(function (obj, f) {
@@ -43,7 +46,30 @@ export var addMeta = function (record, index, uploadedRow, transformedRow) {
43
46
  if (transformedRow === void 0) { transformedRow = null; }
44
47
  var rId = getRowId(index);
45
48
  var meta = (_a = record._meta) !== null && _a !== void 0 ? _a : {};
46
- return __assign(__assign({}, record), { _meta: __assign(__assign({}, meta), { id: rId, rowIndex: index, touched: false, uploadedRow: uploadedRow, transformedRow: __assign(__assign({}, meta.transformedRow), transformedRow) }) });
49
+ return __assign(__assign({}, record), { _meta: __assign(__assign({}, meta), { id: rId, rowIndex: index, uploadedRow: uploadedRow, transformedRow: __assign(__assign({}, meta.transformedRow), transformedRow) }) });
50
+ };
51
+ export var calculatePossibleDateFormats = function (fieldsWithDateTransformations, sample) {
52
+ var possibleDateFormats = [];
53
+ for (var _i = 0, sample_1 = sample; _i < sample_1.length; _i++) {
54
+ var record = sample_1[_i];
55
+ for (var _a = 0, fieldsWithDateTransformations_1 = fieldsWithDateTransformations; _a < fieldsWithDateTransformations_1.length; _a++) {
56
+ var field = fieldsWithDateTransformations_1[_a];
57
+ var value = record[field.name];
58
+ if (!value)
59
+ continue;
60
+ for (var i = 0; i < allowedPatternValues.length; i++) {
61
+ var format = allowedPatternValues[i];
62
+ try {
63
+ var currentDate = DateTime.fromFormat(value, format);
64
+ if (currentDate.isValid) {
65
+ possibleDateFormats.push(format);
66
+ }
67
+ }
68
+ catch (e) { }
69
+ }
70
+ }
71
+ }
72
+ return Array.from(new Set(possibleDateFormats));
47
73
  };
48
74
  export var recordListToDataSet = function (data, fields) {
49
75
  var fieldWithTransformations = fields.filter(function (field) { var _a; return ((_a = field === null || field === void 0 ? void 0 : field.transformations) === null || _a === void 0 ? void 0 : _a.length) > 0; });
@@ -51,12 +77,22 @@ export var recordListToDataSet = function (data, fields) {
51
77
  if (data.length < MINIMUM_ROW_COUNT) {
52
78
  initialData = addEmptyRows(data, fields);
53
79
  }
80
+ var fieldsWithDateTransformations = fieldWithTransformations.filter(function (field) {
81
+ return field.transformations.some(function (t) {
82
+ return Object.keys(datesDateTimesAndTimesTransformations).includes(t.transformation_type);
83
+ });
84
+ });
85
+ var possibleDateFormats = [];
86
+ if (fieldsWithDateTransformations.length > 0) {
87
+ possibleDateFormats.push.apply(possibleDateFormats, calculatePossibleDateFormats(fieldsWithDateTransformations, _.sampleSize(initialData, 100)));
88
+ }
54
89
  return initialData.reduce(function (dataSet, record, i) {
55
90
  var transformedRecord = null;
56
91
  if (fieldWithTransformations.length > 0) {
57
92
  transformedRecord = transformRecord({
58
93
  record: record,
59
94
  fields: fieldWithTransformations,
95
+ possibleDateFormats: possibleDateFormats,
60
96
  });
61
97
  }
62
98
  var recordWithMeta = addMeta(record, i, undefined, transformedRecord);
@@ -119,7 +155,8 @@ export var transformToRecords = function (_a) {
119
155
  export var getPreviewDataSet = function (_a) {
120
156
  var uploadedData = _a.uploadedData;
121
157
  var rowLen = 0;
122
- for (var i = 0; i < uploadedData.length; i++)
158
+ var previewSize = Math.min(100, uploadedData.length);
159
+ for (var i = 0; i < previewSize; i++)
123
160
  rowLen = Math.max(rowLen, uploadedData[i].length);
124
161
  var fields = new Array(rowLen).fill(null).map(function (_, i) {
125
162
  var key = String.fromCharCode(65 + i);
@@ -131,7 +168,9 @@ export var getPreviewDataSet = function (_a) {
131
168
  };
132
169
  });
133
170
  var getInitialDataSet = function () {
134
- var data = uploadedData.map(function (row, index) {
171
+ var data = uploadedData
172
+ .slice(0, previewSize)
173
+ .map(function (row, index) {
135
174
  var entry = addMeta({}, index);
136
175
  fields.forEach(function (field, index) {
137
176
  entry[field.name] = row[index];
@@ -0,0 +1,5 @@
1
+ import { RecordDataSet } from "../../types";
2
+ import { ExportDataType } from "../Review/ReviewContextProvider";
3
+ export declare const useExportDataToFile: () => {
4
+ onExport: (dataSet: RecordDataSet, dataType: ExportDataType) => void;
5
+ };
@@ -0,0 +1,54 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { useCallback } from "react";
13
+ import Papa from "papaparse";
14
+ import { useImporterContext } from "../contexts/ImporterContextProvider";
15
+ function downloadCsv(data, fileName) {
16
+ var blob = new Blob([data], { type: "text/csv;charset=utf-8;" });
17
+ var link = document.createElement("a");
18
+ link.href = URL.createObjectURL(blob);
19
+ link.download = fileName;
20
+ document.body.appendChild(link);
21
+ link.click();
22
+ document.body.removeChild(link);
23
+ }
24
+ function csvExport(data) {
25
+ var valuesWithQuotesWhenNecessary = data.map(function (obj) {
26
+ var newObj = {};
27
+ for (var key in obj) {
28
+ var value = obj[key];
29
+ newObj[key] =
30
+ typeof value === "string" && value.includes(",") ? "\"".concat(value, "\"") : value;
31
+ }
32
+ return newObj;
33
+ });
34
+ var csv = Papa.unparse(valuesWithQuotesWhenNecessary);
35
+ downloadCsv(csv, "export.csv");
36
+ }
37
+ export var useExportDataToFile = function () {
38
+ var selectedRows = useImporterContext().selectedRows;
39
+ var onExport = useCallback(function (dataSet, dataType) {
40
+ if (!dataSet)
41
+ return;
42
+ var dataSetValues = Object.values(dataSet);
43
+ if (dataType === "csv") {
44
+ var valuesWithoutMeta = dataSetValues.map(function (_a) {
45
+ var _meta = _a._meta, rest = __rest(_a, ["_meta"]);
46
+ return rest;
47
+ });
48
+ csvExport(valuesWithoutMeta);
49
+ }
50
+ }, [selectedRows]);
51
+ return {
52
+ onExport: onExport,
53
+ };
54
+ };
@@ -0,0 +1,7 @@
1
+ import { AppResponse, RecordDataSet } from "../../types";
2
+ export declare const useSubmitToServer: () => {
3
+ appResponse: AppResponse;
4
+ isSubmitting: boolean;
5
+ onSubmitToServer: (dataSet: RecordDataSet, afterSubmitCallback: (dataSet: RecordDataSet) => void) => Promise<void>;
6
+ importWasSuccessful: boolean;
7
+ };