@rebasepro/admin 0.6.1 → 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.
Files changed (134) hide show
  1. package/dist/{CollectionEditorDialog-HNXGxXdO.js → CollectionEditorDialog-iGgS4rLX.js} +233 -152
  2. package/dist/CollectionEditorDialog-iGgS4rLX.js.map +1 -0
  3. package/dist/{PropertyEditView-C2wp8kQ9.js → PropertyEditView-C9yhLyja.js} +129 -15
  4. package/dist/PropertyEditView-C9yhLyja.js.map +1 -0
  5. package/dist/{CollectionsStudioView-B1mN33GB.js → RouterCollectionsStudioView-Dqx27GD8.js} +61 -39
  6. package/dist/RouterCollectionsStudioView-Dqx27GD8.js.map +1 -0
  7. package/dist/collection_editor/extensibility_types.d.ts +135 -0
  8. package/dist/collection_editor/index.d.ts +6 -0
  9. package/dist/collection_editor/serializable_types.d.ts +374 -0
  10. package/dist/collection_editor/serializable_utils.d.ts +50 -0
  11. package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +2 -1
  12. package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +12 -1
  13. package/dist/collection_editor/ui/collection_editor/CollectionStudioView.d.ts +13 -1
  14. package/dist/collection_editor/ui/collection_editor/CollectionsStudioView.d.ts +24 -2
  15. package/dist/collection_editor/ui/collection_editor/DisplaySettingsForm.d.ts +2 -1
  16. package/dist/collection_editor/ui/collection_editor/GeneralSettingsForm.d.ts +4 -1
  17. package/dist/collection_editor/ui/collection_editor/PropertyEditView.d.ts +12 -1
  18. package/dist/collection_editor/ui/collection_editor/RouterCollectionStudioView.d.ts +15 -0
  19. package/dist/collection_editor/ui/collection_editor/RouterCollectionsStudioView.d.ts +14 -0
  20. package/dist/collection_editor/useJsonCollectionsConfigController.d.ts +37 -0
  21. package/dist/collection_editor/useSafeSnackbarController.d.ts +2 -0
  22. package/dist/collection_editor_ui.d.ts +4 -0
  23. package/dist/collection_editor_ui.js +33 -4
  24. package/dist/collection_editor_ui.js.map +1 -0
  25. package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +3 -3
  26. package/dist/components/EntityCollectionView/hooks/useKanbanDragAndDrop.d.ts +3 -3
  27. package/dist/components/EntityEditView.d.ts +3 -2
  28. package/dist/components/RebaseCMS.d.ts +1 -1
  29. package/dist/form/EntityForm.d.ts +10 -9
  30. package/dist/form/EntityFormBinding.d.ts +27 -0
  31. package/dist/form/form_utils.d.ts +8 -0
  32. package/dist/form/index.d.ts +5 -1
  33. package/dist/{history-BO6VT85a.js → history-ChHgyyvM.js} +2 -2
  34. package/dist/{history-BO6VT85a.js.map → history-ChHgyyvM.js.map} +1 -1
  35. package/dist/hooks/navigation/contexts/CollectionRegistryContext.d.ts +1 -1
  36. package/dist/hooks/navigation/useAsyncResolver.d.ts +26 -0
  37. package/dist/hooks/navigation/useBuildCollectionRegistryController.d.ts +2 -0
  38. package/dist/hooks/navigation/useTopLevelNavigation.d.ts +1 -1
  39. package/dist/hooks/navigation/utils.d.ts +1 -1
  40. package/dist/index.d.ts +2 -0
  41. package/dist/index.js +2 -2
  42. package/dist/routes/CustomViewRoute.d.ts +2 -1
  43. package/dist/{src-BYniefVu.js → src-DOX2nOyh.js} +1586 -1283
  44. package/dist/src-DOX2nOyh.js.map +1 -0
  45. package/dist/types/components/EntityFormActionsProps.d.ts +1 -1
  46. package/dist/types/components/EntityFormProps.d.ts +59 -0
  47. package/dist/types/fields.d.ts +6 -1
  48. package/dist/util/dataControllerAdapter.d.ts +30 -0
  49. package/dist/util/navigation_utils.d.ts +1 -1
  50. package/dist/util/propertyConfigMapper.d.ts +17 -0
  51. package/package.json +18 -18
  52. package/src/collection_editor/extensibility_types.ts +168 -0
  53. package/src/collection_editor/index.ts +46 -0
  54. package/src/collection_editor/serializable_types.ts +487 -0
  55. package/src/collection_editor/serializable_utils.ts +588 -0
  56. package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +4 -4
  57. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +134 -70
  58. package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +95 -78
  59. package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +23 -20
  60. package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +79 -27
  61. package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +9 -7
  62. package/src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx +22 -5
  63. package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +3 -3
  64. package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +155 -10
  65. package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +6 -6
  66. package/src/collection_editor/ui/collection_editor/PropertyTree.tsx +1 -0
  67. package/src/collection_editor/ui/collection_editor/RouterCollectionStudioView.tsx +44 -0
  68. package/src/collection_editor/ui/collection_editor/RouterCollectionsStudioView.tsx +41 -0
  69. package/src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx +4 -3
  70. package/src/collection_editor/useJsonCollectionsConfigController.tsx +286 -0
  71. package/src/collection_editor/useSafeSnackbarController.ts +9 -0
  72. package/src/collection_editor_ui.ts +6 -0
  73. package/src/components/DefaultDrawer.tsx +13 -3
  74. package/src/components/DrawerNavigationGroup.tsx +2 -2
  75. package/src/components/EntityCollectionView/EntityBoardCard.tsx +6 -6
  76. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +12 -11
  77. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +40 -190
  78. package/src/components/EntityCollectionView/EntityCollectionListView.tsx +54 -183
  79. package/src/components/EntityCollectionView/hooks/useKanbanDragAndDrop.ts +6 -6
  80. package/src/components/EntityEditView.tsx +5 -4
  81. package/src/components/EntityEditViewFormActions.tsx +32 -26
  82. package/src/components/HomePage/ContentHomePage.tsx +13 -4
  83. package/src/components/RebaseCMS.tsx +3 -2
  84. package/src/components/RebaseNavigation.tsx +71 -7
  85. package/src/components/SelectableTable/SelectableTable.tsx +2 -2
  86. package/src/components/SideDialogs.tsx +0 -7
  87. package/src/components/common/default_entity_actions.tsx +9 -9
  88. package/src/contexts/BreacrumbsContext.tsx +15 -6
  89. package/src/editor/selectors/ai-selector.tsx +0 -1
  90. package/src/form/EntityForm.tsx +191 -428
  91. package/src/form/EntityFormActions.tsx +33 -47
  92. package/src/form/EntityFormBinding.tsx +323 -0
  93. package/src/form/components/FormLayout.tsx +1 -1
  94. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +7 -2
  95. package/src/form/form_utils.ts +163 -0
  96. package/src/form/index.tsx +14 -5
  97. package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +2 -2
  98. package/src/hooks/navigation/contexts/NavigationStateContext.tsx +2 -2
  99. package/src/hooks/navigation/contexts/UrlContext.tsx +1 -2
  100. package/src/hooks/navigation/useAsyncResolver.ts +100 -0
  101. package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +15 -8
  102. package/src/hooks/navigation/useBuildNavigationStateController.tsx +12 -8
  103. package/src/hooks/navigation/useNavigationResolution.ts +33 -0
  104. package/src/hooks/navigation/useResolvedCollections.ts +29 -71
  105. package/src/hooks/navigation/useResolvedViews.tsx +40 -70
  106. package/src/hooks/navigation/useTopLevelNavigation.ts +20 -16
  107. package/src/hooks/navigation/utils.ts +7 -4
  108. package/src/index.ts +5 -0
  109. package/src/routes/CustomViewRoute.tsx +14 -6
  110. package/src/types/components/EntityFormActionsProps.tsx +1 -1
  111. package/src/types/components/EntityFormProps.tsx +68 -0
  112. package/src/types/fields.tsx +7 -1
  113. package/src/util/dataControllerAdapter.ts +93 -0
  114. package/src/util/navigation_utils.ts +1 -1
  115. package/src/util/propertyConfigMapper.ts +134 -0
  116. package/LICENSE +0 -21
  117. package/dist/CollectionEditorDialog-HNXGxXdO.js.map +0 -1
  118. package/dist/CollectionsStudioView-B1mN33GB.js.map +0 -1
  119. package/dist/PropertyEditView-C2wp8kQ9.js.map +0 -1
  120. package/dist/components/EntityCollectionView/Board.d.ts +0 -3
  121. package/dist/components/EntityCollectionView/BoardColumn.d.ts +0 -42
  122. package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +0 -9
  123. package/dist/components/EntityCollectionView/BoardSortableList.d.ts +0 -14
  124. package/dist/components/EntityCollectionView/board_types.d.ts +0 -105
  125. package/dist/hooks/navigation/useNavigationRegistry.d.ts +0 -12
  126. package/dist/hooks/navigation/useNavigationURLs.d.ts +0 -11
  127. package/dist/src-BYniefVu.js.map +0 -1
  128. package/src/components/EntityCollectionView/Board.tsx +0 -475
  129. package/src/components/EntityCollectionView/BoardColumn.tsx +0 -165
  130. package/src/components/EntityCollectionView/BoardColumnTitle.tsx +0 -46
  131. package/src/components/EntityCollectionView/BoardSortableList.tsx +0 -177
  132. package/src/components/EntityCollectionView/board_types.ts +0 -113
  133. package/src/hooks/navigation/useNavigationRegistry.ts +0 -164
  134. package/src/hooks/navigation/useNavigationURLs.ts +0 -56
