@rebasepro/admin 0.14.1-canary.g7e666eb → 0.14.1

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 (22) hide show
  1. package/dist/{CollectionEditorDialog-BykOIZH4.js → CollectionEditorDialog-BeS4lxGh.js} +3 -3
  2. package/dist/{CollectionEditorDialog-BykOIZH4.js.map → CollectionEditorDialog-BeS4lxGh.js.map} +1 -1
  3. package/dist/{PropertyEditView-C9Der_Ej.js → PropertyEditView-BFJ6H9-Q.js} +2 -2
  4. package/dist/{PropertyEditView-C9Der_Ej.js.map → PropertyEditView-BFJ6H9-Q.js.map} +1 -1
  5. package/dist/{RouterCollectionsStudioView-CfTHbBCA.js → RouterCollectionsStudioView-sfsUpEJz.js} +4 -4
  6. package/dist/{RouterCollectionsStudioView-CfTHbBCA.js.map → RouterCollectionsStudioView-sfsUpEJz.js.map} +1 -1
  7. package/dist/collection_editor_ui.js +4 -4
  8. package/dist/{export-BDynF1En.js → export-KEf57Jso.js} +2 -2
  9. package/dist/{export-BDynF1En.js.map → export-KEf57Jso.js.map} +1 -1
  10. package/dist/{history-DS2iXiGi.js → history-Ctd2cRn_.js} +2 -2
  11. package/dist/{history-DS2iXiGi.js.map → history-Ctd2cRn_.js.map} +1 -1
  12. package/dist/{import-J5vb86xj.js → import-BujhycMq.js} +2 -2
  13. package/dist/{import-J5vb86xj.js.map → import-BujhycMq.js.map} +1 -1
  14. package/dist/index.js +6 -6
  15. package/dist/{util-WQP-ljKW.js → util-bL-fk6C6.js} +46 -37
  16. package/dist/util-bL-fk6C6.js.map +1 -0
  17. package/package.json +9 -9
  18. package/src/components/CollectionViewBinding/CollectionListViewBinding.tsx +25 -1
  19. package/src/components/CollectionViewBinding/CollectionViewStartActions.tsx +11 -8
  20. package/src/components/CollectionViewBinding/SortButton.tsx +82 -41
  21. package/src/components/DetailViewBinding.tsx +6 -1
  22. package/dist/util-WQP-ljKW.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"import-J5vb86xj.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 { isPrototypePollutingKey, 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 {/* Conditional because it is only true when a column was chosen as\n the id: without one, every row is created and nothing can be\n overwritten. With one, the import asks for an upsert — which it\n did not, back when this sentence was unconditional and false. */}\n <Typography variant={\"caption\"}>\n {importConfig.idColumn\n ? \"Entities with the same id will be overwritten\"\n : \"All rows will be imported as new entities\"}\n </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 // The keys are the uploaded file's header row; `headersMapping[key] = …`\n // is the same setter the import pipeline refuses elsewhere.\n if (isPrototypePollutingKey(key)) return;\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-BujhycMq.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 { isPrototypePollutingKey, 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 {/* Conditional because it is only true when a column was chosen as\n the id: without one, every row is created and nothing can be\n overwritten. With one, the import asks for an upsert — which it\n did not, back when this sentence was unconditional and false. */}\n <Typography variant={\"caption\"}>\n {importConfig.idColumn\n ? \"Entities with the same id will be overwritten\"\n : \"All rows will be imported as new entities\"}\n </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 // The keys are the uploaded file's header row; `headersMapping[key] = …`\n // is the same setter the import pipeline refuses elsewhere.\n if (isPrototypePollutingKey(key)) return;\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 getEntityViewWidth, $n as SkeletonPropertyComponent, $t as resolveCollectionPathIds, A as SelectFieldBinding, An as ArrayOfStringsPreview, At as saveImportedEntities, B as useSelectionDialog, Bn as useSidePanel, Bt as FieldCaption, C as getDefaultFieldId, Cn as UserPreview, Cr as isReferenceProperty, Ct as convertDataToEntity, D as TextFieldBinding, Dn as KeyValuePreview, Dt as useImportConfig, E as VectorFieldBinding, En as DatePreview, Et as getInferenceType, F as MapFieldBinding, Fn as ArrayOfReferencesPreview, Ft as parseCsvToObjects, G as useTopLevelNavigation, Gn as getEntityPreviewKeys, Gt as mergeEntityActions, H as SideDialogs, Hn as useCollectionRegistryController, Ht as BreadcrumbsProvider, I as KeyValueFieldBinding, In as InlineEntityListPreview, It as unflattenObject, J as useBuildCollectionRegistryController, Jn as ArrayPropertyPreview, Jt as getCollectionPathsCombinations, K as useResolvedViews, Kn as getEntityTitlePropertyKey, Kt as addInitialSlash, L as DateTimeFieldBinding, Ln as ReferencePreview, Lt as ArrayContainer, M as ReferenceFieldBinding, Mn as ArrayEnumPreview, Mt as convertFileToJson, N as MultiSelectFieldBinding, Nn as ArrayOfStorageComponentsPreview, Nt as detectCsvDelimiter, O as SwitchFieldBinding, On as MapPropertyPreview, Ot as ImportSaveInProgress, P as MarkdownEditorFieldBinding, Pn as RelationPreview, Pt as parseCsvRows, Q as buildSidePanelsFromUrl, Qn as StorageThumbnailInternal, Qt as removeTrailingSlash, R as BlockFieldBinding, Rn as EntityPreviewBinding, Rt as PropertyConfigBadge, S as getDefaultFieldConfig, Sn as PropertyPreview, Sr as getResolvedPropertyInPath, St as DataNewPropertiesMapping, T as getFieldId, Tn as BooleanPreview, Tt as processValueMapping, U as useBuildUrlController, Un as getUserLabel, Ut as resolveEntityAction, V as SelectionTableBinding, Vn as CollectionRegistryContext, Vt as useBreadcrumbsController, W as useBuildNavigationStateController, Wn as useResolvedUser, Wt as resolveEntityView, X as resolveNavigationFrom, Xn as EnumValuesChip, Xt as removeInitialAndTrailingSlashes, Y as useHistory, Yn as StringPropertyPreview, Yt as getLastSegment, Z as useResolvedNavigationFrom, Zn as StorageThumbnail, Zt as removeInitialSlash, _ as useCollectionsConfigController, _n as ReadOnlyFieldBinding, _r as getDefaultPropertiesOrder, _t as CollectionViewActions, a as namespaceToPropertiesPath, an as SelectableTable, ar as ImagePreview, at as removeEmptyContainers, b as PropertyFieldBinding, bn as FieldHelperText, br as getPropertiesWithPropertiesOrder, bt as useCollectionEditorDialogsState, c as buildCollectionGenerationCallback, cn as UrlContext, cr as FormSections, ct as copyEntityAction, d as fromSerializableCollectionConfigs, dn as useNavigationStateController, dr as FieldBlock, dt as resetPasswordAction, en as resolveOpenEntityMode, er as renderSkeletonCaptionText, et as useBuildSidePanel, f as fromSerializableProperties, fn as useSideDialogsController, fr as LABEL_ICON_SIZE, ft as CreationResultDialog, g as toSerializableProperty, gn as useClearRestoreValue, gr as getBracketNotation, gt as EntityCardBinding, h as toSerializableProperties, hn as ArrayCustomShapedFieldBinding, hr as PropertyIdCopyTooltip, ht as CollectionCardViewBinding, i as namespaceToPropertiesOrderPath, in as CollectionTableBinding, ir as UrlComponentPreview, it as getInitialEntityValues, j as RepeatFieldBinding, jn as ArrayPropertyEnumPreview, jt as ImportFileUpload, k as StorageUploadFieldBinding, kn as ArrayOneOfPreview, kt as IMPORT_BATCH_SIZE, l as validateCollectionJson, ln as useUrlController, lr as FormRail, lt as deleteEntityAction, m as toSerializableCollectionConfig, mn as SelectableTableContext, mr as spanClass, mt as EntityViewBinding, n as getFullIdPath, nn as useSelectionController, nr as renderSkeletonImageThumbnail, nt as extractTouchedValues, o as CollectionGenerationApiError, on as CollectionRowActions, or as sanitizeUrl, ot as zodToFormErrors, p as fromSerializableProperty, pn as SideDialogsControllerContext, pr as isSelfLabellingProperty, pt as DetailViewBinding, q as useResolvedCollections, qn as getEntityTitlePropertyKeyForEntity, qt as getCollectionBySlugWithin, r as idToPropertiesPath, rn as VirtualTableInput, rr as renderSkeletonText, rt as getChanges, s as DEFAULT_COLLECTION_GENERATION_ENDPOINT, sn as useAdminContext, sr as EmptyValue, st as CollectionViewBinding, t as getFullId, tn as resolveViewMode, tr as renderSkeletonIcon, tt as EditViewBinding, u as fromSerializableCollectionConfig, un as NavigationStateContext, ur as RecordMeta, ut as editEntityAction, v as EntityFormBinding, vn as LabelWithIconAndTooltip, vr as getIconForProperty, vt as useCollectionEditorController, w as getFieldConfig, wn as NumberPropertyPreview, wr as isRelationProperty, wt as flattenEntry, x as DEFAULT_FIELD_CONFIGS, xn as ArrayOfMapsPreview, xr as getPropertyInPath, xt as ImportNewPropertyFieldPreview, y as EntityForm, yn as LabelWithIcon, yr as getIconForWidget, yt as ConfigControllerProvider, z as ArrayOfReferencesFieldBinding, zn as SidePanelControllerContext, zt as SearchIconsView } from "./util-WQP-ljKW.js";
