@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
|
@@ -1,30 +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 {
|
|
7
|
-
|
|
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";
|
|
19
|
+
import { useSafeSnackbarController } from "../../useSafeSnackbarController";
|
|
8
20
|
import {
|
|
9
21
|
ArrowLeftIcon,
|
|
10
22
|
Button,
|
|
11
23
|
CheckIcon,
|
|
24
|
+
CircularProgressCenter,
|
|
12
25
|
cls,
|
|
13
26
|
coolIconKeys,
|
|
14
27
|
defaultBorderMixin,
|
|
15
28
|
Dialog,
|
|
16
|
-
DialogActions,
|
|
17
|
-
DialogContent,
|
|
18
29
|
DialogTitle,
|
|
19
30
|
IconButton,
|
|
20
31
|
LoadingButton,
|
|
21
32
|
Tab,
|
|
22
|
-
Tabs
|
|
23
|
-
Typography
|
|
33
|
+
Tabs
|
|
24
34
|
} from "@rebasepro/ui";
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
|
|
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";
|
|
28
48
|
import { CollectionEditorSchema } from "./CollectionYupValidation";
|
|
29
49
|
import { GeneralSettingsForm } from "./GeneralSettingsForm";
|
|
30
50
|
import { DisplaySettingsForm } from "./DisplaySettingsForm";
|
|
@@ -32,7 +52,6 @@ import { CollectionPropertiesEditorForm } from "./CollectionPropertiesEditorForm
|
|
|
32
52
|
import { CollectionsConfigController } from "../../types/config_controller";
|
|
33
53
|
import { CollectionEditorWelcomeView } from "./CollectionEditorWelcomeView";
|
|
34
54
|
import { CollectionInference } from "../../types/collection_inference";
|
|
35
|
-
import { getInferenceType, ImportSaveInProgress, useImportConfig } from "../../_cms_internals";
|
|
36
55
|
import { buildEntityPropertiesFromData } from "@rebasepro/schema-inference";
|
|
37
56
|
import { CollectionEditorImportMapping } from "./import/CollectionEditorImportMapping";
|
|
38
57
|
import { CollectionEditorImportDataPreview } from "./import/CollectionEditorImportDataPreview";
|
|
@@ -41,13 +60,13 @@ import { Formex, FormexController, useCreateFormex } from "@rebasepro/formex";
|
|
|
41
60
|
import { getFullIdPath } from "./util";
|
|
42
61
|
import { AICollectionGeneratorPopover } from "./AICollectionGeneratorPopover";
|
|
43
62
|
import { AIModifiedPathsProvider, useAIModifiedPaths } from "./AIModifiedPathsContext";
|
|
44
|
-
import {
|
|
63
|
+
import { CollectionGenerationCallback, CollectionOperation } from "../../api/generateCollectionApi";
|
|
45
64
|
import { CollectionRLSTab } from "./CollectionRLSTab";
|
|
46
65
|
import { buildCollectionFromTableMetadata } from "../../pgColumnToProperty";
|
|
47
|
-
import { TableMetadata } from "@rebasepro/types";
|
|
48
66
|
import { mergeDeep, randomString, removeUndefined } from "@rebasepro/utils";
|
|
67
|
+
import type { CollectionEditorExtensionProps, CollectionEditorTab } from "../../extensibility_types";
|
|
49
68
|
|
|
50
|
-
export interface CollectionEditorDialogProps {
|
|
69
|
+
export interface CollectionEditorDialogProps extends CollectionEditorExtensionProps {
|
|
51
70
|
open: boolean;
|
|
52
71
|
isNewCollection: boolean;
|
|
53
72
|
initialValues?: {
|
|
@@ -139,6 +158,7 @@ export function CollectionEditorDialog(props: CollectionEditorDialogProps) {
|
|
|
139
158
|
fullHeight={true}
|
|
140
159
|
scrollable={false}
|
|
141
160
|
maxWidth={"7xl"}
|
|
161
|
+
className="bg-surface-50 dark:bg-surface-800"
|
|
142
162
|
onOpenChange={(open) => !open ? handleCancel() : undefined}
|
|
143
163
|
>
|
|
144
164
|
<DialogTitle hidden>Collection editor</DialogTitle>
|
|
@@ -168,17 +188,23 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
168
188
|
handleCancel: () => void,
|
|
169
189
|
setFormDirty: (dirty: boolean) => void
|
|
170
190
|
}) {
|
|
171
|
-
const {
|
|
191
|
+
const { standalone } = props;
|
|
192
|
+
|
|
193
|
+
const customizationController = useCustomizationController();
|
|
172
194
|
const navigationState = useNavigationStateController();
|
|
173
195
|
const collectionRegistry = useCollectionRegistryController();
|
|
174
196
|
const authController = useAuthController();
|
|
175
197
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
198
|
+
// In standalone mode, use safe defaults instead of context values
|
|
199
|
+
const propertyConfigs = standalone
|
|
200
|
+
? (customizationController?.propertyConfigs ?? {})
|
|
201
|
+
: customizationController.propertyConfigs;
|
|
202
|
+
const topLevelNavigation = standalone
|
|
203
|
+
? (navigationState?.topLevelNavigation ?? [])
|
|
204
|
+
: navigationState.topLevelNavigation;
|
|
205
|
+
const collections = standalone
|
|
206
|
+
? (collectionRegistry?.collections ?? [])
|
|
207
|
+
: collectionRegistry.collections;
|
|
182
208
|
|
|
183
209
|
const initialValuesProp = props.initialValues;
|
|
184
210
|
const copyFromProp = props.copyFrom;
|
|
@@ -192,7 +218,13 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
192
218
|
|
|
193
219
|
useEffect(() => {
|
|
194
220
|
try {
|
|
195
|
-
|
|
221
|
+
const initialised = (standalone
|
|
222
|
+
? true
|
|
223
|
+
: (collectionRegistry?.initialised ?? true)) && !props.configController?.loading;
|
|
224
|
+
const getRawCollection = standalone
|
|
225
|
+
? (() => undefined)
|
|
226
|
+
: collectionRegistry.getRawCollection;
|
|
227
|
+
if (initialised) {
|
|
196
228
|
if (props.editedCollectionId) {
|
|
197
229
|
// We must use getRawCollection so the editor schema fields
|
|
198
230
|
// aren't polluted with dynamically injected runtime `relations`.
|
|
@@ -200,7 +232,9 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
200
232
|
const collectionPath = [...(props.parentCollectionSlugs ?? []), props.editedCollectionId]
|
|
201
233
|
.reduce((acc, segment, i) => i === 0 ? segment : `${acc}/fake_id/${segment}`, "");
|
|
202
234
|
|
|
203
|
-
|
|
235
|
+
const registryCol = getRawCollection ? getRawCollection(collectionPath) : undefined;
|
|
236
|
+
const configCol = props.configController?.collections?.find(c => c.slug === props.editedCollectionId);
|
|
237
|
+
setCollection((registryCol ?? configCol) as EntityCollection<any>);
|
|
204
238
|
} else {
|
|
205
239
|
setCollection(undefined);
|
|
206
240
|
}
|
|
@@ -209,44 +243,51 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
209
243
|
} catch (e) {
|
|
210
244
|
console.error(e);
|
|
211
245
|
}
|
|
212
|
-
}, [props.editedCollectionId, props.parentCollectionSlugs, props.parentEntityIds, collectionRegistry.initialised, collectionRegistry.getRawCollection]);
|
|
246
|
+
}, [props.editedCollectionId, props.parentCollectionSlugs, props.parentEntityIds, standalone, collectionRegistry.initialised, collectionRegistry.getRawCollection, props.configController.collections, props.configController.loading, collections]);
|
|
213
247
|
|
|
214
248
|
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
249
|
+
const initialIcon = React.useMemo(() => coolIconKeys[Math.floor(Math.random() * coolIconKeys.length)], []);
|
|
250
|
+
const fallbackSlug = React.useMemo(() => randomString(16), []);
|
|
251
|
+
|
|
252
|
+
const initialCollection = React.useMemo(() => {
|
|
253
|
+
return collection
|
|
254
|
+
? {
|
|
255
|
+
...collection,
|
|
256
|
+
slug: collection.slug ?? fallbackSlug
|
|
257
|
+
}
|
|
258
|
+
: undefined;
|
|
259
|
+
}, [collection, fallbackSlug]);
|
|
221
260
|
|
|
222
261
|
// Build initial values - handle copyFrom for duplication
|
|
223
|
-
const initialValues: EntityCollection<any>
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
262
|
+
const initialValues = React.useMemo((): EntityCollection<any> => {
|
|
263
|
+
return (initialCollection
|
|
264
|
+
? applyPropertyConfigs(initialCollection, propertyConfigs)
|
|
265
|
+
: copyFromProp
|
|
266
|
+
? (() => {
|
|
267
|
+
// When duplicating, copy all properties but clear identifiers
|
|
268
|
+
const { subcollections: _sub, ...rest } = copyFromProp as unknown as Record<string, unknown>;
|
|
269
|
+
return {
|
|
270
|
+
...rest,
|
|
271
|
+
name: "",
|
|
272
|
+
ownerId: authController.user?.uid ?? ""
|
|
273
|
+
} as EntityCollection<any>;
|
|
274
|
+
})()
|
|
275
|
+
: {
|
|
276
|
+
slug: initialValuesProp?.slug ?? fallbackSlug,
|
|
277
|
+
table: initialValuesProp?.slug ?? "",
|
|
278
|
+
name: initialValuesProp?.name ?? "",
|
|
279
|
+
properties: {} as EngineProperties,
|
|
280
|
+
propertiesOrder: [],
|
|
281
|
+
icon: initialIcon,
|
|
232
282
|
ownerId: authController.user?.uid ?? ""
|
|
233
|
-
} as EntityCollection<any>;
|
|
234
|
-
|
|
235
|
-
: {
|
|
236
|
-
slug: initialValuesProp?.slug ?? randomString(16),
|
|
237
|
-
table: initialValuesProp?.slug ?? "",
|
|
238
|
-
name: initialValuesProp?.name ?? "",
|
|
239
|
-
properties: {} as Properties,
|
|
240
|
-
propertiesOrder: [],
|
|
241
|
-
icon: coolIconKeys[Math.floor(Math.random() * coolIconKeys.length)],
|
|
242
|
-
ownerId: authController.user?.uid ?? ""
|
|
243
|
-
};
|
|
283
|
+
}) as EntityCollection<any>;
|
|
284
|
+
}, [initialCollection, propertyConfigs, copyFromProp, initialValuesProp, fallbackSlug, initialIcon, authController.user?.uid]);
|
|
244
285
|
|
|
245
286
|
if (!initialLoadingCompleted) {
|
|
246
287
|
return <CircularProgressCenter/>;
|
|
247
288
|
}
|
|
248
289
|
|
|
249
|
-
if (!props.isNewCollection && (!collectionRegistry
|
|
290
|
+
if (!props.isNewCollection && (!(standalone ? true : (collectionRegistry?.initialised ?? true)) || !initialLoadingCompleted)) {
|
|
250
291
|
return <CircularProgressCenter/>;
|
|
251
292
|
}
|
|
252
293
|
|
|
@@ -290,7 +331,13 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
290
331
|
onAnalyticsEvent,
|
|
291
332
|
fullScreen,
|
|
292
333
|
unmappedTables,
|
|
293
|
-
onFetchTableMetadata
|
|
334
|
+
onFetchTableMetadata,
|
|
335
|
+
propertyTypePresets,
|
|
336
|
+
hiddenPropertyTypes,
|
|
337
|
+
renderExtraPropertyFields,
|
|
338
|
+
renderExtraCollectionFields,
|
|
339
|
+
visibleTabs,
|
|
340
|
+
standalone
|
|
294
341
|
}: CollectionEditorDialogProps & {
|
|
295
342
|
handleCancel: () => void,
|
|
296
343
|
setFormDirty: (dirty: boolean) => void,
|
|
@@ -304,10 +351,33 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
304
351
|
}
|
|
305
352
|
) {
|
|
306
353
|
|
|
307
|
-
const
|
|
308
|
-
const
|
|
309
|
-
const
|
|
310
|
-
const
|
|
354
|
+
const importConfigRaw = useImportConfig();
|
|
355
|
+
const urlControllerRaw = useUrlController();
|
|
356
|
+
const collectionRegistryRaw = useCollectionRegistryController();
|
|
357
|
+
const snackbarControllerRaw = useSafeSnackbarController();
|
|
358
|
+
|
|
359
|
+
// In standalone mode, use safe defaults
|
|
360
|
+
const importConfig = standalone ? undefined : importConfigRaw;
|
|
361
|
+
const urlController = standalone
|
|
362
|
+
? {
|
|
363
|
+
basePath: "/",
|
|
364
|
+
baseCollectionPath: "/c",
|
|
365
|
+
urlPathToDataPath: () => "",
|
|
366
|
+
homeUrl: "/",
|
|
367
|
+
isUrlCollectionPath: () => false,
|
|
368
|
+
buildUrlCollectionPath: () => "",
|
|
369
|
+
buildAppUrlPath: () => "",
|
|
370
|
+
resolveDatabasePathsFrom: (p: string) => p,
|
|
371
|
+
navigate: () => { }
|
|
372
|
+
}
|
|
373
|
+
: urlControllerRaw;
|
|
374
|
+
const collectionRegistryInternal = standalone
|
|
375
|
+
? { convertIdsToPaths: (ids: string[]) => ids }
|
|
376
|
+
: collectionRegistryRaw;
|
|
377
|
+
const snackbarController = snackbarControllerRaw ?? {
|
|
378
|
+
open: () => { },
|
|
379
|
+
close: () => { }
|
|
380
|
+
};
|
|
311
381
|
|
|
312
382
|
// Use this ref to store which properties have errors
|
|
313
383
|
const propertyErrorsRef = useRef<Record<string, any>>({});
|
|
@@ -317,6 +387,12 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
317
387
|
: (initialViewProp ?? "properties");
|
|
318
388
|
const [currentView, setCurrentView] = useState<EditorView>(initialView); // this view can edit either the details view or the properties one
|
|
319
389
|
|
|
390
|
+
useEffect(() => {
|
|
391
|
+
if (visibleTabs && !visibleTabs.includes(currentView as CollectionEditorTab)) {
|
|
392
|
+
setCurrentView(visibleTabs[0] || "general");
|
|
393
|
+
}
|
|
394
|
+
}, [visibleTabs, currentView]);
|
|
395
|
+
|
|
320
396
|
const [error, setError] = React.useState<Error | undefined>();
|
|
321
397
|
|
|
322
398
|
const saveCollection = (updatedCollection: EntityCollection<M>): Promise<boolean> => {
|
|
@@ -345,7 +421,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
345
421
|
|
|
346
422
|
const setNextMode = () => {
|
|
347
423
|
if (currentView === "general") {
|
|
348
|
-
if (importConfig
|
|
424
|
+
if (importConfig?.inUse) {
|
|
349
425
|
setCurrentView("import_data_saving");
|
|
350
426
|
} else if (extraView) {
|
|
351
427
|
setCurrentView("extra_view");
|
|
@@ -396,7 +472,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
396
472
|
};
|
|
397
473
|
|
|
398
474
|
if (Object.keys(inferredCollection.properties ?? {}).length > 0) {
|
|
399
|
-
values.properties = inferredCollection.properties as
|
|
475
|
+
values.properties = inferredCollection.properties as EngineProperties;
|
|
400
476
|
values.propertiesOrder = inferredCollection.propertiesOrder as Extract<keyof M, string>[];
|
|
401
477
|
}
|
|
402
478
|
|
|
@@ -439,7 +515,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
439
515
|
setNextMode();
|
|
440
516
|
formexController.resetForm({ values: newCollectionState });
|
|
441
517
|
} else if (currentView === "general") {
|
|
442
|
-
if (extraView || importConfig
|
|
518
|
+
if (extraView || importConfig?.inUse) {
|
|
443
519
|
formexController.resetForm({ values: newCollectionState });
|
|
444
520
|
setNextMode();
|
|
445
521
|
} else if (isNewCollection) {
|
|
@@ -537,7 +613,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
537
613
|
const usedPath = getTableName(values);
|
|
538
614
|
const pathError = validatePath(usedPath, isNewCollection, existingPaths, values.slug);
|
|
539
615
|
|
|
540
|
-
const parentPaths = !pathError && parentCollectionSlugs ?
|
|
616
|
+
const parentPaths = !pathError && parentCollectionSlugs ? collectionRegistryInternal.convertIdsToPaths(parentCollectionSlugs) : undefined;
|
|
541
617
|
|
|
542
618
|
const updatedFullPath = parentPaths && parentPaths.length > 0
|
|
543
619
|
? [...parentPaths, usedPath].join("/fake_id/")
|
|
@@ -558,18 +634,18 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
558
634
|
}, [dirty]);
|
|
559
635
|
|
|
560
636
|
function onImportDataSet(data: object[], propertiesOrder?: string[]) {
|
|
561
|
-
importConfig
|
|
637
|
+
importConfig?.setInUse(true);
|
|
562
638
|
buildEntityPropertiesFromData(data, getInferenceType)
|
|
563
|
-
.then((properties:
|
|
639
|
+
.then((properties: unknown) => {
|
|
564
640
|
const res = cleanPropertiesFromImport(properties as Properties);
|
|
565
641
|
|
|
566
|
-
importConfig
|
|
567
|
-
importConfig
|
|
568
|
-
importConfig
|
|
642
|
+
importConfig?.setIdColumn(res.idColumn);
|
|
643
|
+
importConfig?.setImportData(data);
|
|
644
|
+
importConfig?.setHeadersMapping(res.headersMapping);
|
|
569
645
|
const filteredHeadingsOrder = ((propertiesOrder ?? [])
|
|
570
646
|
.filter((key) => res.headersMapping[key]) as string[]) ?? Object.keys(res.properties);
|
|
571
|
-
importConfig
|
|
572
|
-
importConfig
|
|
647
|
+
importConfig?.setHeadingsOrder(filteredHeadingsOrder);
|
|
648
|
+
importConfig?.setOriginProperties(res.properties);
|
|
573
649
|
|
|
574
650
|
const mappedHeadings = (propertiesOrder ?? []).map((key) => res.headersMapping[key]).filter(Boolean) as string[] ?? Object.keys(res.properties);
|
|
575
651
|
setFieldValue("properties", res.properties);
|
|
@@ -581,7 +657,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
581
657
|
|
|
582
658
|
const onImportMappingComplete = () => {
|
|
583
659
|
const updatedProperties = { ...values.properties };
|
|
584
|
-
if (importConfig
|
|
660
|
+
if (importConfig?.idColumn)
|
|
585
661
|
delete updatedProperties[importConfig.idColumn];
|
|
586
662
|
setFieldValue("properties", updatedProperties);
|
|
587
663
|
// setFieldValue("propertiesOrder", Object.values(importConfig.headersMapping));
|
|
@@ -620,25 +696,25 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
620
696
|
}
|
|
621
697
|
};
|
|
622
698
|
|
|
623
|
-
return <div className="h-full w-full flex flex-col bg-
|
|
699
|
+
return <div className="h-full w-full flex flex-col bg-surface-50 dark:bg-surface-800">
|
|
624
700
|
<Formex value={formController}>
|
|
625
701
|
|
|
626
702
|
<>
|
|
627
|
-
{!isNewCollection && <div className={cls("px-4 py-2 w-full flex shrink-0 items-center justify-between gap-4 bg-surface-50 dark:bg-surface-
|
|
703
|
+
{!isNewCollection && <div className={cls("px-4 py-2 w-full flex shrink-0 items-center justify-between gap-4 bg-surface-50 dark:bg-surface-900 border-b", defaultBorderMixin)}>
|
|
628
704
|
<div className="flex flex-1 items-center justify-end gap-4 min-w-0">
|
|
629
705
|
<Tabs value={currentView}
|
|
630
706
|
className="bg-transparent !w-fit max-w-full"
|
|
631
707
|
onValueChange={(v) => setCurrentView(v as EditorView)}>
|
|
632
|
-
<Tab value={"general"}>
|
|
708
|
+
{(!visibleTabs || visibleTabs.includes("general")) && <Tab value={"general"}>
|
|
633
709
|
General
|
|
634
|
-
</Tab>
|
|
635
|
-
<Tab value={"display"}>
|
|
710
|
+
</Tab>}
|
|
711
|
+
{(!visibleTabs || visibleTabs.includes("display")) && <Tab value={"display"}>
|
|
636
712
|
Display
|
|
637
|
-
</Tab>
|
|
638
|
-
<Tab value={"properties"}>
|
|
713
|
+
</Tab>}
|
|
714
|
+
{(!visibleTabs || visibleTabs.includes("properties")) && <Tab value={"properties"}>
|
|
639
715
|
Properties
|
|
640
|
-
</Tab>
|
|
641
|
-
{getDataSourceCapabilities(values.
|
|
716
|
+
</Tab>}
|
|
717
|
+
{(!visibleTabs || visibleTabs.includes("rls")) && getDataSourceCapabilities(values.engine).supportsRLS && <Tab value={"rls"}>
|
|
642
718
|
RLS
|
|
643
719
|
</Tab>}
|
|
644
720
|
</Tabs>
|
|
@@ -673,7 +749,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
673
749
|
onSubmit={formController.handleSubmit}
|
|
674
750
|
className="flex-grow flex flex-col min-h-0 relative">
|
|
675
751
|
|
|
676
|
-
<div className="flex-grow flex flex-col min-h-0
|
|
752
|
+
<div className="flex-grow flex flex-col min-h-0 no-scrollbar relative w-full h-full bg-surface-50 dark:bg-surface-800">
|
|
677
753
|
|
|
678
754
|
{currentView === "loading" &&
|
|
679
755
|
<CircularProgressCenter/>}
|
|
@@ -736,17 +812,19 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
736
812
|
|
|
737
813
|
{currentView === "general" &&
|
|
738
814
|
<GeneralSettingsForm
|
|
815
|
+
isNewCollection={isNewCollection}
|
|
739
816
|
existingPaths={existingPaths}
|
|
740
817
|
existingIds={existingIds}
|
|
741
818
|
parentCollection={parentCollection}
|
|
742
|
-
|
|
819
|
+
renderExtraCollectionFields={renderExtraCollectionFields}
|
|
820
|
+
standalone={standalone}/>
|
|
743
821
|
}
|
|
744
822
|
|
|
745
823
|
{currentView === "display" &&
|
|
746
|
-
<DisplaySettingsForm expandKanban={expandKanban}/>
|
|
824
|
+
<DisplaySettingsForm expandKanban={expandKanban} standalone={standalone}/>
|
|
747
825
|
}
|
|
748
826
|
|
|
749
|
-
{currentView === "rls" && getDataSourceCapabilities(values.
|
|
827
|
+
{currentView === "rls" && getDataSourceCapabilities(values.engine).supportsRLS &&
|
|
750
828
|
<CollectionRLSTab/>
|
|
751
829
|
}
|
|
752
830
|
|
|
@@ -766,25 +844,28 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
766
844
|
getData={getDataWithPath}
|
|
767
845
|
doCollectionInference={doCollectionInference}
|
|
768
846
|
propertyConfigs={propertyConfigs}
|
|
769
|
-
|
|
847
|
+
propertyTypePresets={propertyTypePresets}
|
|
848
|
+
hiddenPropertyTypes={hiddenPropertyTypes}
|
|
849
|
+
renderExtraPropertyFields={renderExtraPropertyFields}
|
|
770
850
|
extraIcon={extraView?.icon &&
|
|
771
851
|
<IconButton
|
|
772
852
|
color={"primary"}
|
|
773
853
|
onClick={() => setCurrentView("extra_view")}>
|
|
774
854
|
{extraView.icon}
|
|
775
|
-
</IconButton>}
|
|
855
|
+
</IconButton>}
|
|
856
|
+
standalone={standalone}/>
|
|
776
857
|
}
|
|
777
858
|
|
|
778
859
|
</div>
|
|
779
860
|
{(!fullScreen || isNewCollection || !!error) && (
|
|
780
|
-
<div className="shrink-0 w-full p-4 sm:px-6 sm:py-4 border-t border-surface-200 dark:border-surface-900 flex items-center justify-between gap-4 bg-
|
|
861
|
+
<div className="shrink-0 w-full p-4 sm:px-6 sm:py-4 border-t border-surface-200 dark:border-surface-900 flex items-center justify-between gap-4 bg-surface-50 dark:bg-surface-900">
|
|
781
862
|
{error && <ErrorView error={error}/>}
|
|
782
863
|
|
|
783
864
|
{isNewCollection && includeTemplates && currentView === "import_data_mapping" &&
|
|
784
865
|
<Button variant={"text"}
|
|
785
866
|
type="button"
|
|
786
867
|
onClick={() => {
|
|
787
|
-
importConfig
|
|
868
|
+
importConfig?.setInUse(false);
|
|
788
869
|
return setCurrentView("welcome");
|
|
789
870
|
}}>
|
|
790
871
|
Back
|
|
@@ -910,8 +991,8 @@ function applyPropertyConfigs<M extends Record<string, unknown> = Record<string,
|
|
|
910
991
|
|
|
911
992
|
return {
|
|
912
993
|
...rest,
|
|
913
|
-
properties: propertiesResult
|
|
914
|
-
}
|
|
994
|
+
properties: propertiesResult as EngineProperties
|
|
995
|
+
} as EntityCollection<M>;
|
|
915
996
|
}
|
|
916
997
|
|
|
917
998
|
function applyPropertiesConfig(property: Property, propertyConfigs: Record<string, PropertyConfig>) {
|