@firecms/data_import_export 3.0.0-canary.8 → 3.0.0-canary.80

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 (38) hide show
  1. package/LICENSE +113 -21
  2. package/README.md +1 -1
  3. package/dist/components/DataNewPropertiesMapping.d.ts +3 -5
  4. package/dist/components/ImportFileUpload.d.ts +1 -1
  5. package/dist/export_import/BasicExportAction.d.ts +7 -0
  6. package/dist/export_import/ExportCollectionAction.d.ts +1 -1
  7. package/dist/export_import/export.d.ts +15 -4
  8. package/dist/export_import/index.d.ts +4 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.es.js +940 -570
  11. package/dist/index.es.js.map +1 -1
  12. package/dist/index.umd.js +2 -2
  13. package/dist/index.umd.js.map +1 -1
  14. package/dist/types/column_mapping.d.ts +5 -7
  15. package/dist/useImportExportPlugin.d.ts +1 -1
  16. package/dist/utils/data.d.ts +3 -10
  17. package/dist/utils/file_headers.d.ts +1 -0
  18. package/dist/utils/file_to_json.d.ts +6 -1
  19. package/dist/utils/get_properties_mapping.d.ts +0 -3
  20. package/dist/utils/index.d.ts +0 -1
  21. package/package.json +20 -34
  22. package/src/components/DataNewPropertiesMapping.tsx +153 -40
  23. package/src/components/ImportFileUpload.tsx +12 -4
  24. package/src/components/ImportNewPropertyFieldPreview.tsx +7 -2
  25. package/src/export_import/BasicExportAction.tsx +147 -0
  26. package/src/export_import/ExportCollectionAction.tsx +45 -9
  27. package/src/export_import/ImportCollectionAction.tsx +22 -22
  28. package/src/export_import/export.ts +63 -29
  29. package/src/export_import/index.ts +4 -0
  30. package/src/hooks/useImportConfig.tsx +6 -0
  31. package/src/index.ts +1 -0
  32. package/src/types/column_mapping.ts +6 -6
  33. package/src/useImportExportPlugin.tsx +2 -2
  34. package/src/utils/data.ts +36 -126
  35. package/src/utils/file_headers.ts +90 -0
  36. package/src/utils/file_to_json.ts +33 -15
  37. package/src/utils/get_properties_mapping.ts +63 -59
  38. package/src/utils/index.ts +0 -1