2
- import { i as PropertySelectEntry, n as ImportCollectionAction, r as ImportDataPreview } from "./import-J5vb86xj.js";
3
- import { a as MAX_EXPORT_ROWS, c as downloadDataAsCsv, d as escapeCsvFormula, f as getEntityCSVExportableData, i as EXPORT_PAGE_SIZE, l as downloadEntitiesExport, n as ExportCollectionAction, o as fetchAllEntitiesForExport, p as getEntityJsonExportableData, r as BasicExportAction, s as downloadBlob, u as entryToCSVRow } from "./export-BDynF1En.js";
1
+ import { $ as getEntityViewWidth, $n as SkeletonPropertyComponent, $t as resolveCollectionPathIds, A as SelectFieldBinding, An as ArrayOfStringsPreview, At as saveImportedEntities, B as useSelectionDialog, Bn as useSidePanel, Bt as FieldCaption, C as getDefaultFieldId, Cn as UserPreview, Cr as isReferenceProperty, Ct as convertDataToEntity, D as TextFieldBinding, Dn as KeyValuePreview, Dt as useImportConfig, E as VectorFieldBinding, En as DatePreview, Et as getInferenceType, F as MapFieldBinding, Fn as ArrayOfReferencesPreview, Ft as parseCsvToObjects, G as useTopLevelNavigation, Gn as getEntityPreviewKeys, Gt as mergeEntityActions, H as SideDialogs, Hn as useCollectionRegistryController, Ht as BreadcrumbsProvider, I as KeyValueFieldBinding, In as InlineEntityListPreview, It as unflattenObject, J as useBuildCollectionRegistryController, Jn as ArrayPropertyPreview, Jt as getCollectionPathsCombinations, K as useResolvedViews, Kn as getEntityTitlePropertyKey, Kt as addInitialSlash, L as DateTimeFieldBinding, Ln as ReferencePreview, Lt as ArrayContainer, M as ReferenceFieldBinding, Mn as ArrayEnumPreview, Mt as convertFileToJson, N as MultiSelectFieldBinding, Nn as ArrayOfStorageComponentsPreview, Nt as detectCsvDelimiter, O as SwitchFieldBinding, On as MapPropertyPreview, Ot as ImportSaveInProgress, P as MarkdownEditorFieldBinding, Pn as RelationPreview, Pt as parseCsvRows, Q as buildSidePanelsFromUrl, Qn as StorageThumbnailInternal, Qt as removeTrailingSlash, R as BlockFieldBinding, Rn as EntityPreviewBinding, Rt as PropertyConfigBadge, S as getDefaultFieldConfig, Sn as PropertyPreview, Sr as getResolvedPropertyInPath, St as DataNewPropertiesMapping, T as getFieldId, Tn as BooleanPreview, Tt as processValueMapping, U as useBuildUrlController, Un as getUserLabel, Ut as resolveEntityAction, V as SelectionTableBinding, Vn as CollectionRegistryContext, Vt as useBreadcrumbsController, W as useBuildNavigationStateController, Wn as useResolvedUser, Wt as resolveEntityView, X as resolveNavigationFrom, Xn as EnumValuesChip, Xt as removeInitialAndTrailingSlashes, Y as useHistory, Yn as StringPropertyPreview, Yt as getLastSegment, Z as useResolvedNavigationFrom, Zn as StorageThumbnail, Zt as removeInitialSlash, _ as useCollectionsConfigController, _n as ReadOnlyFieldBinding, _r as getDefaultPropertiesOrder, _t as CollectionViewActions, a as namespaceToPropertiesPath, an as SelectableTable, ar as ImagePreview, at as removeEmptyContainers, b as PropertyFieldBinding, bn as FieldHelperText, br as getPropertiesWithPropertiesOrder, bt as useCollectionEditorDialogsState, c as buildCollectionGenerationCallback, cn as UrlContext, cr as FormSections, ct as copyEntityAction, d as fromSerializableCollectionConfigs, dn as useNavigationStateController, dr as FieldBlock, dt as resetPasswordAction, en as resolveOpenEntityMode, er as renderSkeletonCaptionText, et as useBuildSidePanel, f as fromSerializableProperties, fn as useSideDialogsController, fr as LABEL_ICON_SIZE, ft as CreationResultDialog, g as toSerializableProperty, gn as useClearRestoreValue, gr as getBracketNotation, gt as EntityCardBinding, h as toSerializableProperties, hn as ArrayCustomShapedFieldBinding, hr as PropertyIdCopyTooltip, ht as CollectionCardViewBinding, i as namespaceToPropertiesOrderPath, in as CollectionTableBinding, ir as UrlComponentPreview, it as getInitialEntityValues, j as RepeatFieldBinding, jn as ArrayPropertyEnumPreview, jt as ImportFileUpload, k as StorageUploadFieldBinding, kn as ArrayOneOfPreview, kt as IMPORT_BATCH_SIZE, l as validateCollectionJson, ln as useUrlController, lr as FormRail, lt as deleteEntityAction, m as toSerializableCollectionConfig, mn as SelectableTableContext, mr as spanClass, mt as EntityViewBinding, n as getFullIdPath, nn as useSelectionController, nr as renderSkeletonImageThumbnail, nt as extractTouchedValues, o as CollectionGenerationApiError, on as CollectionRowActions, or as sanitizeUrl, ot as zodToFormErrors, p as fromSerializableProperty, pn as SideDialogsControllerContext, pr as isSelfLabellingProperty, pt as DetailViewBinding, q as useResolvedCollections, qn as getEntityTitlePropertyKeyForEntity, qt as getCollectionBySlugWithin, r as idToPropertiesPath, rn as VirtualTableInput, rr as renderSkeletonText, rt as getChanges, s as DEFAULT_COLLECTION_GENERATION_ENDPOINT, sn as useAdminContext, sr as EmptyValue, st as CollectionViewBinding, t as getFullId, tn as resolveViewMode, tr as renderSkeletonIcon, tt as EditViewBinding, u as fromSerializableCollectionConfig, un as NavigationStateContext, ur as RecordMeta, ut as editEntityAction, v as EntityFormBinding, vn as LabelWithIconAndTooltip, vr as getIconForProperty, vt as useCollectionEditorController, w as getFieldConfig, wn as NumberPropertyPreview, wr as isRelationProperty, wt as flattenEntry, x as DEFAULT_FIELD_CONFIGS, xn as ArrayOfMapsPreview, xr as getPropertyInPath, xt as ImportNewPropertyFieldPreview, y as EntityForm, yn as LabelWithIcon, yr as getIconForWidget, yt as ConfigControllerProvider, z as ArrayOfReferencesFieldBinding, zn as SidePanelControllerContext, zt as SearchIconsView } from "./util-bL-fk6C6.js";
2
+ import { i as PropertySelectEntry, n as ImportCollectionAction, r as ImportDataPreview } from "./import-BujhycMq.js";
3
+ import { a as MAX_EXPORT_ROWS, c as downloadDataAsCsv, d as escapeCsvFormula, f as getEntityCSVExportableData, i as EXPORT_PAGE_SIZE, l as downloadEntitiesExport, n as ExportCollectionAction, o as fetchAllEntitiesForExport, p as getEntityJsonExportableData, r as BasicExportAction, s as downloadBlob, u as entryToCSVRow } from "./export-KEf57Jso.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, CenteredView, 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";
@@ -1663,7 +1663,7 @@ function useLocalCollectionsConfigController(clientOrUrl, baseCollections = [],
1663
1663
  //#region src/components/RebaseNavigation.tsx
1664
1664
  var EMPTY_PLUGINS = [];
1665
1665
  var EMPTY_COLLECTIONS = [];
1666
- var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-CfTHbBCA.js").then((n) => n.n).then((m) => ({ default: m.RouterCollectionsStudioView })));
1666
+ var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-sfsUpEJz.js").then((n) => n.n).then((m) => ({ default: m.RouterCollectionsStudioView })));
1667
1667
  /**
1668
1668
  * Navigation layer — builds and provides all admin navigation controllers:
1669
1669
  * collection registry, URL controller, navigation state, side entity,
@@ -2892,8 +2892,8 @@ function ContentHomePage({ additionalActions, additionalChildrenStart, additiona
2892
2892
  }
2893
2893
  //#endregion
2894
2894
  //#region src/components/CollectionEditorDialogs.tsx
2895
- var CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-BykOIZH4.js").then((n) => n.r).then((m) => ({ default: m.CollectionEditorDialog })));
2896
- var PropertyFormDialog = lazy(() => import("./PropertyEditView-C9Der_Ej.js").then((n) => n.t).then((m) => ({ default: m.PropertyFormDialog })));
2895
+ var CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-BeS4lxGh.js").then((n) => n.r).then((m) => ({ default: m.CollectionEditorDialog })));
2896
+ var PropertyFormDialog = lazy(() => import("./PropertyEditView-BFJ6H9-Q.js").then((n) => n.t).then((m) => ({ default: m.PropertyFormDialog })));
2897
2897
  /**
2898
2898
  * Renders the CollectionEditorDialog and PropertyFormDialog inside
2899
2899
  * the RebaseShell tree where admin-internal contexts
@@ -9318,8 +9318,8 @@ function EditorCollectionAction({ path, parentCollectionSlugs, parentEntityIds,
9318
9318
  }
9319
9319
  //#endregion
9320
9320
  //#region src/components/CollectionViewBinding/CollectionViewActions.tsx
9321
- var ImportCollectionAction = lazy(() => import("./import-J5vb86xj.js").then((n) => n.t).then((m) => ({ default: m.ImportCollectionAction })));
9322
- var ExportCollectionAction = lazy(() => import("./export-BDynF1En.js").then((n) => n.t).then((m) => ({ default: m.ExportCollectionAction })));
9321
+ var ImportCollectionAction = lazy(() => import("./import-BujhycMq.js").then((n) => n.t).then((m) => ({ default: m.ImportCollectionAction })));
9322
+ var ExportCollectionAction = lazy(() => import("./export-KEf57Jso.js").then((n) => n.t).then((m) => ({ default: m.ExportCollectionAction })));
9323
9323
  function CollectionViewActions({ collection, relativePath, parentCollectionSlugs, parentEntityIds, onNewClick, onAddExistingClick, onMultipleDeleteClick, selectionEnabled, path, selectionController, tableController, collectionEntitiesCount, compact, children, openNewDocument }) {
9324
9324
  const context = useAdminContext();
9325
9325
  const { canCreate, canDelete } = usePermissions();
@@ -10983,6 +10983,7 @@ function ListHeader({ titleColumn, columns, selectionEnabled, showImage, actions
10983
10983
  * answer to "how is this sorted".
10984
10984
  */
10985
10985
  function ListHeaderLabel({ column, direction, position, onSort }) {
10986
+ const { t } = useTranslation();
10986
10987
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
10987
10988
  /* @__PURE__ */ jsx("span", {
10988
10989
  className: "truncate",
@@ -11007,9 +11008,13 @@ function ListHeaderLabel({ column, direction, position, onSort }) {
11007
11008
  className: cls(base, tone),
11008
11009
  children: content
11009
11010
  });
11011
+ const nextAction = direction === "asc" ? t("sort_descending") : direction === "desc" ? t("sort_remove") : t("sort_ascending");
11012
+ const rank = direction && position !== void 0 ? ` (${t("sort_key_position", { position: position + 1 })})` : "";
11013
+ const label = `${column.label}${rank} — ${nextAction}. ${t("sort_shift_click_hint")}`;
11010
11014
  return /* @__PURE__ */ jsx("button", {
11011
11015
  type: "button",
11012
- title: `Sort by ${column.label} — shift-click to add it under the current sort`,
11016
+ title: label,
11017
+ "aria-label": label,
11013
11018
  onClick: (event) => onSort(event.shiftKey),
11014
11019
  className: cls(base, tone, "cursor-pointer hover:text-surface-700 dark:hover:text-surface-200 transition-colors"),
11015
11020
  children: content
@@ -11668,7 +11673,7 @@ function JsonPreviewBinding({ values }) {
11668
11673
  }
11669
11674
  //#endregion
11670
11675
  //#region src/components/EntityInspector.tsx
11671
- var EntityHistoryView = lazy(() => import("./history-DS2iXiGi.js").then((m) => ({ default: m.EntityHistoryView })));
11676
+ var EntityHistoryView = lazy(() => import("./history-Ctd2cRn_.js").then((m) => ({ default: m.EntityHistoryView })));
11672
11677
  /**
11673
11678
  * Raw values and revision history, as an inspector rather than as tabs.
11674
11679
  *
@@ -11978,7 +11983,7 @@ function DetailViewBindingInner({ path, entityId, selectedTab: selectedTabProp,
11978
11983
  className: "flex items-center justify-center w-full h-full p-3",
11979
11984
  children: /* @__PURE__ */ jsx(Typography, {
11980
11985
  variant: "label",
11981
- children: t("save_entity_before_subcollections") ?? "You need to save your entity before adding additional collections"
11986
+ children: t("save_entity_before_subcollections")
11982
11987
  })
11983
11988
  }))]
11984
11989
  }, `subcol_${subcollectionId}`);
