@rebasepro/admin 0.12.1-canary.gf4240e3 → 0.13.0

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 (27) hide show
  1. package/dist/{CollectionEditorDialog-Dhn0S4FT.js → CollectionEditorDialog-CjXkWZ64.js} +3 -3
  2. package/dist/{CollectionEditorDialog-Dhn0S4FT.js.map → CollectionEditorDialog-CjXkWZ64.js.map} +1 -1
  3. package/dist/{PropertyEditView-JPN12E-0.js → PropertyEditView-W8I3YV89.js} +2 -2
  4. package/dist/{PropertyEditView-JPN12E-0.js.map → PropertyEditView-W8I3YV89.js.map} +1 -1
  5. package/dist/{RouterCollectionsStudioView-Cv0tAxtu.js → RouterCollectionsStudioView-BsLTNoqX.js} +4 -4
  6. package/dist/{RouterCollectionsStudioView-Cv0tAxtu.js.map → RouterCollectionsStudioView-BsLTNoqX.js.map} +1 -1
  7. package/dist/collection_editor_ui.js +4 -4
  8. package/dist/components/EntityInspector.d.ts +9 -3
  9. package/dist/components/history/EntityHistoryView.d.ts +4 -1
  10. package/dist/{export-DghFk-W0.js → export-J79rMoNj.js} +2 -2
  11. package/dist/{export-DghFk-W0.js.map → export-J79rMoNj.js.map} +1 -1
  12. package/dist/{history-c-iE7d4k.js → history-D7L_JlLO.js} +5 -4
  13. package/dist/history-D7L_JlLO.js.map +1 -0
  14. package/dist/hooks/useHistory.d.ts +7 -0
  15. package/dist/{import-DLY5UYDa.js → import-BvYl--U4.js} +2 -2
  16. package/dist/{import-DLY5UYDa.js.map → import-BvYl--U4.js.map} +1 -1
  17. package/dist/index.js +6 -6
  18. package/dist/{util-BnRLzp4j.js → util-GiwPgxnL.js} +95 -84
  19. package/dist/util-GiwPgxnL.js.map +1 -0
  20. package/package.json +9 -9
  21. package/src/components/DetailViewBinding.tsx +21 -14
  22. package/src/components/EditViewBinding.tsx +31 -17
  23. package/src/components/EntityInspector.tsx +56 -51
  24. package/src/components/history/EntityHistoryView.tsx +8 -3
  25. package/src/hooks/useHistory.ts +15 -6
  26. package/dist/history-c-iE7d4k.js.map +0 -1
  27. package/dist/util-BnRLzp4j.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"import-DLY5UYDa.js","names":[],"sources":["../src/data_import/import/ImportCollectionAction.tsx","../src/data_import/import/index.ts"],"sourcesContent":["import React, { useCallback, useEffect } from \"react\";\nimport {\n useAuthController,\n useCustomizationController,\n useSnackbarController\n} from \"@rebasepro/app\";\nimport { getPropertiesWithPropertiesOrder, getPropertyInPath } from \"../../util\";\nimport { Properties, Property, User } from \"@rebasepro/types\";\nimport { CollectionActionsProps, AdminCollection } from \"@rebasepro/admin-types\";\nimport { getFieldConfig } from \"../../components/field_configs\";\nimport { PropertyConfigBadge } from \"../../components/PropertyConfigBadge\";\nimport { useSelectionController } from \"../../components/CollectionViewBinding/useSelectionController\";\nimport { CollectionTableBinding } from \"../../components/CollectionTableBinding/CollectionTableBinding\";\nimport { useCollectionRegistryController } from \"../../hooks\";\nimport {\n Button,\n cls,\n defaultBorderMixin,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n IconButton,\n iconSize,\n Select,\n SelectItem,\n Tooltip,\n Typography,\n UploadIcon\n} from \"@rebasepro/ui\";\nimport { buildEntityPropertiesFromData } from \"@rebasepro/inference\";\nimport { useImportConfig } from \"../hooks\";\nimport { convertDataToEntity, getInferenceType } from \"../utils\";\nimport { DataNewPropertiesMapping } from \"../components/DataNewPropertiesMapping\";\nimport { ImportFileUpload } from \"../components/ImportFileUpload\";\nimport { ImportSaveInProgress } from \"../components/ImportSaveInProgress\";\nimport { ImportConfig } from \"../types\";\nimport { slugify } from \"@rebasepro/utils\";\n\ntype ImportState = \"initial\" | \"mapping\" | \"preview\" | \"import_data_saving\";\n\nexport function ImportCollectionAction<M extends Record<string, unknown>, USER extends User>({\n collection,\n path,\n onAnalyticsEvent\n}: CollectionActionsProps<M, USER> & {\n onAnalyticsEvent?: (event: string, params?: any) => void;\n}\n) {\n\n const snackbarController = useSnackbarController();\n\n const [open, setOpen] = React.useState(false);\n\n const [step, setStep] = React.useState<ImportState>(\"initial\");\n\n const importConfig = useImportConfig();\n\n const handleClickOpen = useCallback(() => {\n setOpen(true);\n onAnalyticsEvent?.(\"import_open\");\n setStep(\"initial\");\n }, [onAnalyticsEvent]);\n\n const handleClose = useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n const onMappingComplete = useCallback(() => {\n onAnalyticsEvent?.(\"import_mapping_complete\");\n setStep(\"preview\");\n }, [onAnalyticsEvent]);\n\n const onPreviewComplete = useCallback(() => {\n onAnalyticsEvent?.(\"import_data_save\");\n setStep(\"import_data_saving\");\n }, [onAnalyticsEvent]);\n\n const onDataAdded = async (data: object[]) => {\n importConfig.setImportData(data);\n\n if (data.length > 0) {\n const originProperties = await buildEntityPropertiesFromData(data, getInferenceType);\n importConfig.setOriginProperties(originProperties as Properties);\n\n const headersMapping = buildHeadersMappingFromData(data, collection?.properties);\n importConfig.setHeadersMapping(headersMapping);\n const firstKey = Object.keys(headersMapping)?.[0];\n if (firstKey?.includes(\"id\") || firstKey?.includes(\"key\")) {\n importConfig.setIdColumn(firstKey);\n }\n }\n setTimeout(() => {\n onAnalyticsEvent?.(\"import_data_added\");\n setStep(\"mapping\");\n }, 100);\n };\n\n const properties = getPropertiesWithPropertiesOrder(collection.properties, collection.propertiesOrder as Extract<keyof M, string>[]);\n\n const propertiesAndLevel = Object.entries(properties)\n .flatMap(([key, property]) => getPropertiesAndLevel(key, property, 0));\n const propertiesOrder = (collection.propertiesOrder ?? Object.keys(collection.properties)) as Extract<keyof M, string>[];\n\n return <>\n\n <Tooltip title={\"Import\"}\n asChild={true}>\n <IconButton\n size={\"small\"}\n color={\"primary\"} onClick={handleClickOpen}>\n <UploadIcon size={iconSize.small}/>\n </IconButton>\n </Tooltip>\n\n <Dialog open={open}\n fullWidth={step !== \"initial\"}\n fullHeight={step !== \"initial\"}\n maxWidth={step === \"initial\" ? \"lg\" : \"7xl\"}>\n\n <DialogTitle variant={\"h6\"} hidden={step === \"preview\"}>Import data</DialogTitle>\n\n <DialogContent className={\"h-full flex flex-col gap-4 my-4\"} fullHeight={step === \"preview\"}>\n\n {step === \"initial\" && <>\n <Typography variant={\"body2\"}>Upload a CSV, Excel or JSON file and map it to your existing\n schema</Typography>\n <ImportFileUpload onDataAdded={onDataAdded}/>\n </>}\n\n {step === \"mapping\" && <>\n <DataNewPropertiesMapping importConfig={importConfig}\n destinationProperties={properties}\n buildPropertyView={({\n isIdColumn,\n property,\n propertyKey,\n importKey\n }) => {\n return <PropertyTreeSelect\n selectedPropertyKey={propertyKey ?? \"\"}\n properties={properties}\n propertiesAndLevel={propertiesAndLevel}\n isIdColumn={isIdColumn}\n onIdSelected={() => {\n importConfig.setIdColumn(importKey);\n }}\n onPropertySelected={(newPropertyKey) => {\n\n onAnalyticsEvent?.(\"import_mapping_field_updated\");\n const newHeadersMapping: Record<string, string | null> = Object.entries(importConfig.headersMapping)\n .map(([currentImportKey, currentPropertyKey]) => {\n if (currentPropertyKey === newPropertyKey) {\n return { [currentImportKey]: null };\n }\n if (currentImportKey === importKey) {\n return { [currentImportKey]: newPropertyKey };\n }\n return { [currentImportKey]: currentPropertyKey };\n })\n .reduce((acc, curr) => ({ ...acc,\n...curr }), {});\n importConfig.setHeadersMapping(newHeadersMapping as Record<string, string>);\n\n if (newPropertyKey === importConfig.idColumn) {\n importConfig.setIdColumn(undefined);\n }\n\n }}\n />;\n }}/>\n </>}\n\n {step === \"preview\" && <ImportDataPreview importConfig={importConfig}\n properties={properties}\n propertiesOrder={propertiesOrder}/>}\n\n {step === \"import_data_saving\" && importConfig &&\n <ImportSaveInProgress importConfig={importConfig}\n collection={collection as AdminCollection}\n path={path}\n onImportSuccess={(importedCollection) => {\n handleClose();\n snackbarController.open({\n type: \"info\",\n message: \"Data imported successfully\"\n });\n }}\n />}\n\n </DialogContent>\n <DialogActions>\n\n {step === \"mapping\" && <Button\n onClick={() => setStep(\"initial\")}\n variant={\"text\"}>\n Back\n </Button>}\n\n {step === \"preview\" && <Button\n onClick={() => setStep(\"mapping\")}\n variant={\"text\"}>\n Back\n </Button>}\n\n <Button onClick={handleClose}\n variant={\"text\"}>\n Cancel\n </Button>\n\n {step === \"mapping\" && <Button variant=\"filled\"\n color={\"primary\"}\n onClick={onMappingComplete}>\n Next\n </Button>}\n\n {step === \"preview\" && <Button variant=\"filled\"\n color={\"primary\"}\n onClick={onPreviewComplete}>\n Save data\n </Button>}\n\n </DialogActions>\n </Dialog>\n\n </>;\n}\n\nconst internalIDValue = \"__internal_id__\";\n\nfunction PropertyTreeSelect({\n selectedPropertyKey,\n properties,\n onPropertySelected,\n onIdSelected,\n propertiesAndLevel,\n isIdColumn\n}: {\n selectedPropertyKey: string | null;\n properties: Record<string, Property>;\n onPropertySelected: (propertyKey: string | null) => void;\n onIdSelected: () => void;\n propertiesAndLevel: PropertyAndLevel[];\n isIdColumn?: boolean;\n}) {\n\n const selectedProperty = selectedPropertyKey ? getPropertyInPath(properties, selectedPropertyKey) : null;\n\n const renderValue = useCallback((selectedPropertyKey: string) => {\n\n if (selectedPropertyKey === internalIDValue) {\n return <Typography variant={\"body2\"} className={\"p-4\"}>Use this column as ID</Typography>;\n }\n\n if (!selectedPropertyKey || !selectedProperty) {\n return <Typography variant={\"body2\"} color=\"disabled\" className={\"p-4\"}>Do not import this\n property</Typography>;\n }\n\n return <PropertySelectEntry propertyKey={selectedPropertyKey}\n property={selectedProperty as Property}/>;\n }, [selectedProperty]);\n\n const onSelectValueChange = (value: string) => {\n if (value === internalIDValue) {\n onIdSelected();\n onPropertySelected(null);\n } else if (value === \"__do_not_import\") {\n onPropertySelected(null);\n } else {\n onPropertySelected(value);\n }\n };\n\n return <Select value={isIdColumn ? internalIDValue : (selectedPropertyKey ?? undefined)}\n fullWidth={true}\n onValueChange={onSelectValueChange}\n renderValue={renderValue}>\n\n <SelectItem value={\"__do_not_import\"}>\n <Typography variant={\"body2\"} color={\"disabled\"} className={\"p-4\"}>Do not import this property</Typography>\n </SelectItem>\n\n <SelectItem value={internalIDValue}>\n <Typography variant={\"body2\"} className={\"p-4\"}>Use this column as ID</Typography>\n </SelectItem>\n\n {propertiesAndLevel.map(({\n property,\n level,\n propertyKey\n }) => {\n return <SelectItem value={propertyKey}\n key={propertyKey}\n disabled={property.type === \"map\"}>\n <PropertySelectEntry propertyKey={propertyKey}\n property={property}\n level={level}/>\n </SelectItem>;\n })}\n\n </Select>;\n}\n\ntype PropertyAndLevel = {\n property: Property,\n level: number,\n propertyKey: string\n};\n\nfunction getPropertiesAndLevel(key: string, property: Property, level: number): PropertyAndLevel[] {\n const properties: PropertyAndLevel[] = [];\n properties.push({\n property,\n level,\n propertyKey: key\n });\n if (property.type === \"map\" && property.properties) {\n Object.entries(property.properties).forEach(([childKey, value]) => {\n properties.push(...getPropertiesAndLevel(`${key}.${childKey}`, value as Property, level + 1));\n });\n }\n return properties;\n}\n\nexport function PropertySelectEntry({\n propertyKey,\n property,\n level = 0\n}: {\n propertyKey: string;\n property: Property;\n level?: number;\n}) {\n\n const { propertyConfigs } = useCustomizationController();\n const widget = getFieldConfig(property, propertyConfigs);\n\n return <div\n className=\"flex flex-row w-full text-start items-center h-full\">\n\n {new Array(level).fill(0).map((_, index) =>\n <div className={cls(defaultBorderMixin, \"ml-8 border-l h-12\")} key={index}/>)}\n\n <div className={\"m-4\"}>\n <Tooltip title={widget?.name}>\n <PropertyConfigBadge propertyConfig={widget}/>\n </Tooltip>\n </div>\n\n <div className={\"flex flex-col grow p-2 pl-2\"}>\n <Typography variant=\"body1\"\n component=\"span\"\n className=\"grow pr-2\">\n {property.name\n ? property.name\n : \"\\u00a0\"\n }\n </Typography>\n\n <Typography className=\" pr-2\"\n variant={\"body2\"}\n component=\"span\"\n color=\"secondary\">\n {propertyKey}\n </Typography>\n </div>\n\n </div>;\n\n}\n\nexport function ImportDataPreview<M extends Record<string, unknown>>({\n importConfig,\n properties,\n propertiesOrder\n}: {\n importConfig: ImportConfig,\n properties: Properties,\n propertiesOrder: Extract<keyof M, string>[],\n}) {\n const authController = useAuthController();\n const collectionRegistry = useCollectionRegistryController();\n useEffect(() => {\n const mappedData = importConfig.importData.map(d => convertDataToEntity(\n authController,\n collectionRegistry,\n d,\n importConfig.idColumn,\n importConfig.headersMapping,\n properties,\n \"TEMP_PATH\",\n importConfig.defaultValues\n ));\n importConfig.setEntities(mappedData);\n }, []);\n\n const selectionController = useSelectionController();\n\n return <CollectionTableBinding\n title={<div>\n <Typography variant={\"subtitle2\"}>Imported data preview</Typography>\n <Typography variant={\"caption\"}>Entities with the same id will be overwritten</Typography>\n </div>}\n tableController={{\n data: importConfig.entities,\n dataLoading: false,\n noMoreToLoad: false\n }}\n enablePopupIcon={false}\n endAdornment={<div className={\"h-12\"}/>}\n filterable={false}\n sortable={false}\n openEntityMode={\"full_screen\"}\n selectionController={selectionController}\n properties={properties}/>\n\n}\n\nfunction buildHeadersMappingFromData(objArr: object[], properties?: Properties) {\n const headersMapping: Record<string, string> = {};\n objArr.filter(Boolean).forEach((obj) => {\n Object.keys(obj).forEach((key) => {\n const child = (obj as Record<string, unknown>)[key];\n if (child != null && typeof child === \"object\" && !Array.isArray(child)) {\n const childProperty = properties?.[key];\n const childProperties = childProperty && \"properties\" in childProperty ? childProperty.properties : undefined;\n const childHeadersMapping = buildHeadersMappingFromData([child as object], childProperties);\n Object.entries(childHeadersMapping).forEach(([subKey, mapping]) => {\n headersMapping[`${key}.${subKey}`] = `${key}.${mapping}`;\n });\n }\n\n if (!properties) {\n headersMapping[key] = key;\n } else if (key in properties) {\n headersMapping[key] = key;\n } else {\n const slug = slugify(key);\n if (slug in properties) {\n headersMapping[key] = slug;\n } else {\n headersMapping[key] = key;\n }\n }\n\n });\n });\n return headersMapping;\n}\n","export * from \"./ImportCollectionAction\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"import-BvYl--U4.js","names":[],"sources":["../src/data_import/import/ImportCollectionAction.tsx","../src/data_import/import/index.ts"],"sourcesContent":["import React, { useCallback, useEffect } from \"react\";\nimport {\n useAuthController,\n useCustomizationController,\n useSnackbarController\n} from \"@rebasepro/app\";\nimport { getPropertiesWithPropertiesOrder, getPropertyInPath } from \"../../util\";\nimport { Properties, Property, User } from \"@rebasepro/types\";\nimport { CollectionActionsProps, AdminCollection } from \"@rebasepro/admin-types\";\nimport { getFieldConfig } from \"../../components/field_configs\";\nimport { PropertyConfigBadge } from \"../../components/PropertyConfigBadge\";\nimport { useSelectionController } from \"../../components/CollectionViewBinding/useSelectionController\";\nimport { CollectionTableBinding } from \"../../components/CollectionTableBinding/CollectionTableBinding\";\nimport { useCollectionRegistryController } from \"../../hooks\";\nimport {\n Button,\n cls,\n defaultBorderMixin,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n IconButton,\n iconSize,\n Select,\n SelectItem,\n Tooltip,\n Typography,\n UploadIcon\n} from \"@rebasepro/ui\";\nimport { buildEntityPropertiesFromData } from \"@rebasepro/inference\";\nimport { useImportConfig } from \"../hooks\";\nimport { convertDataToEntity, getInferenceType } from \"../utils\";\nimport { DataNewPropertiesMapping } from \"../components/DataNewPropertiesMapping\";\nimport { ImportFileUpload } from \"../components/ImportFileUpload\";\nimport { ImportSaveInProgress } from \"../components/ImportSaveInProgress\";\nimport { ImportConfig } from \"../types\";\nimport { slugify } from \"@rebasepro/utils\";\n\ntype ImportState = \"initial\" | \"mapping\" | \"preview\" | \"import_data_saving\";\n\nexport function ImportCollectionAction<M extends Record<string, unknown>, USER extends User>({\n collection,\n path,\n onAnalyticsEvent\n}: CollectionActionsProps<M, USER> & {\n onAnalyticsEvent?: (event: string, params?: any) => void;\n}\n) {\n\n const snackbarController = useSnackbarController();\n\n const [open, setOpen] = React.useState(false);\n\n const [step, setStep] = React.useState<ImportState>(\"initial\");\n\n const importConfig = useImportConfig();\n\n const handleClickOpen = useCallback(() => {\n setOpen(true);\n onAnalyticsEvent?.(\"import_open\");\n setStep(\"initial\");\n }, [onAnalyticsEvent]);\n\n const handleClose = useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n const onMappingComplete = useCallback(() => {\n onAnalyticsEvent?.(\"import_mapping_complete\");\n setStep(\"preview\");\n }, [onAnalyticsEvent]);\n\n const onPreviewComplete = useCallback(() => {\n onAnalyticsEvent?.(\"import_data_save\");\n setStep(\"import_data_saving\");\n }, [onAnalyticsEvent]);\n\n const onDataAdded = async (data: object[]) => {\n importConfig.setImportData(data);\n\n if (data.length > 0) {\n const originProperties = await buildEntityPropertiesFromData(data, getInferenceType);\n importConfig.setOriginProperties(originProperties as Properties);\n\n const headersMapping = buildHeadersMappingFromData(data, collection?.properties);\n importConfig.setHeadersMapping(headersMapping);\n const firstKey = Object.keys(headersMapping)?.[0];\n if (firstKey?.includes(\"id\") || firstKey?.includes(\"key\")) {\n importConfig.setIdColumn(firstKey);\n }\n }\n setTimeout(() => {\n onAnalyticsEvent?.(\"import_data_added\");\n setStep(\"mapping\");\n }, 100);\n };\n\n const properties = getPropertiesWithPropertiesOrder(collection.properties, collection.propertiesOrder as Extract<keyof M, string>[]);\n\n const propertiesAndLevel = Object.entries(properties)\n .flatMap(([key, property]) => getPropertiesAndLevel(key, property, 0));\n const propertiesOrder = (collection.propertiesOrder ?? Object.keys(collection.properties)) as Extract<keyof M, string>[];\n\n return <>\n\n <Tooltip title={\"Import\"}\n asChild={true}>\n <IconButton\n size={\"small\"}\n color={\"primary\"} onClick={handleClickOpen}>\n <UploadIcon size={iconSize.small}/>\n </IconButton>\n </Tooltip>\n\n <Dialog open={open}\n fullWidth={step !== \"initial\"}\n fullHeight={step !== \"initial\"}\n maxWidth={step === \"initial\" ? \"lg\" : \"7xl\"}>\n\n <DialogTitle variant={\"h6\"} hidden={step === \"preview\"}>Import data</DialogTitle>\n\n <DialogContent className={\"h-full flex flex-col gap-4 my-4\"} fullHeight={step === \"preview\"}>\n\n {step === \"initial\" && <>\n <Typography variant={\"body2\"}>Upload a CSV, Excel or JSON file and map it to your existing\n schema</Typography>\n <ImportFileUpload onDataAdded={onDataAdded}/>\n </>}\n\n {step === \"mapping\" && <>\n <DataNewPropertiesMapping importConfig={importConfig}\n destinationProperties={properties}\n buildPropertyView={({\n isIdColumn,\n property,\n propertyKey,\n importKey\n }) => {\n return <PropertyTreeSelect\n selectedPropertyKey={propertyKey ?? \"\"}\n properties={properties}\n propertiesAndLevel={propertiesAndLevel}\n isIdColumn={isIdColumn}\n onIdSelected={() => {\n importConfig.setIdColumn(importKey);\n }}\n onPropertySelected={(newPropertyKey) => {\n\n onAnalyticsEvent?.(\"import_mapping_field_updated\");\n const newHeadersMapping: Record<string, string | null> = Object.entries(importConfig.headersMapping)\n .map(([currentImportKey, currentPropertyKey]) => {\n if (currentPropertyKey === newPropertyKey) {\n return { [currentImportKey]: null };\n }\n if (currentImportKey === importKey) {\n return { [currentImportKey]: newPropertyKey };\n }\n return { [currentImportKey]: currentPropertyKey };\n })\n .reduce((acc, curr) => ({ ...acc,\n...curr }), {});\n importConfig.setHeadersMapping(newHeadersMapping as Record<string, string>);\n\n if (newPropertyKey === importConfig.idColumn) {\n importConfig.setIdColumn(undefined);\n }\n\n }}\n />;\n }}/>\n </>}\n\n {step === \"preview\" && <ImportDataPreview importConfig={importConfig}\n properties={properties}\n propertiesOrder={propertiesOrder}/>}\n\n {step === \"import_data_saving\" && importConfig &&\n <ImportSaveInProgress importConfig={importConfig}\n collection={collection as AdminCollection}\n path={path}\n onImportSuccess={(importedCollection) => {\n handleClose();\n snackbarController.open({\n type: \"info\",\n message: \"Data imported successfully\"\n });\n }}\n />}\n\n </DialogContent>\n <DialogActions>\n\n {step === \"mapping\" && <Button\n onClick={() => setStep(\"initial\")}\n variant={\"text\"}>\n Back\n </Button>}\n\n {step === \"preview\" && <Button\n onClick={() => setStep(\"mapping\")}\n variant={\"text\"}>\n Back\n </Button>}\n\n <Button onClick={handleClose}\n variant={\"text\"}>\n Cancel\n </Button>\n\n {step === \"mapping\" && <Button variant=\"filled\"\n color={\"primary\"}\n onClick={onMappingComplete}>\n Next\n </Button>}\n\n {step === \"preview\" && <Button variant=\"filled\"\n color={\"primary\"}\n onClick={onPreviewComplete}>\n Save data\n </Button>}\n\n </DialogActions>\n </Dialog>\n\n </>;\n}\n\nconst internalIDValue = \"__internal_id__\";\n\nfunction PropertyTreeSelect({\n selectedPropertyKey,\n properties,\n onPropertySelected,\n onIdSelected,\n propertiesAndLevel,\n isIdColumn\n}: {\n selectedPropertyKey: string | null;\n properties: Record<string, Property>;\n onPropertySelected: (propertyKey: string | null) => void;\n onIdSelected: () => void;\n propertiesAndLevel: PropertyAndLevel[];\n isIdColumn?: boolean;\n}) {\n\n const selectedProperty = selectedPropertyKey ? getPropertyInPath(properties, selectedPropertyKey) : null;\n\n const renderValue = useCallback((selectedPropertyKey: string) => {\n\n if (selectedPropertyKey === internalIDValue) {\n return <Typography variant={\"body2\"} className={\"p-4\"}>Use this column as ID</Typography>;\n }\n\n if (!selectedPropertyKey || !selectedProperty) {\n return <Typography variant={\"body2\"} color=\"disabled\" className={\"p-4\"}>Do not import this\n property</Typography>;\n }\n\n return <PropertySelectEntry propertyKey={selectedPropertyKey}\n property={selectedProperty as Property}/>;\n }, [selectedProperty]);\n\n const onSelectValueChange = (value: string) => {\n if (value === internalIDValue) {\n onIdSelected();\n onPropertySelected(null);\n } else if (value === \"__do_not_import\") {\n onPropertySelected(null);\n } else {\n onPropertySelected(value);\n }\n };\n\n return <Select value={isIdColumn ? internalIDValue : (selectedPropertyKey ?? undefined)}\n fullWidth={true}\n onValueChange={onSelectValueChange}\n renderValue={renderValue}>\n\n <SelectItem value={\"__do_not_import\"}>\n <Typography variant={\"body2\"} color={\"disabled\"} className={\"p-4\"}>Do not import this property</Typography>\n </SelectItem>\n\n <SelectItem value={internalIDValue}>\n <Typography variant={\"body2\"} className={\"p-4\"}>Use this column as ID</Typography>\n </SelectItem>\n\n {propertiesAndLevel.map(({\n property,\n level,\n propertyKey\n }) => {\n return <SelectItem value={propertyKey}\n key={propertyKey}\n disabled={property.type === \"map\"}>\n <PropertySelectEntry propertyKey={propertyKey}\n property={property}\n level={level}/>\n </SelectItem>;\n })}\n\n </Select>;\n}\n\ntype PropertyAndLevel = {\n property: Property,\n level: number,\n propertyKey: string\n};\n\nfunction getPropertiesAndLevel(key: string, property: Property, level: number): PropertyAndLevel[] {\n const properties: PropertyAndLevel[] = [];\n properties.push({\n property,\n level,\n propertyKey: key\n });\n if (property.type === \"map\" && property.properties) {\n Object.entries(property.properties).forEach(([childKey, value]) => {\n properties.push(...getPropertiesAndLevel(`${key}.${childKey}`, value as Property, level + 1));\n });\n }\n return properties;\n}\n\nexport function PropertySelectEntry({\n propertyKey,\n property,\n level = 0\n}: {\n propertyKey: string;\n property: Property;\n level?: number;\n}) {\n\n const { propertyConfigs } = useCustomizationController();\n const widget = getFieldConfig(property, propertyConfigs);\n\n return <div\n className=\"flex flex-row w-full text-start items-center h-full\">\n\n {new Array(level).fill(0).map((_, index) =>\n <div className={cls(defaultBorderMixin, \"ml-8 border-l h-12\")} key={index}/>)}\n\n <div className={\"m-4\"}>\n <Tooltip title={widget?.name}>\n <PropertyConfigBadge propertyConfig={widget}/>\n </Tooltip>\n </div>\n\n <div className={\"flex flex-col grow p-2 pl-2\"}>\n <Typography variant=\"body1\"\n component=\"span\"\n className=\"grow pr-2\">\n {property.name\n ? property.name\n : \"\\u00a0\"\n }\n </Typography>\n\n <Typography className=\" pr-2\"\n variant={\"body2\"}\n component=\"span\"\n color=\"secondary\">\n {propertyKey}\n </Typography>\n </div>\n\n </div>;\n\n}\n\nexport function ImportDataPreview<M extends Record<string, unknown>>({\n importConfig,\n properties,\n propertiesOrder\n}: {\n importConfig: ImportConfig,\n properties: Properties,\n propertiesOrder: Extract<keyof M, string>[],\n}) {\n const authController = useAuthController();\n const collectionRegistry = useCollectionRegistryController();\n useEffect(() => {\n const mappedData = importConfig.importData.map(d => convertDataToEntity(\n authController,\n collectionRegistry,\n d,\n importConfig.idColumn,\n importConfig.headersMapping,\n properties,\n \"TEMP_PATH\",\n importConfig.defaultValues\n ));\n importConfig.setEntities(mappedData);\n }, []);\n\n const selectionController = useSelectionController();\n\n return <CollectionTableBinding\n title={<div>\n <Typography variant={\"subtitle2\"}>Imported data preview</Typography>\n <Typography variant={\"caption\"}>Entities with the same id will be overwritten</Typography>\n </div>}\n tableController={{\n data: importConfig.entities,\n dataLoading: false,\n noMoreToLoad: false\n }}\n enablePopupIcon={false}\n endAdornment={<div className={\"h-12\"}/>}\n filterable={false}\n sortable={false}\n openEntityMode={\"full_screen\"}\n selectionController={selectionController}\n properties={properties}/>\n\n}\n\nfunction buildHeadersMappingFromData(objArr: object[], properties?: Properties) {\n const headersMapping: Record<string, string> = {};\n objArr.filter(Boolean).forEach((obj) => {\n Object.keys(obj).forEach((key) => {\n const child = (obj as Record<string, unknown>)[key];\n if (child != null && typeof child === \"object\" && !Array.isArray(child)) {\n const childProperty = properties?.[key];\n const childProperties = childProperty && \"properties\" in childProperty ? childProperty.properties : undefined;\n const childHeadersMapping = buildHeadersMappingFromData([child as object], childProperties);\n Object.entries(childHeadersMapping).forEach(([subKey, mapping]) => {\n headersMapping[`${key}.${subKey}`] = `${key}.${mapping}`;\n });\n }\n\n if (!properties) {\n headersMapping[key] = key;\n } else if (key in properties) {\n headersMapping[key] = key;\n } else {\n const slug = slugify(key);\n if (slug in properties) {\n headersMapping[key] = slug;\n } else {\n headersMapping[key] = key;\n }\n }\n\n });\n });\n return headersMapping;\n}\n","export * from \"./ImportCollectionAction\";\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { $ as useBuildCollectionRegistryController, $n as sanitizeUrl, $t as CollectionTableBinding, A as getFieldId, An as ArrayOfReferencesPreview, At as convertFileToJson, B as MapFieldBinding, Bn as getEntityTitlePropertyKeyForEntity, Bt as mergeEntityActions, C as removeEmptyContainers, Cn as MapPropertyPreview, Ct as convertDataToEntity, D as getDefaultFieldConfig, Dn as ArrayEnumPreview, Dt as useImportConfig, E as DEFAULT_FIELD_CONFIGS, En as ArrayPropertyEnumPreview, Et as getInferenceType, F as SelectFieldBinding, Fn as useSidePanel, Ft as FieldCaption, G as useSelectionDialog, Gn as StorageThumbnailInternal, Gt as removeInitialAndTrailingSlashes, H as DateTimeFieldBinding, Hn as StringPropertyPreview, Ht as getCollectionBySlugWithin, I as RepeatFieldBinding, In as CollectionRegistryContext, It as useBreadcrumbsController, J as useBuildUrlController, Jn as renderSkeletonIcon, Jt as resolveCollectionPathIds, K as SelectionTableBinding, Kn as SkeletonPropertyComponent, Kt as removeInitialSlash, L as ReferenceFieldBinding, Ln as useCollectionRegistryController, Lt as BreadcrumbsProvider, M as TextFieldBinding, Mn as ReferencePreview, Mt as ArrayContainer, N as SwitchFieldBinding, Nn as EntityPreviewBinding, Nt as PropertyConfigBadge, O as getDefaultFieldId, On as ArrayOfStorageComponentsPreview, Ot as ImportSaveInProgress, P as StorageUploadFieldBinding, Pn as SidePanelControllerContext, Pt as SearchIconsView, Q as useResolvedCollections, Qn as ImagePreview, Qt as VirtualTableInput, R as MultiSelectFieldBinding, Rn as getEntityPreviewKeys, Rt as resolveEntityAction, S as getInitialEntityValues, Sn as KeyValuePreview, St as DataNewPropertiesMapping, T as PropertyFieldBinding, Tn as ArrayOfStringsPreview, Tt as processValueMapping, U as BlockFieldBinding, Un as EnumValuesChip, Ut as getCollectionPathsCombinations, V as KeyValueFieldBinding, Vn as ArrayPropertyPreview, Vt as addInitialSlash, W as ArrayOfReferencesFieldBinding, Wn as StorageThumbnail, Wt as getLastSegment, X as useTopLevelNavigation, Xn as renderSkeletonText, Xt as resolveViewMode, Y as useBuildNavigationStateController, Yn as renderSkeletonImageThumbnail, Yt as resolveOpenEntityMode, Z as useResolvedViews, Zn as UrlComponentPreview, Zt as useSelectionController, _ as useCollectionsConfigController, _n as getUserLabel, _t as CollectionViewActions, a as namespaceToPropertiesPath, an as NavigationStateContext, ar as FieldBlock, at as useBuildSidePanel, b as extractTouchedValues, bn as BooleanPreview, bt as useCollectionEditorDialogsState, c as buildCollectionGenerationCallback, cn as SideDialogsControllerContext, cr as getBracketNotation, ct as copyEntityAction, d as fromSerializableCollectionConfigs, dn as useClearRestoreValue, dr as getIconForWidget, dt as resetPasswordAction, en as SelectableTable, er as EmptyValue, et as useHistory, f as fromSerializableProperties, fn as ReadOnlyFieldBinding, fr as getPropertiesWithPropertiesOrder, ft as CreationResultDialog, g as toSerializableProperty, gn as UserPreview, gr as isRelationProperty, gt as EntityCardBinding, h as toSerializableProperties, hn as PropertyPreview, hr as isReferenceProperty, ht as CollectionCardViewBinding, i as namespaceToPropertiesOrderPath, in as useUrlController, ir as FormRail, it as getEntityViewWidth, j as VectorFieldBinding, jn as InlineEntityListPreview, jt as unflattenObject, k as getFieldConfig, kn as RelationPreview, kt as ImportFileUpload, l as validateCollectionJson, ln as SelectableTableContext, lr as getDefaultPropertiesOrder, lt as deleteEntityAction, m as toSerializableCollectionConfig, mn as ArrayOfMapsPreview, mr as getResolvedPropertyInPath, mt as EntityViewBinding, n as getFullIdPath, nn as useAdminContext, nr as LabelWithIcon, nt as useResolvedNavigationFrom, o as CollectionGenerationApiError, on as useNavigationStateController, or as isSelfLabellingProperty, ot as EditViewBinding, p as fromSerializableProperty, pn as FieldHelperText, pr as getPropertyInPath, pt as DetailViewBinding, q as SideDialogs, qn as renderSkeletonCaptionText, qt as removeTrailingSlash, r as idToPropertiesPath, rn as UrlContext, rr as FormSections, rt as buildSidePanelsFromUrl, s as DEFAULT_COLLECTION_GENERATION_ENDPOINT, sn as useSideDialogsController, sr as PropertyIdCopyTooltip, st as CollectionViewBinding, t as getFullId, tn as CollectionRowActions, tr as LabelWithIconAndTooltip, tt as resolveNavigationFrom, u as fromSerializableCollectionConfig, un as ArrayCustomShapedFieldBinding, ur as getIconForProperty, ut as editEntityAction, v as EntityFormBinding, vn as useResolvedUser, vt as useCollectionEditorController, w as zodToFormErrors, wn as ArrayOneOfPreview, wt as flattenEntry, x as getChanges, xn as DatePreview, xt as ImportNewPropertyFieldPreview, y as EntityForm, yn as NumberPropertyPreview, yt as ConfigControllerProvider, z as MarkdownEditorFieldBinding, zn as getEntityTitlePropertyKey, zt as resolveEntityView } from "./util-BnRLzp4j.js";
2
- import { i as PropertySelectEntry, n as ImportCollectionAction, r as ImportDataPreview } from "./import-DLY5UYDa.js";
3
- import { a as downloadDataAsCsv, c as getEntityJsonExportableData, i as downloadBlob, n as ExportCollectionAction, o as downloadEntitiesExport, r as BasicExportAction, s as getEntityCSVExportableData } from "./export-DghFk-W0.js";
1
+ import { $ as useBuildCollectionRegistryController, $n as sanitizeUrl, $t as CollectionTableBinding, A as getFieldId, An as ArrayOfReferencesPreview, At as convertFileToJson, B as MapFieldBinding, Bn as getEntityTitlePropertyKeyForEntity, Bt as mergeEntityActions, C as removeEmptyContainers, Cn as MapPropertyPreview, Ct as convertDataToEntity, D as getDefaultFieldConfig, Dn as ArrayEnumPreview, Dt as useImportConfig, E as DEFAULT_FIELD_CONFIGS, En as ArrayPropertyEnumPreview, Et as getInferenceType, F as SelectFieldBinding, Fn as useSidePanel, Ft as FieldCaption, G as useSelectionDialog, Gn as StorageThumbnailInternal, Gt as removeInitialAndTrailingSlashes, H as DateTimeFieldBinding, Hn as StringPropertyPreview, Ht as getCollectionBySlugWithin, I as RepeatFieldBinding, In as CollectionRegistryContext, It as useBreadcrumbsController, J as useBuildUrlController, Jn as renderSkeletonIcon, Jt as resolveCollectionPathIds, K as SelectionTableBinding, Kn as SkeletonPropertyComponent, Kt as removeInitialSlash, L as ReferenceFieldBinding, Ln as useCollectionRegistryController, Lt as BreadcrumbsProvider, M as TextFieldBinding, Mn as ReferencePreview, Mt as ArrayContainer, N as SwitchFieldBinding, Nn as EntityPreviewBinding, Nt as PropertyConfigBadge, O as getDefaultFieldId, On as ArrayOfStorageComponentsPreview, Ot as ImportSaveInProgress, P as StorageUploadFieldBinding, Pn as SidePanelControllerContext, Pt as SearchIconsView, Q as useResolvedCollections, Qn as ImagePreview, Qt as VirtualTableInput, R as MultiSelectFieldBinding, Rn as getEntityPreviewKeys, Rt as resolveEntityAction, S as getInitialEntityValues, Sn as KeyValuePreview, St as DataNewPropertiesMapping, T as PropertyFieldBinding, Tn as ArrayOfStringsPreview, Tt as processValueMapping, U as BlockFieldBinding, Un as EnumValuesChip, Ut as getCollectionPathsCombinations, V as KeyValueFieldBinding, Vn as ArrayPropertyPreview, Vt as addInitialSlash, W as ArrayOfReferencesFieldBinding, Wn as StorageThumbnail, Wt as getLastSegment, X as useTopLevelNavigation, Xn as renderSkeletonText, Xt as resolveViewMode, Y as useBuildNavigationStateController, Yn as renderSkeletonImageThumbnail, Yt as resolveOpenEntityMode, Z as useResolvedViews, Zn as UrlComponentPreview, Zt as useSelectionController, _ as useCollectionsConfigController, _n as getUserLabel, _t as CollectionViewActions, a as namespaceToPropertiesPath, an as NavigationStateContext, ar as FieldBlock, at as useBuildSidePanel, b as extractTouchedValues, bn as BooleanPreview, bt as useCollectionEditorDialogsState, c as buildCollectionGenerationCallback, cn as SideDialogsControllerContext, cr as getBracketNotation, ct as copyEntityAction, d as fromSerializableCollectionConfigs, dn as useClearRestoreValue, dr as getIconForWidget, dt as resetPasswordAction, en as SelectableTable, er as EmptyValue, et as useHistory, f as fromSerializableProperties, fn as ReadOnlyFieldBinding, fr as getPropertiesWithPropertiesOrder, ft as CreationResultDialog, g as toSerializableProperty, gn as UserPreview, gr as isRelationProperty, gt as EntityCardBinding, h as toSerializableProperties, hn as PropertyPreview, hr as isReferenceProperty, ht as CollectionCardViewBinding, i as namespaceToPropertiesOrderPath, in as useUrlController, ir as FormRail, it as getEntityViewWidth, j as VectorFieldBinding, jn as InlineEntityListPreview, jt as unflattenObject, k as getFieldConfig, kn as RelationPreview, kt as ImportFileUpload, l as validateCollectionJson, ln as SelectableTableContext, lr as getDefaultPropertiesOrder, lt as deleteEntityAction, m as toSerializableCollectionConfig, mn as ArrayOfMapsPreview, mr as getResolvedPropertyInPath, mt as EntityViewBinding, n as getFullIdPath, nn as useAdminContext, nr as LabelWithIcon, nt as useResolvedNavigationFrom, o as CollectionGenerationApiError, on as useNavigationStateController, or as isSelfLabellingProperty, ot as EditViewBinding, p as fromSerializableProperty, pn as FieldHelperText, pr as getPropertyInPath, pt as DetailViewBinding, q as SideDialogs, qn as renderSkeletonCaptionText, qt as removeTrailingSlash, r as idToPropertiesPath, rn as UrlContext, rr as FormSections, rt as buildSidePanelsFromUrl, s as DEFAULT_COLLECTION_GENERATION_ENDPOINT, sn as useSideDialogsController, sr as PropertyIdCopyTooltip, st as CollectionViewBinding, t as getFullId, tn as CollectionRowActions, tr as LabelWithIconAndTooltip, tt as resolveNavigationFrom, u as fromSerializableCollectionConfig, un as ArrayCustomShapedFieldBinding, ur as getIconForProperty, ut as editEntityAction, v as EntityFormBinding, vn as useResolvedUser, vt as useCollectionEditorController, w as zodToFormErrors, wn as ArrayOneOfPreview, wt as flattenEntry, x as getChanges, xn as DatePreview, xt as ImportNewPropertyFieldPreview, y as EntityForm, yn as NumberPropertyPreview, yt as ConfigControllerProvider, z as MarkdownEditorFieldBinding, zn as getEntityTitlePropertyKey, zt as resolveEntityView } from "./util-GiwPgxnL.js";
2
+ import { i as PropertySelectEntry, n as ImportCollectionAction, r as ImportDataPreview } from "./import-BvYl--U4.js";
3
+ import { a as downloadDataAsCsv, c as getEntityJsonExportableData, i as downloadBlob, n as ExportCollectionAction, o as downloadEntitiesExport, r as BasicExportAction, s as getEntityCSVExportableData } from "./export-J79rMoNj.js";
4
4
  import React, { Suspense, lazy, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
5
5
  import { deepEqual } from "fast-equals";
6
6
  import { Avatar, Button, Card, ChevronDownIcon, ChevronsLeftIcon, ChevronsRightIcon, Chip, CircularProgressCenter, Collapse, Container, Dialog, DialogActions, DialogContent, DialogTitle, ErrorBoundary, ExpandablePanel, IconButton, LogOutIcon, Markdown, Menu, MenuIcon, MenuItem, MoonIcon, PencilIcon, SearchBar, SettingsIcon, Sheet, Skeleton, StarIcon, SunIcon, SunMoonIcon, TextField, Tooltip, Typography, cls, defaultBorderMixin, iconSize } from "@rebasepro/ui";
@@ -1561,7 +1561,7 @@ function useLocalCollectionsConfigController(clientOrUrl, baseCollections = [],
1561
1561
  //#region src/components/RebaseNavigation.tsx
1562
1562
  var EMPTY_PLUGINS = [];
1563
1563
  var EMPTY_COLLECTIONS = [];
1564
- var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-Cv0tAxtu.js").then((n) => n.n).then((m) => ({ default: m.RouterCollectionsStudioView })));
1564
+ var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-BsLTNoqX.js").then((n) => n.n).then((m) => ({ default: m.RouterCollectionsStudioView })));
1565
1565
  /**
1566
1566
  * Navigation layer — builds and provides all admin navigation controllers:
1567
1567
  * collection registry, URL controller, navigation state, side entity,
@@ -2790,8 +2790,8 @@ function ContentHomePage({ additionalActions, additionalChildrenStart, additiona
2790
2790
  }
2791
2791
  //#endregion
2792
2792
  //#region src/components/CollectionEditorDialogs.tsx
2793
- var CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-Dhn0S4FT.js").then((n) => n.r).then((m) => ({ default: m.CollectionEditorDialog })));
2794
- var PropertyFormDialog = lazy(() => import("./PropertyEditView-JPN12E-0.js").then((n) => n.t).then((m) => ({ default: m.PropertyFormDialog })));
2793
+ var CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-CjXkWZ64.js").then((n) => n.r).then((m) => ({ default: m.CollectionEditorDialog })));
2794
+ var PropertyFormDialog = lazy(() => import("./PropertyEditView-W8I3YV89.js").then((n) => n.t).then((m) => ({ default: m.PropertyFormDialog })));
2795
2795
  /**
2796
2796
  * Renders the CollectionEditorDialog and PropertyFormDialog inside
2797
2797
  * the RebaseShell tree where admin-internal contexts
@@ -8072,8 +8072,8 @@ function EditorCollectionAction({ path, parentCollectionSlugs, parentEntityIds,
8072
8072
  }
8073
8073
  //#endregion
8074
8074
  //#region src/components/CollectionViewBinding/CollectionViewActions.tsx
8075
- var ImportCollectionAction = lazy(() => import("./import-DLY5UYDa.js").then((n) => n.t).then((m) => ({ default: m.ImportCollectionAction })));
8076
- var ExportCollectionAction = lazy(() => import("./export-DghFk-W0.js").then((n) => n.t).then((m) => ({ default: m.ExportCollectionAction })));
8075
+ var ImportCollectionAction = lazy(() => import("./import-BvYl--U4.js").then((n) => n.t).then((m) => ({ default: m.ImportCollectionAction })));
8076
+ var ExportCollectionAction = lazy(() => import("./export-J79rMoNj.js").then((n) => n.t).then((m) => ({ default: m.ExportCollectionAction })));
8077
8077
  function CollectionViewActions({ collection, relativePath, parentCollectionSlugs, parentEntityIds, onNewClick, onAddExistingClick, onMultipleDeleteClick, selectionEnabled, path, selectionController, tableController, collectionEntitiesCount, compact, children, openNewDocument }) {
8078
8078
  const context = useAdminContext();
8079
8079
  const { canCreate, canDelete } = usePermissions();
@@ -9744,7 +9744,7 @@ function JsonPreviewBinding({ values }) {
9744
9744
  }
9745
9745
  //#endregion
9746
9746
  //#region src/components/EntityInspector.tsx
9747
- var EntityHistoryView = lazy(() => import("./history-c-iE7d4k.js").then((m) => ({ default: m.EntityHistoryView })));
9747
+ var EntityHistoryView = lazy(() => import("./history-D7L_JlLO.js").then((m) => ({ default: m.EntityHistoryView })));
9748
9748
  /**
9749
9749
  * Raw values and revision history, as an inspector rather than as tabs.
9750
9750
  *
@@ -9753,10 +9753,10 @@ var EntityHistoryView = lazy(() => import("./history-c-iE7d4k.js").then((m) => (
9753
9753
  * to edit. They are developer tools, not places the record lives, so they belong
9754
9754
  * behind one affordance in the bar; a content editor should never meet `<>`.
9755
9755
  *
9756
- * The panel starts below the identity bar deliberately: you keep seeing which
9757
- * record you are inspecting while you inspect it.
9756
+ * The panel sits below the identity bar and beside the record deliberately: you
9757
+ * keep seeing which record you are inspecting, and keep being able to edit it.
9758
9758
  */
9759
- function EntityInspector({ tab, onTabChange, onClose, collection, entity, formContext, values, includeHistory }) {
9759
+ function EntityInspector({ tab, onTabChange, onClose, collection, entity, formContext, values, includeHistory, refreshToken }) {
9760
9760
  const { t } = useTranslation();
9761
9761
  const open = tab !== null;
9762
9762
  useEffect(() => {
@@ -9772,56 +9772,50 @@ function EntityInspector({ tab, onTabChange, onClose, collection, entity, formCo
9772
9772
  }, [open, onClose]);
9773
9773
  if (!open) return null;
9774
9774
  return /* @__PURE__ */ jsxs("div", {
9775
- className: "absolute inset-x-0 bottom-0 top-[52px] z-30 flex justify-end",
9776
- role: "dialog",
9775
+ className: cls("relative flex flex-col shrink-0 h-full w-full max-w-md border-l", "bg-white dark:bg-surface-800", defaultBorderMixin),
9776
+ role: "complementary",
9777
9777
  "aria-label": t("inspect_record") ?? "Inspect record",
9778
- children: [/* @__PURE__ */ jsx("div", {
9779
- className: "absolute inset-0 bg-black/25",
9780
- onClick: onClose,
9781
- "aria-hidden": true
9782
- }), /* @__PURE__ */ jsxs("div", {
9783
- className: cls("relative flex flex-col w-full max-w-md border-l shadow-xl", "bg-white dark:bg-surface-800", defaultBorderMixin),
9784
- children: [/* @__PURE__ */ jsxs("div", {
9785
- className: cls("h-11 shrink-0 flex items-center gap-2 pl-4 pr-1.5 border-b", defaultBorderMixin),
9786
- children: [
9787
- /* @__PURE__ */ jsx("span", {
9788
- className: "text-sm font-semibold",
9789
- children: t("inspect") ?? "Inspect"
9790
- }),
9791
- /* @__PURE__ */ jsx("div", { className: "flex-1" }),
9792
- includeHistory ? /* @__PURE__ */ jsxs(Tabs, {
9793
- value: tab ?? "json",
9794
- className: "!w-fit",
9795
- onValueChange: (v) => onTabChange(v),
9796
- children: [/* @__PURE__ */ jsx(Tab, {
9797
- value: "json",
9798
- className: "text-xs",
9799
- children: t("json")
9800
- }), /* @__PURE__ */ jsx(Tab, {
9801
- value: "history",
9802
- className: "text-xs",
9803
- children: t("record_history") ?? "History"
9804
- })]
9805
- }) : null,
9806
- /* @__PURE__ */ jsx(IconButton, {
9807
- size: "small",
9808
- onClick: onClose,
9809
- "aria-label": t("close_inspector") ?? "Close inspector",
9810
- children: /* @__PURE__ */ jsx(XIcon, { size: iconSize.smallest })
9811
- })
9812
- ]
9813
- }), /* @__PURE__ */ jsx("div", {
9814
- className: "flex-1 min-h-0 overflow-auto",
9815
- children: /* @__PURE__ */ jsxs(ErrorBoundary, { children: [tab === "json" && /* @__PURE__ */ jsx(JsonPreviewBinding, { values: values ?? entity?.values ?? {} }), tab === "history" && includeHistory && formContext && /* @__PURE__ */ jsx(Suspense, {
9816
- fallback: /* @__PURE__ */ jsx(CircularProgressCenter, {}),
9817
- children: /* @__PURE__ */ jsx(EntityHistoryView, {
9818
- collection,
9819
- entity,
9820
- formContext,
9821
- modifiedValues: values ?? entity?.values
9822
- })
9823
- })] })
9824
- })]
9778
+ children: [/* @__PURE__ */ jsxs("div", {
9779
+ className: cls("h-11 shrink-0 flex items-center gap-2 pl-4 pr-1.5 border-b", defaultBorderMixin),
9780
+ children: [
9781
+ /* @__PURE__ */ jsx("span", {
9782
+ className: "text-sm font-semibold",
9783
+ children: t("inspect") ?? "Inspect"
9784
+ }),
9785
+ /* @__PURE__ */ jsx("div", { className: "flex-1" }),
9786
+ includeHistory ? /* @__PURE__ */ jsxs(Tabs, {
9787
+ value: tab ?? "json",
9788
+ className: "!w-fit",
9789
+ onValueChange: (v) => onTabChange(v),
9790
+ children: [/* @__PURE__ */ jsx(Tab, {
9791
+ value: "json",
9792
+ className: "text-xs",
9793
+ children: t("json")
9794
+ }), /* @__PURE__ */ jsx(Tab, {
9795
+ value: "history",
9796
+ className: "text-xs",
9797
+ children: t("record_history") ?? "History"
9798
+ })]
9799
+ }) : null,
9800
+ /* @__PURE__ */ jsx(IconButton, {
9801
+ size: "small",
9802
+ onClick: onClose,
9803
+ "aria-label": t("close_inspector") ?? "Close inspector",
9804
+ children: /* @__PURE__ */ jsx(XIcon, { size: iconSize.smallest })
9805
+ })
9806
+ ]
9807
+ }), /* @__PURE__ */ jsx("div", {
9808
+ className: "flex-1 min-h-0 overflow-auto",
9809
+ children: /* @__PURE__ */ jsxs(ErrorBoundary, { children: [tab === "json" && /* @__PURE__ */ jsx(JsonPreviewBinding, { values: values ?? entity?.values ?? {} }), tab === "history" && includeHistory && formContext && /* @__PURE__ */ jsx(Suspense, {
9810
+ fallback: /* @__PURE__ */ jsx(CircularProgressCenter, {}),
9811
+ children: /* @__PURE__ */ jsx(EntityHistoryView, {
9812
+ collection,
9813
+ entity,
9814
+ formContext,
9815
+ refreshToken,
9816
+ modifiedValues: values ?? entity?.values
9817
+ })
9818
+ })] })
9825
9819
  })]
9826
9820
  });
9827
9821
  }
@@ -10176,18 +10170,25 @@ function DetailViewBindingInner({ path, entityId, selectedTab: selectedTabProp,
10176
10170
  ]
10177
10171
  })
10178
10172
  }),
10179
- globalLoading ? /* @__PURE__ */ jsx(DetailViewSkeleton, { collection }) : mainView,
10180
- customViewsView,
10181
- subCollectionsViews,
10182
- /* @__PURE__ */ jsx(EntityInspector, {
10183
- tab: inspectorTab,
10184
- onTabChange: setInspectorTab,
10185
- onClose: () => setInspectorTab(null),
10186
- collection,
10187
- entity: usedEntity,
10188
- formContext: readOnlyFormContext,
10189
- values: usedEntity?.values,
10190
- includeHistory: includeHistoryView
10173
+ /* @__PURE__ */ jsxs("div", {
10174
+ className: "flex-1 min-h-0 flex",
10175
+ children: [/* @__PURE__ */ jsxs("div", {
10176
+ className: "flex-1 min-w-0 flex flex-col",
10177
+ children: [
10178
+ globalLoading ? /* @__PURE__ */ jsx(DetailViewSkeleton, { collection }) : mainView,
10179
+ customViewsView,
10180
+ subCollectionsViews
10181
+ ]
10182
+ }), /* @__PURE__ */ jsx(EntityInspector, {
10183
+ tab: inspectorTab,
10184
+ onTabChange: setInspectorTab,
10185
+ onClose: () => setInspectorTab(null),
10186
+ collection,
10187
+ entity: usedEntity,
10188
+ formContext: readOnlyFormContext,
10189
+ values: usedEntity?.values,
10190
+ includeHistory: includeHistoryView
10191
+ })]
10191
10192
  })
10192
10193
  ]
10193
10194
  });
@@ -14867,6 +14868,7 @@ function EditViewBindingInner({ path, entityId, selectedTab: selectedTabProp, co
14867
14868
  const hasFormErrors = Boolean(formex && Object.keys(formex.errors).length > 0 && formex.submitCount > 0);
14868
14869
  const saveDisabled = Boolean(!formContext || formContext.disabled || formex?.isSubmitting || status === "existing" && !formex?.dirty);
14869
14870
  const [inspectorTab, setInspectorTab] = useState(null);
14871
+ const [savedCount, setSavedCount] = useState(0);
14870
14872
  const sideDialogContext = useSideDialogContext();
14871
14873
  const canCloseAfterSave = layout === "side_panel" || layout === "dialog";
14872
14874
  const recordActions = useRecordActions({
@@ -15009,6 +15011,7 @@ function EditViewBindingInner({ path, entityId, selectedTab: selectedTabProp, co
15009
15011
  formProps?.onFormContextReady?.(formContext);
15010
15012
  },
15011
15013
  onSaved: (params) => {
15014
+ setSavedCount((count) => count + 1);
15012
15015
  const res = {
15013
15016
  ...params,
15014
15017
  selectedTab: "__main_##Q$SC^#S6" === activeTab ? void 0 : activeTab
@@ -15125,18 +15128,26 @@ function EditViewBindingInner({ path, entityId, selectedTab: selectedTabProp, co
15125
15128
  ]
15126
15129
  })
15127
15130
  }),
15128
- globalLoading ? /* @__PURE__ */ jsx(EntityFormSkeleton, { collection }) : /* @__PURE__ */ jsxs(Fragment, { children: [entityReadOnlyView, entityView] }),
15129
- customViewsView,
15130
- subCollectionsViews,
15131
- /* @__PURE__ */ jsx(EntityInspector, {
15132
- tab: inspectorTab,
15133
- onTabChange: setInspectorTab,
15134
- onClose: () => setInspectorTab(null),
15135
- collection,
15136
- entity: usedEntity,
15137
- formContext,
15138
- values: formContext?.values ?? usedEntity?.values,
15139
- includeHistory: includeHistoryView
15131
+ /* @__PURE__ */ jsxs("div", {
15132
+ className: "flex-1 min-h-0 flex",
15133
+ children: [/* @__PURE__ */ jsxs("div", {
15134
+ className: "flex-1 min-w-0 flex flex-col",
15135
+ children: [
15136
+ globalLoading ? /* @__PURE__ */ jsx(EntityFormSkeleton, { collection }) : /* @__PURE__ */ jsxs(Fragment, { children: [entityReadOnlyView, entityView] }),
15137
+ customViewsView,
15138
+ subCollectionsViews
15139
+ ]
15140
+ }), /* @__PURE__ */ jsx(EntityInspector, {
15141
+ tab: inspectorTab,
15142
+ onTabChange: setInspectorTab,
15143
+ onClose: () => setInspectorTab(null),
15144
+ collection,
15145
+ entity: usedEntity,
15146
+ formContext,
15147
+ values: formContext?.values ?? usedEntity?.values,
15148
+ refreshToken: savedCount,
15149
+ includeHistory: includeHistoryView
15150
+ })]
15140
15151
  })
15141
15152
  ]
15142
15153
  });
@@ -15724,7 +15735,7 @@ function useResolvedNavigationFrom({ path }) {
15724
15735
  * Replaces the old subcollection-based approach with a proper API call.
15725
15736
  */
15726
15737
  function useHistory(params) {
15727
- const { slug, entityId, enabled = true, pageSize = 10 } = params;
15738
+ const { slug, entityId, enabled = true, pageSize = 10, refreshToken } = params;
15728
15739
  const apiConfig = useApiConfig();
15729
15740
  const apiBase = useApiBase();
15730
15741
  const [entries, setEntries] = useState([]);
@@ -15734,6 +15745,7 @@ function useHistory(params) {
15734
15745
  const [error, setError] = useState();
15735
15746
  const [offset, setOffset] = useState(0);
15736
15747
  const [refreshTrigger, setRefreshTrigger] = useState(0);
15748
+ const entityKey = `${slug}/${entityId}/${refreshToken ?? 0}`;
15737
15749
  const currentEntityRef = useRef(void 0);
15738
15750
  const fetchEntries = useCallback(async (currentOffset, signal) => {
15739
15751
  if (!apiConfig?.apiUrl || !entityId || !enabled) return;
@@ -15749,7 +15761,6 @@ function useHistory(params) {
15749
15761
  signal
15750
15762
  });
15751
15763
  if (signal?.aborted) return;
15752
- const entityKey = `${slug}/${entityId}`;
15753
15764
  if (currentEntityRef.current !== entityKey) return;
15754
15765
  if (!response.ok) {
15755
15766
  const errorData = await response.json().catch(() => ({ error: { message: response.statusText } }));
@@ -15771,11 +15782,11 @@ function useHistory(params) {
15771
15782
  apiBase,
15772
15783
  slug,
15773
15784
  entityId,
15785
+ entityKey,
15774
15786
  enabled,
15775
15787
  pageSize
15776
15788
  ]);
15777
15789
  useEffect(() => {
15778
- const entityKey = `${slug}/${entityId}`;
15779
15790
  const isNewEntity = currentEntityRef.current !== entityKey;
15780
15791
  if (isNewEntity) {
15781
15792
  currentEntityRef.current = entityKey;
@@ -15795,7 +15806,7 @@ function useHistory(params) {
15795
15806
  offset,
15796
15807
  enabled,
15797
15808
  entityId,
15798
- slug,
15809
+ entityKey,
15799
15810
  refreshTrigger
15800
15811
  ]);
15801
15812
  const loadMore = useCallback(() => {
@@ -22078,4 +22089,4 @@ function getFullIdPath(propertyKey, propertyNamespace) {
22078
22089
  //#endregion
22079
22090
  export { useBuildCollectionRegistryController as $, sanitizeUrl as $n, CollectionTableBinding as $t, getFieldId as A, ArrayOfReferencesPreview as An, convertFileToJson as At, MapFieldBinding as B, getEntityTitlePropertyKeyForEntity as Bn, mergeEntityActions as Bt, removeEmptyContainers as C, MapPropertyPreview as Cn, convertDataToEntity as Ct, getDefaultFieldConfig as D, ArrayEnumPreview as Dn, useImportConfig as Dt, DEFAULT_FIELD_CONFIGS as E, ArrayPropertyEnumPreview as En, getInferenceType as Et, SelectFieldBinding as F, useSidePanel as Fn, FieldCaption as Ft, useSelectionDialog as G, StorageThumbnailInternal as Gn, removeInitialAndTrailingSlashes$1 as Gt, DateTimeFieldBinding as H, StringPropertyPreview as Hn, getCollectionBySlugWithin as Ht, RepeatFieldBinding as I, CollectionRegistryContext as In, useBreadcrumbsController as It, useBuildUrlController as J, renderSkeletonIcon as Jn, resolveCollectionPathIds$1 as Jt, SelectionTableBinding as K, SkeletonPropertyComponent as Kn, removeInitialSlash as Kt, ReferenceFieldBinding as L, useCollectionRegistryController as Ln, BreadcrumbsProvider as Lt, TextFieldBinding as M, ReferencePreview as Mn, ArrayContainer as Mt, SwitchFieldBinding as N, EntityPreviewBinding as Nn, PropertyConfigBadge as Nt, getDefaultFieldId as O, ArrayOfStorageComponentsPreview as On, ImportSaveInProgress as Ot, StorageUploadFieldBinding as P, SidePanelControllerContext as Pn, SearchIconsView as Pt, useResolvedCollections as Q, ImagePreview as Qn, VirtualTableInput$1 as Qt, MultiSelectFieldBinding as R, getEntityPreviewKeys as Rn, resolveEntityAction as Rt, getInitialEntityValues as S, KeyValuePreview as Sn, DataNewPropertiesMapping as St, PropertyFieldBinding as T, ArrayOfStringsPreview as Tn, processValueMapping as Tt, BlockFieldBinding as U, EnumValuesChip as Un, getCollectionPathsCombinations as Ut, KeyValueFieldBinding as V, ArrayPropertyPreview as Vn, addInitialSlash as Vt, ArrayOfReferencesFieldBinding as W, StorageThumbnail as Wn, getLastSegment$1 as Wt, useTopLevelNavigation as X, renderSkeletonText as Xn, resolveViewMode as Xt, useBuildNavigationStateController as Y, renderSkeletonImageThumbnail as Yn, resolveOpenEntityMode as Yt, useResolvedViews as Z, UrlComponentPreview as Zn, useSelectionController as Zt, useCollectionsConfigController as _, getUserLabel as _n, CollectionViewActions as _t, namespaceToPropertiesPath as a, NavigationStateContext as an, FieldBlock as ar, useBuildSidePanel as at, extractTouchedValues as b, BooleanPreview as bn, useCollectionEditorDialogsState as bt, buildCollectionGenerationCallback as c, SideDialogsControllerContext as cn, getBracketNotation as cr, copyEntityAction as ct, fromSerializableCollectionConfigs as d, useClearRestoreValue as dn, getIconForWidget as dr, resetPasswordAction as dt, SelectableTable as en, EmptyValue as er, useHistory as et, fromSerializableProperties as f, ReadOnlyFieldBinding as fn, getPropertiesWithPropertiesOrder as fr, CreationResultDialog as ft, toSerializableProperty as g, UserPreview as gn, isRelationProperty as gr, EntityCardBinding as gt, toSerializableProperties as h, PropertyPreview as hn, isReferenceProperty as hr, CollectionCardViewBinding as ht, namespaceToPropertiesOrderPath as i, useUrlController as in, FormRail as ir, getEntityViewWidth as it, VectorFieldBinding as j, InlineEntityListPreview as jn, unflattenObject as jt, getFieldConfig as k, RelationPreview as kn, ImportFileUpload as kt, validateCollectionJson as l, SelectableTableContext as ln, getDefaultPropertiesOrder as lr, deleteEntityAction as lt, toSerializableCollectionConfig as m, ArrayOfMapsPreview as mn, getResolvedPropertyInPath as mr, EntityViewBinding as mt, getFullIdPath as n, useAdminContext as nn, LabelWithIcon as nr, useResolvedNavigationFrom as nt, CollectionGenerationApiError as o, useNavigationStateController as on, isSelfLabellingProperty as or, EditViewBinding as ot, fromSerializableProperty as p, FieldHelperText as pn, getPropertyInPath as pr, DetailViewBinding as pt, SideDialogs as q, renderSkeletonCaptionText as qn, removeTrailingSlash$1 as qt, idToPropertiesPath as r, UrlContext as rn, FormSections as rr, buildSidePanelsFromUrl as rt, DEFAULT_COLLECTION_GENERATION_ENDPOINT as s, useSideDialogsController as sn, PropertyIdCopyTooltip as sr, CollectionViewBinding as st, getFullId as t, CollectionRowActions as tn, LabelWithIconAndTooltip as tr, resolveNavigationFrom as tt, fromSerializableCollectionConfig as u, ArrayCustomShapedFieldBinding as un, getIconForProperty as ur, editEntityAction as ut, EntityFormBinding as v, useResolvedUser as vn, useCollectionEditorController as vt, zodToFormErrors as w, ArrayOneOfPreview as wn, flattenEntry as wt, getChanges as x, DatePreview as xn, ImportNewPropertyFieldPreview as xt, EntityForm as y, NumberPropertyPreview as yn, ConfigControllerProvider as yt, MarkdownEditorFieldBinding as z, getEntityTitlePropertyKey as zn, resolveEntityView as zt };
22080
22091
 
22081
- //# sourceMappingURL=util-BnRLzp4j.js.map
22092
+ //# sourceMappingURL=util-GiwPgxnL.js.map