@rebasepro/admin 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -3
- package/dist/{CollectionEditorDialog-jA-PLh6N.js → CollectionEditorDialog-iGgS4rLX.js} +233 -152
- package/dist/CollectionEditorDialog-iGgS4rLX.js.map +1 -0
- package/dist/{PropertyEditView-DEUddmg_.js → PropertyEditView-C9yhLyja.js} +129 -15
- package/dist/PropertyEditView-C9yhLyja.js.map +1 -0
- package/dist/{CollectionsStudioView-UKouBPOm.js → RouterCollectionsStudioView-Dqx27GD8.js} +61 -39
- package/dist/RouterCollectionsStudioView-Dqx27GD8.js.map +1 -0
- package/dist/collection_editor/extensibility_types.d.ts +135 -0
- package/dist/collection_editor/index.d.ts +6 -0
- package/dist/collection_editor/serializable_types.d.ts +374 -0
- package/dist/collection_editor/serializable_utils.d.ts +50 -0
- package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +2 -1
- package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +12 -1
- package/dist/collection_editor/ui/collection_editor/CollectionStudioView.d.ts +13 -1
- package/dist/collection_editor/ui/collection_editor/CollectionsStudioView.d.ts +24 -2
- package/dist/collection_editor/ui/collection_editor/DisplaySettingsForm.d.ts +2 -1
- package/dist/collection_editor/ui/collection_editor/GeneralSettingsForm.d.ts +4 -1
- package/dist/collection_editor/ui/collection_editor/PropertyEditView.d.ts +12 -1
- package/dist/collection_editor/ui/collection_editor/RouterCollectionStudioView.d.ts +15 -0
- package/dist/collection_editor/ui/collection_editor/RouterCollectionsStudioView.d.ts +14 -0
- package/dist/collection_editor/useJsonCollectionsConfigController.d.ts +37 -0
- package/dist/collection_editor/useSafeSnackbarController.d.ts +2 -0
- package/dist/collection_editor_ui.d.ts +4 -0
- package/dist/collection_editor_ui.js +33 -4
- package/dist/collection_editor_ui.js.map +1 -0
- package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +3 -3
- package/dist/components/EntityCollectionView/hooks/useKanbanDragAndDrop.d.ts +3 -3
- package/dist/components/EntityEditView.d.ts +3 -2
- package/dist/components/RebaseCMS.d.ts +1 -1
- package/dist/editor/editor.d.ts +10 -4
- package/dist/editor.js +6 -4
- package/dist/editor.js.map +1 -1
- package/dist/form/EntityForm.d.ts +10 -9
- package/dist/form/EntityFormBinding.d.ts +27 -0
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +2 -2
- package/dist/form/form_utils.d.ts +8 -0
- package/dist/form/index.d.ts +5 -1
- package/dist/{history-BL49TIDb.js → history-ChHgyyvM.js} +2 -2
- package/dist/{history-BL49TIDb.js.map → history-ChHgyyvM.js.map} +1 -1
- package/dist/hooks/navigation/contexts/CollectionRegistryContext.d.ts +1 -1
- package/dist/hooks/navigation/useAsyncResolver.d.ts +26 -0
- package/dist/hooks/navigation/useBuildCollectionRegistryController.d.ts +2 -0
- package/dist/hooks/navigation/useTopLevelNavigation.d.ts +1 -1
- package/dist/hooks/navigation/utils.d.ts +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -2
- package/dist/routes/CustomViewRoute.d.ts +2 -1
- package/dist/{src-BJ8fkM8y.js → src-DOX2nOyh.js} +1634 -1330
- package/dist/src-DOX2nOyh.js.map +1 -0
- package/dist/types/components/EntityFormActionsProps.d.ts +1 -1
- package/dist/types/components/EntityFormProps.d.ts +59 -0
- package/dist/types/fields.d.ts +6 -1
- package/dist/util/dataControllerAdapter.d.ts +30 -0
- package/dist/util/navigation_utils.d.ts +1 -1
- package/dist/util/propertyConfigMapper.d.ts +17 -0
- package/package.json +18 -18
- package/src/collection_editor/extensibility_types.ts +168 -0
- package/src/collection_editor/index.ts +46 -0
- package/src/collection_editor/serializable_types.ts +487 -0
- package/src/collection_editor/serializable_utils.ts +588 -0
- package/src/collection_editor/ui/AddKanbanColumnAction.tsx +2 -0
- package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +4 -4
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +134 -70
- package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +95 -78
- package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +23 -20
- package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +79 -27
- package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +9 -7
- package/src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx +22 -5
- package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +155 -10
- package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +6 -6
- package/src/collection_editor/ui/collection_editor/PropertyTree.tsx +1 -0
- package/src/collection_editor/ui/collection_editor/RouterCollectionStudioView.tsx +44 -0
- package/src/collection_editor/ui/collection_editor/RouterCollectionsStudioView.tsx +41 -0
- package/src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx +4 -3
- package/src/collection_editor/useJsonCollectionsConfigController.tsx +286 -0
- package/src/collection_editor/useSafeSnackbarController.ts +9 -0
- package/src/collection_editor_ui.ts +6 -0
- package/src/components/ArrayContainer.tsx +5 -5
- package/src/components/DefaultDrawer.tsx +13 -3
- package/src/components/DrawerNavigationGroup.tsx +2 -2
- package/src/components/DrawerNavigationItem.tsx +4 -4
- package/src/components/EntityCollectionView/EntityBoardCard.tsx +6 -6
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +14 -11
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +40 -190
- package/src/components/EntityCollectionView/EntityCollectionListView.tsx +54 -183
- package/src/components/EntityCollectionView/hooks/useKanbanDragAndDrop.ts +6 -6
- package/src/components/EntityEditView.tsx +5 -4
- package/src/components/EntityEditViewFormActions.tsx +32 -26
- package/src/components/HomePage/ContentHomePage.tsx +13 -4
- package/src/components/HomePage/NavigationCard.tsx +8 -14
- package/src/components/HomePage/NavigationGroup.tsx +1 -1
- package/src/components/HomePage/SmallNavigationCard.tsx +1 -5
- package/src/components/RebaseCMS.tsx +3 -2
- package/src/components/RebaseNavigation.tsx +71 -7
- package/src/components/SelectableTable/SelectableTable.tsx +2 -2
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +28 -21
- package/src/components/SideDialogs.tsx +0 -7
- package/src/components/common/default_entity_actions.tsx +18 -10
- package/src/contexts/BreacrumbsContext.tsx +15 -6
- package/src/editor/editor.tsx +14 -8
- package/src/editor/selectors/ai-selector.tsx +0 -1
- package/src/form/EntityForm.tsx +191 -428
- package/src/form/EntityFormActions.tsx +33 -47
- package/src/form/EntityFormBinding.tsx +323 -0
- package/src/form/components/FormLayout.tsx +1 -1
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +4 -4
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +7 -2
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +1 -1
- package/src/form/form_utils.ts +163 -0
- package/src/form/index.tsx +14 -5
- package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +2 -2
- package/src/hooks/navigation/contexts/NavigationStateContext.tsx +2 -2
- package/src/hooks/navigation/contexts/UrlContext.tsx +1 -2
- package/src/hooks/navigation/useAsyncResolver.ts +100 -0
- package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +15 -8
- package/src/hooks/navigation/useBuildNavigationStateController.tsx +12 -8
- package/src/hooks/navigation/useNavigationResolution.ts +33 -0
- package/src/hooks/navigation/useResolvedCollections.ts +29 -71
- package/src/hooks/navigation/useResolvedViews.tsx +40 -70
- package/src/hooks/navigation/useTopLevelNavigation.ts +20 -16
- package/src/hooks/navigation/utils.ts +7 -4
- package/src/index.ts +7 -2
- package/src/routes/CustomViewRoute.tsx +14 -6
- package/src/types/components/EntityFormActionsProps.tsx +1 -1
- package/src/types/components/EntityFormProps.tsx +68 -0
- package/src/types/fields.tsx +7 -1
- package/src/util/dataControllerAdapter.ts +93 -0
- package/src/util/navigation_utils.ts +1 -1
- package/src/util/propertyConfigMapper.ts +134 -0
- package/LICENSE +0 -21
- package/dist/CollectionEditorDialog-jA-PLh6N.js.map +0 -1
- package/dist/CollectionsStudioView-UKouBPOm.js.map +0 -1
- package/dist/PropertyEditView-DEUddmg_.js.map +0 -1
- package/dist/components/EntityCollectionView/Board.d.ts +0 -3
- package/dist/components/EntityCollectionView/BoardColumn.d.ts +0 -42
- package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +0 -9
- package/dist/components/EntityCollectionView/BoardSortableList.d.ts +0 -14
- package/dist/components/EntityCollectionView/board_types.d.ts +0 -105
- package/dist/hooks/navigation/useNavigationRegistry.d.ts +0 -12
- package/dist/hooks/navigation/useNavigationURLs.d.ts +0 -11
- package/dist/src-BJ8fkM8y.js.map +0 -1
- package/src/components/EntityCollectionView/Board.tsx +0 -475
- package/src/components/EntityCollectionView/BoardColumn.tsx +0 -165
- package/src/components/EntityCollectionView/BoardColumnTitle.tsx +0 -46
- package/src/components/EntityCollectionView/BoardSortableList.tsx +0 -177
- package/src/components/EntityCollectionView/board_types.ts +0 -113
- package/src/hooks/navigation/useNavigationRegistry.ts +0 -164
- package/src/hooks/navigation/useNavigationURLs.ts +0 -56
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { Vn as useUrlController } from "./src-DOX2nOyh.js";
|
|
3
|
+
import { s as AIModifiedPathsProvider } from "./PropertyEditView-C9yhLyja.js";
|
|
4
|
+
import { t as CollectionEditor } from "./CollectionEditorDialog-iGgS4rLX.js";
|
|
5
5
|
import { useEffect, useState } from "react";
|
|
6
6
|
import { Button, IconButton, PlusIcon, ResizablePanels, Tooltip, Typography, cls, defaultBorderMixin, iconSize } from "@rebasepro/ui";
|
|
7
|
-
import { IconForView, UnsavedChangesDialog,
|
|
7
|
+
import { IconForView, UnsavedChangesDialog, useUnsavedChangesDialog } from "@rebasepro/core";
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
import { useLocation, useNavigate } from "react-router-dom";
|
|
10
10
|
//#region src/collection_editor/ui/collection_editor/CollectionStudioView.tsx
|
|
11
|
-
function CollectionStudioView({ collectionId, ...props }) {
|
|
12
|
-
const snackbarController = useSnackbarController();
|
|
13
|
-
const navigate = useNavigate();
|
|
14
|
-
const urlController = useUrlController();
|
|
11
|
+
function CollectionStudioView({ collectionId, onSave, onCancel, ...props }) {
|
|
15
12
|
const [formDirty, setFormDirty] = useState(false);
|
|
16
13
|
const [cancelRequested, setCancelRequested] = useState(false);
|
|
17
14
|
const { dialogProps, triggerDialog } = useUnsavedChangesDialog(formDirty, () => setFormDirty(false));
|
|
18
15
|
const activeCollectionId = collectionId;
|
|
19
16
|
const handleCancelClick = () => {
|
|
20
|
-
if (!formDirty)
|
|
17
|
+
if (!formDirty) onCancel?.();
|
|
21
18
|
else {
|
|
22
19
|
setCancelRequested(true);
|
|
23
20
|
triggerDialog();
|
|
24
21
|
}
|
|
25
22
|
};
|
|
26
23
|
return /* @__PURE__ */ jsx("div", {
|
|
27
|
-
className: "flex-grow flex flex-col h-full w-full bg-
|
|
24
|
+
className: "flex-grow flex flex-col h-full w-full bg-surface-50 dark:bg-surface-800",
|
|
28
25
|
children: /* @__PURE__ */ jsxs(AIModifiedPathsProvider, { children: [activeCollectionId ? /* @__PURE__ */ jsx(CollectionEditor, {
|
|
29
26
|
...props,
|
|
30
27
|
fullScreen: true,
|
|
@@ -34,13 +31,9 @@ function CollectionStudioView({ collectionId, ...props }) {
|
|
|
34
31
|
handleCancel: handleCancelClick,
|
|
35
32
|
handleClose: (savedCollection) => {
|
|
36
33
|
setFormDirty(false);
|
|
37
|
-
if (savedCollection) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
message: `Collection ${savedCollection.name || savedCollection.slug} saved`
|
|
41
|
-
});
|
|
42
|
-
if (activeCollectionId === "new") navigate(urlController.buildAppUrlPath(`s/schema/${savedCollection.slug}`));
|
|
43
|
-
}
|
|
34
|
+
if (savedCollection) setTimeout(() => {
|
|
35
|
+
onSave?.(savedCollection);
|
|
36
|
+
}, 0);
|
|
44
37
|
},
|
|
45
38
|
setFormDirty
|
|
46
39
|
}, activeCollectionId) : /* @__PURE__ */ jsxs("div", {
|
|
@@ -50,7 +43,7 @@ function CollectionStudioView({ collectionId, ...props }) {
|
|
|
50
43
|
children: "Select a collection or create a new one"
|
|
51
44
|
}), /* @__PURE__ */ jsxs(Button, {
|
|
52
45
|
disabled: props.configController?.readOnly,
|
|
53
|
-
onClick: () =>
|
|
46
|
+
onClick: () => onSave?.(),
|
|
54
47
|
children: [/* @__PURE__ */ jsx(PlusIcon, {}), "Add new collection"]
|
|
55
48
|
})]
|
|
56
49
|
}), /* @__PURE__ */ jsx(UnsavedChangesDialog, {
|
|
@@ -58,7 +51,7 @@ function CollectionStudioView({ collectionId, ...props }) {
|
|
|
58
51
|
handleOk: () => {
|
|
59
52
|
dialogProps.handleOk();
|
|
60
53
|
if (cancelRequested) {
|
|
61
|
-
|
|
54
|
+
onCancel?.();
|
|
62
55
|
setCancelRequested(false);
|
|
63
56
|
}
|
|
64
57
|
},
|
|
@@ -71,13 +64,15 @@ function CollectionStudioView({ collectionId, ...props }) {
|
|
|
71
64
|
}
|
|
72
65
|
//#endregion
|
|
73
66
|
//#region src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
67
|
+
function CollectionsStudioView({ configController, collections: collectionsProp, activeCollectionId: controlledActiveId, onActiveCollectionChange, propertyTypePresets, hiddenPropertyTypes, renderExtraPropertyFields, renderExtraCollectionFields, visibleTabs, standalone }) {
|
|
68
|
+
const [internalActiveId, setInternalActiveId] = useState(void 0);
|
|
69
|
+
const isControlled = onActiveCollectionChange !== void 0;
|
|
70
|
+
const activeCollectionId = isControlled ? controlledActiveId : internalActiveId;
|
|
71
|
+
const setActiveCollectionId = (id) => {
|
|
72
|
+
if (isControlled) onActiveCollectionChange?.(id);
|
|
73
|
+
else setInternalActiveId(id);
|
|
74
|
+
};
|
|
75
|
+
const collections = collectionsProp ?? configController.collections ?? [];
|
|
81
76
|
const [sidebarSize, setSidebarSize] = useState(() => {
|
|
82
77
|
try {
|
|
83
78
|
const saved = localStorage.getItem("rebase_collections_editor_sidebar_size");
|
|
@@ -91,28 +86,27 @@ function CollectionsStudioView({ configController }) {
|
|
|
91
86
|
localStorage.setItem("rebase_collections_editor_sidebar_size", sidebarSize.toString());
|
|
92
87
|
} catch (e) {}
|
|
93
88
|
}, [sidebarSize]);
|
|
94
|
-
const collections = configController.collections || [];
|
|
95
89
|
return /* @__PURE__ */ jsx("div", {
|
|
96
|
-
className: "flex h-full w-full bg-
|
|
90
|
+
className: "flex h-full w-full bg-surface-50 dark:bg-surface-800 overflow-hidden text-text-primary dark:text-text-primary-dark",
|
|
97
91
|
children: /* @__PURE__ */ jsx(ResizablePanels, {
|
|
98
92
|
orientation: "horizontal",
|
|
99
93
|
panelSizePercent: sidebarSize,
|
|
100
94
|
onPanelSizeChange: setSidebarSize,
|
|
101
95
|
minPanelSizePx: 220,
|
|
102
96
|
firstPanel: /* @__PURE__ */ jsxs("div", {
|
|
103
|
-
className: cls("flex flex-col h-full w-full bg-
|
|
97
|
+
className: cls("flex flex-col h-full w-full bg-surface-50 dark:bg-surface-800 border-r", defaultBorderMixin),
|
|
104
98
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
105
99
|
className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin),
|
|
106
100
|
children: [/* @__PURE__ */ jsx(Typography, {
|
|
107
101
|
variant: "caption",
|
|
108
|
-
className: "font-
|
|
102
|
+
className: "font-semibold text-[11px] uppercase tracking-wider text-surface-400 dark:text-surface-400",
|
|
109
103
|
children: "Collections"
|
|
110
104
|
}), /* @__PURE__ */ jsx(Tooltip, {
|
|
111
105
|
title: configController.readOnly ? configController.readOnlyReason || "Read only" : "Add collection",
|
|
112
106
|
children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(IconButton, {
|
|
113
107
|
size: "small",
|
|
114
108
|
disabled: configController.readOnly,
|
|
115
|
-
onClick: () =>
|
|
109
|
+
onClick: () => setActiveCollectionId("new"),
|
|
116
110
|
className: activeCollectionId === "new" ? "text-primary dark:text-primary-dark" : "text-text-secondary dark:text-text-secondary-dark",
|
|
117
111
|
children: /* @__PURE__ */ jsx(PlusIcon, { size: iconSize.smallest })
|
|
118
112
|
}) })
|
|
@@ -130,12 +124,12 @@ function CollectionsStudioView({ configController }) {
|
|
|
130
124
|
const collectionKey = collection.slug;
|
|
131
125
|
const isSelected = activeCollectionId === collectionKey;
|
|
132
126
|
return /* @__PURE__ */ jsxs("div", {
|
|
133
|
-
onClick: () =>
|
|
134
|
-
className: cls("flex items-center gap-
|
|
127
|
+
onClick: () => setActiveCollectionId(collectionKey),
|
|
128
|
+
className: cls("flex items-center gap-2.5 px-3 h-[30px] cursor-pointer rounded-lg text-[13px] font-medium transition-colors", isSelected ? "bg-primary/8 text-primary dark:bg-primary/10 dark:text-primary-light font-semibold" : "hover:bg-primary/5 dark:hover:bg-primary/5 text-surface-700 dark:text-surface-300 hover:text-surface-900 dark:hover:text-white"),
|
|
135
129
|
children: [/* @__PURE__ */ jsx(IconForView, {
|
|
136
130
|
collectionOrView: collection,
|
|
137
|
-
size: "
|
|
138
|
-
className: cls(isSelected ? "text-primary dark:text-primary-light" : "text-
|
|
131
|
+
size: "smallest",
|
|
132
|
+
className: cls(isSelected ? "text-primary dark:text-primary-light" : "text-surface-500 dark:text-text-secondary-dark")
|
|
139
133
|
}), /* @__PURE__ */ jsx("span", {
|
|
140
134
|
className: "truncate flex-1",
|
|
141
135
|
children: collection.name || collection.slug
|
|
@@ -148,7 +142,17 @@ function CollectionsStudioView({ configController }) {
|
|
|
148
142
|
className: "flex-grow flex flex-col min-w-0 h-full w-full",
|
|
149
143
|
children: activeCollectionId ? /* @__PURE__ */ jsx(CollectionStudioView, {
|
|
150
144
|
configController,
|
|
151
|
-
collectionId: activeCollectionId
|
|
145
|
+
collectionId: activeCollectionId,
|
|
146
|
+
onSave: (savedCollection) => {
|
|
147
|
+
if (activeCollectionId === "new" && savedCollection?.slug) setActiveCollectionId(savedCollection.slug);
|
|
148
|
+
},
|
|
149
|
+
onCancel: () => setActiveCollectionId(void 0),
|
|
150
|
+
propertyTypePresets,
|
|
151
|
+
hiddenPropertyTypes,
|
|
152
|
+
renderExtraPropertyFields,
|
|
153
|
+
renderExtraCollectionFields,
|
|
154
|
+
visibleTabs,
|
|
155
|
+
standalone
|
|
152
156
|
}, activeCollectionId) : /* @__PURE__ */ jsxs("div", {
|
|
153
157
|
className: "flex flex-col items-center justify-center h-full gap-4",
|
|
154
158
|
children: [/* @__PURE__ */ jsx(Typography, {
|
|
@@ -156,7 +160,7 @@ function CollectionsStudioView({ configController }) {
|
|
|
156
160
|
children: "Select a collection or create a new one to start editing"
|
|
157
161
|
}), /* @__PURE__ */ jsxs(Button, {
|
|
158
162
|
disabled: configController.readOnly,
|
|
159
|
-
onClick: () =>
|
|
163
|
+
onClick: () => setActiveCollectionId("new"),
|
|
160
164
|
children: [/* @__PURE__ */ jsx(PlusIcon, {}), "Add new collection"]
|
|
161
165
|
})]
|
|
162
166
|
})
|
|
@@ -165,6 +169,24 @@ function CollectionsStudioView({ configController }) {
|
|
|
165
169
|
});
|
|
166
170
|
}
|
|
167
171
|
//#endregion
|
|
168
|
-
|
|
172
|
+
//#region src/collection_editor/ui/collection_editor/RouterCollectionsStudioView.tsx
|
|
173
|
+
var RouterCollectionsStudioView_exports = /* @__PURE__ */ __exportAll({ RouterCollectionsStudioView: () => RouterCollectionsStudioView });
|
|
174
|
+
function RouterCollectionsStudioView(props) {
|
|
175
|
+
const navigate = useNavigate();
|
|
176
|
+
const urlController = useUrlController();
|
|
177
|
+
const location = useLocation();
|
|
178
|
+
const basePath = urlController.buildAppUrlPath("schema");
|
|
179
|
+
const activeCollectionId = location.pathname.replace(basePath, "").replace(/^\//, "").split("/")[0] || void 0;
|
|
180
|
+
return /* @__PURE__ */ jsx(CollectionsStudioView, {
|
|
181
|
+
...props,
|
|
182
|
+
activeCollectionId,
|
|
183
|
+
onActiveCollectionChange: (id) => {
|
|
184
|
+
if (id) navigate(urlController.buildAppUrlPath(`schema/${id}`));
|
|
185
|
+
else navigate(urlController.buildAppUrlPath("schema"));
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
//#endregion
|
|
190
|
+
export { CollectionStudioView as i, RouterCollectionsStudioView_exports as n, CollectionsStudioView as r, RouterCollectionsStudioView as t };
|
|
169
191
|
|
|
170
|
-
//# sourceMappingURL=
|
|
192
|
+
//# sourceMappingURL=RouterCollectionsStudioView-Dqx27GD8.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouterCollectionsStudioView-Dqx27GD8.js","names":[],"sources":["../src/collection_editor/ui/collection_editor/CollectionStudioView.tsx","../src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx","../src/collection_editor/ui/collection_editor/RouterCollectionsStudioView.tsx"],"sourcesContent":["\nimport { useUnsavedChangesDialog, UnsavedChangesDialog } from \"@rebasepro/core\";\nimport * as React from \"react\";\nimport { useState } from \"react\";\nimport { Button, PlusIcon, Typography } from \"@rebasepro/ui\";\nimport { CollectionEditorDialogProps } from \"./CollectionEditorDialog\";\nimport { AIModifiedPathsProvider } from \"./AIModifiedPathsContext\";\nimport { CollectionEditor } from \"./CollectionEditorDialog\";\nimport type { EntityCollection } from \"@rebasepro/types\";\n\nexport type CollectionStudioViewProps = Omit<CollectionEditorDialogProps, \"open\" | \"isNewCollection\" | \"editedCollectionId\" | \"handleClose\" | \"handleCancel\"> & {\n collectionId?: string | \"new\";\n\n /**\n * Called after a successful save.\n * Receives the saved collection (or undefined if dismissed without saving).\n * When not provided, save completes silently.\n */\n onSave?: (collection?: EntityCollection) => void;\n\n /**\n * Called when the user cancels editing.\n * When not provided, cancel is a no-op.\n */\n onCancel?: () => void;\n};\n\nexport function CollectionStudioView({ collectionId, onSave, onCancel, ...props }: CollectionStudioViewProps) {\n\n // Form state from the editor\n const [formDirty, setFormDirty] = useState<boolean>(false);\n const [cancelRequested, setCancelRequested] = useState<boolean>(false);\n\n const { dialogProps, triggerDialog } = useUnsavedChangesDialog(\n formDirty,\n () => setFormDirty(false)\n );\n\n const activeCollectionId = collectionId;\n\n const handleCancelClick = () => {\n if (!formDirty) {\n onCancel?.();\n } else {\n setCancelRequested(true);\n triggerDialog();\n }\n };\n\n return (\n <div className=\"flex-grow flex flex-col h-full w-full bg-surface-50 dark:bg-surface-800\">\n <AIModifiedPathsProvider>\n {activeCollectionId ? (\n <CollectionEditor\n key={activeCollectionId}\n {...props}\n fullScreen={true}\n open={true}\n isNewCollection={activeCollectionId === \"new\"}\n editedCollectionId={activeCollectionId !== \"new\" ? activeCollectionId : undefined}\n handleCancel={handleCancelClick}\n handleClose={(savedCollection) => {\n setFormDirty(false);\n if (savedCollection) {\n setTimeout(() => {\n onSave?.(savedCollection);\n }, 0);\n }\n }}\n setFormDirty={setFormDirty}\n />\n ) : (\n <div className=\"flex-grow flex flex-col items-center justify-center h-full gap-4\">\n <Typography variant=\"label\">\n Select a collection or create a new one\n </Typography>\n <Button\n disabled={props.configController?.readOnly}\n onClick={() => onSave?.()}\n >\n <PlusIcon/>\n Add new collection\n </Button>\n </div>\n )}\n\n <UnsavedChangesDialog\n {...dialogProps}\n handleOk={() => {\n dialogProps.handleOk();\n if (cancelRequested) {\n onCancel?.();\n setCancelRequested(false);\n }\n }}\n handleCancel={() => {\n dialogProps.handleCancel();\n setCancelRequested(false);\n }}\n />\n </AIModifiedPathsProvider>\n </div>\n );\n}\n","\nimport { IconForView } from \"@rebasepro/core\";\nimport React, { useState, useEffect } from \"react\";\nimport {\n Button,\n cls,\n defaultBorderMixin,\n IconButton,\n iconSize,\n PlusIcon,\n ResizablePanels,\n Tooltip,\n Typography\n} from \"@rebasepro/ui\";\nimport type { EntityCollection } from \"@rebasepro/types\";\nimport { CollectionsConfigController } from \"../../types/config_controller\";\nimport { CollectionStudioView } from \"./CollectionStudioView\";\nimport type { CollectionEditorExtensionProps } from \"../../extensibility_types\";\n\nexport interface CollectionsStudioViewProps extends CollectionEditorExtensionProps {\n configController: CollectionsConfigController;\n\n /**\n * Collections to show in the sidebar.\n * When provided, overrides the collections from `configController`.\n * Use this to control exactly which collections the editor displays.\n */\n collections?: EntityCollection[];\n\n /**\n * Controlled active collection ID.\n * When provided together with `onActiveCollectionChange`,\n * navigation is fully external — no internal state is used.\n */\n activeCollectionId?: string;\n\n /**\n * Called when the user clicks a collection, \"new\", or navigates.\n * When provided, the component is fully controlled (no internal state).\n * When not provided, the component manages selection via internal state.\n *\n * Pass `\"new\"` to create a new collection. Pass `undefined` to deselect.\n */\n onActiveCollectionChange?: (collectionId: string | undefined) => void;\n}\n\nexport function CollectionsStudioView({\n configController,\n collections: collectionsProp,\n activeCollectionId: controlledActiveId,\n onActiveCollectionChange,\n propertyTypePresets,\n hiddenPropertyTypes,\n renderExtraPropertyFields,\n renderExtraCollectionFields,\n visibleTabs,\n standalone,\n}: CollectionsStudioViewProps) {\n\n // ── Navigation state ────────────────────────────────────────────────\n // If onActiveCollectionChange is provided, the component is controlled.\n // Otherwise, use internal state.\n const [internalActiveId, setInternalActiveId] = useState<string | undefined>(undefined);\n const isControlled = onActiveCollectionChange !== undefined;\n const activeCollectionId = isControlled ? controlledActiveId : internalActiveId;\n\n const setActiveCollectionId = (id: string | undefined) => {\n if (isControlled) {\n onActiveCollectionChange?.(id);\n } else {\n setInternalActiveId(id);\n }\n };\n\n // ── Collections list ────────────────────────────────────────────────\n const collections = collectionsProp ?? configController.collections ?? [];\n\n // ── Sidebar sizing ──────────────────────────────────────────────────\n const [sidebarSize, setSidebarSize] = useState(() => {\n try {\n const saved = localStorage.getItem(\"rebase_collections_editor_sidebar_size\");\n return saved !== null ? parseFloat(saved) : 25;\n } catch (e) {\n return 25;\n }\n });\n\n useEffect(() => {\n try {\n localStorage.setItem(\"rebase_collections_editor_sidebar_size\", sidebarSize.toString());\n } catch (e) {\n // ignore local storage error\n }\n }, [sidebarSize]);\n\n return (\n <div className=\"flex h-full w-full bg-surface-50 dark:bg-surface-800 overflow-hidden text-text-primary dark:text-text-primary-dark\">\n <ResizablePanels\n orientation=\"horizontal\"\n panelSizePercent={sidebarSize}\n onPanelSizeChange={setSidebarSize}\n minPanelSizePx={220}\n firstPanel={\n <div className={cls(\"flex flex-col h-full w-full bg-surface-50 dark:bg-surface-800 border-r\", defaultBorderMixin)}>\n <div className={cls(\"flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]\", defaultBorderMixin)}>\n <Typography variant=\"caption\" className=\"font-semibold text-[11px] uppercase tracking-wider text-surface-400 dark:text-surface-400\">\n Collections\n </Typography>\n <Tooltip title={configController.readOnly ? configController.readOnlyReason || \"Read only\" : \"Add collection\"}>\n <div>\n <IconButton\n size=\"small\"\n disabled={configController.readOnly}\n onClick={() => setActiveCollectionId(\"new\")}\n className={activeCollectionId === \"new\" ? \"text-primary dark:text-primary-dark\" : \"text-text-secondary dark:text-text-secondary-dark\"}\n >\n <PlusIcon size={iconSize.smallest}/>\n </IconButton>\n </div>\n </Tooltip>\n </div>\n\n <div className=\"flex-grow overflow-y-auto w-full no-scrollbar p-2 space-y-0.5\">\n {collections.length === 0 && (\n <div className=\"p-4 text-center\">\n <Typography variant=\"caption\" className=\"text-text-disabled dark:text-text-disabled-dark italic\">\n No collections yet.\n </Typography>\n </div>\n )}\n {collections.map((collection) => {\n const collectionKey = collection.slug;\n const isSelected = activeCollectionId === collectionKey;\n return (\n <div\n key={collectionKey}\n onClick={() => setActiveCollectionId(collectionKey)}\n className={cls(\n \"flex items-center gap-2.5 px-3 h-[30px] cursor-pointer rounded-lg text-[13px] font-medium transition-colors\",\n isSelected\n ? \"bg-primary/8 text-primary dark:bg-primary/10 dark:text-primary-light font-semibold\"\n : \"hover:bg-primary/5 dark:hover:bg-primary/5 text-surface-700 dark:text-surface-300 hover:text-surface-900 dark:hover:text-white\"\n )}\n >\n <IconForView collectionOrView={collection} size={\"smallest\"} className={cls(\n isSelected\n ? \"text-primary dark:text-primary-light\"\n : \"text-surface-500 dark:text-text-secondary-dark\"\n )}/>\n <span className=\"truncate flex-1\">\n {collection.name || collection.slug}\n </span>\n </div>\n );\n })}\n </div>\n </div>\n }\n secondPanel={\n <div className=\"flex-grow flex flex-col min-w-0 h-full w-full\">\n {/* We use key to force unmount when switching collections, preventing stale state */}\n {activeCollectionId ? (\n <CollectionStudioView\n key={activeCollectionId}\n configController={configController}\n collectionId={activeCollectionId}\n onSave={(savedCollection) => {\n // After creating a new collection, switch to it\n if (activeCollectionId === \"new\" && savedCollection?.slug) {\n setActiveCollectionId(savedCollection.slug);\n }\n }}\n onCancel={() => setActiveCollectionId(undefined)}\n propertyTypePresets={propertyTypePresets}\n hiddenPropertyTypes={hiddenPropertyTypes}\n renderExtraPropertyFields={renderExtraPropertyFields}\n renderExtraCollectionFields={renderExtraCollectionFields}\n visibleTabs={visibleTabs}\n standalone={standalone}\n />\n ) : (\n <div className=\"flex flex-col items-center justify-center h-full gap-4\">\n <Typography variant=\"label\">\n Select a collection or create a new one to start editing\n </Typography>\n <Button\n disabled={configController.readOnly}\n onClick={() => setActiveCollectionId(\"new\")}\n >\n <PlusIcon/>\n Add new collection\n </Button>\n </div>\n )}\n </div>\n }\n />\n </div>\n );\n}\n","/**\n * Router-aware wrapper around CollectionsStudioView.\n *\n * This component provides the react-router-based navigation behavior\n * that Rebase Studio expects: the active collection is derived from the\n * URL, and clicking a collection navigates via react-router.\n *\n * External consumers should use `CollectionsStudioView` directly\n * (which has no react-router dependency).\n */\nimport React from \"react\";\nimport { useLocation, useNavigate } from \"react-router-dom\";\nimport { useUrlController } from \"../../_cms_internals\";\nimport { CollectionsStudioView, CollectionsStudioViewProps } from \"./CollectionsStudioView\";\n\nexport type RouterCollectionsStudioViewProps = Omit<CollectionsStudioViewProps, \"activeCollectionId\" | \"onActiveCollectionChange\">;\n\nexport function RouterCollectionsStudioView(props: RouterCollectionsStudioViewProps) {\n const navigate = useNavigate();\n const urlController = useUrlController();\n const location = useLocation();\n\n // Determine the active collection from the URL segment after \"schema/\"\n const basePath = urlController.buildAppUrlPath(\"schema\");\n const relativePath = location.pathname.replace(basePath, \"\").replace(/^\\//, \"\");\n const activeCollectionId = relativePath.split(\"/\")[0] || undefined;\n\n return (\n <CollectionsStudioView\n {...props}\n activeCollectionId={activeCollectionId}\n onActiveCollectionChange={(id) => {\n if (id) {\n navigate(urlController.buildAppUrlPath(`schema/${id}`));\n } else {\n navigate(urlController.buildAppUrlPath(\"schema\"));\n }\n }}\n />\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension point types for the collection editor UI.
|
|
3
|
+
*
|
|
4
|
+
* These types define props that let external consumers customize the editor
|
|
5
|
+
* without forking the UI: property type presets, type filtering,
|
|
6
|
+
* custom form field slots, and tab visibility.
|
|
7
|
+
*
|
|
8
|
+
* All extension points are additive and optional — the standard Rebase
|
|
9
|
+
* editor experience is unchanged when these props are not provided.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import type React from "react";
|
|
14
|
+
import type { SerializableProperty, SerializableCollection } from "./serializable_types";
|
|
15
|
+
/**
|
|
16
|
+
* The base property data types supported by Rebase.
|
|
17
|
+
* Derived from the `type` discriminant on `SerializableProperty`.
|
|
18
|
+
*/
|
|
19
|
+
export type PropertyType = SerializableProperty["type"];
|
|
20
|
+
/**
|
|
21
|
+
* A higher-level "preset" that maps to a base Rebase property type
|
|
22
|
+
* with pre-filled configuration. Presets replace the default type picker
|
|
23
|
+
* in the property form when provided.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const emailPreset: PropertyTypePreset = {
|
|
28
|
+
* id: "email",
|
|
29
|
+
* label: "Email",
|
|
30
|
+
* baseType: "string",
|
|
31
|
+
* icon: "Mail",
|
|
32
|
+
* defaults: { email: true },
|
|
33
|
+
* detect: (p) => p.type === "string" && "email" in p && p.email === true,
|
|
34
|
+
* };
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export interface PropertyTypePreset {
|
|
38
|
+
/** Unique identifier for this preset (e.g. "email", "phone", "currency"). */
|
|
39
|
+
id: string;
|
|
40
|
+
/** Display label shown in the type picker. */
|
|
41
|
+
label: string;
|
|
42
|
+
/** The underlying Rebase property type this maps to. */
|
|
43
|
+
baseType: PropertyType;
|
|
44
|
+
/** Icon to show in the picker (Lucide icon name string or React node). */
|
|
45
|
+
icon?: string | React.ReactNode;
|
|
46
|
+
/** Default property config applied when this preset is selected. */
|
|
47
|
+
defaults: Partial<SerializableProperty>;
|
|
48
|
+
/**
|
|
49
|
+
* Optional: detect this preset from an existing property.
|
|
50
|
+
* Used when loading existing schemas to show the correct preset label
|
|
51
|
+
* instead of the raw base type. First match wins.
|
|
52
|
+
* If not provided, falls back to matching by `baseType` alone.
|
|
53
|
+
*/
|
|
54
|
+
detect?: (property: SerializableProperty) => boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The tabs available in the collection editor.
|
|
58
|
+
*/
|
|
59
|
+
export type CollectionEditorTab = "general" | "display" | "properties" | "rls";
|
|
60
|
+
/**
|
|
61
|
+
* Parameters passed to the `renderExtraPropertyFields` render prop.
|
|
62
|
+
*/
|
|
63
|
+
export interface ExtraPropertyFieldsParams {
|
|
64
|
+
/** Current metadata values from `property.metadata`. */
|
|
65
|
+
metadata: Record<string, unknown>;
|
|
66
|
+
/** Callback to update a single metadata key. Triggers dirty-state tracking. */
|
|
67
|
+
onMetadataChange: (key: string, value: unknown) => void;
|
|
68
|
+
/** The full current property being edited (serializable form). */
|
|
69
|
+
property: SerializableProperty;
|
|
70
|
+
/** The collection this property belongs to (serializable form). */
|
|
71
|
+
collection: SerializableCollection;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parameters passed to the `renderExtraCollectionFields` render prop.
|
|
75
|
+
*/
|
|
76
|
+
export interface ExtraCollectionFieldsParams {
|
|
77
|
+
/** Current metadata values from `collection.metadata`. */
|
|
78
|
+
metadata: Record<string, unknown>;
|
|
79
|
+
/** Callback to update a single metadata key. Triggers dirty-state tracking. */
|
|
80
|
+
onMetadataChange: (key: string, value: unknown) => void;
|
|
81
|
+
/** The full current collection being edited (serializable form). */
|
|
82
|
+
collection: SerializableCollection;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* All extension props for the collection editor UI.
|
|
86
|
+
*
|
|
87
|
+
* This interface groups every customization point into a single type
|
|
88
|
+
* that can be intersected with component props interfaces for clean threading.
|
|
89
|
+
*
|
|
90
|
+
* All fields are optional — when not provided, the standard Rebase
|
|
91
|
+
* editor experience is unchanged (backward compatible).
|
|
92
|
+
*/
|
|
93
|
+
export interface CollectionEditorExtensionProps {
|
|
94
|
+
/**
|
|
95
|
+
* Custom property type presets. When provided, these REPLACE the default
|
|
96
|
+
* type picker entirely. To include standard Rebase types alongside custom
|
|
97
|
+
* ones, include them explicitly in the array.
|
|
98
|
+
*
|
|
99
|
+
* When not provided, the standard Rebase widget picker is shown.
|
|
100
|
+
*/
|
|
101
|
+
propertyTypePresets?: PropertyTypePreset[];
|
|
102
|
+
/**
|
|
103
|
+
* Property types to hide from the type picker.
|
|
104
|
+
* Only applies when `propertyTypePresets` is NOT provided.
|
|
105
|
+
* When `propertyTypePresets` IS provided, this prop is ignored.
|
|
106
|
+
*/
|
|
107
|
+
hiddenPropertyTypes?: PropertyType[];
|
|
108
|
+
/**
|
|
109
|
+
* Render additional form fields below the standard property configuration.
|
|
110
|
+
* Metadata is stored in `property.metadata`.
|
|
111
|
+
*/
|
|
112
|
+
renderExtraPropertyFields?: (params: ExtraPropertyFieldsParams) => React.ReactNode;
|
|
113
|
+
/**
|
|
114
|
+
* Render additional form fields in the collection editor's General tab.
|
|
115
|
+
* Metadata is stored in `collection.metadata`.
|
|
116
|
+
*/
|
|
117
|
+
renderExtraCollectionFields?: (params: ExtraCollectionFieldsParams) => React.ReactNode;
|
|
118
|
+
/**
|
|
119
|
+
* Which tabs to show in the collection editor.
|
|
120
|
+
* Default: all tabs are shown (current behavior).
|
|
121
|
+
*/
|
|
122
|
+
visibleTabs?: CollectionEditorTab[];
|
|
123
|
+
/**
|
|
124
|
+
* When true, the editor runs in standalone mode — all Rebase-specific
|
|
125
|
+
* context dependencies (snackbar, auth, collection registry, import,
|
|
126
|
+
* navigation state, URL controller) use safe defaults instead of
|
|
127
|
+
* reading from React contexts.
|
|
128
|
+
*
|
|
129
|
+
* Use this when embedding the collection editor outside of the Rebase
|
|
130
|
+
* CMS, where the Rebase context providers are not available.
|
|
131
|
+
*
|
|
132
|
+
* Default: false (standard Rebase mode).
|
|
133
|
+
*/
|
|
134
|
+
standalone?: boolean;
|
|
135
|
+
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export { useCollectionEditorController } from "./useCollectionEditorController";
|
|
2
2
|
export { useCollectionsConfigController } from "./useCollectionsConfigController";
|
|
3
3
|
export { useLocalCollectionsConfigController } from "./useLocalCollectionsConfigController";
|
|
4
|
+
export { useJsonCollectionsConfigController, type UseJsonCollectionsConfigControllerOptions, } from "./useJsonCollectionsConfigController";
|
|
5
|
+
export { toSerializableCollection, toSerializableProperty, toSerializableProperties, fromSerializableCollection, fromSerializableProperty, fromSerializableProperties, } from "./serializable_utils";
|
|
6
|
+
export type { SerializableCollection, SerializableProperty, SerializableProperties, SerializableBaseProperty, SerializableStringProperty, SerializableNumberProperty, SerializableBooleanProperty, SerializableDateProperty, SerializableGeopointProperty, SerializableReferenceProperty, SerializableRelationProperty, SerializableArrayProperty, SerializableMapProperty, SerializableVectorProperty, SerializableBinaryProperty, SerializableStorageConfig, SerializableStringValidation, SerializableDateValidation, JsonCollectionStore, } from "./serializable_types";
|
|
7
|
+
export type { PropertyTypePreset, PropertyType, CollectionEditorTab, CollectionEditorExtensionProps, ExtraPropertyFieldsParams, ExtraCollectionFieldsParams, } from "./extensibility_types";
|
|
4
8
|
export { validateCollectionJson, type CollectionValidationError, type CollectionValidationResult } from "./validateCollectionJson";
|
|
5
9
|
export type { CollectionsConfigController, DeleteCollectionParams, SaveCollectionParams, UpdateCollectionParams, CollectionsSetupInfo, UpdatePropertiesOrderParams, UpdateKanbanColumnsOrderParams } from "./types/config_controller";
|
|
6
10
|
export type { CollectionEditorController } from "./types/collection_editor_controller";
|
|
@@ -12,4 +16,6 @@ export * from "./ui/collection_editor/util";
|
|
|
12
16
|
export type { CollectionEditorDialogProps } from "./ui/collection_editor/CollectionEditorDialog";
|
|
13
17
|
export type { CollectionStudioViewProps } from "./ui/collection_editor/CollectionStudioView";
|
|
14
18
|
export type { CollectionsStudioViewProps } from "./ui/collection_editor/CollectionsStudioView";
|
|
19
|
+
export type { RouterCollectionStudioViewProps } from "./ui/collection_editor/RouterCollectionStudioView";
|
|
20
|
+
export type { RouterCollectionsStudioViewProps } from "./ui/collection_editor/RouterCollectionsStudioView";
|
|
15
21
|
export type { PropertyFormProps, OnPropertyChangedParams } from "./ui/collection_editor/PropertyEditView";
|