@rebasepro/admin 0.6.1 → 0.8.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/dist/{CollectionEditorDialog-HNXGxXdO.js → CollectionEditorDialog-BO_aQ-Z4.js} +236 -155
- package/dist/CollectionEditorDialog-BO_aQ-Z4.js.map +1 -0
- package/dist/{PropertyEditView-C2wp8kQ9.js → PropertyEditView-DKzOpMjR.js} +190 -50
- package/dist/PropertyEditView-DKzOpMjR.js.map +1 -0
- package/dist/{CollectionsStudioView-B1mN33GB.js → RouterCollectionsStudioView-BQTIExjA.js} +61 -39
- package/dist/RouterCollectionsStudioView-BQTIExjA.js.map +1 -0
- package/dist/collection_editor/_cms_internals.d.ts +1 -1
- package/dist/collection_editor/api/generateCollectionApi.d.ts +3 -2
- 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 +370 -0
- package/dist/collection_editor/serializable_utils.d.ts +50 -0
- package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +3 -3
- 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/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/index.d.ts +1 -1
- 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/components/SelectableTable/SelectionStore.d.ts +12 -21
- package/dist/components/field_configs.d.ts +1 -1
- package/dist/editor/editor.d.ts +0 -6
- package/dist/editor.js +1 -3
- 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/components/StorageUploadProgress.d.ts +6 -1
- package/dist/form/form_utils.d.ts +8 -0
- package/dist/form/index.d.ts +5 -2
- package/dist/{history-BO6VT85a.js → history-B3cqBzEV.js} +2 -2
- package/dist/{history-BO6VT85a.js.map → history-B3cqBzEV.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/preview/components/StorageThumbnail.d.ts +3 -1
- package/dist/routes/CustomViewRoute.d.ts +2 -1
- package/dist/{src-BYniefVu.js → src-cxV1ODRG.js} +1731 -1710
- package/dist/src-cxV1ODRG.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/components/PropertyPreviewProps.d.ts +2 -1
- package/dist/types/fields.d.ts +10 -7
- 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 +8 -8
- package/src/collection_editor/_cms_internals.ts +1 -1
- package/src/collection_editor/api/generateCollectionApi.ts +3 -2
- package/src/collection_editor/extensibility_types.ts +168 -0
- package/src/collection_editor/index.ts +46 -0
- package/src/collection_editor/pgColumnToProperty.ts +2 -2
- package/src/collection_editor/serializable_types.ts +474 -0
- package/src/collection_editor/serializable_utils.ts +576 -0
- package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +6 -6
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +170 -89
- 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 +154 -18
- 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/ui/collection_editor/properties/StoragePropertyField.tsx +35 -1
- package/src/collection_editor/ui/collection_editor/templates/blog_template.ts +1 -1
- package/src/collection_editor/ui/collection_editor/utils/supported_fields.tsx +0 -1
- package/src/collection_editor/ui/collection_editor/utils/update_property_for_widget.ts +7 -29
- 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/DefaultDrawer.tsx +14 -4
- package/src/components/DrawerNavigationGroup.tsx +2 -2
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +11 -9
- package/src/components/EntityCollectionTable/fields/TableMultipleRelationField.tsx +2 -1
- package/src/components/EntityCollectionTable/fields/TableRelationField.tsx +2 -1
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +23 -20
- package/src/components/EntityCollectionTable/index.tsx +1 -1
- package/src/components/EntityCollectionTable/table_bindings.tsx +24 -44
- package/src/components/EntityCollectionView/EntityBoardCard.tsx +6 -6
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +13 -12
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +40 -190
- package/src/components/EntityCollectionView/EntityCollectionListView.tsx +66 -184
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +8 -25
- package/src/components/EntityCollectionView/hooks/useCollectionInlineEditor.ts +1 -1
- package/src/components/EntityCollectionView/hooks/useKanbanDragAndDrop.ts +6 -6
- package/src/components/EntityCollectionView/useBoardDataController.tsx +12 -40
- package/src/components/EntityCollectionView/useEntityPreviewSlots.ts +3 -3
- package/src/components/EntityDetailView.tsx +2 -2
- package/src/components/EntityEditView.tsx +7 -6
- package/src/components/EntityEditViewFormActions.tsx +35 -29
- package/src/components/HomePage/ContentHomePage.tsx +14 -5
- package/src/components/RebaseCMS.tsx +3 -3
- package/src/components/RebaseNavigation.tsx +74 -9
- package/src/components/RelationSelector.tsx +2 -2
- package/src/components/SelectableTable/SelectableTable.tsx +13 -5
- package/src/components/SelectableTable/SelectionStore.ts +18 -48
- package/src/components/SideDialogs.tsx +0 -7
- package/src/components/common/default_entity_actions.tsx +22 -11
- package/src/components/field_configs.tsx +0 -14
- package/src/contexts/BreacrumbsContext.tsx +15 -6
- package/src/editor/editor.tsx +4 -7
- package/src/editor/selectors/ai-selector.tsx +0 -1
- package/src/form/EntityForm.tsx +191 -428
- package/src/form/EntityFormActions.tsx +35 -49
- package/src/form/EntityFormBinding.tsx +323 -0
- package/src/form/components/FormLayout.tsx +1 -1
- package/src/form/components/StorageUploadProgress.tsx +9 -2
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +12 -1
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +4 -4
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +7 -2
- package/src/form/field_bindings/RelationFieldBinding.tsx +5 -7
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +19 -15
- package/src/form/form_utils.ts +163 -0
- package/src/form/index.tsx +14 -6
- 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 +6 -1
- package/src/preview/PropertyPreview.tsx +1 -16
- package/src/preview/components/StorageThumbnail.tsx +24 -7
- 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/components/PropertyPreviewProps.tsx +1 -1
- package/src/types/fields.tsx +9 -8
- package/src/util/dataControllerAdapter.ts +93 -0
- package/src/util/navigation_utils.ts +1 -1
- package/src/util/previews.ts +20 -0
- package/src/util/propertyConfigMapper.ts +134 -0
- package/src/util/property_utils.tsx +1 -2
- package/dist/CollectionEditorDialog-HNXGxXdO.js.map +0 -1
- package/dist/CollectionsStudioView-B1mN33GB.js.map +0 -1
- package/dist/PropertyEditView-C2wp8kQ9.js.map +0 -1
- package/dist/components/EntityCollectionTable/fields/VirtualTableDateField.d.ts +0 -12
- package/dist/components/EntityCollectionTable/fields/VirtualTableInput.d.ts +0 -10
- package/dist/components/EntityCollectionTable/fields/VirtualTableNumberInput.d.ts +0 -9
- package/dist/components/EntityCollectionTable/fields/VirtualTableSwitch.d.ts +0 -8
- 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/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +0 -11
- package/dist/hooks/navigation/useNavigationRegistry.d.ts +0 -12
- package/dist/hooks/navigation/useNavigationURLs.d.ts +0 -11
- package/dist/src-BYniefVu.js.map +0 -1
- package/src/components/EntityCollectionTable/fields/VirtualTableDateField.tsx +0 -39
- package/src/components/EntityCollectionTable/fields/VirtualTableInput.tsx +0 -90
- package/src/components/EntityCollectionTable/fields/VirtualTableNumberInput.tsx +0 -83
- package/src/components/EntityCollectionTable/fields/VirtualTableSwitch.tsx +0 -32
- 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/form/field_bindings/ReferenceAsStringFieldBinding.tsx +0 -141
- package/src/hooks/navigation/useNavigationRegistry.ts +0 -164
- package/src/hooks/navigation/useNavigationURLs.ts +0 -56
package/src/types/fields.tsx
CHANGED
|
@@ -19,7 +19,6 @@ export type DefaultFieldConfig =
|
|
|
19
19
|
| "multi_number_select"
|
|
20
20
|
| "file_upload"
|
|
21
21
|
| "multi_file_upload"
|
|
22
|
-
| "reference_as_string"
|
|
23
22
|
| "reference"
|
|
24
23
|
| "multi_references"
|
|
25
24
|
| "relation"
|
|
@@ -51,12 +50,8 @@ export interface FieldProps<
|
|
|
51
50
|
/**
|
|
52
51
|
* Current value of this field, inferred from the property type P
|
|
53
52
|
*/
|
|
54
|
-
value: any;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Set value of field directly
|
|
58
|
-
*/
|
|
59
|
-
setValue: (value: any | null, shouldValidate?: boolean) => void;
|
|
53
|
+
value: InferPropertyType<P> | any;
|
|
54
|
+
setValue: (value: InferPropertyType<P> | null | any, shouldValidate?: boolean) => void;
|
|
60
55
|
|
|
61
56
|
/**
|
|
62
57
|
* Set value of a different field directly
|
|
@@ -213,7 +208,7 @@ export interface FormContext<M extends Record<string, unknown> = Record<string,
|
|
|
213
208
|
|
|
214
209
|
savingError?: Error;
|
|
215
210
|
|
|
216
|
-
openEntityMode
|
|
211
|
+
openEntityMode?: "side_panel" | "full_screen" | "split" | "dialog";
|
|
217
212
|
|
|
218
213
|
/**
|
|
219
214
|
* This is the underlying formex controller that powers the form.
|
|
@@ -223,6 +218,12 @@ export interface FormContext<M extends Record<string, unknown> = Record<string,
|
|
|
223
218
|
formex: FormexController<M>;
|
|
224
219
|
|
|
225
220
|
disabled: boolean;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Whether the form context is in read-only detail view mode.
|
|
224
|
+
* Custom entity views can use this to adjust their rendering.
|
|
225
|
+
*/
|
|
226
|
+
readOnly?: boolean;
|
|
226
227
|
}
|
|
227
228
|
|
|
228
229
|
/**
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapts an `EntityTableController<M>` (from @rebasepro/types) to a
|
|
3
|
+
* `CollectionDataController<T>` (from @rebasepro/ui), bridging the
|
|
4
|
+
* entity-aware data layer to the headless collection view.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useMemo } from "react";
|
|
8
|
+
import type { Entity, EntityTableController } from "@rebasepro/types";
|
|
9
|
+
import type { CollectionDataController } from "@rebasepro/ui";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Flatten Entity<M> objects to plain row objects.
|
|
13
|
+
* The headless view works with flat `Record<string, unknown>` rows,
|
|
14
|
+
* while the entity system uses `{ id, path, values: M }`.
|
|
15
|
+
*
|
|
16
|
+
* The flattened row includes `id` and `path` at the top level,
|
|
17
|
+
* plus all values spread.
|
|
18
|
+
*/
|
|
19
|
+
function flattenEntities<M extends Record<string, unknown>>(
|
|
20
|
+
entities: Entity<M>[]
|
|
21
|
+
): Array<M & { id: string | number; path: string }> {
|
|
22
|
+
return entities.map(entity => ({
|
|
23
|
+
id: entity.id,
|
|
24
|
+
path: entity.path,
|
|
25
|
+
...entity.values
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* React hook that adapts an EntityTableController to a CollectionDataController.
|
|
31
|
+
*
|
|
32
|
+
* Usage:
|
|
33
|
+
* ```tsx
|
|
34
|
+
* const tableController = useDataTableController({ path, collection });
|
|
35
|
+
* const dataController = useCollectionDataController(tableController);
|
|
36
|
+
*
|
|
37
|
+
* <CollectionView dataController={dataController} ... />
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function useCollectionDataController<M extends Record<string, unknown>>(
|
|
41
|
+
tableController: EntityTableController<M>
|
|
42
|
+
): CollectionDataController<M & { id: string | number; path: string }> {
|
|
43
|
+
const flatData = useMemo(
|
|
44
|
+
() => flattenEntities(tableController.data),
|
|
45
|
+
[tableController.data]
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return useMemo((): CollectionDataController<M & { id: string | number; path: string }> => ({
|
|
49
|
+
data: flatData,
|
|
50
|
+
loading: tableController.dataLoading,
|
|
51
|
+
noMoreToLoad: tableController.noMoreToLoad,
|
|
52
|
+
error: tableController.dataLoadingError,
|
|
53
|
+
|
|
54
|
+
filterValues: tableController.filterValues as Record<string, [string, unknown]> | undefined,
|
|
55
|
+
setFilterValues: tableController.setFilterValues as
|
|
56
|
+
((values: Record<string, [string, unknown]> | undefined) => void) | undefined,
|
|
57
|
+
|
|
58
|
+
sortBy: tableController.sortBy,
|
|
59
|
+
setSortBy: tableController.setSortBy,
|
|
60
|
+
|
|
61
|
+
searchString: tableController.searchString,
|
|
62
|
+
setSearchString: tableController.setSearchString,
|
|
63
|
+
|
|
64
|
+
clearFilter: tableController.clearFilter,
|
|
65
|
+
|
|
66
|
+
initialScroll: tableController.initialScroll,
|
|
67
|
+
onScroll: tableController.onScroll,
|
|
68
|
+
|
|
69
|
+
paginationEnabled: tableController.paginationEnabled,
|
|
70
|
+
pageSize: tableController.pageSize,
|
|
71
|
+
itemCount: tableController.itemCount,
|
|
72
|
+
setItemCount: tableController.setItemCount,
|
|
73
|
+
}), [flatData, tableController]);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Non-hook version for cases where you already have the data
|
|
78
|
+
* and just need to build a static controller.
|
|
79
|
+
*/
|
|
80
|
+
export function createStaticDataController<T extends Record<string, unknown>>(
|
|
81
|
+
data: T[],
|
|
82
|
+
options?: {
|
|
83
|
+
loading?: boolean;
|
|
84
|
+
error?: Error;
|
|
85
|
+
}
|
|
86
|
+
): CollectionDataController<T> {
|
|
87
|
+
return {
|
|
88
|
+
data,
|
|
89
|
+
loading: options?.loading ?? false,
|
|
90
|
+
noMoreToLoad: true,
|
|
91
|
+
error: options?.error,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
@@ -31,7 +31,7 @@ export function navigateToEntity({
|
|
|
31
31
|
}:
|
|
32
32
|
|
|
33
33
|
{
|
|
34
|
-
openEntityMode
|
|
34
|
+
openEntityMode?: "side_panel" | "full_screen" | "split" | "dialog";
|
|
35
35
|
collection?: EntityCollection;
|
|
36
36
|
entityId?: string | number;
|
|
37
37
|
selectedTab?: string;
|
package/src/util/previews.ts
CHANGED
|
@@ -8,6 +8,25 @@ function isHiddenProperty(property: Property | undefined): boolean {
|
|
|
8
8
|
return Boolean(property.ui?.hideFromCollection);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Returns true when the property holds file-storage content (single image,
|
|
13
|
+
* array of images, generic upload, …). These properties are rendered by the
|
|
14
|
+
* dedicated image-slot and should NOT appear as regular preview columns.
|
|
15
|
+
*/
|
|
16
|
+
function isStorageProperty(property: Property | undefined): boolean {
|
|
17
|
+
if (!property) return false;
|
|
18
|
+
// Single string with storage config
|
|
19
|
+
if (property.type === "string" && property.storage) return true;
|
|
20
|
+
// String displayed as image URL
|
|
21
|
+
if (property.type === "string" && property.ui?.url === "image") return true;
|
|
22
|
+
// Array whose inner element has storage config or image URL
|
|
23
|
+
if (property.type === "array" && property.of && !Array.isArray(property.of)) {
|
|
24
|
+
const inner = property.of;
|
|
25
|
+
if (inner.type === "string" && (inner.storage || inner.ui?.url === "image")) return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
11
30
|
export function getEntityPreviewKeys(
|
|
12
31
|
authController: AuthController,
|
|
13
32
|
targetCollection: EntityCollection<any>,
|
|
@@ -33,6 +52,7 @@ export function getEntityPreviewKeys(
|
|
|
33
52
|
.filter(key => {
|
|
34
53
|
const property = targetCollection.properties[key];
|
|
35
54
|
return property && !isPropertyBuilder(property) && !isReferenceProperty(property) && !isHiddenProperty(property)
|
|
55
|
+
&& !isStorageProperty(property as Property)
|
|
36
56
|
&& (hasExplicitOrder || !isRelationProperty(property));
|
|
37
57
|
}).slice(0, limit);
|
|
38
58
|
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps a Rebase `Property` (from @rebasepro/types) to a `CollectionPropertyConfig`
|
|
3
|
+
* (from @rebasepro/ui), stripping all entity-specific fields and keeping only
|
|
4
|
+
* the UI-relevant subset.
|
|
5
|
+
*
|
|
6
|
+
* This is the bridge between the entity-aware and headless layers.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { Property, Properties, EnumValues, EnumValueConfig } from "@rebasepro/types";
|
|
10
|
+
import type { CollectionPropertyConfig, CollectionEnumValueConfig } from "@rebasepro/ui";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Map Rebase property types to headless-supported types.
|
|
14
|
+
* `vector` and `binary` are not directly renderable, so we fall back to `string`.
|
|
15
|
+
*/
|
|
16
|
+
const TYPE_MAP: Record<string, CollectionPropertyConfig["type"]> = {
|
|
17
|
+
string: "string",
|
|
18
|
+
number: "number",
|
|
19
|
+
boolean: "boolean",
|
|
20
|
+
date: "date",
|
|
21
|
+
geopoint: "geopoint",
|
|
22
|
+
reference: "reference",
|
|
23
|
+
relation: "relation",
|
|
24
|
+
array: "array",
|
|
25
|
+
map: "map",
|
|
26
|
+
vector: "string", // vectors display as text
|
|
27
|
+
binary: "string", // binary displays as text
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Convert a single Property to a CollectionPropertyConfig.
|
|
32
|
+
*/
|
|
33
|
+
export function mapPropertyToConfig(property: Property): CollectionPropertyConfig {
|
|
34
|
+
const base: CollectionPropertyConfig = {
|
|
35
|
+
type: TYPE_MAP[property.type] ?? "string",
|
|
36
|
+
name: property.name,
|
|
37
|
+
description: property.description,
|
|
38
|
+
columnWidth: property.ui?.columnWidth,
|
|
39
|
+
hideFromCollection: property.ui?.hideFromCollection,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// String-specific
|
|
43
|
+
if (property.type === "string") {
|
|
44
|
+
if (property.enum) {
|
|
45
|
+
base.enum = mapEnumValues(property.enum);
|
|
46
|
+
}
|
|
47
|
+
if (property.ui?.multiline) base.multiline = true;
|
|
48
|
+
if (property.ui?.previewAsTag) base.previewAsTag = true;
|
|
49
|
+
if (property.ui?.url) base.url = property.ui.url;
|
|
50
|
+
if (property.ui?.markdown) base.markdown = true;
|
|
51
|
+
if (property.storage) base.storage = true;
|
|
52
|
+
if (property.email) base.email = true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Number-specific
|
|
56
|
+
if (property.type === "number" && property.enum) {
|
|
57
|
+
base.enum = mapEnumValues(property.enum);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Array-specific
|
|
61
|
+
if (property.type === "array" && property.of && !Array.isArray(property.of)) {
|
|
62
|
+
base.of = mapPropertyToConfig(property.of);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Map-specific
|
|
66
|
+
if (property.type === "map" && property.properties) {
|
|
67
|
+
base.properties = mapPropertiesToConfigs(property.properties);
|
|
68
|
+
if (property.propertiesOrder) {
|
|
69
|
+
base.propertiesOrder = property.propertiesOrder;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Date-specific
|
|
74
|
+
if (property.type === "date" && property.mode) {
|
|
75
|
+
base.mode = property.mode;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Custom preview component
|
|
79
|
+
if (property.ui?.Preview) {
|
|
80
|
+
// The connected wrapper will handle this by injecting via cellRenderer override
|
|
81
|
+
// We don't copy it here because Preview may reference entity-aware components
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return base;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Convert a Properties record to a CollectionPropertyConfig record.
|
|
89
|
+
*/
|
|
90
|
+
export function mapPropertiesToConfigs(
|
|
91
|
+
properties: Properties
|
|
92
|
+
): Record<string, CollectionPropertyConfig> {
|
|
93
|
+
const result: Record<string, CollectionPropertyConfig> = {};
|
|
94
|
+
for (const [key, property] of Object.entries(properties)) {
|
|
95
|
+
result[key] = mapPropertyToConfig(property);
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Convert Rebase EnumValues to CollectionEnumValueConfig format.
|
|
102
|
+
* Handles both array form (EnumValueConfig[]) and record form.
|
|
103
|
+
*/
|
|
104
|
+
function mapEnumValues(
|
|
105
|
+
enumValues: EnumValues | undefined
|
|
106
|
+
): Record<string, CollectionEnumValueConfig> | Map<string | number, CollectionEnumValueConfig> | undefined {
|
|
107
|
+
if (!enumValues) return undefined;
|
|
108
|
+
|
|
109
|
+
// Array form: EnumValueConfig[]
|
|
110
|
+
if (Array.isArray(enumValues)) {
|
|
111
|
+
const result: Record<string, CollectionEnumValueConfig> = {};
|
|
112
|
+
for (const item of enumValues) {
|
|
113
|
+
result[String(item.id)] = normalizeEnumValueConfig(item);
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Record form: Record<string | number, string | EnumValueConfig>
|
|
119
|
+
const result: Record<string, CollectionEnumValueConfig> = {};
|
|
120
|
+
for (const [key, value] of Object.entries(enumValues)) {
|
|
121
|
+
result[key] = typeof value === "string"
|
|
122
|
+
? value
|
|
123
|
+
: normalizeEnumValueConfig(value);
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function normalizeEnumValueConfig(config: EnumValueConfig): CollectionEnumValueConfig {
|
|
129
|
+
return {
|
|
130
|
+
label: config.label,
|
|
131
|
+
color: typeof config.color === "string" ? config.color : undefined,
|
|
132
|
+
disabled: config.disabled,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import type { Properties } from "@rebasepro/types";
|
|
3
|
-
import type { EntityCollection, MapProperty, Property, PropertyConfig
|
|
3
|
+
import type { EntityCollection, MapProperty, Property, PropertyConfig } from "@rebasepro/types";
|
|
4
4
|
import React from "react";
|
|
5
5
|
|
|
6
6
|
import { isPropertyBuilder } from "@rebasepro/common";
|
|
@@ -75,7 +75,6 @@ function getDefaultIconForProperty(property: Property): LucideIcon {
|
|
|
75
75
|
if (property.ui?.url) return GlobeIcon;
|
|
76
76
|
if (property.email) return MailIcon;
|
|
77
77
|
if (property.ui?.multiline || property.ui?.markdown) return AlignLeftIcon;
|
|
78
|
-
if ((property as StringProperty).reference) return LinkIcon;
|
|
79
78
|
return TextIcon;
|
|
80
79
|
}
|
|
81
80
|
case "number":
|