@@ -15238,6 +15243,8 @@ function SortButton({ tableController, properties, compact }) {
15238
15243
  const removeKey = useCallback((key) => {
15239
15244
  applySort(keys.filter(([existing]) => existing !== key));
15240
15245
  }, [applySort, keys]);
15246
+ /** What a click on an active key will do to it, for the tooltip and the label. */
15247
+ const flipLabel = useCallback((direction) => direction === "asc" ? t("sort_descending") : t("sort_ascending"), [t]);
15241
15248
  /** Swap a key with its neighbour, which is what changes which one decides. */
15242
15249
  const moveKey = useCallback((position, delta) => {
15243
15250
  const target = position + delta;
@@ -15248,15 +15255,15 @@ function SortButton({ tableController, properties, compact }) {
15248
15255
  }, [applySort, keys]);
15249
15256
  if (!setSortBy || options.length === 0) return null;
15250
15257
  const primary = keys[0];
15251
- const primaryOption = primary ? options.find((option) => option.key === primary[0]) : void 0;
15252
- const label = primaryOption ? keys.length > 1 ? `${t("sort_by")}: ${primaryOption.title} +${keys.length - 1}` : `${t("sort_by")}: ${primaryOption.title}` : t("sort");
15258
+ const primaryTitle = primary ? options.find((option) => option.key === primary[0])?.title ?? primary[0] : void 0;
15259
+ const label = primaryTitle ? keys.length > 1 ? `${t("sort_by")}: ${primaryTitle} +${keys.length - 1}` : `${t("sort_by")}: ${primaryTitle}` : t("sort");
15253
15260
  const arrowSize = compact ? iconSize.smallest : iconSize.small;
15254
15261
  const primaryDirection = primary?.[1];
15255
15262
  const trigger = /* @__PURE__ */ jsx(IconButton, {
15256
15263
  size: "small",
15257
15264
  "aria-label": label,
15258
15265
  title: label,
15259
- className: cls(primaryOption && "text-primary"),
15266
+ className: cls(primaryTitle && "text-primary"),
15260
15267
  children: primaryDirection === "desc" ? /* @__PURE__ */ jsx(ArrowDownIcon, { size: arrowSize }) : primaryDirection === "asc" ? /* @__PURE__ */ jsx(ArrowUpIcon, { size: arrowSize }) : /* @__PURE__ */ jsx(ArrowUpDownIcon, { size: arrowSize })
15261
15268
  });
15262
15269
  const inactiveOptions = options.filter((option) => !activeIndex.has(option.key));
@@ -15277,7 +15284,7 @@ function SortButton({ tableController, properties, compact }) {
15277
15284
  children: t("sort_by")
15278
15285
  }),
15279
15286
  keys.length > 0 && /* @__PURE__ */ jsx("div", {
15280
- className: "flex flex-col",
15287
+ className: "flex flex-col max-h-[200px] overflow-y-auto",
15281
15288
  children: keys.map(([key, direction], position) => {
15282
15289
  const option = options.find((o) => o.key === key);
15283
15290
  return /* @__PURE__ */ jsxs("div", {
@@ -15290,7 +15297,8 @@ function SortButton({ tableController, properties, compact }) {
15290
15297
  /* @__PURE__ */ jsxs("button", {
15291
15298
  type: "button",
15292
15299
  onClick: () => onOptionClick(key),
15293
- title: direction === "asc" ? t("sort_descending") : t("sort_ascending"),
15300
+ title: flipLabel(direction),
15301
+ "aria-label": `${option?.title ?? key} — ${t("sort_key_position", { position: position + 1 })}. ${flipLabel(direction)}`,
15294
15302
  className: "flex items-center gap-2 flex-grow min-w-0 text-left cursor-pointer",
15295
15303
  children: [
15296
15304
  option && /* @__PURE__ */ jsx("span", {
@@ -15307,37 +15315,39 @@ function SortButton({ tableController, properties, compact }) {
15307
15315
  })
15308
15316
  ]
15309
15317
  }),
15310
- keys.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(IconButton, {
15311
- size: "smallest",
15312
- "aria-label": t("sort_move_up"),
15313
- title: t("sort_move_up"),
15314
- disabled: position === 0,
15315
- onClick: () => moveKey(position, -1),
15316
- children: /* @__PURE__ */ jsx(ChevronUpIcon, { size: iconSize.smallest })
15317
- }), /* @__PURE__ */ jsx(IconButton, {
15318
- size: "smallest",
15319
- "aria-label": t("sort_move_down"),
15320
- title: t("sort_move_down"),
15321
- disabled: position === keys.length - 1,
15322
- onClick: () => moveKey(position, 1),
15323
- children: /* @__PURE__ */ jsx(ChevronDownIcon, { size: iconSize.smallest })
15324
- })] }),
15325
- /* @__PURE__ */ jsx(IconButton, {
15326
- size: "smallest",
15327
- "aria-label": t("sort_remove_key"),
15328
- title: t("sort_remove_key"),
15329
- onClick: () => removeKey(key),
15330
- children: /* @__PURE__ */ jsx(XIcon, { size: iconSize.smallest })
15318
+ /* @__PURE__ */ jsxs("div", {
15319
+ className: cls("flex-shrink-0 flex items-center gap-0.5 ml-1 pl-1 border-l", defaultBorderMixin),
15320
+ children: [keys.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(IconButton, {
15321
+ size: "smallest",
15322
+ "aria-label": t("sort_move_up"),
15323
+ title: t("sort_move_up"),
15324
+ disabled: position === 0,
15325
+ onClick: () => moveKey(position, -1),
15326
+ children: /* @__PURE__ */ jsx(ChevronUpIcon, { size: iconSize.smallest })
15327
+ }), /* @__PURE__ */ jsx(IconButton, {
15328
+ size: "smallest",
15329
+ "aria-label": t("sort_move_down"),
15330
+ title: t("sort_move_down"),
15331
+ disabled: position === keys.length - 1,
15332
+ onClick: () => moveKey(position, 1),
15333
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, { size: iconSize.smallest })
15334
+ })] }), /* @__PURE__ */ jsx(IconButton, {
15335
+ size: "smallest",
15336
+ "aria-label": t("sort_remove_key"),
15337
+ title: t("sort_remove_key"),
15338
+ onClick: () => removeKey(key),
15339
+ children: /* @__PURE__ */ jsx(XIcon, { size: iconSize.smallest })
15340
+ })]
15331
15341
  })
15332
15342
  ]
15333
15343
  }, key);
15334
15344
  })