@@ -0,0 +1,286 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import type { EntityCollection, NavigationGroupMapping, Property } from "@rebasepro/types";
3
+ import type {
4
+ CollectionsConfigController,
5
+ SaveCollectionParams,
6
+ UpdateCollectionParams,
7
+ DeleteCollectionParams,
8
+ SavePropertyParams,
9
+ DeletePropertyParams,
10
+ UpdatePropertiesOrderParams,
11
+ UpdateKanbanColumnsOrderParams,
12
+ } from "./types/config_controller";
13
+ import type { JsonCollectionStore, SerializableCollection } from "./serializable_types";
14
+ import { toSerializableCollection, toSerializableProperty, fromSerializableCollection } from "./serializable_utils";
15
+
16
+ export interface UseJsonCollectionsConfigControllerOptions {
17
+ /**
18
+ * The store adapter for persisting/loading collections.
19
+ */
20
+ store: JsonCollectionStore;
21
+
22
+ /**
23
+ * If true, the configuration cannot be modified.
24
+ */
25
+ readOnly?: boolean;
26
+
27
+ /**
28
+ * If true, collections will be loaded from the store on mount.
29
+ * Defaults to true.
30
+ */
31
+ autoLoad?: boolean;
32
+ }
33
+
34
+ /**
35
+ * A `CollectionsConfigController` implementation that persists collection
36
+ * configurations as JSON via a pluggable `JsonCollectionStore` adapter.
37
+ *
38
+ * Use this when you want to store collection schemas in a database, API,
39
+ * localStorage, or any other JSON-compatible backend — as opposed to the
40
+ * default code-based persistence.
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * const store: JsonCollectionStore = {
45
+ * load: async () => { const res = await fetch('/api/schemas'); return res.json(); },
46
+ * save: async (slug, data) => { await fetch(`/api/schemas/${slug}`, { method: 'PUT', body: JSON.stringify(data) }); },
47
+ * delete: async (slug) => { await fetch(`/api/schemas/${slug}`, { method: 'DELETE' }); },
48
+ * };
49
+ *
50
+ * const configController = useJsonCollectionsConfigController({ store });
51
+ * ```
52
+ */
53
+ export function useJsonCollectionsConfigController({
54
+ store,
55
+ readOnly = false,
56
+ autoLoad = true,
57
+ }: UseJsonCollectionsConfigControllerOptions): CollectionsConfigController {
58
+ const [collections, setCollections] = useState<EntityCollection[]>([]);
59
+ const [loading, setLoading] = useState(autoLoad);
60
+ const [navigationEntries, setNavigationEntries] = useState<NavigationGroupMapping[]>([]);
61
+
62
+ // Keep store ref stable to avoid stale closures in callbacks
63
+ const storeRef = useRef(store);
64
+ storeRef.current = store;
65
+
66
+ // ── Load on mount ─────────────────────────────────────────────────
67
+ useEffect(() => {
68
+ if (!autoLoad) return;
69
+ let cancelled = false;
70
+
71
+ (async () => {
72
+ try {
73
+ const [serialized, navEntries] = await Promise.all([
74
+ storeRef.current.load(),
75
+ storeRef.current.loadNavigationEntries?.() ?? Promise.resolve([]),
76
+ ]);
77
+ if (cancelled) return;
78
+ setCollections(serialized.map(fromSerializableCollection));
79
+ setNavigationEntries(navEntries);
80
+ } catch (e) {
81
+ console.error("useJsonCollectionsConfigController: failed to load collections", e);
82
+ } finally {
83
+ if (!cancelled) setLoading(false);
84
+ }
85
+ })();
86
+
87
+ return () => { cancelled = true; };
88
+ }, [autoLoad]);
89
+
90
+ // ── Helpers ────────────────────────────────────────────────────────
91
+
92
+ /**
93
+ * Update local state and persist a collection to the store.
94
+ */
95
+ const persistCollection = useCallback(async (collection: EntityCollection) => {
96
+ const serializable = toSerializableCollection(collection);
97
+ await storeRef.current.save(collection.slug, serializable);
98
+ }, []);
99
+
100
+ /**
101
+ * Find collection by id (slug).
102
+ */
103
+ const getCollection = useCallback((id: string): EntityCollection => {
104
+ const found = collections.find(c => c.slug === id);
105
+ if (found) return found;
106
+ throw new Error(`Collection "${id}" not found`);
107
+ }, [collections]);
108
+
109
+ // ── CRUD operations ───────────────────────────────────────────────
110
+
111
+ const saveCollection = useCallback(async <M extends Record<string, unknown>>(
112
+ { id, collectionData }: SaveCollectionParams<M>
113
+ ) => {
114
+ const collection = collectionData as EntityCollection;
115
+ await persistCollection(collection);
116
+ setCollections(prev => {
117
+ const idx = prev.findIndex(c => c.slug === id);
118
+ if (idx >= 0) {
119
+ const next = [...prev];
120
+ next[idx] = collection;
121
+ return next;
122
+ }
123
+ return [...prev, collection];
124
+ });
125
+ }, [persistCollection]);
126
+
127
+ const updateCollection = useCallback(async <M extends Record<string, unknown>>(
128
+ { id, collectionData, previousId }: UpdateCollectionParams<M>
129
+ ) => {
130
+ setCollections(prev => {
131
+ const lookupId = previousId ?? id;
132
+ const idx = prev.findIndex(c => c.slug === lookupId);
133
+ if (idx < 0) return prev;
134
+
135
+ const merged = { ...prev[idx], ...collectionData } as EntityCollection;
136
+ const next = [...prev];
137
+ next[idx] = merged;
138
+
139
+ // Persist async — fire-and-forget with error logging
140
+ persistCollection(merged).catch(e =>
141
+ console.error("useJsonCollectionsConfigController: failed to update collection", e)
142
+ );
143
+
144
+ // If slug changed, clean up the old entry in the store
145
+ if (previousId && previousId !== id) {
146
+ storeRef.current.delete(previousId).catch(e =>
147
+ console.error("useJsonCollectionsConfigController: failed to delete old slug", e)
148
+ );
149
+ }
150
+
151
+ return next;
152
+ });
153
+ }, [persistCollection]);
154
+
155
+ const deleteCollection = useCallback(async ({ id }: DeleteCollectionParams) => {
156
+ await storeRef.current.delete(id);
157
+ setCollections(prev => prev.filter(c => c.slug !== id));
158
+ }, []);
159
+
160
+ const saveProperty = useCallback(async ({
161
+ path,
162
+ propertyKey,
163
+ property,
164
+ newPropertiesOrder,
165
+ }: SavePropertyParams) => {
166
+ setCollections(prev => {
167
+ const idx = prev.findIndex(c => c.slug === path);
168
+ if (idx < 0) return prev;
169
+
170
+ const collection = { ...prev[idx] };
171
+ collection.properties = {
172
+ ...collection.properties,
173
+ [propertyKey]: property,
174
+ };
175
+ if (newPropertiesOrder) {
176
+ collection.propertiesOrder = newPropertiesOrder as typeof collection.propertiesOrder;
177
+ }
178
+
179
+ const next = [...prev];
180
+ next[idx] = collection as EntityCollection;
181
+
182
+ persistCollection(next[idx]).catch(e =>
183
+ console.error("useJsonCollectionsConfigController: failed to save property", e)
184
+ );
185
+
186
+ return next;
187
+ });
188
+ }, [persistCollection]);
189
+
190
+ const deleteProperty = useCallback(async ({
191
+ path,
192
+ propertyKey,
193
+ newPropertiesOrder,
194
+ }: DeletePropertyParams) => {
195
+ setCollections(prev => {
196
+ const idx = prev.findIndex(c => c.slug === path);
197
+ if (idx < 0) return prev;
198
+
199
+ const collection = { ...prev[idx] };
200
+ const { [propertyKey]: _removed, ...remaining } = collection.properties;
201
+ collection.properties = remaining;
202
+ if (newPropertiesOrder) {
203
+ collection.propertiesOrder = newPropertiesOrder as typeof collection.propertiesOrder;
204
+ }
205
+
206
+ const next = [...prev];
207
+ next[idx] = collection as EntityCollection;
208
+
209
+ persistCollection(next[idx]).catch(e =>
210
+ console.error("useJsonCollectionsConfigController: failed to delete property", e)
211
+ );
212
+
213
+ return next;
214
+ });
215
+ }, [persistCollection]);
216
+
217
+ const updatePropertiesOrder = useCallback(async ({
218
+ collection,
219
+ newPropertiesOrder,
220
+ }: UpdatePropertiesOrderParams) => {
221
+ const updated = {
222
+ ...collection,
223
+ propertiesOrder: newPropertiesOrder,
224
+ } as EntityCollection;
225
+
226
+ setCollections(prev => {
227
+ const idx = prev.findIndex(c => c.slug === collection.slug);
228
+ if (idx < 0) return prev;
229
+ const next = [...prev];
230
+ next[idx] = updated;
231
+ return next;
232
+ });
233
+
234
+ await persistCollection(updated);
235
+ }, [persistCollection]);
236
+
237
+ const updateKanbanColumnsOrder = useCallback(async ({
238
+ collection,
239
+ kanbanColumnProperty,
240
+ newColumnsOrder,
241
+ }: UpdateKanbanColumnsOrderParams) => {
242
+ // Kanban column order is stored in the enum order of the column property.
243
+ // For JSON persistence, we store it as-is — the view layer reads enum order.
244
+ // This is a no-op for now; the kanban order is determined by the enum
245
+ // definition on the property itself.
246
+ }, []);
247
+
248
+ const saveNavigationEntriesHandler = useCallback(async (entries: NavigationGroupMapping[]) => {
249
+ setNavigationEntries(entries);
250
+ if (storeRef.current.saveNavigationEntries) {
251
+ await storeRef.current.saveNavigationEntries(entries);
252
+ }
253
+ }, []);
254
+
255
+ // ── Return controller ─────────────────────────────────────────────
256
+ return useMemo<CollectionsConfigController>(() => ({
257
+ loading,
258
+ readOnly,
259
+ readOnlyReason: readOnly ? "Configuration is read-only." : undefined,
260
+ collections,
261
+ getCollection,
262
+ saveCollection,
263
+ updateCollection,
264
+ deleteCollection,
265
+ saveProperty,
266
+ deleteProperty,
267
+ updatePropertiesOrder,
268
+ updateKanbanColumnsOrder,
269
+ navigationEntries,
270
+ saveNavigationEntries: saveNavigationEntriesHandler,
271
+ }), [
272
+ loading,
273
+ readOnly,
274
+ collections,
275
+ getCollection,
276
+ saveCollection,
277
+ updateCollection,
278
+ deleteCollection,
279
+ saveProperty,
280
+ deleteProperty,
281
+ updatePropertiesOrder,
282
+ updateKanbanColumnsOrder,
283
+ navigationEntries,
284
+ saveNavigationEntriesHandler,
285
+ ]);
286
+ }
@@ -0,0 +1,9 @@
1
+ import { useSnackbarController } from "@rebasepro/core";
2
+
3
+ export function useSafeSnackbarController(): ReturnType<typeof useSnackbarController> | undefined {
4
+ try {
5
+ return useSnackbarController();
6
+ } catch {
7
+ return undefined;
8
+ }
9
+ }
@@ -13,3 +13,9 @@ export type { CollectionStudioViewProps } from "./collection_editor/ui/collectio
13
13
 