@@ -5,6 +5,7 @@ import {
5
5
  Entity,
6
6
  EntityCollection,
7
7
  ExportConfig,
8
+ getDefaultValuesFor,
8
9
  resolveCollection,
9
10
  ResolvedEntityCollection,
10
11
  useCustomizationController,
@@ -18,7 +19,7 @@ import {
18
19
  BooleanSwitchWithLabel,
19
20
  Button,
20
21
  CircularProgress,
21
- cn,
22
+ cls,
22
23
  Dialog,
23
24
  DialogActions,
24
25
  DialogContent,
@@ -26,9 +27,9 @@ import {
26
27
  GetAppIcon,
27
28
  IconButton,
28
29
  Tooltip,
29
- Typography,
30
+ Typography
30
31
  } from "@firecms/ui";
31
- import { downloadExport } from "./export";
32
+ import { downloadEntitiesExport } from "./export";
32
33
 
33
34
  const DOCS_LIMIT = 500;
34
35
 
@@ -36,6 +37,7 @@ export function ExportCollectionAction<M extends Record<string, any>, UserType e
36
37
  collection: inputCollection,
37
38
  path: inputPath,
38
39
  collectionEntitiesCount,
40
+ onAnalyticsEvent,
39
41
  exportAllowed,
40
42
  notAllowedView
41
43
  }: CollectionActionsProps<M, UserType, EntityCollection<M, any>> & {
@@ -49,6 +51,8 @@ export function ExportCollectionAction<M extends Record<string, any>, UserType e
49
51
  const exportConfig = typeof inputCollection.exportable === "object" ? inputCollection.exportable : undefined;
50
52
 
51
53
  const dateRef = React.useRef<Date>(new Date());
54
+
55
+ const [includeUndefinedValues, setIncludeUndefinedValues] = React.useState<boolean>(false);
52
56
  const [flattenArrays, setFlattenArrays] = React.useState<boolean>(true);
53
57
  const [exportType, setExportType] = React.useState<"csv" | "json">("csv");
54
58
  const [dateExportType, setDateExportType] = React.useState<"timestamp" | "string">("string");
@@ -123,6 +127,9 @@ export function ExportCollectionAction<M extends Record<string, any>, UserType e
123
127
  const doDownload = useCallback(async (collection: ResolvedEntityCollection<M>,
124
128
  exportConfig: ExportConfig<any> | undefined) => {
125
129
 
130
+ onAnalyticsEvent?.("export_collection", {
131
+ collection: collection.path
132
+ });
126
133
  setDataLoading(true);
127
134
  dataSource.fetchCollection<M>({
128
135
  path,
@@ -135,7 +142,30 @@ export function ExportCollectionAction<M extends Record<string, any>, UserType e
135
142
  ...exportConfig?.additionalFields?.map(column => column.key) ?? [],
136
143
  ...collection.additionalFields?.map(field => field.key) ?? []
137
144
  ];
138
- downloadExport(data, additionalData, collection, flattenArrays, additionalHeaders, exportType, dateExportType);
145
+
146
+ const dataWithDefaults = includeUndefinedValues
147
+ ? data.map(entity => {
148
+ const defaultValues = getDefaultValuesFor(collection.properties);
149
+ return {
150
+ ...entity,
151
+ values: { ...defaultValues, ...entity.values }
152
+ };
153
+ })
154
+ : data;
155
+ downloadEntitiesExport({
156
+ data: dataWithDefaults,
157
+ additionalData,
158
+ properties: collection.properties,
159
+ propertiesOrder: collection.propertiesOrder,
160
+ name: collection.name,
161
+ flattenArrays,
162
+ additionalHeaders,
163
+ exportType,
164
+ dateExportType
165
+ });
166
+ onAnalyticsEvent?.("export_collection_success", {
167
+ collection: collection.path
168
+ });
139
169
  })
140
170
  .catch((e) => {
141
171
  console.error("Error loading export data", e);
@@ -143,7 +173,7 @@ export function ExportCollectionAction<M extends Record<string, any>, UserType e
143
173
  })
144
174
  .finally(() => setDataLoading(false));
145
175
 
146
- }, [dataSource, path, fetchAdditionalFields, flattenArrays, exportType, dateExportType]);
176
+ }, [onAnalyticsEvent, dataSource, path, fetchAdditionalFields, includeUndefinedValues, flattenArrays, exportType, dateExportType]);
147
177
 
