@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.
Files changed (187) hide show
  1. package/dist/{CollectionEditorDialog-HNXGxXdO.js → CollectionEditorDialog-BO_aQ-Z4.js} +236 -155
  2. package/dist/CollectionEditorDialog-BO_aQ-Z4.js.map +1 -0
  3. package/dist/{PropertyEditView-C2wp8kQ9.js → PropertyEditView-DKzOpMjR.js} +190 -50
  4. package/dist/PropertyEditView-DKzOpMjR.js.map +1 -0
  5. package/dist/{CollectionsStudioView-B1mN33GB.js → RouterCollectionsStudioView-BQTIExjA.js} +61 -39
  6. package/dist/RouterCollectionsStudioView-BQTIExjA.js.map +1 -0
  7. package/dist/collection_editor/_cms_internals.d.ts +1 -1
  8. package/dist/collection_editor/api/generateCollectionApi.d.ts +3 -2
  9. package/dist/collection_editor/extensibility_types.d.ts +135 -0
  10. package/dist/collection_editor/index.d.ts +6 -0
  11. package/dist/collection_editor/serializable_types.d.ts +370 -0
  12. package/dist/collection_editor/serializable_utils.d.ts +50 -0
  13. package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +3 -3
  14. package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +12 -1
  15. package/dist/collection_editor/ui/collection_editor/CollectionStudioView.d.ts +13 -1
  16. package/dist/collection_editor/ui/collection_editor/CollectionsStudioView.d.ts +24 -2
  17. package/dist/collection_editor/ui/collection_editor/DisplaySettingsForm.d.ts +2 -1
  18. package/dist/collection_editor/ui/collection_editor/GeneralSettingsForm.d.ts +4 -1
  19. package/dist/collection_editor/ui/collection_editor/PropertyEditView.d.ts +12 -1
  20. package/dist/collection_editor/ui/collection_editor/RouterCollectionStudioView.d.ts +15 -0
  21. package/dist/collection_editor/ui/collection_editor/RouterCollectionsStudioView.d.ts +14 -0
  22. package/dist/collection_editor/useJsonCollectionsConfigController.d.ts +37 -0
  23. package/dist/collection_editor/useSafeSnackbarController.d.ts +2 -0
  24. package/dist/collection_editor_ui.d.ts +4 -0
  25. package/dist/collection_editor_ui.js +33 -4
  26. package/dist/collection_editor_ui.js.map +1 -0
  27. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
  28. package/dist/components/EntityCollectionTable/index.d.ts +1 -1
  29. package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +3 -3
  30. package/dist/components/EntityCollectionView/hooks/useKanbanDragAndDrop.d.ts +3 -3
  31. package/dist/components/EntityEditView.d.ts +3 -2
  32. package/dist/components/RebaseCMS.d.ts +1 -1
  33. package/dist/components/SelectableTable/SelectionStore.d.ts +12 -21
  34. package/dist/components/field_configs.d.ts +1 -1
  35. package/dist/editor/editor.d.ts +0 -6
  36. package/dist/editor.js +1 -3
  37. package/dist/editor.js.map +1 -1
  38. package/dist/form/EntityForm.d.ts +10 -9
  39. package/dist/form/EntityFormBinding.d.ts +27 -0
  40. package/dist/form/components/StorageUploadProgress.d.ts +6 -1
  41. package/dist/form/form_utils.d.ts +8 -0
  42. package/dist/form/index.d.ts +5 -2
  43. package/dist/{history-BO6VT85a.js → history-B3cqBzEV.js} +2 -2
  44. package/dist/{history-BO6VT85a.js.map → history-B3cqBzEV.js.map} +1 -1
  45. package/dist/hooks/navigation/contexts/CollectionRegistryContext.d.ts +1 -1
  46. package/dist/hooks/navigation/useAsyncResolver.d.ts +26 -0
  47. package/dist/hooks/navigation/useBuildCollectionRegistryController.d.ts +2 -0
  48. package/dist/hooks/navigation/useTopLevelNavigation.d.ts +1 -1
  49. package/dist/hooks/navigation/utils.d.ts +1 -1
  50. package/dist/index.d.ts +3 -1
  51. package/dist/index.js +2 -2
  52. package/dist/preview/components/StorageThumbnail.d.ts +3 -1
  53. package/dist/routes/CustomViewRoute.d.ts +2 -1
  54. package/dist/{src-BYniefVu.js → src-cxV1ODRG.js} +1731 -1710
  55. package/dist/src-cxV1ODRG.js.map +1 -0
  56. package/dist/types/components/EntityFormActionsProps.d.ts +1 -1
  57. package/dist/types/components/EntityFormProps.d.ts +59 -0
  58. package/dist/types/components/PropertyPreviewProps.d.ts +2 -1
  59. package/dist/types/fields.d.ts +10 -7
  60. package/dist/util/dataControllerAdapter.d.ts +30 -0
  61. package/dist/util/navigation_utils.d.ts +1 -1
  62. package/dist/util/propertyConfigMapper.d.ts +17 -0
  63. package/package.json +8 -8
  64. package/src/collection_editor/_cms_internals.ts +1 -1
  65. package/src/collection_editor/api/generateCollectionApi.ts +3 -2
  66. package/src/collection_editor/extensibility_types.ts +168 -0
  67. package/src/collection_editor/index.ts +46 -0
  68. package/src/collection_editor/pgColumnToProperty.ts +2 -2
  69. package/src/collection_editor/serializable_types.ts +474 -0
  70. package/src/collection_editor/serializable_utils.ts +576 -0
  71. package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +6 -6
  72. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +170 -89
  73. package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +95 -78
  74. package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +23 -20
  75. package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +79 -27
  76. package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +9 -7
  77. package/src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx +22 -5
  78. package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +3 -3
  79. package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +154 -18
  80. package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +6 -6
  81. package/src/collection_editor/ui/collection_editor/PropertyTree.tsx +1 -0
  82. package/src/collection_editor/ui/collection_editor/RouterCollectionStudioView.tsx +44 -0
  83. package/src/collection_editor/ui/collection_editor/RouterCollectionsStudioView.tsx +41 -0
  84. package/src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx +4 -3
  85. package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +35 -1
  86. package/src/collection_editor/ui/collection_editor/templates/blog_template.ts +1 -1
  87. package/src/collection_editor/ui/collection_editor/utils/supported_fields.tsx +0 -1
  88. package/src/collection_editor/ui/collection_editor/utils/update_property_for_widget.ts +7 -29
  89. package/src/collection_editor/useJsonCollectionsConfigController.tsx +286 -0
  90. package/src/collection_editor/useSafeSnackbarController.ts +9 -0
  91. package/src/collection_editor_ui.ts +6 -0
  92. package/src/components/DefaultDrawer.tsx +14 -4
  93. package/src/components/DrawerNavigationGroup.tsx +2 -2
  94. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +11 -9
  95. package/src/components/EntityCollectionTable/fields/TableMultipleRelationField.tsx +2 -1
  96. package/src/components/EntityCollectionTable/fields/TableRelationField.tsx +2 -1
  97. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +23 -20
  98. package/src/components/EntityCollectionTable/index.tsx +1 -1
  99. package/src/components/EntityCollectionTable/table_bindings.tsx +24 -44
  100. package/src/components/EntityCollectionView/EntityBoardCard.tsx +6 -6
  101. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +13 -12
  102. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +40 -190
  103. package/src/components/EntityCollectionView/EntityCollectionListView.tsx +66 -184
  104. package/src/components/EntityCollectionView/EntityCollectionView.tsx +8 -25
  105. package/src/components/EntityCollectionView/hooks/useCollectionInlineEditor.ts +1 -1
  106. package/src/components/EntityCollectionView/hooks/useKanbanDragAndDrop.ts +6 -6
  107. package/src/components/EntityCollectionView/useBoardDataController.tsx +12 -40
  108. package/src/components/EntityCollectionView/useEntityPreviewSlots.ts +3 -3
  109. package/src/components/EntityDetailView.tsx +2 -2
  110. package/src/components/EntityEditView.tsx +7 -6
  111. package/src/components/EntityEditViewFormActions.tsx +35 -29
  112. package/src/components/HomePage/ContentHomePage.tsx +14 -5
  113. package/src/components/RebaseCMS.tsx +3 -3
  114. package/src/components/RebaseNavigation.tsx +74 -9
  115. package/src/components/RelationSelector.tsx +2 -2
  116. package/src/components/SelectableTable/SelectableTable.tsx +13 -5
  117. package/src/components/SelectableTable/SelectionStore.ts +18 -48
  118. package/src/components/SideDialogs.tsx +0 -7
  119. package/src/components/common/default_entity_actions.tsx +22 -11
  120. package/src/components/field_configs.tsx +0 -14
  121. package/src/contexts/BreacrumbsContext.tsx +15 -6
  122. package/src/editor/editor.tsx +4 -7
  123. package/src/editor/selectors/ai-selector.tsx +0 -1
  124. package/src/form/EntityForm.tsx +191 -428
  125. package/src/form/EntityFormActions.tsx +35 -49
  126. package/src/form/EntityFormBinding.tsx +323 -0
  127. package/src/form/components/FormLayout.tsx +1 -1
  128. package/src/form/components/StorageUploadProgress.tsx +9 -2
  129. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +12 -1
  130. package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +4 -4
  131. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +7 -2
  132. package/src/form/field_bindings/RelationFieldBinding.tsx +5 -7
  133. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +19 -15
  134. package/src/form/form_utils.ts +163 -0
  135. package/src/form/index.tsx +14 -6
  136. package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +2 -2
  137. package/src/hooks/navigation/contexts/NavigationStateContext.tsx +2 -2
  138. package/src/hooks/navigation/contexts/UrlContext.tsx +1 -2
  139. package/src/hooks/navigation/useAsyncResolver.ts +100 -0
  140. package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +15 -8
  141. package/src/hooks/navigation/useBuildNavigationStateController.tsx +12 -8
  142. package/src/hooks/navigation/useNavigationResolution.ts +33 -0
  143. package/src/hooks/navigation/useResolvedCollections.ts +29 -71
  144. package/src/hooks/navigation/useResolvedViews.tsx +40 -70
  145. package/src/hooks/navigation/useTopLevelNavigation.ts +20 -16
  146. package/src/hooks/navigation/utils.ts +7 -4
  147. package/src/index.ts +6 -1
  148. package/src/preview/PropertyPreview.tsx +1 -16
  149. package/src/preview/components/StorageThumbnail.tsx +24 -7
  150. package/src/routes/CustomViewRoute.tsx +14 -6
  151. package/src/types/components/EntityFormActionsProps.tsx +1 -1
  152. package/src/types/components/EntityFormProps.tsx +68 -0
  153. package/src/types/components/PropertyPreviewProps.tsx +1 -1
  154. package/src/types/fields.tsx +9 -8
  155. package/src/util/dataControllerAdapter.ts +93 -0
  156. package/src/util/navigation_utils.ts +1 -1
  157. package/src/util/previews.ts +20 -0
  158. package/src/util/propertyConfigMapper.ts +134 -0
  159. package/src/util/property_utils.tsx +1 -2
  160. package/dist/CollectionEditorDialog-HNXGxXdO.js.map +0 -1
  161. package/dist/CollectionsStudioView-B1mN33GB.js.map +0 -1
  162. package/dist/PropertyEditView-C2wp8kQ9.js.map +0 -1
  163. package/dist/components/EntityCollectionTable/fields/VirtualTableDateField.d.ts +0 -12
  164. package/dist/components/EntityCollectionTable/fields/VirtualTableInput.d.ts +0 -10
  165. package/dist/components/EntityCollectionTable/fields/VirtualTableNumberInput.d.ts +0 -9
  166. package/dist/components/EntityCollectionTable/fields/VirtualTableSwitch.d.ts +0 -8
  167. package/dist/components/EntityCollectionView/Board.d.ts +0 -3
  168. package/dist/components/EntityCollectionView/BoardColumn.d.ts +0 -42
  169. package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +0 -9
  170. package/dist/components/EntityCollectionView/BoardSortableList.d.ts +0 -14
  171. package/dist/components/EntityCollectionView/board_types.d.ts +0 -105
  172. package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +0 -11
  173. package/dist/hooks/navigation/useNavigationRegistry.d.ts +0 -12
  174. package/dist/hooks/navigation/useNavigationURLs.d.ts +0 -11
  175. package/dist/src-BYniefVu.js.map +0 -1
  176. package/src/components/EntityCollectionTable/fields/VirtualTableDateField.tsx +0 -39
  177. package/src/components/EntityCollectionTable/fields/VirtualTableInput.tsx +0 -90
  178. package/src/components/EntityCollectionTable/fields/VirtualTableNumberInput.tsx +0 -83
  179. package/src/components/EntityCollectionTable/fields/VirtualTableSwitch.tsx +0 -32
  180. package/src/components/EntityCollectionView/Board.tsx +0 -475
  181. package/src/components/EntityCollectionView/BoardColumn.tsx +0 -165
  182. package/src/components/EntityCollectionView/BoardColumnTitle.tsx +0 -46
  183. package/src/components/EntityCollectionView/BoardSortableList.tsx +0 -177
  184. package/src/components/EntityCollectionView/board_types.ts +0 -113
  185. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +0 -141
  186. package/src/hooks/navigation/useNavigationRegistry.ts +0 -164
  187. package/src/hooks/navigation/useNavigationURLs.ts +0 -56
@@ -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: "side_panel" | "full_screen" | "split" | "dialog";
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: "side_panel" | "full_screen" | "split" | "dialog";
34
+ openEntityMode?: "side_panel" | "full_screen" | "split" | "dialog";
35
35
  collection?: EntityCollection;
36
36
  entityId?: string | number;
37
37
  selectedTab?: string;
@@ -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, StringProperty } from "@rebasepro/types";
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":