15335
15345
  }),
15336
- inactiveOptions.length > 0 && /* @__PURE__ */ jsx(Typography, {
15346
+ keys.length > 0 && inactiveOptions.length > 0 && /* @__PURE__ */ jsx(Typography, {
15337
15347
  variant: "caption",
15338
15348
  color: "secondary",
15339
15349
  className: "font-medium uppercase tracking-wider px-3 pt-2 pb-1",
15340
- children: keys.length > 0 ? t("sort_then_by") : ""
15350
+ children: t("sort_then_by")
15341
15351
  }),
15342
15352
  /* @__PURE__ */ jsx("div", {
15343
15353
  className: "max-h-[280px] overflow-y-auto flex flex-col",
@@ -15345,8 +15355,7 @@ function SortButton({ tableController, properties, compact }) {
15345
15355
  const disabled = checkFilterCombination ? !checkFilterCombination(filterValues ?? {}, [...keys, [key, "asc"]]) : false;
15346
15356
  return /* @__PURE__ */ jsxs("button", {
15347
15357
  type: "button",
15348
- role: "menuitemradio",
15349
- "aria-checked": false,
15358
+ "aria-label": keys.length > 0 ? `${t("sort_then_by")} ${title}` : `${t("sort_by")} ${title}`,
15350
15359
  disabled,
15351
15360
  onClick: () => onOptionClick(key),
15352
15361
  className: cls("flex items-center gap-2 px-3 py-1.5 text-sm text-left w-full", disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-surface-accent-100 dark:hover:bg-surface-accent-900"),
@@ -15438,7 +15447,7 @@ function CollectionViewStartActions({ collection, relativePath, parentCollection
15438
15447
  })
15439
15448
  })
15440
15449
  }, "filters_tooltip");
15441
- const sortButton = resolvedProperties && (viewMode === "list" || viewMode === "cards") && /* @__PURE__ */ jsx(SortButton, {
15450
+ const sortButton = resolvedProperties && viewMode !== "kanban" && /* @__PURE__ */ jsx(SortButton, {
15442
15451
  tableController,
15443
15452
  properties: resolvedProperties,
15444
15453
  compact: iconOnlyToolbar
@@ -24557,4 +24566,4 @@ function getFullIdPath(propertyKey, propertyNamespace) {
24557
24566
  //#endregion
24558
24567
  export { getEntityViewWidth as $, SkeletonPropertyComponent as $n, resolveCollectionPathIds$1 as $t, SelectFieldBinding as A, ArrayOfStringsPreview as An, saveImportedEntities as At, useSelectionDialog as B, useSidePanel as Bn, FieldCaption as Bt, getDefaultFieldId as C, UserPreview as Cn, isReferenceProperty as Cr, convertDataToEntity as Ct, TextFieldBinding as D, KeyValuePreview as Dn, useImportConfig as Dt, VectorFieldBinding as E, DatePreview as En, getInferenceType as Et, MapFieldBinding as F, ArrayOfReferencesPreview as Fn, parseCsvToObjects as Ft, useTopLevelNavigation as G, getEntityPreviewKeys as Gn, mergeEntityActions as Gt, SideDialogs as H, useCollectionRegistryController as Hn, BreadcrumbsProvider as Ht, KeyValueFieldBinding as I, InlineEntityListPreview as In, unflattenObject as It, useBuildCollectionRegistryController as J, ArrayPropertyPreview as Jn, getCollectionPathsCombinations as Jt, useResolvedViews as K, getEntityTitlePropertyKey as Kn, addInitialSlash as Kt, DateTimeFieldBinding as L, ReferencePreview as Ln, ArrayContainer as Lt, ReferenceFieldBinding as M, ArrayEnumPreview as Mn, convertFileToJson as Mt, MultiSelectFieldBinding as N, ArrayOfStorageComponentsPreview as Nn, detectCsvDelimiter as Nt, SwitchFieldBinding as O, MapPropertyPreview as On, ImportSaveInProgress as Ot, MarkdownEditorFieldBinding as P, RelationPreview as Pn, parseCsvRows as Pt, buildSidePanelsFromUrl as Q, StorageThumbnailInternal as Qn, removeTrailingSlash$1 as Qt, BlockFieldBinding as R, EntityPreviewBinding as Rn, PropertyConfigBadge as Rt, getDefaultFieldConfig as S, PropertyPreview as Sn, getResolvedPropertyInPath as Sr, DataNewPropertiesMapping as St, getFieldId as T, BooleanPreview as Tn, processValueMapping as Tt, useBuildUrlController as U, getUserLabel as Un, resolveEntityAction as Ut, SelectionTableBinding as V, CollectionRegistryContext as Vn, useBreadcrumbsController as Vt, useBuildNavigationStateController as W, useResolvedUser as Wn, resolveEntityView as Wt, resolveNavigationFrom as X, EnumValuesChip as Xn, removeInitialAndTrailingSlashes$1 as Xt, useHistory as Y, StringPropertyPreview as Yn, getLastSegment$1 as Yt, useResolvedNavigationFrom as Z, StorageThumbnail as Zn, removeInitialSlash as Zt, useCollectionsConfigController as _, ReadOnlyFieldBinding as _n, getDefaultPropertiesOrder as _r, CollectionViewActions as _t, namespaceToPropertiesPath as a, SelectableTable as an, ImagePreview as ar, removeEmptyContainers as at, PropertyFieldBinding as b, FieldHelperText as bn, getPropertiesWithPropertiesOrder as br, useCollectionEditorDialogsState as bt, buildCollectionGenerationCallback as c, UrlContext as cn, FormSections as cr, copyEntityAction as ct, fromSerializableCollectionConfigs as d, useNavigationStateController as dn, FieldBlock as dr, resetPasswordAction as dt, resolveOpenEntityMode as en, renderSkeletonCaptionText as er, useBuildSidePanel as et, fromSerializableProperties as f, useSideDialogsController as fn, LABEL_ICON_SIZE as fr, CreationResultDialog as ft, toSerializableProperty as g, useClearRestoreValue as gn, getBracketNotation as gr, EntityCardBinding as gt, toSerializableProperties as h, ArrayCustomShapedFieldBinding as hn, PropertyIdCopyTooltip as hr, CollectionCardViewBinding as ht, namespaceToPropertiesOrderPath as i, CollectionTableBinding as in, UrlComponentPreview as ir, getInitialEntityValues as it, RepeatFieldBinding as j, ArrayPropertyEnumPreview as jn, ImportFileUpload as jt, StorageUploadFieldBinding as k, ArrayOneOfPreview as kn, IMPORT_BATCH_SIZE as kt, validateCollectionJson as l, useUrlController as ln, FormRail as lr, deleteEntityAction as lt, toSerializableCollectionConfig as m, SelectableTableContext as mn, spanClass as mr, EntityViewBinding as mt, getFullIdPath as n, useSelectionController as nn, renderSkeletonImageThumbnail as nr, extractTouchedValues as nt, CollectionGenerationApiError as o, CollectionRowActions as on, sanitizeUrl as or, zodToFormErrors as ot, fromSerializableProperty as p, SideDialogsControllerContext as pn, isSelfLabellingProperty as pr, DetailViewBinding as pt, useResolvedCollections as q, getEntityTitlePropertyKeyForEntity as qn, getCollectionBySlugWithin as qt, idToPropertiesPath as r, VirtualTableInput$1 as rn, renderSkeletonText as rr, getChanges as rt, DEFAULT_COLLECTION_GENERATION_ENDPOINT as s, useAdminContext as sn, EmptyValue as sr, CollectionViewBinding as st, getFullId as t, resolveViewMode as tn, renderSkeletonIcon as tr, EditViewBinding as tt, fromSerializableCollectionConfig as u, NavigationStateContext as un, RecordMeta as ur, editEntityAction as ut, EntityFormBinding as v, LabelWithIconAndTooltip as vn, getIconForProperty as vr, useCollectionEditorController as vt, getFieldConfig as w, NumberPropertyPreview as wn, isRelationProperty as wr, flattenEntry as wt, DEFAULT_FIELD_CONFIGS as x, ArrayOfMapsPreview as xn, getPropertyInPath$1 as xr, ImportNewPropertyFieldPreview as xt, EntityForm as y, LabelWithIcon as yn, getIconForWidget as yr, ConfigControllerProvider as yt, ArrayOfReferencesFieldBinding as z, SidePanelControllerContext as zn, SearchIconsView as zt };
24559
24568
 
24560
- //# sourceMappingURL=util-WQP-ljKW.js.map
24569
+ //# sourceMappingURL=util-bL-fk6C6.js.map