@rebasepro/admin 0.7.0 → 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/LICENSE +21 -0
- package/dist/{CollectionEditorDialog-iGgS4rLX.js → CollectionEditorDialog-BO_aQ-Z4.js} +7 -7
- package/dist/CollectionEditorDialog-BO_aQ-Z4.js.map +1 -0
- package/dist/{PropertyEditView-C9yhLyja.js → PropertyEditView-DKzOpMjR.js} +64 -38
- package/dist/PropertyEditView-DKzOpMjR.js.map +1 -0
- package/dist/{RouterCollectionsStudioView-Dqx27GD8.js → RouterCollectionsStudioView-BQTIExjA.js} +4 -4
- package/dist/{RouterCollectionsStudioView-Dqx27GD8.js.map → RouterCollectionsStudioView-BQTIExjA.js.map} +1 -1
- package/dist/collection_editor/_cms_internals.d.ts +1 -1
- package/dist/collection_editor/api/generateCollectionApi.d.ts +3 -2
- package/dist/collection_editor/serializable_types.d.ts +5 -9
- package/dist/collection_editor/serializable_utils.d.ts +2 -2
- package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +1 -2
- package/dist/collection_editor_ui.js +4 -4
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/index.d.ts +1 -1
- 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/components/StorageUploadProgress.d.ts +6 -1
- package/dist/form/index.d.ts +0 -1
- package/dist/{history-ChHgyyvM.js → history-B3cqBzEV.js} +2 -2
- package/dist/{history-ChHgyyvM.js.map → history-B3cqBzEV.js.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/preview/components/StorageThumbnail.d.ts +3 -1
- package/dist/{src-DOX2nOyh.js → src-cxV1ODRG.js} +178 -460
- package/dist/src-cxV1ODRG.js.map +1 -0
- package/dist/types/components/PropertyPreviewProps.d.ts +2 -1
- package/dist/types/fields.d.ts +4 -6
- package/package.json +18 -18
- package/src/collection_editor/_cms_internals.ts +1 -1
- package/src/collection_editor/api/generateCollectionApi.ts +3 -2
- package/src/collection_editor/pgColumnToProperty.ts +2 -2
- package/src/collection_editor/serializable_types.ts +14 -27
- package/src/collection_editor/serializable_utils.ts +25 -37
- package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +41 -24
- package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +0 -9
- 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 +2 -2
- package/src/components/DefaultDrawer.tsx +1 -1
- 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/EntityCollectionBoardView.tsx +1 -1
- package/src/components/EntityCollectionView/EntityCollectionListView.tsx +12 -1
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +8 -25
- package/src/components/EntityCollectionView/hooks/useCollectionInlineEditor.ts +1 -1
- 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 +2 -2
- package/src/components/EntityEditViewFormActions.tsx +3 -3
- package/src/components/HomePage/ContentHomePage.tsx +1 -1
- package/src/components/RebaseCMS.tsx +2 -3
- package/src/components/RebaseNavigation.tsx +3 -2
- package/src/components/RelationSelector.tsx +2 -2
- package/src/components/SelectableTable/SelectableTable.tsx +11 -3
- package/src/components/SelectableTable/SelectionStore.ts +18 -48
- package/src/components/common/default_entity_actions.tsx +15 -4
- package/src/components/field_configs.tsx +0 -14
- package/src/editor/editor.tsx +4 -7
- package/src/form/EntityFormActions.tsx +2 -2
- package/src/form/EntityFormBinding.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/RelationFieldBinding.tsx +5 -7
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +19 -15
- package/src/form/index.tsx +0 -1
- package/src/index.ts +1 -1
- package/src/preview/PropertyPreview.tsx +1 -16
- package/src/preview/components/StorageThumbnail.tsx +24 -7
- package/src/types/components/PropertyPreviewProps.tsx +1 -1
- package/src/types/fields.tsx +2 -7
- package/src/util/previews.ts +20 -0
- package/src/util/propertyConfigMapper.ts +3 -3
- package/src/util/property_utils.tsx +1 -2
- package/dist/CollectionEditorDialog-iGgS4rLX.js.map +0 -1
- package/dist/PropertyEditView-C9yhLyja.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/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +0 -11
- package/dist/src-DOX2nOyh.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/form/field_bindings/ReferenceAsStringFieldBinding.tsx +0 -141
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { InferPropertyType } from "@rebasepro/types";
|
|
1
2
|
import { Property } from "@rebasepro/types";
|
|
2
3
|
/**
|
|
3
4
|
* @group Preview components
|
|
@@ -11,7 +12,7 @@ export interface PropertyPreviewProps<P extends Property | Property, CustomProps
|
|
|
11
12
|
* Name of the property
|
|
12
13
|
*/
|
|
13
14
|
propertyKey?: string;
|
|
14
|
-
value: any;
|
|
15
|
+
value: InferPropertyType<P> | any;
|
|
15
16
|
/**
|
|
16
17
|
* Property this display is related to, now strongly typed to P
|
|
17
18
|
*/
|
package/dist/types/fields.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { InferPropertyType } from "@rebasepro/types";
|
|
1
2
|
import { Entity } from "@rebasepro/types";
|
|
2
3
|
import { FormexController } from "./components/formex";
|
|
3
4
|
import { EntityCollection } from "@rebasepro/types";
|
|
4
5
|
import { Property } from "@rebasepro/types";
|
|
5
|
-
export type DefaultFieldConfig = "text_field" | "multiline" | "markdown" | "url" | "email" | "switch" | "select" | "multi_select" | "user_select" | "number_input" | "number_select" | "multi_number_select" | "file_upload" | "multi_file_upload" | "
|
|
6
|
+
export type DefaultFieldConfig = "text_field" | "multiline" | "markdown" | "url" | "email" | "switch" | "select" | "multi_select" | "user_select" | "number_input" | "number_select" | "multi_number_select" | "file_upload" | "multi_file_upload" | "reference" | "multi_references" | "relation" | "date_time" | "group" | "key_value" | "repeat" | "custom_array" | "block" | "vector_input";
|
|
6
7
|
/**
|
|
7
8
|
* When building a custom field you need to create a React component that takes
|
|
8
9
|
* this interface as props.
|
|
@@ -18,11 +19,8 @@ export interface FieldProps<P extends Property | Property = Property, CustomProp
|
|
|
18
19
|
/**
|
|
19
20
|
* Current value of this field, inferred from the property type P
|
|
20
21
|
*/
|
|
21
|
-
value: any;
|
|
22
|
-
|
|
23
|
-
* Set value of field directly
|
|
24
|
-
*/
|
|
25
|
-
setValue: (value: any | null, shouldValidate?: boolean) => void;
|
|
22
|
+
value: InferPropertyType<P> | any;
|
|
23
|
+
setValue: (value: InferPropertyType<P> | null | any, shouldValidate?: boolean) => void;
|
|
26
24
|
/**
|
|
27
25
|
* Set value of a different field directly
|
|
28
26
|
* @param propertyKey
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/admin",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0",
|
|
5
5
|
"description": "Rebase CMS — content management views, forms, and routing",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/rebaseco"
|
|
@@ -31,14 +31,6 @@
|
|
|
31
31
|
"headless cms",
|
|
32
32
|
"content manager"
|
|
33
33
|
],
|
|
34
|
-
"scripts": {
|
|
35
|
-
"watch": "vite build --watch",
|
|
36
|
-
"build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
|
|
37
|
-
"test:lint": "eslint \"src/**\" --quiet",
|
|
38
|
-
"test": "jest --passWithNoTests",
|
|
39
|
-
"clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f",
|
|
40
|
-
"generateIcons": "ts-node --esm src/icons/generateIcons.ts"
|
|
41
|
-
},
|
|
42
34
|
"exports": {
|
|
43
35
|
".": {
|
|
44
36
|
"types": "./dist/index.d.ts",
|
|
@@ -63,13 +55,6 @@
|
|
|
63
55
|
"@dnd-kit/sortable": "^10.0.0",
|
|
64
56
|
"@dnd-kit/utilities": "^3.2.2",
|
|
65
57
|
"@floating-ui/dom": "^1.7.6",
|
|
66
|
-
"@rebasepro/common": "workspace:*",
|
|
67
|
-
"@rebasepro/core": "workspace:*",
|
|
68
|
-
"@rebasepro/formex": "workspace:*",
|
|
69
|
-
"@rebasepro/schema-inference": "workspace:*",
|
|
70
|
-
"@rebasepro/types": "workspace:*",
|
|
71
|
-
"@rebasepro/ui": "workspace:*",
|
|
72
|
-
"@rebasepro/utils": "workspace:*",
|
|
73
58
|
"cmdk": "^1.1.1",
|
|
74
59
|
"date-fns": "^4.4.0",
|
|
75
60
|
"exceljs": "^4.4.0",
|
|
@@ -97,7 +82,14 @@
|
|
|
97
82
|
"prosemirror-view": "^1.41.9",
|
|
98
83
|
"react-dropzone": "^15.0.0",
|
|
99
84
|
"react-use-measure": "^2.1.7",
|
|
100
|
-
"zod": "^4.4.3"
|
|
85
|
+
"zod": "^4.4.3",
|
|
86
|
+
"@rebasepro/common": "0.8.0",
|
|
87
|
+
"@rebasepro/core": "0.8.0",
|
|
88
|
+
"@rebasepro/formex": "0.8.0",
|
|
89
|
+
"@rebasepro/schema-inference": "0.8.0",
|
|
90
|
+
"@rebasepro/types": "0.8.0",
|
|
91
|
+
"@rebasepro/ui": "0.8.0",
|
|
92
|
+
"@rebasepro/utils": "0.8.0"
|
|
101
93
|
},
|
|
102
94
|
"peerDependencies": {
|
|
103
95
|
"react": ">=19.0.0",
|
|
@@ -168,5 +160,13 @@
|
|
|
168
160
|
"^@rebasepro/formex$": "<rootDir>/../formex/src/index.ts",
|
|
169
161
|
"^@rebasepro/utils$": "<rootDir>/../utils/src/index.ts"
|
|
170
162
|
}
|
|
163
|
+
},
|
|
164
|
+
"scripts": {
|
|
165
|
+
"watch": "vite build --watch",
|
|
166
|
+
"build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
|
|
167
|
+
"test:lint": "eslint \"src/**\" --quiet",
|
|
168
|
+
"test": "jest --passWithNoTests",
|
|
169
|
+
"clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f",
|
|
170
|
+
"generateIcons": "ts-node --esm src/icons/generateIcons.ts"
|
|
171
171
|
}
|
|
172
|
-
}
|
|
172
|
+
}
|
|
@@ -16,7 +16,7 @@ export { FieldCaption } from "../components/FieldCaption";
|
|
|
16
16
|
export { SearchIconsView } from "../components/SearchIconsView";
|
|
17
17
|
export { PropertyConfigBadge } from "../components/PropertyConfigBadge";
|
|
18
18
|
export { EntityCollectionTable } from "../components/EntityCollectionTable";
|
|
19
|
-
export { VirtualTableInput } from "
|
|
19
|
+
export { VirtualTableInput } from "@rebasepro/ui";
|
|
20
20
|
export { ArrayContainer } from "../components/ArrayContainer";
|
|
21
21
|
export type { ArrayEntryParams } from "../components/ArrayContainer";
|
|
22
22
|
export { useSelectionController } from "../components/EntityCollectionView/useSelectionController";
|
|
@@ -55,8 +55,9 @@ export const DEFAULT_COLLECTION_GENERATION_ENDPOINT = "https://api.rebase.pro/co
|
|
|
55
55
|
*/
|
|
56
56
|
export interface BuildCollectionGenerationCallbackProps {
|
|
57
57
|
/**
|
|
58
|
-
* Function to get the auth token
|
|
59
|
-
* This is typically `authController.getAuthToken` from `@rebasepro/client
|
|
58
|
+
* Function to get the auth token.
|
|
59
|
+
* This is typically `authController.getAuthToken` from `@rebasepro/client`
|
|
60
|
+
* (or `@rebasepro/client-firebase` if using Firebase).
|
|
60
61
|
*/
|
|
61
62
|
getAuthToken: () => Promise<string>;
|
|
62
63
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EntityCollection, Property, StringProperty, NumberProperty, ArrayProperty, TableColumnInfo, TableMetadata } from "@rebasepro/types";
|
|
1
|
+
import { EntityCollection, Property, StringProperty, NumberProperty, ArrayProperty, TableColumnInfo, TableMetadata, PostgresProperties } from "@rebasepro/types";
|
|
2
2
|
import { prettifyIdentifier } from "@rebasepro/utils";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -282,7 +282,7 @@ export function buildCollectionFromTableMetadata(
|
|
|
282
282
|
name: prettifiedName,
|
|
283
283
|
slug: tableName,
|
|
284
284
|
table: tableName,
|
|
285
|
-
properties,
|
|
285
|
+
properties: properties as PostgresProperties,
|
|
286
286
|
propertiesOrder,
|
|
287
287
|
...(relations.length > 0 ? { relations } : {}),
|
|
288
288
|
...(securityRules.length > 0 ? { securityRules } : {})
|
|
@@ -12,33 +12,22 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type {
|
|
15
|
-
DataType,
|
|
16
|
-
EnumValues,
|
|
17
|
-
PropertyValidationSchema,
|
|
18
|
-
NumberPropertyValidationSchema,
|
|
19
15
|
ArrayPropertyValidationSchema,
|
|
20
|
-
PropertyConditions,
|
|
21
|
-
ImageResize,
|
|
22
|
-
FileType,
|
|
23
|
-
ColorKey,
|
|
24
|
-
ColorScheme,
|
|
25
|
-
} from "@rebasepro/types";
|
|
26
|
-
|
|
27
|
-
import type {
|
|
28
|
-
ViewMode,
|
|
29
16
|
CollectionSize,
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
EnumValues,
|
|
18
|
+
FileType,
|
|
32
19
|
FilterPreset,
|
|
33
|
-
|
|
20
|
+
FilterValues,
|
|
21
|
+
ImageResize,
|
|
22
|
+
JoinStep,
|
|
34
23
|
KanbanConfig,
|
|
35
|
-
SecurityOperation,
|
|
36
24
|
NavigationGroupMapping,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
import type {
|
|
25
|
+
NumberPropertyValidationSchema,
|
|
40
26
|
OnAction,
|
|
41
|
-
|
|
27
|
+
PropertyConditions,
|
|
28
|
+
PropertyValidationSchema,
|
|
29
|
+
SecurityRule,
|
|
30
|
+
ViewMode,
|
|
42
31
|
} from "@rebasepro/types";
|
|
43
32
|
|
|
44
33
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -109,6 +98,8 @@ export interface SerializableStorageConfig {
|
|
|
109
98
|
includeBucketUrl?: boolean;
|
|
110
99
|
storeUrl?: boolean;
|
|
111
100
|
maxSize?: number;
|
|
101
|
+
/** Key of the named storage backend to use (see `StorageConfig.storageSource`). */
|
|
102
|
+
storageSource?: string;
|
|
112
103
|
// processFile, postProcess, previewUrl are dropped (functions)
|
|
113
104
|
}
|
|
114
105
|
|
|
@@ -200,13 +191,9 @@ export interface SerializableStringProperty extends SerializableBaseProperty {
|
|
|
200
191
|
validation?: SerializableStringValidation;
|
|
201
192
|
isId?: boolean | "manual" | "uuid" | "cuid" | string;
|
|
202
193
|
enum?: EnumValues;
|
|
203
|
-
multiline?: boolean;
|
|
204
|
-
markdown?: boolean;
|
|
205
194
|
storage?: SerializableStorageConfig;
|
|
206
195
|
userSelect?: boolean;
|
|
207
|
-
url?: boolean | "image" | "video" | "audio" | "file";
|
|
208
196
|
email?: boolean;
|
|
209
|
-
previewAsTag?: boolean;
|
|
210
197
|
reference?: SerializableReferenceProperty;
|
|
211
198
|
}
|
|
212
199
|
|
|
@@ -236,7 +223,6 @@ export interface SerializableDateProperty extends SerializableBaseProperty {
|
|
|
236
223
|
mode?: "date" | "date_time";
|
|
237
224
|
timezone?: string;
|
|
238
225
|
autoValue?: "on_create" | "on_update";
|
|
239
|
-
clearable?: boolean;
|
|
240
226
|
}
|
|
241
227
|
|
|
242
228
|
/** JSON-serializable `GeopointProperty`. */
|
|
@@ -391,7 +377,8 @@ export interface SerializableCollection {
|
|
|
391
377
|
icon?: string;
|
|
392
378
|
|
|
393
379
|
group?: string;
|
|
394
|
-
|
|
380
|
+
engine?: string;
|
|
381
|
+
dataSource?: string;
|
|
395
382
|
databaseId?: string;
|
|
396
383
|
|
|
397
384
|
properties: SerializableProperties;
|
|
@@ -9,44 +9,44 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
NumberProperty,
|
|
12
|
+
ArrayProperty,
|
|
13
|
+
BaseUIConfig,
|
|
14
|
+
BinaryProperty,
|
|
16
15
|
BooleanProperty,
|
|
17
16
|
DateProperty,
|
|
17
|
+
EntityCollection,
|
|
18
18
|
GeopointProperty,
|
|
19
|
-
ReferenceProperty,
|
|
20
|
-
RelationProperty,
|
|
21
|
-
ArrayProperty,
|
|
22
19
|
MapProperty,
|
|
23
|
-
|
|
24
|
-
BinaryProperty,
|
|
20
|
+
NumberProperty,
|
|
25
21
|
Properties,
|
|
22
|
+
Property,
|
|
23
|
+
ReferenceProperty,
|
|
24
|
+
RelationProperty,
|
|
26
25
|
StorageConfig,
|
|
27
|
-
|
|
26
|
+
StringProperty,
|
|
27
|
+
VectorProperty,
|
|
28
28
|
} from "@rebasepro/types";
|
|
29
29
|
|
|
30
30
|
import type {
|
|
31
|
-
|
|
32
|
-
SerializableProperty,
|
|
33
|
-
SerializableProperties,
|
|
34
|
-
SerializableStorageConfig,
|
|
35
|
-
SerializableBaseUIConfig,
|
|
31
|
+
SerializableArrayProperty,
|
|
36
32
|
SerializableBaseProperty,
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
SerializableBaseUIConfig,
|
|
34
|
+
SerializableBinaryProperty,
|
|
39
35
|
SerializableBooleanProperty,
|
|
36
|
+
SerializableCollection,
|
|
40
37
|
SerializableDateProperty,
|
|
38
|
+
SerializableDateValidation,
|
|
41
39
|
SerializableGeopointProperty,
|
|
40
|
+
SerializableMapProperty,
|
|
41
|
+
SerializableNumberProperty,
|
|
42
|
+
SerializableProperties,
|
|
43
|
+
SerializableProperty,
|
|
42
44
|
SerializableReferenceProperty,
|
|
43
45
|
SerializableRelationProperty,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
SerializableVectorProperty,
|
|
47
|
-
SerializableBinaryProperty,
|
|
46
|
+
SerializableStorageConfig,
|
|
47
|
+
SerializableStringProperty,
|
|
48
48
|
SerializableStringValidation,
|
|
49
|
-
|
|
49
|
+
SerializableVectorProperty,
|
|
50
50
|
} from "./serializable_types";
|
|
51
51
|
|
|
52
52
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -90,6 +90,7 @@ function toSerializableStorageConfig(storage: StorageConfig | undefined): Serial
|
|
|
90
90
|
if (storage.includeBucketUrl !== undefined) result.includeBucketUrl = storage.includeBucketUrl;
|
|
91
91
|
if (storage.storeUrl !== undefined) result.storeUrl = storage.storeUrl;
|
|
92
92
|
if (storage.maxSize !== undefined) result.maxSize = storage.maxSize;
|
|
93
|
+
if (storage.storageSource !== undefined) result.storageSource = storage.storageSource;
|
|
93
94
|
// processFile, postProcess, previewUrl are intentionally dropped (functions)
|
|
94
95
|
|
|
95
96
|
return result;
|
|
@@ -167,12 +168,8 @@ export function toSerializableProperty(property: Property): SerializableProperty
|
|
|
167
168
|
if (sp.columnType) result.columnType = sp.columnType;
|
|
168
169
|
if (sp.isId !== undefined) result.isId = sp.isId;
|
|
169
170
|
if (sp.enum) result.enum = sp.enum;
|
|
170
|
-
if (sp.multiline) result.multiline = sp.multiline;
|
|
171
|
-
if (sp.markdown) result.markdown = sp.markdown;
|
|
172
171
|
if (sp.userSelect) result.userSelect = sp.userSelect;
|
|
173
|
-
if (sp.url) result.url = sp.url;
|
|
174
172
|
if (sp.email) result.email = sp.email;
|
|
175
|
-
if (sp.previewAsTag) result.previewAsTag = sp.previewAsTag;
|
|
176
173
|
|
|
177
174
|
// Convert validation.matches from RegExp to string
|
|
178
175
|
if (sp.validation) {
|
|
@@ -187,11 +184,6 @@ export function toSerializableProperty(property: Property): SerializableProperty
|
|
|
187
184
|
const storage = toSerializableStorageConfig(sp.storage);
|
|
188
185
|
if (storage) result.storage = storage;
|
|
189
186
|
|
|
190
|
-
// Reference sub-property
|
|
191
|
-
if (sp.reference) {
|
|
192
|
-
result.reference = toSerializableProperty(sp.reference) as SerializableReferenceProperty;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
187
|
return result;
|
|
196
188
|
}
|
|
197
189
|
|
|
@@ -228,7 +220,6 @@ export function toSerializableProperty(property: Property): SerializableProperty
|
|
|
228
220
|
if (dp.mode) result.mode = dp.mode;
|
|
229
221
|
if (dp.timezone) result.timezone = dp.timezone;
|
|
230
222
|
if (dp.autoValue) result.autoValue = dp.autoValue;
|
|
231
|
-
if (dp.clearable) result.clearable = dp.clearable;
|
|
232
223
|
|
|
233
224
|
// Convert Date validation min/max to ISO strings
|
|
234
225
|
if (dp.validation) {
|
|
@@ -416,7 +407,8 @@ export function toSerializableCollection(collection: EntityCollection): Serializ
|
|
|
416
407
|
if (collection.singularName) result.singularName = collection.singularName;
|
|
417
408
|
if (collection.description) result.description = collection.description;
|
|
418
409
|
if (collection.group) result.group = collection.group;
|
|
419
|
-
if (collection.
|
|
410
|
+
if (collection.engine) result.engine = collection.engine;
|
|
411
|
+
if (collection.dataSource) result.dataSource = collection.dataSource;
|
|
420
412
|
if (collection.databaseId) result.databaseId = collection.databaseId;
|
|
421
413
|
if (collection.titleProperty) result.titleProperty = collection.titleProperty as string;
|
|
422
414
|
if (collection.ownerId) result.ownerId = collection.ownerId;
|
|
@@ -543,10 +535,6 @@ export function fromSerializableProperty(serialized: SerializableProperty): Prop
|
|
|
543
535
|
case "string": {
|
|
544
536
|
const sp = serialized as SerializableStringProperty;
|
|
545
537
|
const result = { ...sp } as unknown as StringProperty;
|
|
546
|
-
// Convert reference sub-property
|
|
547
|
-
if (sp.reference) {
|
|
548
|
-
result.reference = fromSerializableProperty(sp.reference) as ReferenceProperty;
|
|
549
|
-
}
|
|
550
538
|
return result;
|
|
551
539
|
}
|
|
552
540
|
|
|
@@ -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
|
|
|
@@ -1,31 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
import { useUnsavedChangesDialog, UnsavedChangesDialog } from "@rebasepro/core";
|
|
3
|
-
import { useNavigationStateController, useCollectionRegistryController, useUrlController } from "../../_cms_internals";
|
|
4
1
|
import * as React from "react";
|
|
5
2
|
import { useEffect, useRef, useState } from "react";
|
|
6
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ConfirmationDialog,
|
|
5
|
+
ErrorView,
|
|
6
|
+
UnsavedChangesDialog,
|
|
7
|
+
useAuthController,
|
|
8
|
+
useCustomizationController,
|
|
9
|
+
useUnsavedChangesDialog
|
|
10
|
+
} from "@rebasepro/core";
|
|
11
|
+
import {
|
|
12
|
+
getInferenceType,
|
|
13
|
+
ImportSaveInProgress,
|
|
14
|
+
useCollectionRegistryController,
|
|
15
|
+
useImportConfig,
|
|
16
|
+
useNavigationStateController,
|
|
17
|
+
useUrlController
|
|
18
|
+
} from "../../_cms_internals";
|
|
7
19
|
import { useSafeSnackbarController } from "../../useSafeSnackbarController";
|
|
8
|
-
import { CircularProgressCenter } from "@rebasepro/ui";
|
|
9
20
|
import {
|
|
10
21
|
ArrowLeftIcon,
|
|
11
22
|
Button,
|
|
12
23
|
CheckIcon,
|
|
24
|
+
CircularProgressCenter,
|
|
13
25
|
cls,
|
|
14
26
|
coolIconKeys,
|
|
15
27
|
defaultBorderMixin,
|
|
16
28
|
Dialog,
|
|
17
|
-
DialogActions,
|
|
18
|
-
DialogContent,
|
|
19
29
|
DialogTitle,
|
|
20
30
|
IconButton,
|
|
21
31
|
LoadingButton,
|
|
22
32
|
Tab,
|
|
23
|
-
Tabs
|
|
24
|
-
Typography
|
|
33
|
+
Tabs
|
|
25
34
|
} from "@rebasepro/ui";
|
|
26
|
-
import {
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
import {
|
|
36
|
+
EngineProperties,
|
|
37
|
+
Entity,
|
|
38
|
+
EntityCollection,
|
|
39
|
+
getDataSourceCapabilities,
|
|
40
|
+
MapProperty,
|
|
41
|
+
Properties,
|
|
42
|
+
Property,
|
|
43
|
+
PropertyConfig,
|
|
44
|
+
TableMetadata,
|
|
45
|
+
User
|
|
46
|
+
} from "@rebasepro/types";
|
|
47
|
+
import { getSubcollections, getTableName, isPropertyBuilder, removeInitialAndTrailingSlashes } from "@rebasepro/common";
|
|
29
48
|
import { CollectionEditorSchema } from "./CollectionYupValidation";
|
|
30
49
|
import { GeneralSettingsForm } from "./GeneralSettingsForm";
|
|
31
50
|
import { DisplaySettingsForm } from "./DisplaySettingsForm";
|
|
@@ -33,7 +52,6 @@ import { CollectionPropertiesEditorForm } from "./CollectionPropertiesEditorForm
|
|
|
33
52
|
import { CollectionsConfigController } from "../../types/config_controller";
|
|
34
53
|
import { CollectionEditorWelcomeView } from "./CollectionEditorWelcomeView";
|
|
35
54
|
import { CollectionInference } from "../../types/collection_inference";
|
|
36
|
-
import { getInferenceType, ImportSaveInProgress, useImportConfig } from "../../_cms_internals";
|
|
37
55
|
import { buildEntityPropertiesFromData } from "@rebasepro/schema-inference";
|
|
38
56
|
import { CollectionEditorImportMapping } from "./import/CollectionEditorImportMapping";
|
|
39
57
|
import { CollectionEditorImportDataPreview } from "./import/CollectionEditorImportDataPreview";
|
|
@@ -42,10 +60,9 @@ import { Formex, FormexController, useCreateFormex } from "@rebasepro/formex";
|
|
|
42
60
|
import { getFullIdPath } from "./util";
|
|
43
61
|
import { AICollectionGeneratorPopover } from "./AICollectionGeneratorPopover";
|
|
44
62
|
import { AIModifiedPathsProvider, useAIModifiedPaths } from "./AIModifiedPathsContext";
|
|
45
|
-
import {
|
|
63
|
+
import { CollectionGenerationCallback, CollectionOperation } from "../../api/generateCollectionApi";
|
|
46
64
|
import { CollectionRLSTab } from "./CollectionRLSTab";
|
|
47
65
|
import { buildCollectionFromTableMetadata } from "../../pgColumnToProperty";
|
|
48
|
-
import { TableMetadata } from "@rebasepro/types";
|
|
49
66
|
import { mergeDeep, randomString, removeUndefined } from "@rebasepro/utils";
|
|
50
67
|
import type { CollectionEditorExtensionProps, CollectionEditorTab } from "../../extensibility_types";
|
|
51
68
|
|
|
@@ -242,8 +259,8 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
242
259
|
}, [collection, fallbackSlug]);
|
|
243
260
|
|
|
244
261
|
// Build initial values - handle copyFrom for duplication
|
|
245
|
-
const initialValues
|
|
246
|
-
return initialCollection
|
|
262
|
+
const initialValues = React.useMemo((): EntityCollection<any> => {
|
|
263
|
+
return (initialCollection
|
|
247
264
|
? applyPropertyConfigs(initialCollection, propertyConfigs)
|
|
248
265
|
: copyFromProp
|
|
249
266
|
? (() => {
|
|
@@ -259,11 +276,11 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
259
276
|
slug: initialValuesProp?.slug ?? fallbackSlug,
|
|
260
277
|
table: initialValuesProp?.slug ?? "",
|
|
261
278
|
name: initialValuesProp?.name ?? "",
|
|
262
|
-
properties: {} as
|
|
279
|
+
properties: {} as EngineProperties,
|
|
263
280
|
propertiesOrder: [],
|
|
264
281
|
icon: initialIcon,
|
|
265
282
|
ownerId: authController.user?.uid ?? ""
|
|
266
|
-
}
|
|
283
|
+
}) as EntityCollection<any>;
|
|
267
284
|
}, [initialCollection, propertyConfigs, copyFromProp, initialValuesProp, fallbackSlug, initialIcon, authController.user?.uid]);
|
|
268
285
|
|
|
269
286
|
if (!initialLoadingCompleted) {
|
|
@@ -455,7 +472,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
455
472
|
};
|
|
456
473
|
|
|
457
474
|
if (Object.keys(inferredCollection.properties ?? {}).length > 0) {
|
|
458
|
-
values.properties = inferredCollection.properties as
|
|
475
|
+
values.properties = inferredCollection.properties as EngineProperties;
|
|
459
476
|
values.propertiesOrder = inferredCollection.propertiesOrder as Extract<keyof M, string>[];
|
|
460
477
|
}
|
|
461
478
|
|
|
@@ -697,7 +714,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
697
714
|
{(!visibleTabs || visibleTabs.includes("properties")) && <Tab value={"properties"}>
|
|
698
715
|
Properties
|
|
699
716
|
</Tab>}
|
|
700
|
-
{(!visibleTabs || visibleTabs.includes("rls")) && getDataSourceCapabilities(values.
|
|
717
|
+
{(!visibleTabs || visibleTabs.includes("rls")) && getDataSourceCapabilities(values.engine).supportsRLS && <Tab value={"rls"}>
|
|
701
718
|
RLS
|
|
702
719
|
</Tab>}
|
|
703
720
|
</Tabs>
|
|
@@ -807,7 +824,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
807
824
|
<DisplaySettingsForm expandKanban={expandKanban} standalone={standalone}/>
|
|
808
825
|
}
|
|
809
826
|
|
|
810
|
-
{currentView === "rls" && getDataSourceCapabilities(values.
|
|
827
|
+
{currentView === "rls" && getDataSourceCapabilities(values.engine).supportsRLS &&
|
|
811
828
|
<CollectionRLSTab/>
|
|
812
829
|
}
|
|
813
830
|
|
|
@@ -974,8 +991,8 @@ function applyPropertyConfigs<M extends Record<string, unknown> = Record<string,
|
|
|
974
991
|
|
|
975
992
|
return {
|
|
976
993
|
...rest,
|
|
977
|
-
properties: propertiesResult
|
|
978
|
-
}
|
|
994
|
+
properties: propertiesResult as EngineProperties
|
|
995
|
+
} as EntityCollection<M>;
|
|
979
996
|
}
|
|
980
997
|
|
|
981
998
|
function applyPropertiesConfig(property: Property, propertyConfigs: Record<string, PropertyConfig>) {
|
|
@@ -505,13 +505,6 @@ function PropertyEditFormFields({
|
|
|
505
505
|
existing={existing}
|
|
506
506
|
multiple={false}
|
|
507
507
|
disabled={disabled}/>;
|
|
508
|
-
} else if (selectedFieldConfigId === "reference_as_string") {
|
|
509
|
-
childComponent =
|
|
510
|
-
<ReferencePropertyField showErrors={showErrors}
|
|
511
|
-
existing={existing}
|
|
512
|
-
asString={true}
|
|
513
|
-
multiple={false}
|
|
514
|
-
disabled={disabled}/>;
|
|
515
508
|
} else if (selectedFieldConfigId === "date_time") {
|
|
516
509
|
childComponent = <DateTimePropertyField disabled={disabled}/>;
|
|
517
510
|
} else if (selectedFieldConfigId === "multi_references") {
|
|
@@ -686,7 +679,6 @@ const WIDGET_TYPE_MAP: Record<PropertyConfigId, string> = {
|
|
|
686
679
|
multi_file_upload: "File",
|
|
687
680
|
relation: "Relation",
|
|
688
681
|
reference: "Reference",
|
|
689
|
-
reference_as_string: "Text",
|
|
690
682
|
multi_references: "Reference",
|
|
691
683
|
date_time: "Date",
|
|
692
684
|
group: "Group",
|
|
@@ -707,7 +699,6 @@ const WIDGET_BASE_TYPE_MAP: Record<string, PropertyType> = {
|
|
|
707
699
|
multi_select: "string",
|
|
708
700
|
file_upload: "string",
|
|
709
701
|
multi_file_upload: "string",
|
|
710
|
-
reference_as_string: "string",
|
|
711
702
|
user_select: "string",
|
|
712
703
|
number_input: "number",
|
|
713
704
|
number_select: "number",
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
} from "@rebasepro/ui";
|
|
14
14
|
|
|
15
15
|
import { Field, FormexFieldProps, getIn, useFormex } from "@rebasepro/formex";
|
|
16
|
-
import { useTranslation } from "@rebasepro/core";
|
|
16
|
+
import { useStorageSources, useTranslation } from "@rebasepro/core";
|
|
17
|
+
import { DEFAULT_STORAGE_SOURCE_KEY } from "@rebasepro/types";
|
|
17
18
|
import { GeneralPropertyValidation } from "./validation/GeneralPropertyValidation";
|
|
18
19
|
import { ArrayPropertyValidation } from "./validation/ArrayPropertyValidation";
|
|
19
20
|
import { ValidationPanel } from "./validation/ValidationPanel";
|
|
@@ -42,9 +43,11 @@ export function StoragePropertyField({
|
|
|
42
43
|
setFieldValue
|
|
43
44
|
} = useFormex();
|
|
44
45
|
const { t } = useTranslation();
|
|
46
|
+
const storageSources = useStorageSources();
|
|
45
47
|
|
|
46
48
|
const baseStoragePath = multiple ? "of.storage" : "storage";
|
|
47
49
|
const acceptedFiles = `${baseStoragePath}.acceptedFiles`;
|
|
50
|
+
const storageSource = `${baseStoragePath}.storageSource`;
|
|
48
51
|
|
|
49
52
|
const metadata = `${baseStoragePath}.metadata`;
|
|
50
53
|
const fileName = `${baseStoragePath}.fileName`;
|
|
@@ -76,6 +79,11 @@ export function StoragePropertyField({
|
|
|
76
79
|
const fileTypesValue: string[] | undefined = Array.isArray(storedValue) ? storedValue : undefined;
|
|
77
80
|
const allFileTypesSelected = !fileTypesValue || fileTypesValue.length === 0;
|
|
78
81
|
|
|
82
|
+
// Available storage backends (from `<Rebase storageSources={...}>`).
|
|
83
|
+
const sourceKeys = Object.keys(storageSources.sources)
|
|
84
|
+
.filter((key) => key !== DEFAULT_STORAGE_SOURCE_KEY);
|
|
85
|
+
const storageSourceValue = (getIn(values, storageSource) as string | undefined) ?? DEFAULT_STORAGE_SOURCE_KEY;
|
|
86
|
+
|
|
79
87
|
const handleTypesChange = (value: string[]) => {
|
|
80
88
|
if (!value) setFieldValue(acceptedFiles, undefined);
|
|
81
89
|
else setFieldValue(acceptedFiles, value);
|
|
@@ -102,6 +110,32 @@ export function StoragePropertyField({
|
|
|
102
110
|
|
|
103
111
|
<div className={"grid grid-cols-12 gap-2 p-4"}>
|
|
104
112
|
|
|
113
|
+
{sourceKeys.length > 0 && (
|
|
114
|
+
<div className={"col-span-12"}>
|
|
115
|
+
<Select
|
|
116
|
+
className={"w-full"}
|
|
117
|
+
disabled={disabled}
|
|
118
|
+
name={storageSource}
|
|
119
|
+
value={storageSourceValue}
|
|
120
|
+
onValueChange={(value) =>
|
|
121
|
+
setFieldValue(storageSource, !value || value === DEFAULT_STORAGE_SOURCE_KEY ? undefined : value)}
|
|
122
|
+
label={"Storage backend"}
|
|
123
|
+
renderValue={(key) => {
|
|
124
|
+
const label = storageSources.registry[key]?.label;
|
|
125
|
+
return label ?? (key === DEFAULT_STORAGE_SOURCE_KEY ? "Default" : key);
|
|
126
|
+
}}>
|
|
127
|
+
<SelectItem value={DEFAULT_STORAGE_SOURCE_KEY}>
|
|
128
|
+
Default
|
|
129
|
+
</SelectItem>
|
|
130
|
+
{sourceKeys.map((key) => (
|
|
131
|
+
<SelectItem key={key} value={key}>
|
|
132
|
+
{storageSources.registry[key]?.label ?? key}
|
|
133
|
+
</SelectItem>
|
|
134
|
+
))}
|
|
135
|
+
</Select>
|
|
136
|
+
</div>
|
|
137
|
+
)}
|
|
138
|
+
|
|
105
139
|
<div className={"col-span-12"}>
|
|
106
140
|
|
|
107
141
|
<MultiSelect
|