14
14
  export { CollectionsStudioView } from "./collection_editor/ui/collection_editor/CollectionsStudioView";
15
15
  export type { CollectionsStudioViewProps } from "./collection_editor/ui/collection_editor/CollectionsStudioView";
16
+
17
+ export { RouterCollectionStudioView } from "./collection_editor/ui/collection_editor/RouterCollectionStudioView";
18
+ export type { RouterCollectionStudioViewProps } from "./collection_editor/ui/collection_editor/RouterCollectionStudioView";
19
+
20
+ export { RouterCollectionsStudioView } from "./collection_editor/ui/collection_editor/RouterCollectionsStudioView";
21
+ export type { RouterCollectionsStudioViewProps } from "./collection_editor/ui/collection_editor/RouterCollectionsStudioView";
@@ -165,11 +165,21 @@ function CMSNavigationContent() {
165
165
 
166
166
  const allNavigationEntries = navigationState.topLevelNavigation?.navigationEntries ?? [];
167
167
 
168
- // Studio mode shows view-type entries (devViews) + admin entries (Users/Roles).
169
- // Content mode shows collections and custom entries + admin entries (Users/Roles), but not studio views.
168
+ // Build a set of Studio-only dev view slugs so we can distinguish them from
169
+ // CMS custom views added via <RebaseCMS views={...}> or plugins.
170
+ const studioViewSlugs = useMemo(() => {
171
+ const slugs = new Set<string>();
172
+ (registry.studioConfig?.devViews ?? []).forEach(v => slugs.add(v.slug));
173
+ // The schema view is also a Studio dev view (auto-injected when collectionEditor is enabled)
174
+ if (registry.studioConfig && registry.cmsConfig?.collectionEditor) slugs.add("schema");
175
+ return slugs;
176
+ }, [registry.studioConfig, registry.cmsConfig?.collectionEditor]);
177
+
178
+ // Studio mode shows Studio dev views + admin entries (Users/Roles).
179
+ // Content mode shows collections, CMS custom views, and admin entries — but not Studio dev views.
170
180
  const filteredEntries = adminModeController.mode === "studio"
171
181
  ? allNavigationEntries.filter(e => e.type === "view" || e.type === "admin")
172
- : allNavigationEntries.filter(e => e.type !== "view");
182
+ : allNavigationEntries.filter(e => e.type !== "view" || !studioViewSlugs.has(e.slug));
173
183
 
174
184
  // Derive groups from the filtered entries, preserving the order from topLevelNavigation.groups
175
185
  const entryGroups = new Set(filteredEntries.map(e => e.group).filter(Boolean));
@@ -1,7 +1,7 @@
1
1
  import type { NavigationEntry } from "@rebasepro/types";
2
2
  import React from "react";
3
3
  import { ChevronDownIcon, cls, iconSize, Typography } from "@rebasepro/ui";
4
- ;
4
+
5
5
  import { IconForView } from "@rebasepro/core";
6
6
  import { DrawerNavigationItem } from "./DrawerNavigationItem";
7
7
  import { useTranslation, useComponentOverride } from "@rebasepro/core";
@@ -108,7 +108,7 @@ export function DrawerNavigationGroup({
108
108
  "transition-all duration-200 ease-in-out",
109
109
  "overflow-hidden",
110
110
  !hideHeader && "dark:bg-transparent",
111
- !hideHeader ? (drawerOpen ? "rounded-lg" : "rounded-lg") : "rounded-lg",
111
+ "rounded-lg",
112
112
  (!hideHeader && collapsed) ? "max-h-0 opacity-0" : "max-h-[2000px] opacity-100"
113
113
  )}
114
114
  >
@@ -5,10 +5,10 @@ import { Checkbox, Chip, cls, defaultBorderMixin, Markdown } from "@rebasepro/ui
5
5
  import { PropertyPreview } from "../../preview";
6
6
  import { useAuthController, useCustomizationController } from "@rebasepro/core";
7
7
  import { IconForView } from "@rebasepro/core";
8
- import { BoardItemViewProps } from "./board_types";
8
+ import { BoardItemViewProps } from "@rebasepro/ui";
9
9
  import { useCollectionSlotKeys, resolveEntitySlots } from "./useEntityPreviewSlots";
10
10
 
11
- export type EntityBoardCardProps<M extends Record<string, unknown> = Record<string, unknown>> = BoardItemViewProps<M> & {
11
+ export type EntityBoardCardProps<M extends Record<string, unknown> = Record<string, unknown>> = BoardItemViewProps<Entity<M>> & {
12
12
  collection: EntityCollection<M>;
13
13
  onClick?: (entity: Entity<M>) => void;
14
14
  selected?: boolean;
@@ -35,7 +35,7 @@ function EntityBoardCardInner<M extends Record<string, unknown> = Record<string,
35
35
  onSelectionChange,
36
36
  selectionEnabled = false
37
37
  }: EntityBoardCardProps<M>) {
38
- const entity = item.entity;
38
+ const entity = item.data;
39
39
  const authController = useAuthController();
40
40
  const customizationController = useCustomizationController();
41
41
 
@@ -247,14 +247,14 @@ export function createEntityBoardCardComponent<M extends Record<string, unknown>
247
247
  onSelectionChange?: (entity: Entity<M>, selected: boolean) => void;
248
248
  selectionEnabled?: boolean;
249
249
  }
250
- ): React.ComponentType<BoardItemViewProps<M>> {
251
- return function EntityBoardCardWrapper(props: BoardItemViewProps<M>) {
250
+ ): React.ComponentType<BoardItemViewProps<Entity<M>>> {
251
+ return function EntityBoardCardWrapper(props: BoardItemViewProps<Entity<M>>) {
252
252
  return (
253
253
  <EntityBoardCard
254
254
  {...props}
255
255
  collection={collection}
256
256
  onClick={options.onClick}
257
- selected={options.isEntitySelected?.(props.item.entity)}
257
+ selected={options.isEntitySelected?.(props.item.data)}
258
258
  onSelectionChange={options.onSelectionChange}
259
259
  selectionEnabled={options.selectionEnabled}
260
260
  />
@@ -1,9 +1,6 @@
1
-
2
1
  import type { EntityCollection } from "@rebasepro/types";
3
2
  import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
3
  import { Entity, EntityTableController, EnumValueConfig, SaveEntityProps, SelectionController } from "@rebasepro/types";
5
- import { Board } from "./Board";
6
- import { BoardItem, BoardItemViewProps, ColumnLoadingState } from "./board_types";
7
4
  import { EntityBoardCard } from "./EntityBoardCard";
8
5
  import {
9
6
  Button,
@@ -19,7 +16,11 @@ import {
19
16
  iconSize,
20
17
  RefreshCwIcon,
21
18
  Tooltip,
22
- Typography
19
+ Typography,
20
+ KanbanView,
21
+ BoardItem,
22
+ BoardItemViewProps,
23
+ ColumnLoadingState
23
24
  } from "@rebasepro/ui";
24
25
  import { resolveEnumValues } from "@rebasepro/common";
25
26
  import { getPropertyInPath } from "../../util/property_utils";
@@ -318,10 +319,10 @@ parentEntityIds,
318
319
  }, [columns, boardDataController.columnData]);
319
320
 
320
321
  // Convert entities to board items per column (data already sorted by orderProperty from controller)
321
- const boardItems: BoardItem<M>[] = useMemo(() => {
322
+ const boardItems: BoardItem<Entity<M>>[] = useMemo(() => {
322
323
  return allEntities.map((entity: Entity<M>) => ({
323
324
  id: String(entity.id),
324
- entity
325
+ data: entity
325
326
  }));
326
327
  }, [allEntities]);
327
328
 
@@ -341,11 +342,11 @@ parentEntityIds,
341
342
  }, [columns, boardDataController.columnData]);
342
343
 
343
344
  // Use the lookup map to assign columns - ensures items stay in the column they were fetched for
344
- const assignColumn = useCallback((item: BoardItem<M>): string => {
345
+ const assignColumn = useCallback((item: BoardItem<Entity<M>>): string => {
345
346
  const column = entityColumnMap[item.id];
346
347
  if (column) return column;
347
348
  // Fallback: read from entity values (for newly created items or edge cases)
348
- const value = item.entity.values?.[columnProperty];
349
+ const value = item.data.values?.[columnProperty];
349
350
  if (value && columns.includes(String(value))) return String(value);
350
351
  return columns[0] || "";
351
352
  }, [entityColumnMap, columnProperty, columns]);
@@ -462,12 +463,12 @@ parentEntityIds,
462
463
  // When ItemComponent identity changes, React.memo'd SortableItem remounts
463
464
  // the card → DOM is destroyed/recreated → CSS :hover state is lost → flicker.
464
465
  const ItemComponent = useMemo(() => {
465
- const Comp = (props: BoardItemViewProps<M>) => (
466
+ const Comp = (props: BoardItemViewProps<Entity<M>>) => (
466
467
  <EntityBoardCard
467
468
  {...props}
468
469
  collection={collectionRef.current as EntityCollection<M>}
469
470
  onClick={stableOnClick}
470
- selected={isEntitySelectedRef.current(props.item.entity)}
471
+ selected={isEntitySelectedRef.current(props.item.data)}
471
472
  onSelectionChange={stableOnSelectionChange}
472
473
  selectionEnabled={selectionEnabledRef.current}
473
474
  />
@@ -592,7 +593,7 @@ parentEntityIds,
592
593
 
593
594
  {/* Main board */}
594
595
  <div className="flex-1 overflow-auto no-scrollbar">
595
- <Board
596
+ <KanbanView
596
597
  data={boardItems}
597
598
  columns={columns}
598
599
  columnLabels={columnLabels}