@rebasepro/admin 0.13.0 → 0.13.1-canary.g3660bd5
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.
- package/dist/{CollectionEditorDialog-CjXkWZ64.js → CollectionEditorDialog-MODRemil.js} +3 -3
- package/dist/{CollectionEditorDialog-CjXkWZ64.js.map → CollectionEditorDialog-MODRemil.js.map} +1 -1
- package/dist/{PropertyEditView-W8I3YV89.js → PropertyEditView-Bt-VM0zQ.js} +2 -2
- package/dist/{PropertyEditView-W8I3YV89.js.map → PropertyEditView-Bt-VM0zQ.js.map} +1 -1
- package/dist/{RouterCollectionsStudioView-BsLTNoqX.js → RouterCollectionsStudioView-D54P9o8O.js} +4 -4
- package/dist/{RouterCollectionsStudioView-BsLTNoqX.js.map → RouterCollectionsStudioView-D54P9o8O.js.map} +1 -1
- package/dist/collection_editor_ui.js +4 -4
- package/dist/components/AdditionalFieldValue.d.ts +25 -0
- package/dist/components/CollectionViewBinding/CollectionViewBinding.d.ts +16 -0
- package/dist/components/CollectionViewBinding/SlotValue.d.ts +37 -0
- package/dist/components/CollectionViewBinding/SplitListCloseButton.d.ts +5 -3
- package/dist/components/CollectionViewBinding/SplitListShowButton.d.ts +12 -0
- package/dist/components/CollectionViewBinding/usePreviewSlots.d.ts +29 -4
- package/dist/components/DetailViewBinding.d.ts +6 -0
- package/dist/components/DrawerNavigationGroup.d.ts +5 -4
- package/dist/components/DrawerNavigationItem.d.ts +4 -2
- package/dist/components/EditViewBinding.d.ts +7 -1
- package/dist/components/EntityDisplayHeader.d.ts +53 -0
- package/dist/components/EntityIdentityBar.d.ts +20 -1
- package/dist/components/EntityViewBinding.d.ts +60 -6
- package/dist/components/RebaseLayout.d.ts +1 -1
- package/dist/components/RebaseShell.d.ts +1 -1
- package/dist/components/app/Scaffold.d.ts +9 -3
- package/dist/components/index.d.ts +2 -0
- package/dist/{export-J79rMoNj.js → export-Bl1V7lKO.js} +2 -2
- package/dist/{export-J79rMoNj.js.map → export-Bl1V7lKO.js.map} +1 -1
- package/dist/form/components/FieldBlock.d.ts +47 -4
- package/dist/form/components/FormRail.d.ts +13 -0
- package/dist/form/components/FormSections.d.ts +15 -1
- package/dist/form/components/useRailVisible.d.ts +5 -4
- package/dist/{history-D7L_JlLO.js → history-DN_dzFAF.js} +4 -4
- package/dist/{history-D7L_JlLO.js.map → history-DN_dzFAF.js.map} +1 -1
- package/dist/hooks/useEntityDisplay.d.ts +102 -0
- package/dist/hooks/useEntityDisplayTitle.d.ts +18 -9
- package/dist/{import-BvYl--U4.js → import-BJXrHdFv.js} +3 -3
- package/dist/{import-BvYl--U4.js.map → import-BJXrHdFv.js.map} +1 -1
- package/dist/index.js +149 -51
- package/dist/index.js.map +1 -1
- package/dist/preview/compact_text.d.ts +23 -0
- package/dist/preview/components/BooleanPreview.d.ts +3 -1
- package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +1 -1
- package/dist/preview/property_previews/ArrayOneOfPreview.d.ts +1 -1
- package/dist/preview/property_previews/ArrayPropertyPreview.d.ts +1 -1
- package/dist/preview/property_previews/MapPropertyPreview.d.ts +1 -1
- package/dist/preview/property_previews/StringPropertyPreview.d.ts +1 -1
- package/dist/routes/RebaseRoute.d.ts +1 -1
- package/dist/types/components/PropertyPreviewProps.d.ts +19 -0
- package/dist/util/number_format.d.ts +14 -0
- package/dist/util/previews.d.ts +9 -2
- package/dist/{util-GiwPgxnL.js → util-EXfeGzbH.js} +8142 -7353
- package/dist/util-EXfeGzbH.js.map +1 -0
- package/package.json +9 -9
- package/src/components/AdditionalFieldValue.tsx +68 -0
- package/src/components/CollectionTableBinding/CollectionTableBinding.tsx +5 -6
- package/src/components/CollectionViewBinding/BoardCardBinding.tsx +9 -27
- package/src/components/CollectionViewBinding/CollectionListViewBinding.tsx +11 -24
- package/src/components/CollectionViewBinding/CollectionViewBinding.tsx +26 -6
- package/src/components/CollectionViewBinding/EntityCardBinding.tsx +10 -33
- package/src/components/CollectionViewBinding/SlotValue.tsx +60 -0
- package/src/components/CollectionViewBinding/SplitListCloseButton.tsx +7 -5
- package/src/components/CollectionViewBinding/SplitListShowButton.tsx +28 -0
- package/src/components/CollectionViewBinding/SplitListView.tsx +14 -1
- package/src/components/CollectionViewBinding/useBoardDataController.tsx +12 -3
- package/src/components/CollectionViewBinding/usePreviewSlots.ts +115 -48
- package/src/components/DefaultDrawer.tsx +19 -23
- package/src/components/DetailViewBinding.tsx +74 -54
- package/src/components/DrawerNavigationGroup.tsx +4 -7
- package/src/components/DrawerNavigationItem.tsx +23 -4
- package/src/components/EditViewBinding.tsx +54 -33
- package/src/components/EntityDisplayHeader.tsx +170 -0
- package/src/components/EntityIdentityBar.tsx +49 -5
- package/src/components/EntityPreviewBinding.tsx +54 -17
- package/src/components/EntityViewBinding.tsx +341 -41
- package/src/components/InlineEntityPreview.tsx +10 -10
- package/src/components/RebaseLayout.tsx +2 -2
- package/src/components/RebaseShell.tsx +2 -2
- package/src/components/app/Scaffold.tsx +112 -10
- package/src/components/index.ts +3 -0
- package/src/form/EntityForm.tsx +28 -33
- package/src/form/components/FieldBlock.tsx +65 -8
- package/src/form/components/FormRail.tsx +19 -2
- package/src/form/components/FormSections.tsx +32 -5
- package/src/form/components/StorageUploadProgress.tsx +9 -3
- package/src/form/components/useRailVisible.tsx +5 -4
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +7 -1
- package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +29 -5
- package/src/hooks/useEntityDisplay.tsx +262 -0
- package/src/hooks/useEntityDisplayTitle.tsx +27 -38
- package/src/preview/PropertyPreview.tsx +18 -2
- package/src/preview/compact_text.ts +68 -0
- package/src/preview/components/BooleanPreview.tsx +5 -2
- package/src/preview/components/StorageThumbnail.tsx +5 -2
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +26 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +10 -1
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +10 -1
- package/src/preview/property_previews/MapPropertyPreview.tsx +52 -1
- package/src/preview/property_previews/NumberPropertyPreview.tsx +9 -1
- package/src/preview/property_previews/StringPropertyPreview.tsx +8 -5
- package/src/routes/RebaseRoute.tsx +62 -4
- package/src/types/components/PropertyPreviewProps.tsx +21 -0
- package/src/util/number_format.ts +46 -0
- package/src/util/previews.ts +8 -55
- package/dist/util-GiwPgxnL.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { $t as CollectionTableBinding, Ct as convertDataToEntity, Dt as useImportConfig, Et as getInferenceType,
|
|
2
|
+
import { $t as CollectionTableBinding, Ct as convertDataToEntity, Dt as useImportConfig, Et as getInferenceType, Fn as useCollectionRegistryController, Nt as PropertyConfigBadge, Ot as ImportSaveInProgress, St as DataNewPropertiesMapping, Zt as useSelectionController, gr as getPropertyInPath$1, hr as getPropertiesWithPropertiesOrder, k as getFieldConfig, kt as ImportFileUpload } from "./util-EXfeGzbH.js";
|
|
3
3
|
import React, { useCallback, useEffect } from "react";
|
|
4
4
|
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, Select, SelectItem, Tooltip, Typography, UploadIcon, cls, defaultBorderMixin, iconSize } from "@rebasepro/ui";
|
|
5
5
|
import { useAuthController, useCustomizationController, useSnackbarController } from "@rebasepro/app";
|
|
@@ -155,7 +155,7 @@ function ImportCollectionAction({ collection, path, onAnalyticsEvent }) {
|
|
|
155
155
|
}
|
|
156
156
|
var internalIDValue = "__internal_id__";
|
|
157
157
|
function PropertyTreeSelect({ selectedPropertyKey, properties, onPropertySelected, onIdSelected, propertiesAndLevel, isIdColumn }) {
|
|
158
|
-
const selectedProperty = selectedPropertyKey ? getPropertyInPath(properties, selectedPropertyKey) : null;
|
|
158
|
+
const selectedProperty = selectedPropertyKey ? getPropertyInPath$1(properties, selectedPropertyKey) : null;
|
|
159
159
|
const renderValue = useCallback((selectedPropertyKey) => {
|
|
160
160
|
if (selectedPropertyKey === internalIDValue) return /* @__PURE__ */ jsx(Typography, {
|
|
161
161
|
variant: "body2",
|
|
@@ -325,4 +325,4 @@ var import_exports = /* @__PURE__ */ __exportAll({
|
|
|
325
325
|
//#endregion
|
|
326
326
|
export { PropertySelectEntry as i, ImportCollectionAction as n, ImportDataPreview as r, import_exports as t };
|
|
327
327
|
|
|
328
|
-
//# sourceMappingURL=import-
|
|
328
|
+
//# sourceMappingURL=import-BJXrHdFv.js.map
|
|
@@ -1 +1 @@
|
|
|
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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"}
|
|
1
|
+
{"version":3,"file":"import-BJXrHdFv.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,9 +1,9 @@
|
|
|
1
|
-
import { $ as useBuildCollectionRegistryController, $n as sanitizeUrl, $t as CollectionTableBinding, A as getFieldId, An as
|
|
2
|
-
import { i as PropertySelectEntry, n as ImportCollectionAction, r as ImportDataPreview } from "./import-
|
|
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-
|
|
1
|
+
import { $ as useBuildCollectionRegistryController, $n as sanitizeUrl, $t as CollectionTableBinding, A as getFieldId, An as ReferencePreview, At as convertFileToJson, B as MapFieldBinding, Bn as getEntityTitlePropertyKeyForEntity, Bt as mergeEntityActions, C as removeEmptyContainers, Cn as ArrayOfStringsPreview, Ct as convertDataToEntity, D as getDefaultFieldConfig, Dn as RelationPreview, Dt as useImportConfig, E as DEFAULT_FIELD_CONFIGS, En as ArrayOfStorageComponentsPreview, Et as getInferenceType, F as SelectFieldBinding, Fn as useCollectionRegistryController, 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 getUserLabel, 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 useResolvedUser, Lt as BreadcrumbsProvider, M as TextFieldBinding, Mn as SidePanelControllerContext, Mt as ArrayContainer, N as SwitchFieldBinding, Nn as useSidePanel, Nt as PropertyConfigBadge, O as getDefaultFieldId, On as ArrayOfReferencesPreview, Ot as ImportSaveInProgress, P as StorageUploadFieldBinding, Pn as CollectionRegistryContext, 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 ArrayOneOfPreview, St as DataNewPropertiesMapping, T as PropertyFieldBinding, Tn as ArrayEnumPreview, 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 NumberPropertyPreview, _r as getResolvedPropertyInPath, _t as CollectionViewActions, a as namespaceToPropertiesPath, an as NavigationStateContext, ar as RecordMeta, at as useBuildSidePanel, b as extractTouchedValues, bn as KeyValuePreview, bt as useCollectionEditorDialogsState, c as buildCollectionGenerationCallback, cn as SideDialogsControllerContext, cr as isSelfLabellingProperty, ct as copyEntityAction, d as fromSerializableCollectionConfigs, dn as useClearRestoreValue, dr as getBracketNotation, dt as resetPasswordAction, en as SelectableTable, er as EmptyValue, et as useHistory, f as fromSerializableProperties, fn as ReadOnlyFieldBinding, fr as getDefaultPropertiesOrder, ft as CreationResultDialog, g as toSerializableProperty, gn as UserPreview, gr as getPropertyInPath, gt as EntityCardBinding, h as toSerializableProperties, hn as PropertyPreview, hr as getPropertiesWithPropertiesOrder, ht as CollectionCardViewBinding, i as namespaceToPropertiesOrderPath, in as useUrlController, ir as FormRail, it as getEntityViewWidth, j as VectorFieldBinding, jn as EntityPreviewBinding, jt as unflattenObject, k as getFieldConfig, kn as InlineEntityListPreview, kt as ImportFileUpload, l as validateCollectionJson, ln as SelectableTableContext, lr as spanClass, lt as deleteEntityAction, m as toSerializableCollectionConfig, mn as ArrayOfMapsPreview, mr as getIconForWidget, mt as EntityViewBinding, n as getFullIdPath, nn as useAdminContext, nr as LabelWithIcon, nt as useResolvedNavigationFrom, o as CollectionGenerationApiError, on as useNavigationStateController, or as FieldBlock, ot as EditViewBinding, p as fromSerializableProperty, pn as FieldHelperText, pr as getIconForProperty, 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 LABEL_ICON_SIZE, st as CollectionViewBinding, t as getFullId, tn as CollectionRowActions, tr as LabelWithIconAndTooltip, tt as resolveNavigationFrom, u as fromSerializableCollectionConfig, un as ArrayCustomShapedFieldBinding, ur as PropertyIdCopyTooltip, ut as editEntityAction, v as EntityFormBinding, vn as BooleanPreview, vr as isReferenceProperty, vt as useCollectionEditorController, w as zodToFormErrors, wn as ArrayPropertyEnumPreview, wt as flattenEntry, x as getChanges, xn as MapPropertyPreview, xt as ImportNewPropertyFieldPreview, y as EntityForm, yn as DatePreview, yr as isRelationProperty, yt as ConfigControllerProvider, z as MarkdownEditorFieldBinding, zn as getEntityTitlePropertyKey, zt as resolveEntityView } from "./util-EXfeGzbH.js";
|
|
2
|
+
import { i as PropertySelectEntry, n as ImportCollectionAction, r as ImportDataPreview } from "./import-BJXrHdFv.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-Bl1V7lKO.js";
|
|
4
4
|
import React, { Suspense, lazy, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { deepEqual } from "fast-equals";
|
|
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";
|
|
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";
|
|
7
7
|
import { buildRoutedRebaseData, getReferenceFrom, resolveDataSource } from "@rebasepro/common";
|
|
8
8
|
import { CollectionResolverRegistrationContext, CollectionScopeProvider, CustomizationControllerContext, DEFAULT_API_PATH, ErrorView, IconForView, LanguageToggle, LoginView, NavigationBlockerProvider, NotFoundPage, RebaseDataContext, RebaseLogo, RebaseRoutes, SchemaDriftBanner, StudioBridgeRegistryProvider, UIReferenceView, UnsavedChangesDialog, UserSettingsView, buildCollapsedDefaults, getIcon, getLastSegment as getLastSegment$1, getNavigationEntriesFromPath, useAdminModeController, useAnalyticsController, useAuthController, useBridgeRegistration, useBuildLocalConfigurationPersistence, useCollapsedGroups, useComponentOverride, useCustomizationController, useData, useDataSources, useLargeLayout, useModeController, useNavigationBlocker, useRebaseClient, useRebaseContext, useRebaseRegistry, useRebaseRegistryDispatch, useRestoreScroll, useSlot, useTranslation, useUserConfigurationPersistence } from "@rebasepro/app";
|
|
9
9
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -86,7 +86,7 @@ function RebaseRoute() {
|
|
|
86
86
|
if (!collection) collection = collectionRegistry.getCollection(navigationEntries[0].slug);
|
|
87
87
|
if (!collection) {
|
|
88
88
|
if (!collectionRegistry.initialised) return /* @__PURE__ */ jsx(CircularProgressCenter, {});
|
|
89
|
-
return
|
|
89
|
+
return /* @__PURE__ */ jsx(UnresolvedCollectionView, { path: navigationEntries[0].slug });
|
|
90
90
|
}
|
|
91
91
|
return /* @__PURE__ */ jsx(ResolvedCollectionView, {
|
|
92
92
|
...collection,
|
|
@@ -105,7 +105,7 @@ function RebaseRoute() {
|
|
|
105
105
|
if (!collection) collection = collectionRegistry.getCollection(firstEntry.slug);
|
|
106
106
|
if (!collection) {
|
|
107
107
|
if (!collectionRegistry.initialised) return /* @__PURE__ */ jsx(CircularProgressCenter, {});
|
|
108
|
-
return
|
|
108
|
+
return /* @__PURE__ */ jsx(UnresolvedCollectionView, { path: firstEntry.slug });
|
|
109
109
|
}
|
|
110
110
|
return /* @__PURE__ */ jsx(ResolvedCollectionView, {
|
|
111
111
|
...collection,
|
|
@@ -178,6 +178,7 @@ function EntityFullScreenRoute({ pathname, navigationEntries, isNew, isCopy }) {
|
|
|
178
178
|
const urlController = useUrlController();
|
|
179
179
|
const navigate = useNavigate();
|
|
180
180
|
const location = useLocation();
|
|
181
|
+
const userConfigPersistence = useUserConfigurationPersistence();
|
|
181
182
|
const defaultValues = location.state?.defaultValues;
|
|
182
183
|
const hash = location.hash;
|
|
183
184
|
const navigationPath = urlController.urlPathToDataPath(pathname);
|
|
@@ -225,12 +226,26 @@ function EntityFullScreenRoute({ pathname, navigationEntries, isNew, isCopy }) {
|
|
|
225
226
|
const fullIdPath = isNew ? lastCollectionEntry.slug : lastEntityEntry.slug;
|
|
226
227
|
const collectionPath = urlController.resolveDatabasePathsFrom(fullIdPath);
|
|
227
228
|
const isEditRoute = pathname.endsWith("/edit") || pathname.split("/").pop() === "edit";
|
|
228
|
-
|
|
229
|
+
const isDetailMode = collection.defaultEntityAction === "view" && !isNew && !isCopy && entityId && !isEditRoute;
|
|
230
|
+
const showList = !isNew && !isCopy && entityId !== void 0 && navigationEntries[0]?.type === "collection" && (navigationEntries.length === 2 || navigationEntries.length === 3) && resolveOpenEntityMode({
|
|
231
|
+
collection,
|
|
232
|
+
viewMode: resolveViewMode({
|
|
233
|
+
collection,
|
|
234
|
+
search: location.search,
|
|
235
|
+
savedViewMode: userConfigPersistence?.getCollectionConfig(collection.slug)?.defaultViewMode
|
|
236
|
+
})
|
|
237
|
+
}) === "split" ? () => navigate({
|
|
238
|
+
pathname,
|
|
239
|
+
search: location.search,
|
|
240
|
+
hash: ""
|
|
241
|
+
}) : void 0;
|
|
242
|
+
if (isDetailMode) return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(DetailViewBinding, {
|
|
229
243
|
entityId,
|
|
230
244
|
collection,
|
|
231
245
|
layout: "full_screen",
|
|
232
246
|
path: collectionPath,
|
|
233
247
|
selectedTab: selectedTab ?? void 0,
|
|
248
|
+
onShowList: showList,
|
|
234
249
|
onEditClick: () => {
|
|
235
250
|
const editUrl = urlController.buildUrlCollectionPath(`${collectionPath}/${entityId}`) + "/edit";
|
|
236
251
|
navigate(editUrl + hash);
|
|
@@ -251,6 +266,7 @@ function EntityFullScreenRoute({ pathname, navigationEntries, isNew, isCopy }) {
|
|
|
251
266
|
path: collectionPath,
|
|
252
267
|
copy: isCopy,
|
|
253
268
|
selectedTab: selectedTab ?? void 0,
|
|
269
|
+
onShowList: showList,
|
|
254
270
|
defaultValues: isNew ? defaultValues : void 0,
|
|
255
271
|
onValuesModified: (modified) => blocked.current = modified,
|
|
256
272
|
navigateBack: () => {
|
|
@@ -280,6 +296,29 @@ function EntityFullScreenRoute({ pathname, navigationEntries, isNew, isCopy }) {
|
|
|
280
296
|
body: "You have unsaved changes in this entity."
|
|
281
297
|
})] });
|
|
282
298
|
}
|
|
299
|
+
/**
|
|
300
|
+
* Shown when a URL names a collection the registry cannot resolve.
|
|
301
|
+
*
|
|
302
|
+
* This used to be `return null`, which renders an empty pane inside the app
|
|
303
|
+
* chrome: the sidebar, the nav highlight and the breadcrumb all still work,
|
|
304
|
+
* because those read the collections array directly, while the view itself is
|
|
305
|
+
* blank. Nothing is thrown, and the only trace is a `console.debug` — so the
|
|
306
|
+
* panel looks like it lost its data rather than like it failed to find the
|
|
307
|
+
* collection, and there is no string to search for.
|
|
308
|
+
*
|
|
309
|
+
* A slug containing slashes went unresolvable this way and cost an afternoon to
|
|
310
|
+
* find. The lookup is fixed; this is the part that made it expensive.
|
|
311
|
+
*/
|
|
312
|
+
function UnresolvedCollectionView({ path }) {
|
|
313
|
+
useEffect(() => {
|
|
314
|
+
console.warn(`[rebase] No collection is registered for "${path}", so this route has nothing to render. Check that the collection is in the collections array and that its slug matches the URL.`);
|
|
315
|
+
}, [path]);
|
|
316
|
+
return /* @__PURE__ */ jsx(CenteredView, { children: /* @__PURE__ */ jsx(ErrorView, {
|
|
317
|
+
title: "Collection not found",
|
|
318
|
+
error: `Nothing is registered for "${path}".`,
|
|
319
|
+
tooltip: "The URL names a collection the panel does not know about. It may have been renamed or removed from the collections array, or the slug may not match the path."
|
|
320
|
+
}) });
|
|
321
|
+
}
|
|
283
322
|
//#endregion
|
|
284
323
|
//#region src/components/ReferenceWidget.tsx
|
|
285
324
|
/**
|
|
@@ -735,7 +774,16 @@ function AppBar({ children, ...props }) {
|
|
|
735
774
|
AppBar.componentType = "AppBar";
|
|
736
775
|
//#endregion
|
|
737
776
|
//#region src/components/DrawerNavigationItem.tsx
|
|
738
|
-
function DrawerNavigationItem({ name, icon, drawerOpen,
|
|
777
|
+
function DrawerNavigationItem({ name, icon, drawerOpen, url, onClick, indented = false }) {
|
|
778
|
+
const iconWrap = indented ? /* @__PURE__ */ jsx("div", {
|
|
779
|
+
className: "shrink-0 w-[44px] h-[30px]",
|
|
780
|
+
"aria-hidden": true
|
|
781
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
782
|
+
className: "shrink-0 flex items-center justify-center w-[44px] h-[30px] text-surface-500 dark:text-text-secondary-dark [&>svg]:size-4 group-hover/nav:text-primary transition-colors duration-150",
|
|
783
|
+
children: icon
|
|
784
|
+
});
|
|
785
|
+
const [wantsTooltip, setWantsTooltip] = React.useState(false);
|
|
786
|
+
if (drawerOpen && wantsTooltip) setWantsTooltip(false);
|
|
739
787
|
const listItem = /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(NavLink, {
|
|
740
788
|
onClick,
|
|
741
789
|
style: {
|
|
@@ -744,19 +792,14 @@ function DrawerNavigationItem({ name, icon, drawerOpen, adminMenuOpen, tooltipsO
|
|
|
744
792
|
},
|
|
745
793
|
className: ({ isActive }) => cls("rounded-lg truncate group/nav", "hover:bg-primary/5 dark:hover:bg-primary/5 text-surface-700 dark:text-surface-300 hover:text-surface-900 dark:hover:text-white", "flex flex-row items-center", drawerOpen ? "pr-4 h-[30px]" : "h-[30px]", "font-medium text-[13px]", isActive ? "bg-primary/8 dark:bg-primary/10 text-primary dark:text-primary [&_div]:text-primary" : ""),
|
|
746
794
|
to: url,
|
|
747
|
-
children: [
|
|
748
|
-
className: "shrink-0 w-[44px] h-[30px]",
|
|
749
|
-
"aria-hidden": true
|
|
750
|
-
}) : /* @__PURE__ */ jsx("div", {
|
|
751
|
-
className: "shrink-0 flex items-center justify-center w-[44px] h-[30px] text-surface-500 dark:text-text-secondary-dark [&>svg]:size-4 group-hover/nav:text-primary transition-colors duration-150",
|
|
752
|
-
children: icon
|
|
753
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
795
|
+
children: [iconWrap, /* @__PURE__ */ jsx("div", {
|
|
754
796
|
className: cls("text-text-primary dark:text-surface-200", drawerOpen ? "opacity-100" : "opacity-0 hidden", "font-inherit truncate space-x-2"),
|
|
755
797
|
children: name
|
|
756
798
|
})]
|
|
757
799
|
}) });
|
|
758
800
|
return /* @__PURE__ */ jsx(Tooltip, {
|
|
759
|
-
open: drawerOpen
|
|
801
|
+
open: !drawerOpen && wantsTooltip,
|
|
802
|
+
onOpenChange: setWantsTooltip,
|
|
760
803
|
side: "right",
|
|
761
804
|
title: name,
|
|
762
805
|
children: listItem
|
|
@@ -768,7 +811,7 @@ function DrawerNavigationItem({ name, icon, drawerOpen, adminMenuOpen, tooltipsO
|
|
|
768
811
|
* Shared drawer navigation group component used by both DefaultDrawer and RebaseCloudDrawer.
|
|
769
812
|
* Renders a collapsible group with header and navigation items.
|
|
770
813
|
*/
|
|
771
|
-
function DrawerNavigationGroup({ group, entries, collapsed, onToggleCollapsed, drawerOpen,
|
|
814
|
+
function DrawerNavigationGroup({ group, entries, collapsed, onToggleCollapsed, drawerOpen, headerActions, onItemClick, hideHeader, icon }) {
|
|
772
815
|
const { t } = useTranslation();
|
|
773
816
|
const ResolvedDrawerNavigationItem = useComponentOverride("Shell.DrawerNavigationItem", DrawerNavigationItem);
|
|
774
817
|
const groupIcon = !hideHeader && drawerOpen ? getIcon(icon, void 0, void 0, "small") : void 0;
|
|
@@ -806,8 +849,6 @@ function DrawerNavigationGroup({ group, entries, collapsed, onToggleCollapsed, d
|
|
|
806
849
|
collectionOrView: entry.collection ?? entry.view,
|
|
807
850
|
size: "small"
|
|
808
851
|
}),
|
|
809
|
-
tooltipsOpen: !collapsed && tooltipsOpen,
|
|
810
|
-
adminMenuOpen,
|
|
811
852
|
drawerOpen,
|
|
812
853
|
onClick: () => onItemClick?.(entry),
|
|
813
854
|
url: entry.url,
|
|
@@ -881,11 +922,9 @@ function DefaultDrawer({ title, logo, logoDestination, children, footerActions,
|
|
|
881
922
|
*/
|
|
882
923
|
function AdminNavigationContent() {
|
|
883
924
|
const { drawerHovered, drawerOpen, closeDrawer, closeHover } = useApp();
|
|
884
|
-
const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
|
|
885
925
|
const analyticsController = useAnalyticsController();
|
|
886
926
|
const navigationState = useNavigationStateController();
|
|
887
927
|
const context = useRebaseContext();
|
|
888
|
-
const tooltipsOpen = drawerHovered && !drawerOpen && !adminMenuOpen;
|
|
889
928
|
const largeLayout = useLargeLayout();
|
|
890
929
|
const adminModeController = useAdminModeController();
|
|
891
930
|
const registry = useRebaseRegistry();
|
|
@@ -941,8 +980,6 @@ function AdminNavigationContent() {
|
|
|
941
980
|
collapsed: isGroupCollapsed(group),
|
|
942
981
|
onToggleCollapsed: () => toggleGroupCollapsed(group),
|
|
943
982
|
drawerOpen: drawerVisuallyOpen,
|
|
944
|
-
tooltipsOpen,
|
|
945
|
-
adminMenuOpen,
|
|
946
983
|
onItemClick,
|
|
947
984
|
icon: groupIcons.get(group)
|
|
948
985
|
}, `drawer_group_${group}`);
|
|
@@ -965,7 +1002,7 @@ function DrawerLogo({ logo, title, logoDestination = "/", drawerOpen, drawerHove
|
|
|
965
1002
|
height: "28px"
|
|
966
1003
|
})
|
|
967
1004
|
}), /* @__PURE__ */ jsx("div", {
|
|
968
|
-
className: cls("flex flex-row items-center overflow-hidden transition-all duration-200 ease-in-out", drawerOpen || drawerHovered
|
|
1005
|
+
className: cls("flex flex-row items-center overflow-hidden transition-all duration-200 ease-in-out", drawerOpen || drawerHovered ? "opacity-100 w-full ml-1" : "opacity-0 w-0 ml-0"),
|
|
969
1006
|
children: title && /* @__PURE__ */ jsx(Link, {
|
|
970
1007
|
className: "visited:text-inherit dark:visited:text-inherit block truncate",
|
|
971
1008
|
to: logoDestination,
|
|
@@ -985,32 +1022,25 @@ function DrawerLogo({ logo, title, logoDestination = "/", drawerOpen, drawerHove
|
|
|
985
1022
|
*/
|
|
986
1023
|
function DrawerToggle({ drawerOpen, drawerHovered, openDrawer, closeDrawer }) {
|
|
987
1024
|
const isExpanded = drawerOpen;
|
|
988
|
-
const
|
|
989
|
-
const
|
|
990
|
-
|
|
1025
|
+
const showFullContent = isExpanded || drawerHovered && !drawerOpen;
|
|
1026
|
+
const [wantsTooltip, setWantsTooltip] = React.useState(false);
|
|
1027
|
+
if (showFullContent && wantsTooltip) setWantsTooltip(false);
|
|
991
1028
|
const { t } = useTranslation();
|
|
992
1029
|
return /* @__PURE__ */ jsx("div", {
|
|
993
1030
|
className: "shrink-0 mt-auto px-4 pt-0.5 pb-2",
|
|
994
1031
|
children: /* @__PURE__ */ jsx(Tooltip, {
|
|
995
1032
|
title: isExpanded ? t("collapse") : t("expand"),
|
|
1033
|
+
open: !showFullContent && wantsTooltip,
|
|
1034
|
+
onOpenChange: setWantsTooltip,
|
|
996
1035
|
side: "right",
|
|
997
1036
|
sideOffset: 12,
|
|
998
1037
|
asChild: true,
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
className: cls("flex flex-row items-center rounded-lg cursor-pointer", "hover:bg-surface-accent-100 dark:hover:bg-surface-800", "transition-colors duration-150", "py-2"),
|
|
1002
|
-
role: "button",
|
|
1003
|
-
tabIndex: 0,
|
|
1038
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
1039
|
+
type: "button",
|
|
1040
|
+
className: cls("flex flex-row items-center rounded-lg cursor-pointer w-full", "hover:bg-surface-accent-100 dark:hover:bg-surface-800", "transition-colors duration-150", "py-2"),
|
|
1004
1041
|
"aria-expanded": isExpanded,
|
|
1005
1042
|
"aria-label": isExpanded ? t("collapse") : t("expand"),
|
|
1006
1043
|
onClick: () => isExpanded ? closeDrawer() : openDrawer(),
|
|
1007
|
-
onKeyDown: (e) => {
|
|
1008
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
1009
|
-
e.preventDefault();
|
|
1010
|
-
if (isExpanded) closeDrawer();
|
|
1011
|
-
else openDrawer();
|
|
1012
|
-
}
|
|
1013
|
-
},
|
|
1014
1044
|
children: [/* @__PURE__ */ jsx("div", {
|
|
1015
1045
|
className: "shrink-0 flex items-center justify-center w-[44px] h-[24px] text-surface-500 dark:text-surface-400",
|
|
1016
1046
|
children: isExpanded ? /* @__PURE__ */ jsx(ChevronsLeftIcon, { size: iconSize.small }) : /* @__PURE__ */ jsx(ChevronsRightIcon, { size: iconSize.small })
|
|
@@ -1189,6 +1219,29 @@ function Drawer({ children, title, logo, logoDestination, footerActions, classNa
|
|
|
1189
1219
|
}
|
|
1190
1220
|
Drawer.componentType = "Drawer";
|
|
1191
1221
|
/**
|
|
1222
|
+
* Namespaced by base path: two admins served from one origin are two different
|
|
1223
|
+
* navigations, and a single key would have them overwrite each other's drawer.
|
|
1224
|
+
*/
|
|
1225
|
+
function drawerOpenStorageKey(basePath) {
|
|
1226
|
+
return `rebase-drawer-open:${basePath || "/"}`;
|
|
1227
|
+
}
|
|
1228
|
+
/** `null` when the user has never toggled the drawer, or storage is unavailable. */
|
|
1229
|
+
function readStoredDrawerOpen(key) {
|
|
1230
|
+
if (typeof window === "undefined") return null;
|
|
1231
|
+
try {
|
|
1232
|
+
const stored = window.localStorage.getItem(key);
|
|
1233
|
+
return stored === null ? null : stored === "true";
|
|
1234
|
+
} catch (e) {
|
|
1235
|
+
return null;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
function writeStoredDrawerOpen(key, open) {
|
|
1239
|
+
if (typeof window === "undefined") return;
|
|
1240
|
+
try {
|
|
1241
|
+
window.localStorage.setItem(key, String(open));
|
|
1242
|
+
} catch (e) {}
|
|
1243
|
+
}
|
|
1244
|
+
/**
|
|
1192
1245
|
* This view acts as a scaffold for Rebase.
|
|
1193
1246
|
*
|
|
1194
1247
|
* It is in charge of displaying the navigation drawer, top bar and main
|
|
@@ -1200,7 +1253,7 @@ Drawer.componentType = "Drawer";
|
|
|
1200
1253
|
* @group Core
|
|
1201
1254
|
*/
|
|
1202
1255
|
var Scaffold = React.memo(function Scaffold(props) {
|
|
1203
|
-
const { children, autoOpenDrawer, defaultDrawerOpen = false, logo, className, style, padding = true } = props;
|
|
1256
|
+
const { children, autoOpenDrawer = true, defaultDrawerOpen = false, logo, className, style, padding = true } = props;
|
|
1204
1257
|
const drawerChildren = React.Children.toArray(children).filter((child) => child.type.componentType === "Drawer");
|
|
1205
1258
|
if (drawerChildren.length > 1) throw Error("Only one Drawer component is allowed in Scaffold");
|
|
1206
1259
|
const appBarChildren = React.Children.toArray(children).filter((child) => child.type.componentType === "AppBar");
|
|
@@ -1208,19 +1261,64 @@ var Scaffold = React.memo(function Scaffold(props) {
|
|
|
1208
1261
|
const otherChildren = React.Children.toArray(children).filter((child) => child.type.componentType !== "Drawer" && child.type.componentType !== "AppBar");
|
|
1209
1262
|
const includeDrawer = drawerChildren.length > 0;
|
|
1210
1263
|
const largeLayout = useLargeLayout();
|
|
1211
|
-
const
|
|
1264
|
+
const storageKey = drawerOpenStorageKey(useUrlController().basePath);
|
|
1265
|
+
const [drawerOpen, setDrawerOpenState] = React.useState(defaultDrawerOpen && largeLayout);
|
|
1212
1266
|
const [onHover, setOnHover] = React.useState(false);
|
|
1213
|
-
|
|
1267
|
+
React.useLayoutEffect(() => {
|
|
1268
|
+
const stored = readStoredDrawerOpen(storageKey);
|
|
1269
|
+
if (stored === null) return;
|
|
1270
|
+
setDrawerOpenState(stored && largeLayout);
|
|
1271
|
+
}, [storageKey]);
|
|
1272
|
+
const wasLargeLayout = React.useRef(largeLayout);
|
|
1273
|
+
React.useEffect(() => {
|
|
1274
|
+
if (wasLargeLayout.current === largeLayout) return;
|
|
1275
|
+
wasLargeLayout.current = largeLayout;
|
|
1276
|
+
setDrawerOpenState(largeLayout ? readStoredDrawerOpen(storageKey) ?? defaultDrawerOpen : false);
|
|
1277
|
+
}, [
|
|
1278
|
+
largeLayout,
|
|
1279
|
+
defaultDrawerOpen,
|
|
1280
|
+
storageKey
|
|
1281
|
+
]);
|
|
1282
|
+
const setDrawerOpen = useCallback((open) => {
|
|
1283
|
+
setDrawerOpenState(open);
|
|
1284
|
+
if (!largeLayout) return;
|
|
1285
|
+
writeStoredDrawerOpen(storageKey, open);
|
|
1286
|
+
}, [largeLayout, storageKey]);
|
|
1287
|
+
const collapseWhenPopoverCloses = React.useRef(false);
|
|
1288
|
+
const setOnHoverTrue = useCallback(() => {
|
|
1289
|
+
if (!autoOpenDrawer) return;
|
|
1290
|
+
collapseWhenPopoverCloses.current = false;
|
|
1291
|
+
setOnHover(true);
|
|
1292
|
+
}, [autoOpenDrawer]);
|
|
1214
1293
|
const setOnHoverFalse = useCallback(() => {
|
|
1215
|
-
if (document.querySelector("[data-radix-popper-content-wrapper]"))
|
|
1294
|
+
if (document.querySelector("[data-radix-popper-content-wrapper]")) {
|
|
1295
|
+
collapseWhenPopoverCloses.current = true;
|
|
1296
|
+
return;
|
|
1297
|
+
}
|
|
1298
|
+
collapseWhenPopoverCloses.current = false;
|
|
1216
1299
|
setOnHover(false);
|
|
1217
1300
|
}, []);
|
|
1301
|
+
React.useEffect(() => {
|
|
1302
|
+
if (!onHover) return;
|
|
1303
|
+
const collapseIfOwed = () => {
|
|
1304
|
+
if (!collapseWhenPopoverCloses.current) return;
|
|
1305
|
+
if (document.querySelector("[data-radix-popper-content-wrapper]")) return;
|
|
1306
|
+
collapseWhenPopoverCloses.current = false;
|
|
1307
|
+
setOnHover(false);
|
|
1308
|
+
};
|
|
1309
|
+
const observer = new MutationObserver(collapseIfOwed);
|
|
1310
|
+
observer.observe(document.body, {
|
|
1311
|
+
childList: true,
|
|
1312
|
+
subtree: true
|
|
1313
|
+
});
|
|
1314
|
+
return () => observer.disconnect();
|
|
1315
|
+
}, [onHover]);
|
|
1218
1316
|
const handleDrawerOpen = useCallback(() => {
|
|
1219
1317
|
setDrawerOpen(true);
|
|
1220
|
-
}, []);
|
|
1318
|
+
}, [setDrawerOpen]);
|
|
1221
1319
|
const handleDrawerClose = useCallback(() => {
|
|
1222
1320
|
setDrawerOpen(false);
|
|
1223
|
-
}, []);
|
|
1321
|
+
}, [setDrawerOpen]);
|
|
1224
1322
|
const computedDrawerOpen = drawerOpen;
|
|
1225
1323
|
const computedDrawerHovered = Boolean(largeLayout && onHover);
|
|
1226
1324
|
const isStudioDark = useAdminModeController().mode === "studio";
|
|
@@ -1561,7 +1659,7 @@ function useLocalCollectionsConfigController(clientOrUrl, baseCollections = [],
|
|
|
1561
1659
|
//#region src/components/RebaseNavigation.tsx
|
|
1562
1660
|
var EMPTY_PLUGINS = [];
|
|
1563
1661
|
var EMPTY_COLLECTIONS = [];
|
|
1564
|
-
var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-
|
|
1662
|
+
var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-D54P9o8O.js").then((n) => n.n).then((m) => ({ default: m.RouterCollectionsStudioView })));
|
|
1565
1663
|
/**
|
|
1566
1664
|
* Navigation layer — builds and provides all admin navigation controllers:
|
|
1567
1665
|
* collection registry, URL controller, navigation state, side entity,
|
|
@@ -1764,7 +1862,7 @@ function BridgeAutoRegistrar({ collectionRegistryController, urlController, navi
|
|
|
1764
1862
|
* ```
|
|
1765
1863
|
*/
|
|
1766
1864
|
function RebaseLayout(props) {
|
|
1767
|
-
const { title = "Rebase", appBar, drawer, autoOpenDrawer =
|
|
1865
|
+
const { title = "Rebase", appBar, drawer, autoOpenDrawer = true, defaultDrawerOpen = false, logo, devViews = [] } = props;
|
|
1768
1866
|
const adminModeController = useAdminModeController();
|
|
1769
1867
|
const ResolvedDrawer = useComponentOverride("Shell.Drawer", Drawer);
|
|
1770
1868
|
const ActiveDrawer = drawer ?? /* @__PURE__ */ jsx(ResolvedDrawer, {
|
|
@@ -2790,8 +2888,8 @@ function ContentHomePage({ additionalActions, additionalChildrenStart, additiona
|
|
|
2790
2888
|
}
|
|
2791
2889
|
//#endregion
|
|
2792
2890
|
//#region src/components/CollectionEditorDialogs.tsx
|
|
2793
|
-
var CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-
|
|
2794
|
-
var PropertyFormDialog = lazy(() => import("./PropertyEditView-
|
|
2891
|
+
var CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-MODRemil.js").then((n) => n.r).then((m) => ({ default: m.CollectionEditorDialog })));
|
|
2892
|
+
var PropertyFormDialog = lazy(() => import("./PropertyEditView-Bt-VM0zQ.js").then((n) => n.t).then((m) => ({ default: m.PropertyFormDialog })));
|
|
2795
2893
|
/**
|
|
2796
2894
|
* Renders the CollectionEditorDialog and PropertyFormDialog inside
|
|
2797
2895
|
* the RebaseShell tree where admin-internal contexts
|
|
@@ -2938,7 +3036,7 @@ function RebaseRouteDefs({ children, layout }) {
|
|
|
2938
3036
|
* RebaseShell is sugar that composes them all with sensible defaults.
|
|
2939
3037
|
*/
|
|
2940
3038
|
function RebaseShell(props) {
|
|
2941
|
-
const { title = "Rebase", appBar, drawer, autoOpenDrawer =
|
|
3039
|
+
const { title = "Rebase", appBar, drawer, autoOpenDrawer = true, defaultDrawerOpen = false, logo, children } = props;
|
|
2942
3040
|
const registry = useRebaseRegistry();
|
|
2943
3041
|
return /* @__PURE__ */ jsx(RebaseAuthGate, { children: /* @__PURE__ */ jsx(RebaseNavigation, { children: /* @__PURE__ */ jsx(ErrorBoundary, {
|
|
2944
3042
|
fullPage: true,
|
|
@@ -3389,6 +3487,6 @@ function MissingReferenceWidget({ path: pathProp }) {
|
|
|
3389
3487
|
});
|
|
3390
3488
|
}
|
|
3391
3489
|
//#endregion
|
|
3392
|
-
export { AdminModeSyncer, AppBar, ArrayContainer, ArrayCustomShapedFieldBinding, ArrayEnumPreview, ArrayOfMapsPreview, ArrayOfReferencesFieldBinding, ArrayOfReferencesPreview, ArrayOfStorageComponentsPreview, ArrayOfStringsPreview, ArrayOneOfPreview, ArrayPropertyEnumPreview, ArrayPropertyPreview, BasicExportAction, BlockFieldBinding, BooleanPreview, CollectionCardViewBinding, CollectionGenerationApiError, CollectionPanel, CollectionRegistryContext, CollectionRowActions, CollectionTableBinding, CollectionViewActions, CollectionViewBinding, CreationResultDialog, CustomViewRoute, DEFAULT_COLLECTION_GENERATION_ENDPOINT, DEFAULT_FIELD_CONFIGS, DataNewPropertiesMapping, DatePreview, DateTimeFieldBinding, DefaultDrawer, Drawer, DrawerFooterActions, EmptyValue, EntityCardBinding, EntityForm, EntityFormBinding, EntityPreviewBinding, EntityViewBinding, EnumValuesChip, ExportCollectionAction, FieldBlock, FieldCaption, FieldHelperText, FormRail, FormSections, ImagePreview, ImportCollectionAction, ImportDataPreview, ImportFileUpload, ImportNewPropertyFieldPreview, ImportSaveInProgress, InlineEntityListPreview, KeyValueFieldBinding, KeyValuePreview, LabelWithIcon, LabelWithIconAndTooltip, MapFieldBinding, MapPropertyPreview, MarkdownEditorFieldBinding, MissingReferenceWidget, MultiSelectFieldBinding, NavigationStateContext, NumberPropertyPreview, PropertyConfigBadge, PropertyFieldBinding, PropertyIdCopyTooltip, PropertyPreview, PropertySelectEntry, ReadOnlyFieldBinding, RebaseAdmin, RebaseAuthGate, RebaseLayout, RebaseNavigation, RebaseRoute, RebaseRouteDefs, RebaseShell, ReferenceFieldBinding, ReferencePreview, ReferenceWidget, RelationPreview, RepeatFieldBinding, Scaffold, SearchIconsView, SelectFieldBinding, SelectableTable, SelectableTableContext, SelectionTableBinding, SideDialogs, SidePanelControllerContext, SidePanelProvider, SkeletonPropertyComponent, StorageThumbnail, StorageThumbnailInternal, StorageUploadFieldBinding, StringPropertyPreview, SwitchFieldBinding, TextFieldBinding, UrlComponentPreview, UrlContext, UserPreview, VectorFieldBinding, VirtualTableInput, addInitialSlash, buildCollectionGenerationCallback, buildSidePanelsFromUrl, convertDataToEntity, convertFileToJson, copyEntityAction, createStaticDataController, deleteEntityAction, downloadBlob, downloadDataAsCsv, downloadEntitiesExport, editEntityAction, extractTouchedValues, flattenEntry, fromSerializableCollectionConfig, fromSerializableCollectionConfigs, fromSerializableProperties, fromSerializableProperty, getBracketNotation, getChanges, getCollectionBySlugWithin, getCollectionPathsCombinations, getDefaultFieldConfig, getDefaultFieldId, getDefaultPropertiesOrder, getEntityCSVExportableData, getEntityJsonExportableData, getEntityPreviewKeys, getEntityTitlePropertyKey, getEntityTitlePropertyKeyForEntity, getEntityViewWidth, getFieldConfig, getFieldId, getFullId, getFullIdPath, getIconForProperty, getIconForWidget, getInferenceType, getInitialEntityValues, getLastSegment, getPropertiesWithPropertiesOrder, getPropertyInPath, getResolvedPropertyInPath, getUserLabel, idToPropertiesPath, isReferenceProperty, isRelationProperty, isSelfLabellingProperty, mapPropertiesToConfigs, mapPropertyToConfig, mergeEntityActions, namespaceToPropertiesOrderPath, namespaceToPropertiesPath, processValueMapping, removeEmptyContainers, removeInitialAndTrailingSlashes, removeInitialSlash, removeTrailingSlash, renderSkeletonCaptionText, renderSkeletonIcon, renderSkeletonImageThumbnail, renderSkeletonText, resetPasswordAction, resolveCollectionPathIds, resolveEntityAction, resolveEntityView, resolveNavigationFrom, sanitizeUrl, toSerializableCollectionConfig, toSerializableProperties, toSerializableProperty, unflattenObject, useAdminContext, useApp, useBreadcrumbsController, useBuildCollectionRegistryController, useBuildNavigationStateController, useBuildSidePanel, useBuildUrlController, useClearRestoreValue, useCollectionDataController, useCollectionEditorController, useCollectionRegistryController, useCollectionsConfigController, useHistory, useImportConfig, useJsonCollectionsConfigController, useLocalCollectionsConfigController, useNavigationStateController, useResolvedCollections, useResolvedNavigationFrom, useResolvedUser, useResolvedViews, useSelectionController, useSelectionDialog, useSideDialogsController, useSidePanel, useTopLevelNavigation, useUrlController, validateCollectionJson, zodToFormErrors };
|
|
3490
|
+
export { AdminModeSyncer, AppBar, ArrayContainer, ArrayCustomShapedFieldBinding, ArrayEnumPreview, ArrayOfMapsPreview, ArrayOfReferencesFieldBinding, ArrayOfReferencesPreview, ArrayOfStorageComponentsPreview, ArrayOfStringsPreview, ArrayOneOfPreview, ArrayPropertyEnumPreview, ArrayPropertyPreview, BasicExportAction, BlockFieldBinding, BooleanPreview, CollectionCardViewBinding, CollectionGenerationApiError, CollectionPanel, CollectionRegistryContext, CollectionRowActions, CollectionTableBinding, CollectionViewActions, CollectionViewBinding, CreationResultDialog, CustomViewRoute, DEFAULT_COLLECTION_GENERATION_ENDPOINT, DEFAULT_FIELD_CONFIGS, DataNewPropertiesMapping, DatePreview, DateTimeFieldBinding, DefaultDrawer, Drawer, DrawerFooterActions, EmptyValue, EntityCardBinding, EntityForm, EntityFormBinding, EntityPreviewBinding, EntityViewBinding, EnumValuesChip, ExportCollectionAction, FieldBlock, FieldCaption, FieldHelperText, FormRail, FormSections, ImagePreview, ImportCollectionAction, ImportDataPreview, ImportFileUpload, ImportNewPropertyFieldPreview, ImportSaveInProgress, InlineEntityListPreview, KeyValueFieldBinding, KeyValuePreview, LABEL_ICON_SIZE, LabelWithIcon, LabelWithIconAndTooltip, MapFieldBinding, MapPropertyPreview, MarkdownEditorFieldBinding, MissingReferenceWidget, MultiSelectFieldBinding, NavigationStateContext, NumberPropertyPreview, PropertyConfigBadge, PropertyFieldBinding, PropertyIdCopyTooltip, PropertyPreview, PropertySelectEntry, ReadOnlyFieldBinding, RebaseAdmin, RebaseAuthGate, RebaseLayout, RebaseNavigation, RebaseRoute, RebaseRouteDefs, RebaseShell, RecordMeta, ReferenceFieldBinding, ReferencePreview, ReferenceWidget, RelationPreview, RepeatFieldBinding, Scaffold, SearchIconsView, SelectFieldBinding, SelectableTable, SelectableTableContext, SelectionTableBinding, SideDialogs, SidePanelControllerContext, SidePanelProvider, SkeletonPropertyComponent, StorageThumbnail, StorageThumbnailInternal, StorageUploadFieldBinding, StringPropertyPreview, SwitchFieldBinding, TextFieldBinding, UrlComponentPreview, UrlContext, UserPreview, VectorFieldBinding, VirtualTableInput, addInitialSlash, buildCollectionGenerationCallback, buildSidePanelsFromUrl, convertDataToEntity, convertFileToJson, copyEntityAction, createStaticDataController, deleteEntityAction, downloadBlob, downloadDataAsCsv, downloadEntitiesExport, editEntityAction, extractTouchedValues, flattenEntry, fromSerializableCollectionConfig, fromSerializableCollectionConfigs, fromSerializableProperties, fromSerializableProperty, getBracketNotation, getChanges, getCollectionBySlugWithin, getCollectionPathsCombinations, getDefaultFieldConfig, getDefaultFieldId, getDefaultPropertiesOrder, getEntityCSVExportableData, getEntityJsonExportableData, getEntityPreviewKeys, getEntityTitlePropertyKey, getEntityTitlePropertyKeyForEntity, getEntityViewWidth, getFieldConfig, getFieldId, getFullId, getFullIdPath, getIconForProperty, getIconForWidget, getInferenceType, getInitialEntityValues, getLastSegment, getPropertiesWithPropertiesOrder, getPropertyInPath, getResolvedPropertyInPath, getUserLabel, idToPropertiesPath, isReferenceProperty, isRelationProperty, isSelfLabellingProperty, mapPropertiesToConfigs, mapPropertyToConfig, mergeEntityActions, namespaceToPropertiesOrderPath, namespaceToPropertiesPath, processValueMapping, removeEmptyContainers, removeInitialAndTrailingSlashes, removeInitialSlash, removeTrailingSlash, renderSkeletonCaptionText, renderSkeletonIcon, renderSkeletonImageThumbnail, renderSkeletonText, resetPasswordAction, resolveCollectionPathIds, resolveEntityAction, resolveEntityView, resolveNavigationFrom, sanitizeUrl, spanClass, toSerializableCollectionConfig, toSerializableProperties, toSerializableProperty, unflattenObject, useAdminContext, useApp, useBreadcrumbsController, useBuildCollectionRegistryController, useBuildNavigationStateController, useBuildSidePanel, useBuildUrlController, useClearRestoreValue, useCollectionDataController, useCollectionEditorController, useCollectionRegistryController, useCollectionsConfigController, useHistory, useImportConfig, useJsonCollectionsConfigController, useLocalCollectionsConfigController, useNavigationStateController, useResolvedCollections, useResolvedNavigationFrom, useResolvedUser, useResolvedViews, useSelectionController, useSelectionDialog, useSideDialogsController, useSidePanel, useTopLevelNavigation, useUrlController, validateCollectionJson, zodToFormErrors };
|
|
3393
3491
|
|
|
3394
3492
|
//# sourceMappingURL=index.js.map
|