@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
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversion utilities between the full Rebase types and their
|
|
3
|
+
* JSON-serializable counterparts.
|
|
4
|
+
*
|
|
5
|
+
* - `toSerializableCollection` / `toSerializableProperty` — strip non-serializable fields
|
|
6
|
+
* - `fromSerializableCollection` / `fromSerializableProperty` — reconstruct original types
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type {
|
|
12
|
+
ArrayProperty,
|
|
13
|
+
BaseUIConfig,
|
|
14
|
+
BinaryProperty,
|
|
15
|
+
BooleanProperty,
|
|
16
|
+
DateProperty,
|
|
17
|
+
EntityCollection,
|
|
18
|
+
GeopointProperty,
|
|
19
|
+
MapProperty,
|
|
20
|
+
NumberProperty,
|
|
21
|
+
Properties,
|
|
22
|
+
Property,
|
|
23
|
+
ReferenceProperty,
|
|
24
|
+
RelationProperty,
|
|
25
|
+
StorageConfig,
|
|
26
|
+
StringProperty,
|
|
27
|
+
VectorProperty,
|
|
28
|
+
} from "@rebasepro/types";
|
|
29
|
+
|
|
30
|
+
import type {
|
|
31
|
+
SerializableArrayProperty,
|
|
32
|
+
SerializableBaseProperty,
|
|
33
|
+
SerializableBaseUIConfig,
|
|
34
|
+
SerializableBinaryProperty,
|
|
35
|
+
SerializableBooleanProperty,
|
|
36
|
+
SerializableCollection,
|
|
37
|
+
SerializableDateProperty,
|
|
38
|
+
SerializableDateValidation,
|
|
39
|
+
SerializableGeopointProperty,
|
|
40
|
+
SerializableMapProperty,
|
|
41
|
+
SerializableNumberProperty,
|
|
42
|
+
SerializableProperties,
|
|
43
|
+
SerializableProperty,
|
|
44
|
+
SerializableReferenceProperty,
|
|
45
|
+
SerializableRelationProperty,
|
|
46
|
+
SerializableStorageConfig,
|
|
47
|
+
SerializableStringProperty,
|
|
48
|
+
SerializableStringValidation,
|
|
49
|
+
SerializableVectorProperty,
|
|
50
|
+
} from "./serializable_types";
|
|
51
|
+
|
|
52
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
53
|
+
// PROPERTY CONVERSION: Original → Serializable
|
|
54
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Strip non-serializable fields from a `BaseUIConfig`.
|
|
58
|
+
* Removes `Field` and `Preview` (ComponentRef).
|
|
59
|
+
*/
|
|
60
|
+
function toSerializableUIConfig(ui: BaseUIConfig | undefined): SerializableBaseUIConfig | undefined {
|
|
61
|
+
if (!ui) return undefined;
|
|
62
|
+
const { Field, Preview, ...rest } = ui as BaseUIConfig & Record<string, unknown>;
|
|
63
|
+
// Only return if there are remaining fields
|
|
64
|
+
const result: Record<string, unknown> = {};
|
|
65
|
+
for (const [key, value] of Object.entries(rest)) {
|
|
66
|
+
if (key !== "Field" && key !== "Preview" && value !== undefined) {
|
|
67
|
+
result[key] = value;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return Object.keys(result).length > 0 ? result as SerializableBaseUIConfig : undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Convert a `StorageConfig` to its serializable form.
|
|
75
|
+
* Drops function variants of `storagePath`, `fileName`, and all function fields.
|
|
76
|
+
*/
|
|
77
|
+
function toSerializableStorageConfig(storage: StorageConfig | undefined): SerializableStorageConfig | undefined {
|
|
78
|
+
if (!storage) return undefined;
|
|
79
|
+
|
|
80
|
+
// storagePath must be a string for serialization
|
|
81
|
+
const storagePath = typeof storage.storagePath === "string" ? storage.storagePath : undefined;
|
|
82
|
+
if (!storagePath) return undefined;
|
|
83
|
+
|
|
84
|
+
const result: SerializableStorageConfig = { storagePath };
|
|
85
|
+
|
|
86
|
+
if (storage.acceptedFiles) result.acceptedFiles = storage.acceptedFiles;
|
|
87
|
+
if (storage.imageResize) result.imageResize = storage.imageResize;
|
|
88
|
+
if (storage.metadata) result.metadata = storage.metadata;
|
|
89
|
+
if (typeof storage.fileName === "string") result.fileName = storage.fileName;
|
|
90
|
+
if (storage.includeBucketUrl !== undefined) result.includeBucketUrl = storage.includeBucketUrl;
|
|
91
|
+
if (storage.storeUrl !== undefined) result.storeUrl = storage.storeUrl;
|
|
92
|
+
if (storage.maxSize !== undefined) result.maxSize = storage.maxSize;
|
|
93
|
+
if (storage.storageSource !== undefined) result.storageSource = storage.storageSource;
|
|
94
|
+
// processFile, postProcess, previewUrl are intentionally dropped (functions)
|
|
95
|
+
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Convert a RegExp or string `matches` validation to a plain string.
|
|
101
|
+
*/
|
|
102
|
+
function serializeMatches(matches: string | RegExp | undefined): string | undefined {
|
|
103
|
+
if (matches === undefined) return undefined;
|
|
104
|
+
if (typeof matches === "string") return matches;
|
|
105
|
+
return matches.source;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Resolve a relation target to a string slug.
|
|
110
|
+
* Functions are called to extract the target; EntityCollection objects
|
|
111
|
+
* use their slug.
|
|
112
|
+
*/
|
|
113
|
+
function resolveRelationTarget(target: RelationProperty["target"]): string | undefined {
|
|
114
|
+
if (!target) return undefined;
|
|
115
|
+
if (typeof target === "string") return target;
|
|
116
|
+
if (typeof target === "function") {
|
|
117
|
+
try {
|
|
118
|
+
const resolved = target();
|
|
119
|
+
if (typeof resolved === "string") return resolved;
|
|
120
|
+
if (resolved && typeof resolved === "object" && "slug" in resolved) {
|
|
121
|
+
return (resolved as EntityCollection).slug;
|
|
122
|
+
}
|
|
123
|
+
} catch {
|
|
124
|
+
// If the lazy resolver throws (e.g., circular dependency not yet ready), return undefined
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Strip non-serializable base property fields.
|
|
132
|
+
* Returns a clean object with only the common serializable fields from BaseProperty.
|
|
133
|
+
* Validation is intentionally excluded — each property type handles its own.
|
|
134
|
+
*/
|
|
135
|
+
function toSerializableBaseFields(property: Property): Omit<SerializableBaseProperty, "validation"> {
|
|
136
|
+
const result: Partial<Omit<SerializableBaseProperty, "validation">> = {
|
|
137
|
+
name: property.name,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
if (property.description) result.description = property.description;
|
|
141
|
+
if (property.propertyConfig) result.propertyConfig = property.propertyConfig;
|
|
142
|
+
if (property.columnName) result.columnName = property.columnName;
|
|
143
|
+
if (property.defaultValue !== undefined) result.defaultValue = property.defaultValue;
|
|
144
|
+
if (property.conditions) result.conditions = property.conditions;
|
|
145
|
+
if (property.metadata) result.metadata = property.metadata;
|
|
146
|
+
// dynamicProps and callbacks are intentionally dropped (functions)
|
|
147
|
+
|
|
148
|
+
const ui = toSerializableUIConfig(property.ui);
|
|
149
|
+
if (ui) result.ui = ui;
|
|
150
|
+
|
|
151
|
+
return result as Omit<SerializableBaseProperty, "validation">;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Convert a single `Property` to its JSON-serializable form.
|
|
156
|
+
* Strips functions, converts RegExp to string, Date to ISO string.
|
|
157
|
+
*/
|
|
158
|
+
export function toSerializableProperty(property: Property): SerializableProperty {
|
|
159
|
+
const base = toSerializableBaseFields(property);
|
|
160
|
+
|
|
161
|
+
switch (property.type) {
|
|
162
|
+
case "string": {
|
|
163
|
+
const sp = property as StringProperty;
|
|
164
|
+
const result: SerializableStringProperty = {
|
|
165
|
+
...base,
|
|
166
|
+
type: "string",
|
|
167
|
+
};
|
|
168
|
+
if (sp.columnType) result.columnType = sp.columnType;
|
|
169
|
+
if (sp.isId !== undefined) result.isId = sp.isId;
|
|
170
|
+
if (sp.enum) result.enum = sp.enum;
|
|
171
|
+
if (sp.userSelect) result.userSelect = sp.userSelect;
|
|
172
|
+
if (sp.email) result.email = sp.email;
|
|
173
|
+
|
|
174
|
+
// Convert validation.matches from RegExp to string
|
|
175
|
+
if (sp.validation) {
|
|
176
|
+
const { matches, ...restValidation } = sp.validation;
|
|
177
|
+
const serializedValidation: SerializableStringValidation = { ...restValidation };
|
|
178
|
+
const matchStr = serializeMatches(matches);
|
|
179
|
+
if (matchStr !== undefined) serializedValidation.matches = matchStr;
|
|
180
|
+
result.validation = serializedValidation;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Storage: convert to serializable form
|
|
184
|
+
const storage = toSerializableStorageConfig(sp.storage);
|
|
185
|
+
if (storage) result.storage = storage;
|
|
186
|
+
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
case "number": {
|
|
191
|
+
const np = property as NumberProperty;
|
|
192
|
+
const result: SerializableNumberProperty = {
|
|
193
|
+
...base,
|
|
194
|
+
type: "number",
|
|
195
|
+
};
|
|
196
|
+
if (np.columnType) result.columnType = np.columnType;
|
|
197
|
+
if (np.validation) result.validation = np.validation;
|
|
198
|
+
if (np.isId !== undefined) result.isId = np.isId;
|
|
199
|
+
if (np.enum) result.enum = np.enum;
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
case "boolean": {
|
|
204
|
+
const bp = property as BooleanProperty;
|
|
205
|
+
const result: SerializableBooleanProperty = {
|
|
206
|
+
...base,
|
|
207
|
+
type: "boolean",
|
|
208
|
+
};
|
|
209
|
+
if (bp.validation) result.validation = bp.validation;
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
case "date": {
|
|
214
|
+
const dp = property as DateProperty;
|
|
215
|
+
const result: SerializableDateProperty = {
|
|
216
|
+
...base,
|
|
217
|
+
type: "date",
|
|
218
|
+
};
|
|
219
|
+
if (dp.columnType) result.columnType = dp.columnType;
|
|
220
|
+
if (dp.mode) result.mode = dp.mode;
|
|
221
|
+
if (dp.timezone) result.timezone = dp.timezone;
|
|
222
|
+
if (dp.autoValue) result.autoValue = dp.autoValue;
|
|
223
|
+
|
|
224
|
+
// Convert Date validation min/max to ISO strings
|
|
225
|
+
if (dp.validation) {
|
|
226
|
+
const serializedValidation: SerializableDateValidation = {};
|
|
227
|
+
if (dp.validation.required !== undefined) serializedValidation.required = dp.validation.required;
|
|
228
|
+
if (dp.validation.requiredMessage) serializedValidation.requiredMessage = dp.validation.requiredMessage;
|
|
229
|
+
if (dp.validation.unique) serializedValidation.unique = dp.validation.unique;
|
|
230
|
+
if (dp.validation.uniqueInArray) serializedValidation.uniqueInArray = dp.validation.uniqueInArray;
|
|
231
|
+
if (dp.validation.min instanceof Date) {
|
|
232
|
+
serializedValidation.min = dp.validation.min.toISOString();
|
|
233
|
+
} else if (typeof dp.validation.min === "string") {
|
|
234
|
+
serializedValidation.min = dp.validation.min;
|
|
235
|
+
}
|
|
236
|
+
if (dp.validation.max instanceof Date) {
|
|
237
|
+
serializedValidation.max = dp.validation.max.toISOString();
|
|
238
|
+
} else if (typeof dp.validation.max === "string") {
|
|
239
|
+
serializedValidation.max = dp.validation.max;
|
|
240
|
+
}
|
|
241
|
+
result.validation = serializedValidation;
|
|
242
|
+
}
|
|
243
|
+
return result;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
case "geopoint": {
|
|
247
|
+
const gp = property as GeopointProperty;
|
|
248
|
+
const result: SerializableGeopointProperty = {
|
|
249
|
+
...base,
|
|
250
|
+
type: "geopoint",
|
|
251
|
+
};
|
|
252
|
+
if (gp.validation) result.validation = gp.validation;
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
case "reference": {
|
|
257
|
+
const rp = property as ReferenceProperty;
|
|
258
|
+
const result: SerializableReferenceProperty = {
|
|
259
|
+
...base,
|
|
260
|
+
type: "reference",
|
|
261
|
+
};
|
|
262
|
+
if (rp.isId !== undefined) result.isId = rp.isId;
|
|
263
|
+
if (rp.path) result.path = rp.path;
|
|
264
|
+
if (rp.fixedFilter) result.fixedFilter = rp.fixedFilter;
|
|
265
|
+
if (rp.includeId !== undefined) result.includeId = rp.includeId;
|
|
266
|
+
if (rp.includeEntityLink !== undefined) result.includeEntityLink = rp.includeEntityLink;
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
case "relation": {
|
|
271
|
+
const rl = property as RelationProperty;
|
|
272
|
+
const result: SerializableRelationProperty = {
|
|
273
|
+
...base,
|
|
274
|
+
type: "relation",
|
|
275
|
+
};
|
|
276
|
+
if (rl.isId !== undefined) result.isId = rl.isId;
|
|
277
|
+
// Resolve target to string
|
|
278
|
+
const target = resolveRelationTarget(rl.target);
|
|
279
|
+
if (target) result.target = target;
|
|
280
|
+
if (rl.cardinality) result.cardinality = rl.cardinality;
|
|
281
|
+
if (rl.direction) result.direction = rl.direction;
|
|
282
|
+
if (rl.inverseRelationName) result.inverseRelationName = rl.inverseRelationName;
|
|
283
|
+
if (rl.localKey) result.localKey = rl.localKey;
|
|
284
|
+
if (rl.foreignKeyOnTarget) result.foreignKeyOnTarget = rl.foreignKeyOnTarget;
|
|
285
|
+
if (rl.through) result.through = rl.through;
|
|
286
|
+
if (rl.joinPath) result.joinPath = rl.joinPath;
|
|
287
|
+
if (rl.onUpdate) result.onUpdate = rl.onUpdate;
|
|
288
|
+
if (rl.onDelete) result.onDelete = rl.onDelete;
|
|
289
|
+
if (rl.relationName) result.relationName = rl.relationName;
|
|
290
|
+
if (rl.fixedFilter) result.fixedFilter = rl.fixedFilter;
|
|
291
|
+
if (rl.includeId !== undefined) result.includeId = rl.includeId;
|
|
292
|
+
if (rl.includeEntityLink !== undefined) result.includeEntityLink = rl.includeEntityLink;
|
|
293
|
+
if (rl.widget) result.widget = rl.widget;
|
|
294
|
+
// overrides and relation (resolved) are dropped
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
case "array": {
|
|
299
|
+
const ap = property as ArrayProperty;
|
|
300
|
+
const result: SerializableArrayProperty = {
|
|
301
|
+
...base,
|
|
302
|
+
type: "array",
|
|
303
|
+
};
|
|
304
|
+
if (ap.columnType) result.columnType = ap.columnType;
|
|
305
|
+
if (ap.validation) result.validation = ap.validation;
|
|
306
|
+
if (ap.sortable !== undefined) result.sortable = ap.sortable;
|
|
307
|
+
if (ap.canAddElements !== undefined) result.canAddElements = ap.canAddElements;
|
|
308
|
+
|
|
309
|
+
// Recursively serialize the "of" property
|
|
310
|
+
if (ap.of) {
|
|
311
|
+
if (Array.isArray(ap.of)) {
|
|
312
|
+
result.of = ap.of.map(toSerializableProperty);
|
|
313
|
+
} else {
|
|
314
|
+
result.of = toSerializableProperty(ap.of);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Recursively serialize oneOf properties
|
|
319
|
+
if (ap.oneOf) {
|
|
320
|
+
result.oneOf = {
|
|
321
|
+
properties: toSerializableProperties(ap.oneOf.properties),
|
|
322
|
+
};
|
|
323
|
+
if (ap.oneOf.propertiesOrder) result.oneOf.propertiesOrder = ap.oneOf.propertiesOrder;
|
|
324
|
+
if (ap.oneOf.typeField) result.oneOf.typeField = ap.oneOf.typeField;
|
|
325
|
+
if (ap.oneOf.valueField) result.oneOf.valueField = ap.oneOf.valueField;
|
|
326
|
+
}
|
|
327
|
+
return result;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
case "map": {
|
|
331
|
+
const mp = property as MapProperty;
|
|
332
|
+
const result: SerializableMapProperty = {
|
|
333
|
+
...base,
|
|
334
|
+
type: "map",
|
|
335
|
+
};
|
|
336
|
+
if (mp.columnType) result.columnType = mp.columnType;
|
|
337
|
+
if (mp.validation) result.validation = mp.validation;
|
|
338
|
+
if (mp.propertiesOrder) result.propertiesOrder = mp.propertiesOrder;
|
|
339
|
+
if (mp.previewProperties) result.previewProperties = mp.previewProperties;
|
|
340
|
+
if (mp.keyValue) result.keyValue = mp.keyValue;
|
|
341
|
+
|
|
342
|
+
// Recursively serialize nested properties
|
|
343
|
+
if (mp.properties) {
|
|
344
|
+
result.properties = toSerializableProperties(mp.properties);
|
|
345
|
+
}
|
|
346
|
+
return result;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
case "vector": {
|
|
350
|
+
const vp = property as VectorProperty;
|
|
351
|
+
const result: SerializableVectorProperty = {
|
|
352
|
+
...base,
|
|
353
|
+
type: "vector",
|
|
354
|
+
dimensions: vp.dimensions,
|
|
355
|
+
};
|
|
356
|
+
if (vp.validation) result.validation = vp.validation;
|
|
357
|
+
return result;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
case "binary": {
|
|
361
|
+
const bp = property as BinaryProperty;
|
|
362
|
+
const result: SerializableBinaryProperty = {
|
|
363
|
+
...base,
|
|
364
|
+
type: "binary",
|
|
365
|
+
};
|
|
366
|
+
if (bp.validation) result.validation = bp.validation;
|
|
367
|
+
return result;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
default:
|
|
371
|
+
// Exhaustive check: if new types are added, this will produce a compile error
|
|
372
|
+
return base as SerializableProperty;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Convert a `Properties` record to its serializable form.
|
|
378
|
+
*/
|
|
379
|
+
export function toSerializableProperties(properties: Properties): SerializableProperties {
|
|
380
|
+
const result: SerializableProperties = {};
|
|
381
|
+
for (const [key, property] of Object.entries(properties)) {
|
|
382
|
+
result[key] = toSerializableProperty(property);
|
|
383
|
+
}
|
|
384
|
+
return result;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
388
|
+
// COLLECTION CONVERSION: Original → Serializable
|
|
389
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Convert an `EntityCollection` to its JSON-serializable form.
|
|
393
|
+
*
|
|
394
|
+
* Strips all non-serializable fields (functions, React nodes, class instances)
|
|
395
|
+
* while preserving the structural schema that the collection editor works with.
|
|
396
|
+
*
|
|
397
|
+
* The result is safe for `JSON.stringify()` and database storage.
|
|
398
|
+
*/
|
|
399
|
+
export function toSerializableCollection(collection: EntityCollection): SerializableCollection {
|
|
400
|
+
const result: SerializableCollection = {
|
|
401
|
+
slug: collection.slug,
|
|
402
|
+
name: collection.name,
|
|
403
|
+
properties: toSerializableProperties(collection.properties),
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
// String fields
|
|
407
|
+
if (collection.singularName) result.singularName = collection.singularName;
|
|
408
|
+
if (collection.description) result.description = collection.description;
|
|
409
|
+
if (collection.group) result.group = collection.group;
|
|
410
|
+
if (collection.engine) result.engine = collection.engine;
|
|
411
|
+
if (collection.dataSource) result.dataSource = collection.dataSource;
|
|
412
|
+
if (collection.databaseId) result.databaseId = collection.databaseId;
|
|
413
|
+
if (collection.titleProperty) result.titleProperty = collection.titleProperty as string;
|
|
414
|
+
if (collection.ownerId) result.ownerId = collection.ownerId;
|
|
415
|
+
if (collection.metadata) result.metadata = collection.metadata;
|
|
416
|
+
if (collection.table) result.table = collection.table;
|
|
417
|
+
if ("schema" in collection && collection.schema) result.schema = collection.schema as string;
|
|
418
|
+
if (collection.orderProperty) result.orderProperty = collection.orderProperty as string;
|
|
419
|
+
|
|
420
|
+
// Icon: only keep string variant
|
|
421
|
+
if (typeof collection.icon === "string") result.icon = collection.icon;
|
|
422
|
+
|
|
423
|
+
// Array fields
|
|
424
|
+
if (collection.propertiesOrder) result.propertiesOrder = collection.propertiesOrder as string[];
|
|
425
|
+
if (collection.previewProperties) result.previewProperties = collection.previewProperties;
|
|
426
|
+
if (collection.listProperties) result.listProperties = collection.listProperties;
|
|
427
|
+
if (collection.enabledViews) result.enabledViews = collection.enabledViews;
|
|
428
|
+
if (collection.disableDefaultActions) result.disableDefaultActions = collection.disableDefaultActions;
|
|
429
|
+
if (collection.securityRules) result.securityRules = collection.securityRules;
|
|
430
|
+
|
|
431
|
+
// Enum-like fields
|
|
432
|
+
if (collection.openEntityMode) result.openEntityMode = collection.openEntityMode;
|
|
433
|
+
if (collection.defaultEntityAction) result.defaultEntityAction = collection.defaultEntityAction;
|
|
434
|
+
if (collection.defaultViewMode) result.defaultViewMode = collection.defaultViewMode;
|
|
435
|
+
if (collection.defaultSize) result.defaultSize = collection.defaultSize;
|
|
436
|
+
if (collection.localChangesBackup !== undefined) result.localChangesBackup = collection.localChangesBackup;
|
|
437
|
+
|
|
438
|
+
// Kanban
|
|
439
|
+
if (collection.kanban) result.kanban = collection.kanban as SerializableCollection["kanban"];
|
|
440
|
+
|
|
441
|
+
// Filters and sorting
|
|
442
|
+
if (collection.fixedFilter) result.fixedFilter = collection.fixedFilter as SerializableCollection["fixedFilter"];
|
|
443
|
+
if (collection.defaultFilter) result.defaultFilter = collection.defaultFilter as SerializableCollection["defaultFilter"];
|
|
444
|
+
if (collection.filterPresets) result.filterPresets = collection.filterPresets as SerializableCollection["filterPresets"];
|
|
445
|
+
if (collection.sort) result.sort = collection.sort as SerializableCollection["sort"];
|
|
446
|
+
|
|
447
|
+
// Numeric / boolean flags
|
|
448
|
+
if (collection.pagination !== undefined) result.pagination = collection.pagination;
|
|
449
|
+
if (collection.selectionEnabled !== undefined) result.selectionEnabled = collection.selectionEnabled;
|
|
450
|
+
if (collection.inlineEditing !== undefined) result.inlineEditing = collection.inlineEditing;
|
|
451
|
+
if (collection.hideFromNavigation !== undefined) result.hideFromNavigation = collection.hideFromNavigation;
|
|
452
|
+
if (collection.hideIdFromForm !== undefined) result.hideIdFromForm = collection.hideIdFromForm;
|
|
453
|
+
if (collection.hideIdFromCollection !== undefined) result.hideIdFromCollection = collection.hideIdFromCollection;
|
|
454
|
+
if (collection.formAutoSave !== undefined) result.formAutoSave = collection.formAutoSave;
|
|
455
|
+
if (collection.alwaysApplyDefaultValues !== undefined) result.alwaysApplyDefaultValues = collection.alwaysApplyDefaultValues;
|
|
456
|
+
if (collection.includeJsonView !== undefined) result.includeJsonView = collection.includeJsonView;
|
|
457
|
+
if (collection.history !== undefined) result.history = collection.history;
|
|
458
|
+
if (collection.sideDialogWidth !== undefined) result.sideDialogWidth = collection.sideDialogWidth;
|
|
459
|
+
|
|
460
|
+
// Exportable: only keep boolean variant
|
|
461
|
+
if (typeof collection.exportable === "boolean") result.exportable = collection.exportable;
|
|
462
|
+
|
|
463
|
+
// Auth: only keep boolean variant
|
|
464
|
+
if (typeof collection.auth === "boolean") result.auth = collection.auth;
|
|
465
|
+
|
|
466
|
+
// defaultSelectedView: only keep string variant
|
|
467
|
+
if (typeof collection.defaultSelectedView === "string") result.defaultSelectedView = collection.defaultSelectedView;
|
|
468
|
+
|
|
469
|
+
return result;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
473
|
+
// PROPERTY CONVERSION: Serializable → Original
|
|
474
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Convert a serializable property back to the original `Property` type.
|
|
478
|
+
*
|
|
479
|
+
* This is a mostly pass-through operation since serializable properties
|
|
480
|
+
* are a subset of the original types. The main conversions are:
|
|
481
|
+
* - `validation.matches` (string) stays as string (compatible with Property)
|
|
482
|
+
* - `validation.min/max` on dates: ISO strings → Date objects
|
|
483
|
+
*/
|
|
484
|
+
export function fromSerializableProperty(serialized: SerializableProperty): Property {
|
|
485
|
+
switch (serialized.type) {
|
|
486
|
+
case "date": {
|
|
487
|
+
const sp = serialized as SerializableDateProperty;
|
|
488
|
+
const { validation: dateValidation, ...dateRest } = sp;
|
|
489
|
+
const result: Record<string, unknown> = { ...dateRest, type: "date" };
|
|
490
|
+
// Convert ISO string dates back to Date objects
|
|
491
|
+
if (dateValidation) {
|
|
492
|
+
const convertedValidation: Record<string, unknown> = { ...dateValidation };
|
|
493
|
+
if (typeof dateValidation.min === "string") {
|
|
494
|
+
convertedValidation.min = new Date(dateValidation.min);
|
|
495
|
+
}
|
|
496
|
+
if (typeof dateValidation.max === "string") {
|
|
497
|
+
convertedValidation.max = new Date(dateValidation.max);
|
|
498
|
+
}
|
|
499
|
+
result.validation = convertedValidation;
|
|
500
|
+
}
|
|
501
|
+
return result as unknown as DateProperty;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
case "array": {
|
|
505
|
+
const sp = serialized as SerializableArrayProperty;
|
|
506
|
+
const result = { ...sp } as unknown as ArrayProperty;
|
|
507
|
+
// Recursively convert "of" property
|
|
508
|
+
if (sp.of) {
|
|
509
|
+
if (Array.isArray(sp.of)) {
|
|
510
|
+
result.of = sp.of.map(fromSerializableProperty);
|
|
511
|
+
} else {
|
|
512
|
+
result.of = fromSerializableProperty(sp.of);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
// Recursively convert oneOf properties
|
|
516
|
+
if (sp.oneOf) {
|
|
517
|
+
result.oneOf = {
|
|
518
|
+
...sp.oneOf,
|
|
519
|
+
properties: fromSerializableProperties(sp.oneOf.properties),
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
return result;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
case "map": {
|
|
526
|
+
const sp = serialized as SerializableMapProperty;
|
|
527
|
+
const result = { ...sp } as unknown as MapProperty;
|
|
528
|
+
// Recursively convert nested properties
|
|
529
|
+
if (sp.properties) {
|
|
530
|
+
result.properties = fromSerializableProperties(sp.properties);
|
|
531
|
+
}
|
|
532
|
+
return result;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
case "string": {
|
|
536
|
+
const sp = serialized as SerializableStringProperty;
|
|
537
|
+
const result = { ...sp } as unknown as StringProperty;
|
|
538
|
+
return result;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
default:
|
|
542
|
+
// For all other types, the serializable form is already a valid Property
|
|
543
|
+
return serialized as unknown as Property;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Convert a `SerializableProperties` record back to `Properties`.
|
|
549
|
+
*/
|
|
550
|
+
export function fromSerializableProperties(serialized: SerializableProperties): Properties {
|
|
551
|
+
const result: Properties = {};
|
|
552
|
+
for (const [key, property] of Object.entries(serialized)) {
|
|
553
|
+
result[key] = fromSerializableProperty(property);
|
|
554
|
+
}
|
|
555
|
+
return result;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
559
|
+
// COLLECTION CONVERSION: Serializable → Original
|
|
560
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Convert a `SerializableCollection` back to an `EntityCollection`.
|
|
564
|
+
*
|
|
565
|
+
* The result will NOT contain any of the non-serializable fields
|
|
566
|
+
* (callbacks, entityActions, etc.) — those must be re-attached by the
|
|
567
|
+
* consumer if needed.
|
|
568
|
+
*/
|
|
569
|
+
export function fromSerializableCollection(serialized: SerializableCollection): EntityCollection {
|
|
570
|
+
const { properties, ...rest } = serialized;
|
|
571
|
+
|
|
572
|
+
return {
|
|
573
|
+
...rest,
|
|
574
|
+
properties: fromSerializableProperties(properties),
|
|
575
|
+
} as EntityCollection;
|
|
576
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { AIIcon } from "@rebasepro/core";
|
|
3
3
|
import { useCollectionRegistryController } from "../../_cms_internals";
|
|
4
4
|
import React, { useState } from "react";
|
|
5
|
-
import {
|
|
5
|
+
import { useSafeSnackbarController } from "../../useSafeSnackbarController";
|
|
6
6
|
import { EntityCollection } from "@rebasepro/types";
|
|
7
7
|
import {
|
|
8
8
|
Button,
|
|
@@ -76,7 +76,7 @@ export function AICollectionGeneratorPopover({
|
|
|
76
76
|
|
|
77
77
|
const collectionRegistry = useCollectionRegistryController();
|
|
78
78
|
const configController = useCollectionsConfigController();
|
|
79
|
-
const snackbarController =
|
|
79
|
+
const snackbarController = useSafeSnackbarController();
|
|
80
80
|
|
|
81
81
|
const existingCollections = collectionRegistry.collections ?? [];
|
|
82
82
|
|
|
@@ -95,7 +95,7 @@ export function AICollectionGeneratorPopover({
|
|
|
95
95
|
name: c.name,
|
|
96
96
|
properties: c.properties,
|
|
97
97
|
propertiesOrder: c.propertiesOrder
|
|
98
|
-
}));
|
|
98
|
+
} as Partial<EntityCollection>));
|
|
99
99
|
|
|
100
100
|
const result = await generateCollection({
|
|
101
101
|
prompt: prompt.trim(),
|
|
@@ -106,7 +106,7 @@ export function AICollectionGeneratorPopover({
|
|
|
106
106
|
name: existingCollection.name,
|
|
107
107
|
properties: existingCollection.properties,
|
|
108
108
|
propertiesOrder: existingCollection.propertiesOrder
|
|
109
|
-
}
|
|
109
|
+
} as Partial<EntityCollection>
|
|
110
110
|
})
|
|
111
111
|
});
|
|
112
112
|
|
|
@@ -117,7 +117,7 @@ export function AICollectionGeneratorPopover({
|
|
|
117
117
|
mode,
|
|
118
118
|
operationsCount: result.operations?.length
|
|
119
119
|
});
|
|
120
|
-
snackbarController
|
|
120
|
+
snackbarController?.open({
|
|
121
121
|
type: "success",
|
|
122
122
|
message: existingCollection
|
|
123
123
|
? "Collection updated with AI suggestions"
|
|
@@ -133,7 +133,7 @@ export function AICollectionGeneratorPopover({
|
|
|
133
133
|
mode,
|
|
134
134
|
error: errorMessage
|
|
135
135
|
});
|
|
136
|
-
snackbarController
|
|
136
|
+
snackbarController?.open({
|
|
137
137
|
type: "error",
|
|
138
138
|
message: errorMessage
|
|
139
139
|
});
|