148
178
  const onOkClicked = useCallback(() => {
149
179
  doDownload(collection, exportConfig);
@@ -182,7 +212,7 @@ export function ExportCollectionAction<M extends Record<string, any>, UserType e
182
212
  <input id="radio-csv" type="radio" value="csv" name="exportType"
183
213
  checked={exportType === "csv"}
184
214
  onChange={() => setExportType("csv")}
185
- className={cn(focusedMixin, "w-4 text-primary-dark bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600")}/>
215
+ className={cls(focusedMixin, "w-4 text-primary-dark bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600")}/>
186
216
  <label htmlFor="radio-csv"
187
217
  className="p-2 text-sm font-medium text-gray-900 dark:text-slate-300">CSV</label>
188
218
  </div>
@@ -190,7 +220,7 @@ export function ExportCollectionAction<M extends Record<string, any>, UserType e
190
220
  <input id="radio-json" type="radio" value="json" name="exportType"
191
221
  checked={exportType === "json"}
192
222
  onChange={() => setExportType("json")}
193
- className={cn(focusedMixin, "w-4 text-primary-dark bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600")}/>
223
+ className={cls(focusedMixin, "w-4 text-primary-dark bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600")}/>
194
224
  <label htmlFor="radio-json"
195
225
  className="p-2 text-sm font-medium text-gray-900 dark:text-slate-300">JSON</label>
196
226
  </div>
@@ -201,7 +231,7 @@ export function ExportCollectionAction<M extends Record<string, any>, UserType e
201
231
  <input id="radio-timestamp" type="radio" value="timestamp" name="dateExportType"
202
232
  checked={dateExportType === "timestamp"}
203
233
  onChange={() => setDateExportType("timestamp")}
204
- className={cn(focusedMixin, "w-4 text-primary-dark bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600")}/>
234
+ className={cls(focusedMixin, "w-4 text-primary-dark bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600")}/>
205
235
  <label htmlFor="radio-timestamp"
206
236
  className="p-2 text-sm font-medium text-gray-900 dark:text-slate-300">Dates as
207
237
  timestamps ({dateRef.current.getTime()})</label>
@@ -210,7 +240,7 @@ export function ExportCollectionAction<M extends Record<string, any>, UserType e
210
240
  <input id="radio-string" type="radio" value="string" name="dateExportType"
211
241
  checked={dateExportType === "string"}
212
242
  onChange={() => setDateExportType("string")}
213
- className={cn(focusedMixin, "w-4 text-primary-dark bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600")}/>
243
+ className={cls(focusedMixin, "w-4 text-primary-dark bg-gray-100 border-gray-300 dark:bg-gray-700 dark:border-gray-600")}/>
214
244
  <label htmlFor="radio-string"
215
245
  className="p-2 text-sm font-medium text-gray-900 dark:text-slate-300">Dates as
216
246
  strings ({dateRef.current.toISOString()})</label>
@@ -225,6 +255,12 @@ export function ExportCollectionAction<M extends Record<string, any>, UserType e
225
255
  onValueChange={setFlattenArrays}
226
256
  label={"Flatten arrays"}/>
227
257
 
258
+ <BooleanSwitchWithLabel
259
+ size={"small"}
260
+ value={includeUndefinedValues}
261
+ onValueChange={setIncludeUndefinedValues}
262
+ label={"Include undefined values"}/>
263
+
228
264
  {!canExport && notAllowedView}
229
265
 
230
266
  </DialogContent>
@@ -18,7 +18,7 @@ import {
18
18
  } from "@firecms/core";
19
19
  import {
20
20
  Button,
21
- cn,
21
+ cls,
22
22
  defaultBorderMixin,
23
23
  Dialog,
24
24
  DialogActions,
@@ -32,7 +32,7 @@ import {
32
32
  } from "@firecms/ui";
33
33
  import { buildEntityPropertiesFromData } from "@firecms/schema_inference";
34
34
  import { useImportConfig } from "../hooks";
35
- import { convertDataToEntity, getInferenceType, getPropertiesMapping } from "../utils";
35
+ import { convertDataToEntity, getInferenceType } from "../utils";
36
36
  import { DataNewPropertiesMapping, ImportFileUpload, ImportSaveInProgress } from "../components";
37
37
  import { ImportConfig } from "../types";
38
38
 
@@ -60,20 +60,23 @@ export function ImportCollectionAction<M extends Record<string, any>, UserType e
60
60
 
61
61
  const handleClickOpen = useCallback(() => {
62
62
  setOpen(true);
63
+ onAnalyticsEvent?.("import_open");
63
64
  setStep("initial");
64
- }, [setOpen]);
65
+ }, [onAnalyticsEvent]);
65
66
 
66
67
  const handleClose = useCallback(() => {
67
68
  setOpen(false);
68
69
  }, [setOpen]);
69
70
 
70
71
  const onMappingComplete = useCallback(() => {
72
+ onAnalyticsEvent?.("import_mapping_complete");
71
73
  setStep("preview");
72
- }, []);
74
+ }, [onAnalyticsEvent]);
73
75
 
74
76
  const onPreviewComplete = useCallback(() => {
77
+ onAnalyticsEvent?.("import_data_save");
75
78
  setStep("import_data_saving");
76
- }, []);
79
+ }, [onAnalyticsEvent]);
77
80
 
78
81
  const onDataAdded = async (data: object[]) => {
79
82
  importConfig.setImportData(data);
@@ -90,6 +93,7 @@ export function ImportCollectionAction<M extends Record<string, any>, UserType e
90
93
  }
91
94
  }
92
95
  setTimeout(() => {
96
+ onAnalyticsEvent?.("import_data_added");
93
97
  setStep("mapping");
94
98
  }, 100);
95
99
  // setStep("mapping");
@@ -109,6 +113,7 @@ export function ImportCollectionAction<M extends Record<string, any>, UserType e
109
113
  if (collection.collectionGroup) {
110
114
  return null;
111
115
  }
116
+
112
117
  return <>
113
118
 
114
119
  <Tooltip title={"Import"}>
@@ -131,17 +136,14 @@ export function ImportCollectionAction<M extends Record<string, any>, UserType e
131
136
  </>}
132
137
 
133
138
  {step === "mapping" && <>
134
- <Typography variant={"h6"}>Map fields</Typography>
135
- <DataNewPropertiesMapping headersMapping={importConfig.headersMapping}
136
- idColumn={importConfig.idColumn}
137
- originProperties={importConfig.originProperties}
139
+ <Typography variant={"h6"} className={"ml-3.5"}>Map fields</Typography>
140
+ <DataNewPropertiesMapping importConfig={importConfig}
138
141
  destinationProperties={properties}
139
- onIdPropertyChanged={(value) => importConfig.setIdColumn(value ?? undefined)}
140
142
  buildPropertyView={({
141
143
  isIdColumn,
142
144
  property,
143
145
  propertyKey,
144
- importKey
146
+ importKey,
145
147
  }) => {
146
148
  return <PropertyTreeSelect
147
149
  selectedPropertyKey={propertyKey ?? ""}
@@ -153,6 +155,7 @@ export function ImportCollectionAction<M extends Record<string, any>, UserType e
153
155
  }}
154
156
  onPropertySelected={(newPropertyKey) => {
155
157
 
158
+ onAnalyticsEvent?.("import_mapping_field_updated");
156
159
  const newHeadersMapping: Record<string, string | null> = Object.entries(importConfig.headersMapping)
157
160
  .map(([currentImportKey, currentPropertyKey]) => {
158
161
  if (currentPropertyKey === newPropertyKey) {
@@ -253,14 +256,15 @@ function PropertyTreeSelect({
253
256
  }
254
257
 
255
258
  if (!selectedPropertyKey || !selectedProperty) {
256
- return <Typography variant={"body2"} className={"p-4"}>Do not import this property</Typography>;
259
+ return <Typography variant={"body2"} color="disabled" className={"p-4"}>Do not import this
260
+ property</Typography>;
257
261
  }
258
262
 
259
263
  return <PropertySelectEntry propertyKey={selectedPropertyKey}
260
264
  property={selectedProperty as Property}/>;
261
265
  }, [selectedProperty]);
262
266
 
263
- const onSelectValueChange = useCallback((value: string) => {
267
+ const onSelectValueChange = (value: string) => {
264
268
  if (value === internalIDValue) {
265
269
  onIdSelected();
266
270
  onPropertySelected(null);
@@ -269,14 +273,14 @@ function PropertyTreeSelect({
269
273
  } else {
270
274
  onPropertySelected(value);
271
275
  }
272
- }, []);
276
+ };
273
277
 
274
278
  return <Select value={isIdColumn ? internalIDValue : (selectedPropertyKey ?? undefined)}
275
279
  onValueChange={onSelectValueChange}
276
280
  renderValue={renderValue}>
277
281
 
278
282
  <SelectItem value={"__do_not_import"}>
279
- <Typography variant={"body2"} className={"p-4"}>Do not import this property</Typography>
283
+ <Typography variant={"body2"} color={"disabled"} className={"p-4"}>Do not import this property</Typography>
280
284
  </SelectItem>
281
285
 
282
286
  <SelectItem value={internalIDValue}>
@@ -338,7 +342,7 @@ export function PropertySelectEntry({
338
342
  className="flex flex-row w-full text-start items-center h-full">
339
343
 
340
344
  {new Array(level).fill(0).map((_, index) =>
341
- <div className={cn(defaultBorderMixin, "ml-8 border-l h-12")} key={index}/>)}
345
+ <div className={cls(defaultBorderMixin, "ml-8 border-l h-12")} key={index}/>)}
342
346
 
343
347
  <div className={"m-4"}>
344
348
  <Tooltip title={widget?.name}>
@@ -379,8 +383,7 @@ export function ImportDataPreview<M extends Record<string, any>>({
379
383
  }) {
380
384
 
381
385
  useEffect(() => {
382
- const propertiesMapping = getPropertiesMapping(importConfig.originProperties, properties);
383
- const mappedData = importConfig.importData.map(d => convertDataToEntity(d, importConfig.idColumn, importConfig.headersMapping, properties, propertiesMapping, "TEMP_PATH"));
386
+ const mappedData = importConfig.importData.map(d => convertDataToEntity(d, importConfig.idColumn, importConfig.headersMapping, properties, "TEMP_PATH", importConfig.defaultValues));
384
387
  importConfig.setEntities(mappedData);
385
388
  }, []);
386
389
 
@@ -396,14 +399,11 @@ export function ImportDataPreview<M extends Record<string, any>>({
396
399
  dataLoading: false,
397
400
  noMoreToLoad: false
398
401
  }}
402
+ enablePopupIcon={false}
399
403
  endAdornment={<div className={"h-12"}/>}
400
404
  filterable={false}
401
405
  sortable={false}
402
406
  selectionController={selectionController}
403
- displayedColumnIds={propertiesOrder.map(p => ({
404
- key: p,
405
- disabled: false
406
- }))}
407
407
  properties={properties}/>
408
408
 
409
409
  }
@@ -4,7 +4,6 @@ import {
4
4
  EntityReference,
5
5
  getArrayValuesCount,
6
6
  getValueInPath,
7
- ResolvedEntityCollection,
8
7
  ResolvedProperties,
9
8
  ResolvedProperty
10
9
  } from "@firecms/core";
@@ -14,37 +13,57 @@ interface Header {
14
13
  label: string;
15
14
  }
16
15
 
17
- export function downloadExport<M extends Record<string, any>>(data: Entity<M>[],
18
- additionalData: Record<string, any>[] | undefined,
19
- collection: ResolvedEntityCollection<M>,
20
- flattenArrays: boolean,
21
- additionalHeaders: string[] | undefined,
22
- exportType: "csv" | "json",
23
- dateExportType: "timestamp" | "string"
16
+ export interface DownloadEntitiesExportParams<M extends Record<string, any>> {
17
+ data: Entity<M>[];
18
+ additionalData: Record<string, any>[] | undefined;
19
+ properties: ResolvedProperties<M>;
20
+ propertiesOrder: string[] | undefined;
21
+ name: string;
22
+ flattenArrays: boolean;
23
+ additionalHeaders: string[] | undefined;
24
+ exportType: "csv" | "json";
25
+ dateExportType: "timestamp" | "string";
26
+ }
27
+
28
+ export function downloadEntitiesExport<M extends Record<string, any>>({
29
+ data,
30
+ additionalData,
31
+ properties,
32
+ propertiesOrder,
33
+ name,
34
+ flattenArrays,
35
+ additionalHeaders,
36
+ exportType,
37
+ dateExportType
38
+ }: DownloadEntitiesExportParams<M>
24
39
  ) {
25
40
 
26
- console.debug("Downloading export", { dataLength: data.length, collection, exportType, dateExportType });
27
- const properties = collection.properties;
41
+ console.debug("Downloading export", {
42
+ dataLength: data.length,
43
+ properties,
44
+ exportType,
45
+ dateExportType
46
+ });
28
47
 
29
48
  if (exportType === "csv") {
30
49
  const arrayValuesCount = flattenArrays ? getArrayValuesCount(data.map(d => d.values)) : {};
31
- const headers = getExportHeaders(properties, additionalHeaders, arrayValuesCount);
32
- const exportableData = getCSVExportableData(data, additionalData, properties, headers, dateExportType);
50
+ const headers = getExportHeaders(properties, propertiesOrder, additionalHeaders, arrayValuesCount);
51
+ const exportableData = getEntityCSVExportableData(data, additionalData, properties, headers, dateExportType);
33
52
  const headersData = entryToCSVRow(headers.map(h => h.label));
34
53
  const csvData = exportableData.map(entry => entryToCSVRow(entry));
35
- downloadBlob([headersData, ...csvData], `${collection.name}.csv`, "text/csv");
54
+ downloadBlob([headersData, ...csvData], `${name}.csv`, "text/csv");
36
55
  } else {
37
- const exportableData = getJsonExportableData(data, additionalData, properties, dateExportType);
56
+ const exportableData = getEntityJsonExportableData(data, additionalData, properties, dateExportType);
38
57
  const json = JSON.stringify(exportableData, null, 2);
39
- downloadBlob([json], `${collection.name}.json`, "application/json");
58
+ downloadBlob([json], `${name}.json`, "application/json");
40
59
  }
41
60
  }
42
61
 
43
- export function getCSVExportableData(data: Entity<any>[],
44
- additionalData: Record<string, any>[] | undefined,
45
- properties: ResolvedProperties,
46
- headers: Header[],
47
- dateExportType: "timestamp" | "string"
62
+ export function getEntityCSVExportableData(data: Entity<any>[],
63
+ additionalData: Record<string, any>[] | undefined,
64
+ properties: ResolvedProperties,
65
+ headers: Header[],
66
+ dateExportType: "timestamp" | "string"
48
67
  ) {
49
68
 
50
69
  const mergedData: any[] = data.map(e => ({
@@ -63,10 +82,10 @@ export function getCSVExportableData(data: Entity<any>[],
63
82
  });
64
83
  }
65
84
 
66
- export function getJsonExportableData(data: Entity<any>[],
67
- additionalData: Record<string, any>[] | undefined,
68
- properties: ResolvedProperties,
69
- dateExportType: "timestamp" | "string"
85
+ export function getEntityJsonExportableData(data: Entity<any>[],
86
+ additionalData: Record<string, any>[] | undefined,
87
+ properties: ResolvedProperties,
88
+ dateExportType: "timestamp" | "string"
70
89
  ) {
71
90
 
72
91
  const mergedData: any[] = data.map(e => ({
@@ -84,13 +103,22 @@ export function getJsonExportableData(data: Entity<any>[],
84
103
  }
85
104
 
86
105
  function getExportHeaders<M extends Record<string, any>>(properties: ResolvedProperties<M>,
106
+ propertiesOrder: string[] | undefined,
87
107
  additionalHeaders: string[] | undefined,
88
108
  arrayValuesCount?: ArrayValuesCount): Header[] {
89
109
 
90
110
  const headers: Header[] = [
91
- { label: "id", key: "id" },
92
- ...Object.entries(properties)
93
- .flatMap(([childKey, property]) => {
111
+ {
112
+ label: "id",
113
+ key: "id"
114
+ },
115
+ ...(propertiesOrder ?? Object.keys(properties))
116
+ .flatMap((childKey) => {
117
+ const property = properties[childKey];
118
+ if (!property) {
119
+ console.warn("Property not found", childKey, properties);
120
+ return [];
121
+ }
94
122
  if (arrayValuesCount && arrayValuesCount[childKey] > 1) {
95
123
  return Array.from({ length: arrayValuesCount[childKey] },
96
124
  (_, i) => getHeaders(property as ResolvedProperty, `${childKey}[${i}]`, ""))
@@ -102,7 +130,10 @@ function getExportHeaders<M extends Record<string, any>>(properties: ResolvedPro
102
130
  ];
103
131
 
104
132
  if (additionalHeaders) {
105
- headers.push(...additionalHeaders.map(h => ({ label: h, key: h })));
133
+ headers.push(...additionalHeaders.map(h => ({
134
+ label: h,
135
+ key: h
136
+ })));
106
137
  }
107
138
 
108
139
  return headers;
@@ -121,7 +152,10 @@ function getHeaders(property: ResolvedProperty, propertyKey: string, prefix = ""
121
152
  .map(([childKey, p]) => getHeaders(p, childKey, currentKey))
122
153
  .flat();
123
154
  } else {
124
- return [{ label: currentKey, key: currentKey }];
155
+ return [{
156
+ label: currentKey,
157
+ key: currentKey
158
+ }];
125
159
  }
126
160
  }
127
161
 
@@ -0,0 +1,4 @@
1
+ export * from "./export";
2
+ export * from "./BasicExportAction";
3
+ export * from "./ExportCollectionAction";
4
+ export * from "./ImportCollectionAction";
@@ -5,10 +5,12 @@ import { ImportConfig } from "../types";
5
5
  export const useImportConfig = (): ImportConfig => {
6
6
 
7
7
  const [inUse, setInUse] = useState<boolean>(false);
8
+ const [defaultValues, setDefaultValues] = useState<Record<string, any>>({});
8
9
  const [idColumn, setIdColumn] = useState<string | undefined>();
9
10
  const [importData, setImportData] = useState<object[]>([]);
10
11
  const [entities, setEntities] = useState<Entity<any>[]>([]);
11
12
  const [headersMapping, setHeadersMapping] = useState<Record<string, string | null>>({});
13
+ const [headingsOrder, setHeadingsOrder] = useState<string[]>([]);
12
14
  const [originProperties, setOriginProperties] = useState<Record<string, Property>>({});
13
15
 
14
16
  return {
@@ -20,9 +22,13 @@ export const useImportConfig = (): ImportConfig => {
20
22
  setEntities,
21
23
  importData,
22
24
  setImportData,
25
+ headingsOrder: (headingsOrder ?? []).length > 0 ? headingsOrder : Object.keys(headersMapping),
26
+ setHeadingsOrder,
23
27
  headersMapping,
24
28
  setHeadersMapping,
25
29
  originProperties,
26
30
  setOriginProperties,
31
+ defaultValues,
32
+ setDefaultValues
27
33
  };
28
34
  };
package/src/index.ts CHANGED
@@ -3,3 +3,4 @@ export * from "./components";
3
3
  export * from "./types";
4
4
  export * from "./utils";
5
5
  export * from "./hooks";
6
+ export * from "./export_import";
@@ -22,11 +22,11 @@ export type ImportConfig = {
22
22
  originProperties: Record<string, Property>;
23
23
  setOriginProperties: React.Dispatch<React.SetStateAction<Record<string, Property>>>;
24
24
 
25
- }
25
+ // unmapped headings order
26
+ headingsOrder: string[];
27
+ setHeadingsOrder: React.Dispatch<React.SetStateAction<string[]>>;
28
+
29
+ defaultValues: Record<string, any>;
30
+ setDefaultValues: React.Dispatch<React.SetStateAction<Record<string, any>>>;
26
31
 
27
- export type DataTypeMapping = {
28
- from: DataType;
29
- fromSubtype?: DataType;
30
- to: DataType;
31
- toSubtype?: DataType;
32
32
  }
@@ -9,7 +9,7 @@ import { ExportCollectionAction } from "./export_import/ExportCollectionAction";
9
9
  export function useImportExportPlugin(props?: ImportExportPluginProps): FireCMSPlugin<any, any, any, ImportExportPluginProps> {
10
10
 
11
11
  return useMemo(() => ({
12
- name: "Import/Export",
12
+ key: "import_export",
13
13
  collectionView: {
14
14
  CollectionActions: [ImportCollectionAction, ExportCollectionAction],
15
15
  collectionActionsProps: props
@@ -19,7 +19,7 @@ export function useImportExportPlugin(props?: ImportExportPluginProps): FireCMSP
19
19
 
20
20
  export type ImportExportPluginProps = {
21
21
  exportAllowed?: (props: ExportAllowedParams) => boolean;
22
- notAllowedView: React.ReactNode;
22
+ notAllowedView?: React.ReactNode;
23
23
  onAnalyticsEvent?: (event: string, params?: any) => void;
24
24
  }
25
25
  export type ExportAllowedParams = { collectionEntitiesCount: number, path: string, collection: EntityCollection };