@rebasepro/admin 0.0.1-canary.eae7889 → 0.1.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-B2M9lCyL.js → CollectionEditorDialog-MbvXGzEq.js} +42 -31
- package/dist/CollectionEditorDialog-MbvXGzEq.js.map +1 -0
- package/dist/{CollectionsStudioView-WG6soyfs.js → CollectionsStudioView-D9X6aiAr.js} +12 -12
- package/dist/CollectionsStudioView-D9X6aiAr.js.map +1 -0
- package/dist/{ContentHomePage-CDF_a6Lp.js → ContentHomePage-CfVB1eUo.js} +26 -26
- package/dist/ContentHomePage-CfVB1eUo.js.map +1 -0
- package/dist/{ExportCollectionAction-Dc0VOWMN.js → ExportCollectionAction-CUwJg4F9.js} +2 -2
- package/dist/{ExportCollectionAction-Dc0VOWMN.js.map → ExportCollectionAction-CUwJg4F9.js.map} +1 -1
- package/dist/{ImportCollectionAction-DpCagAOy.js → ImportCollectionAction-DGa_SF_8.js} +2 -2
- package/dist/{ImportCollectionAction-DpCagAOy.js.map → ImportCollectionAction-DGa_SF_8.js.map} +1 -1
- package/dist/{PropertyEditView-DS67DxoT.js → PropertyEditView-C4nlYmAc.js} +82 -104
- package/dist/PropertyEditView-C4nlYmAc.js.map +1 -0
- package/dist/{RolesView-CIuYBimF.js → RolesView-CNWxnR8e.js} +7 -5
- package/dist/RolesView-CNWxnR8e.js.map +1 -0
- package/dist/{UsersView-B5zelXnH.js → UsersView-YiTIcXkA.js} +14 -35
- package/dist/UsersView-YiTIcXkA.js.map +1 -0
- package/dist/collection_editor/ConfigControllerProvider.d.ts +0 -4
- package/dist/collection_editor/types/collection_editor_controller.d.ts +6 -3
- package/dist/collection_editor/types/config_controller.d.ts +14 -7
- package/dist/collection_editor/ui/AddKanbanColumnAction.d.ts +3 -2
- package/dist/collection_editor/ui/CollectionViewHeaderAction.d.ts +3 -2
- package/dist/collection_editor/ui/EditorCollectionAction.d.ts +1 -1
- package/dist/collection_editor/ui/EditorCollectionActionStart.d.ts +1 -1
- package/dist/collection_editor/ui/EditorEntityAction.d.ts +1 -1
- package/dist/collection_editor/ui/KanbanSetupAction.d.ts +3 -2
- package/dist/collection_editor/ui/PropertyAddColumnComponent.d.ts +3 -2
- package/dist/collection_editor/ui/collection_editor/CollectionDetailsForm.d.ts +3 -4
- package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +2 -3
- package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +1 -2
- package/dist/collection_editor/ui/collection_editor/SubcollectionsEditTab.d.ts +3 -2
- package/dist/collection_editor_ui.js +3 -3
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +1 -1
- package/dist/components/EntityCollectionTable/column_utils.d.ts +2 -2
- package/dist/components/EntityCollectionTable/fields/TableMultipleRelationField.d.ts +1 -1
- package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
- package/dist/components/EntityCollectionTable/fields/TableRelationField.d.ts +1 -1
- package/dist/components/EntityCollectionTable/fields/TableRelationSelectorField.d.ts +2 -2
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +5 -1
- package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +3 -2
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +2 -1
- package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +4 -2
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +4 -2
- package/dist/components/EntityCollectionView/FiltersDialog.d.ts +2 -2
- package/dist/components/EntityCollectionView/SplitListView.d.ts +3 -2
- package/dist/components/EntityEditView.d.ts +9 -2
- package/dist/components/RebaseCMS.d.ts +1 -1
- package/dist/components/ReferenceTable/EntitySelectionTable.d.ts +2 -2
- package/dist/components/ReferenceWidget.d.ts +2 -2
- package/dist/components/RelationSelector.d.ts +1 -1
- package/dist/components/SelectableTable/SelectableTable.d.ts +2 -2
- package/dist/editor.js +2 -2
- package/dist/editor.js.map +1 -1
- package/dist/hooks/navigation/useNavigationRegistry.d.ts +2 -1
- package/dist/hooks/useEntityHistory.d.ts +1 -1
- package/dist/{index-CHxgwt6E.js → index-CtzpHzMQ.js} +11 -4
- package/dist/index-CtzpHzMQ.js.map +1 -0
- package/dist/{index-Dey5WJpO.js → index-DKlrVD1m.js} +3 -3
- package/dist/index-DKlrVD1m.js.map +1 -0
- package/dist/{index-CBhrgpR7.js → index-kHJXfLNI.js} +3 -3
- package/dist/index-kHJXfLNI.js.map +1 -0
- package/dist/index.js +79 -63
- package/dist/index.js.map +1 -1
- package/dist/{useEntityHistory-Dcj4zhGj.js → useEntityHistory-UVsSclfZ.js} +3 -1
- package/dist/useEntityHistory-UVsSclfZ.js.map +1 -0
- package/dist/util/navigation_utils.d.ts +10 -1
- package/dist/{util-BQ82ySL3.js → util-CwLmSpGp.js} +1653 -1257
- package/dist/util-CwLmSpGp.js.map +1 -0
- package/package.json +9 -17
- package/src/collection_editor/ConfigControllerProvider.tsx +19 -28
- package/src/collection_editor/types/collection_editor_controller.tsx +3 -3
- package/src/collection_editor/types/config_controller.tsx +7 -7
- package/src/collection_editor/ui/AddKanbanColumnAction.tsx +4 -4
- package/src/collection_editor/ui/CollectionViewHeaderAction.tsx +3 -3
- package/src/collection_editor/ui/EditorCollectionAction.tsx +3 -3
- package/src/collection_editor/ui/EditorCollectionActionStart.tsx +7 -7
- package/src/collection_editor/ui/EditorEntityAction.tsx +3 -3
- package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +4 -2
- package/src/collection_editor/ui/KanbanSetupAction.tsx +4 -3
- package/src/collection_editor/ui/MissingReferenceWidget.tsx +3 -2
- package/src/collection_editor/ui/NewCollectionButton.tsx +2 -1
- package/src/collection_editor/ui/NewCollectionCard.tsx +2 -1
- package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/CollectionDetailsForm.tsx +5 -50
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +12 -20
- package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +1 -3
- package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +17 -2
- package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +2 -1
- package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +18 -12
- package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +1 -2
- package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +1 -2
- package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +6 -6
- package/src/collection_editor/ui/collection_editor/SubcollectionsEditTab.tsx +4 -4
- package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/ReferencePropertyField.tsx +15 -49
- package/src/collection_editor/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +4 -5
- package/src/collection_editor/ui/collection_editor/templates/pages_template.ts +1 -1
- package/src/collection_editor/ui/collection_editor/templates/products_template.ts +2 -2
- package/src/components/DefaultAppBar.tsx +2 -2
- package/src/components/DefaultDrawer.tsx +25 -17
- package/src/components/DrawerNavigationGroup.tsx +4 -4
- package/src/components/DrawerNavigationItem.tsx +6 -6
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +4 -4
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +1 -1
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +4 -4
- package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableMultipleRelationField.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableRelationField.tsx +4 -4
- package/src/components/EntityCollectionTable/fields/TableRelationSelectorField.tsx +3 -3
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +8 -2
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/common.tsx +5 -5
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +1 -1
- package/src/components/EntityCollectionTable/table_bindings.tsx +45 -35
- package/src/components/EntityCollectionView/EntityBoardCard.tsx +18 -19
- package/src/components/EntityCollectionView/EntityCard.tsx +2 -2
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +42 -14
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +4 -3
- package/src/components/EntityCollectionView/EntityCollectionListView.tsx +157 -54
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +169 -75
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +23 -13
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +21 -12
- package/src/components/EntityCollectionView/FiltersDialog.tsx +7 -7
- package/src/components/EntityCollectionView/SplitListView.tsx +24 -8
- package/src/components/EntityCollectionView/useEntityPreviewSlots.ts +33 -5
- package/src/components/EntityEditView.tsx +85 -85
- package/src/components/EntitySidePanel.tsx +18 -10
- package/src/components/HomePage/ContentHomePage.tsx +24 -15
- package/src/components/HomePage/NavigationCard.tsx +4 -4
- package/src/components/HomePage/NavigationGroup.tsx +2 -2
- package/src/components/RebaseAuthGate.tsx +2 -0
- package/src/components/RebaseCMS.tsx +4 -3
- package/src/components/RebaseNavigation.tsx +8 -5
- package/src/components/ReferenceTable/EntitySelectionTable.tsx +4 -4
- package/src/components/ReferenceWidget.tsx +3 -3
- package/src/components/RelationSelector.tsx +33 -5
- package/src/components/SelectableTable/SelectableTable.tsx +6 -6
- package/src/components/UserSelector.tsx +1 -1
- package/src/components/admin/RolesView.tsx +10 -3
- package/src/components/admin/UsersView.tsx +13 -25
- package/src/components/app/Scaffold.tsx +4 -4
- package/src/components/field_configs.tsx +29 -32
- package/src/components/history/EntityHistoryView.tsx +12 -1
- package/src/editor/editor.tsx +2 -2
- package/src/form/EntityForm.tsx +5 -4
- package/src/form/PropertyFieldBinding.tsx +14 -10
- package/src/form/components/FieldHelperText.tsx +1 -1
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +3 -3
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +5 -5
- package/src/form/field_bindings/BlockFieldBinding.tsx +4 -4
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
- package/src/form/field_bindings/MapFieldBinding.tsx +7 -7
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +1 -1
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +3 -3
- package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +7 -7
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +2 -2
- package/src/form/field_bindings/RelationFieldBinding.tsx +4 -4
- package/src/form/field_bindings/RepeatFieldBinding.tsx +5 -5
- package/src/form/field_bindings/SelectFieldBinding.tsx +1 -1
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +1 -1
- package/src/form/field_bindings/SwitchFieldBinding.tsx +1 -1
- package/src/form/field_bindings/TextFieldBinding.tsx +7 -7
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +1 -1
- package/src/form/useClearRestoreValue.tsx +1 -1
- package/src/form/validation.ts +1 -1
- package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +2 -1
- package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +15 -3
- package/src/hooks/navigation/useNavigationRegistry.ts +14 -3
- package/src/hooks/navigation/useResolvedViews.tsx +1 -3
- package/src/hooks/navigation/useTopLevelNavigation.ts +1 -1
- package/src/hooks/navigation/utils.ts +1 -1
- package/src/hooks/useEntityHistory.ts +7 -2
- package/src/preview/PropertyPreview.tsx +27 -23
- package/src/preview/components/StorageThumbnail.tsx +4 -1
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +1 -1
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +3 -3
- package/src/preview/property_previews/StringPropertyPreview.tsx +3 -3
- package/src/routes/RebaseRoute.tsx +57 -11
- package/src/util/navigation_utils.ts +21 -2
- package/src/util/previews.ts +15 -6
- package/src/util/property_utils.tsx +3 -3
- package/dist/CollectionEditorDialog-B2M9lCyL.js.map +0 -1
- package/dist/CollectionsStudioView-WG6soyfs.js.map +0 -1
- package/dist/ContentHomePage-CDF_a6Lp.js.map +0 -1
- package/dist/PropertyEditView-DS67DxoT.js.map +0 -1
- package/dist/RolesView-CIuYBimF.js.map +0 -1
- package/dist/UsersView-B5zelXnH.js.map +0 -1
- package/dist/index-CBhrgpR7.js.map +0 -1
- package/dist/index-CHxgwt6E.js.map +0 -1
- package/dist/index-Dey5WJpO.js.map +0 -1
- package/dist/useEntityHistory-Dcj4zhGj.js.map +0 -1
- package/dist/util-BQ82ySL3.js.map +0 -1
|
@@ -5,7 +5,7 @@ import React, { useMemo, useState } from "react";
|
|
|
5
5
|
import { useAuthController, useCustomizationController } from "@rebasepro/core";
|
|
6
6
|
import { getFieldConfig, PropertyConfigBadge, SearchIconsView } from "../../_cms_internals";
|
|
7
7
|
import { EntityCollection, Property } from "@rebasepro/types";
|
|
8
|
-
import { BooleanSwitchWithLabel, Chip, cls, Container, DebouncedTextField, Dialog, IconButton, Select, SelectItem, TextField, Tooltip, Typography,
|
|
8
|
+
import { BooleanSwitchWithLabel, Chip, cls, Container, DebouncedTextField, Dialog, IconButton, Select, SelectItem, TextField, Tooltip, Typography, Button, iconSize } from "@rebasepro/ui";
|
|
9
9
|
import { XIcon, HistoryIcon } from "lucide-react";
|
|
10
10
|
|
|
11
11
|
import { Field, getIn, useFormex } from "@rebasepro/formex";
|
|
@@ -18,24 +18,20 @@ import { singular, toSnakeCase, unslugify } from "@rebasepro/utils";
|
|
|
18
18
|
|
|
19
19
|
export function CollectionDetailsForm({
|
|
20
20
|
isNewCollection,
|
|
21
|
-
reservedGroups,
|
|
22
21
|
existingPaths,
|
|
23
22
|
existingIds,
|
|
24
|
-
groups,
|
|
25
23
|
parentCollection,
|
|
26
24
|
expandKanban
|
|
27
25
|
}: {
|
|
28
26
|
isNewCollection: boolean,
|
|
29
|
-
reservedGroups?: string[];
|
|
30
27
|
existingPaths?: string[];
|
|
31
28
|
existingIds?: string[];
|
|
32
|
-
groups: string[] | null;
|
|
33
29
|
parentCollection?: EntityCollection;
|
|
34
|
-
|
|
30
|
+
parentCollectionSlugs?: string[], parentEntityIds?: string[];
|
|
35
31
|
expandKanban?: boolean;
|
|
36
32
|
}) {
|
|
37
33
|
|
|
38
|
-
|
|
34
|
+
|
|
39
35
|
const {
|
|
40
36
|
values,
|
|
41
37
|
setFieldValue,
|
|
@@ -98,15 +94,7 @@ export function CollectionDetailsForm({
|
|
|
98
94
|
|
|
99
95
|
const collectionIcon = <IconForView collectionOrView={values}/>;
|
|
100
96
|
|
|
101
|
-
const groupOptions = groups?.filter((group) => !reservedGroups?.includes(group));
|
|
102
97
|
|
|
103
|
-
const {
|
|
104
|
-
inputFocused,
|
|
105
|
-
autoCompleteOpen,
|
|
106
|
-
setAutoCompleteOpen
|
|
107
|
-
} = useAutoComplete({
|
|
108
|
-
ref: groupRef
|
|
109
|
-
});
|
|
110
98
|
|
|
111
99
|
const isSubcollection = !!parentCollection;
|
|
112
100
|
|
|
@@ -172,39 +160,7 @@ export function CollectionDetailsForm({
|
|
|
172
160
|
|
|
173
161
|
</div>
|
|
174
162
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
{/* <TextField error={showErrors && Boolean(errors.group)}*/}
|
|
178
|
-
{/* disabled={isSubmitting}*/}
|
|
179
|
-
{/* value={values.group ?? ""}*/}
|
|
180
|
-
{/* autoComplete="off"*/}
|
|
181
|
-
{/* onChange={(event) => setFieldValue("group", event.target.value)}*/}
|
|
182
|
-
{/* name={"group"}*/}
|
|
183
|
-
{/* inputRef={groupRef}*/}
|
|
184
|
-
{/* label="Group"/>*/}
|
|
185
|
-
{/* <Autocomplete*/}
|
|
186
|
-
{/* open={autoCompleteOpen && (groupOptions ?? []).length > 0}*/}
|
|
187
|
-
{/* setOpen={setAutoCompleteOpen}>*/}
|
|
188
|
-
{/* {groupOptions?.map((group, index) => {*/}
|
|
189
|
-
{/* return <AutocompleteItem*/}
|
|
190
|
-
{/* key={index + "_" + group}*/}
|
|
191
|
-
{/* className={"pr-6 pl-14"}*/}
|
|
192
|
-
{/* onClick={() => {*/}
|
|
193
|
-
{/* setAutoCompleteOpen(false);*/}
|
|
194
|
-
{/* setFieldValue("group", group ?? null);*/}
|
|
195
|
-
{/* }}*/}
|
|
196
|
-
{/* >*/}
|
|
197
|
-
{/* <div className={"flex-grow"}>*/}
|
|
198
|
-
{/* {group}*/}
|
|
199
|
-
{/* </div>*/}
|
|
200
|
-
{/* </AutocompleteItem>;*/}
|
|
201
|
-
{/* })}*/}
|
|
202
|
-
{/* </Autocomplete>*/}
|
|
203
|
-
{/* <FieldCaption>*/}
|
|
204
|
-
{/* {showErrors && Boolean(errors.group) ? errors.group : "Group in the home page"}*/}
|
|
205
|
-
{/* </FieldCaption>*/}
|
|
206
|
-
|
|
207
|
-
{/*</div>}*/}
|
|
163
|
+
|
|
208
164
|
|
|
209
165
|
<LayoutModeSwitch
|
|
210
166
|
className={"col-span-12"}
|
|
@@ -324,8 +280,7 @@ export function CollectionDetailsForm({
|
|
|
324
280
|
property={{
|
|
325
281
|
type: "string",
|
|
326
282
|
name: dialogPropertyName,
|
|
327
|
-
disabled: true,
|
|
328
|
-
hideFromCollection: true
|
|
283
|
+
ui: { disabled: true, hideFromCollection: true }
|
|
329
284
|
}}
|
|
330
285
|
propertyKey={dialogPropertyKey}
|
|
331
286
|
existingProperty={false}
|
|
@@ -37,7 +37,6 @@ export interface CollectionEditorDialogProps {
|
|
|
37
37
|
open: boolean;
|
|
38
38
|
isNewCollection: boolean;
|
|
39
39
|
initialValues?: {
|
|
40
|
-
group?: string,
|
|
41
40
|
slug?: string,
|
|
42
41
|
name?: string,
|
|
43
42
|
}
|
|
@@ -48,10 +47,9 @@ export interface CollectionEditorDialogProps {
|
|
|
48
47
|
copyFrom?: EntityCollection;
|
|
49
48
|
editedCollectionId?: string;
|
|
50
49
|
path?: string; // full path of this particular collection, like `products/123/locales`
|
|
51
|
-
|
|
50
|
+
parentCollectionSlugs?: string[], parentEntityIds?: string[]; // path ids of the parent collection, like [`products`]
|
|
52
51
|
handleClose: (collection?: EntityCollection) => void;
|
|
53
52
|
configController: CollectionsConfigController;
|
|
54
|
-
reservedGroups?: string[];
|
|
55
53
|
collectionInference?: CollectionInference;
|
|
56
54
|
extraView?: {
|
|
57
55
|
View: React.ComponentType<{
|
|
@@ -172,7 +170,7 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
172
170
|
const initialValuesProp = props.initialValues;
|
|
173
171
|
const copyFromProp = props.copyFrom;
|
|
174
172
|
// Skip templates when duplicating (copyFrom is provided)
|
|
175
|
-
const includeTemplates = !copyFromProp && !initialValuesProp?.slug && (props.
|
|
173
|
+
const includeTemplates = !copyFromProp && !initialValuesProp?.slug && (props.parentCollectionSlugs ?? []).length === 0;
|
|
176
174
|
const collectionsInThisLevel = (props.parentCollection ? getSubcollections(props.parentCollection) : collections) ?? [];
|
|
177
175
|
const existingPaths = collectionsInThisLevel.map(col => getTableName(col)?.trim().toLowerCase()).filter(Boolean);
|
|
178
176
|
const existingIds = collectionsInThisLevel.map(col => col.slug?.trim().toLowerCase()).filter(Boolean) as string[];
|
|
@@ -186,7 +184,7 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
186
184
|
// We must use getRawCollection so the editor schema fields
|
|
187
185
|
// aren't polluted with dynamically injected runtime `relations`.
|
|
188
186
|
// The path lookup relies on generating a fake child path to resolve through the registry
|
|
189
|
-
const collectionPath = [...(props.
|
|
187
|
+
const collectionPath = [...(props.parentCollectionSlugs ?? []), props.editedCollectionId]
|
|
190
188
|
.reduce((acc, segment, i) => i === 0 ? segment : `${acc}/fake_id/${segment}`, "");
|
|
191
189
|
|
|
192
190
|
setCollection(collectionRegistry.getRawCollection(collectionPath) as EntityCollection<any>);
|
|
@@ -198,9 +196,9 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
198
196
|
} catch (e) {
|
|
199
197
|
console.error(e);
|
|
200
198
|
}
|
|
201
|
-
}, [props.editedCollectionId, props.
|
|
199
|
+
}, [props.editedCollectionId, props.parentCollectionSlugs, props.parentEntityIds, collectionRegistry.initialised, collectionRegistry.getRawCollection]);
|
|
200
|
+
|
|
202
201
|
|
|
203
|
-
const groups = topLevelNavigation?.groups ?? [];
|
|
204
202
|
|
|
205
203
|
const initialCollection = collection
|
|
206
204
|
? {
|
|
@@ -226,7 +224,6 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
226
224
|
slug: initialValuesProp?.slug ?? randomString(16),
|
|
227
225
|
table: initialValuesProp?.slug ?? "",
|
|
228
226
|
name: initialValuesProp?.name ?? "",
|
|
229
|
-
group: initialValuesProp?.group ?? "",
|
|
230
227
|
properties: {} as Properties,
|
|
231
228
|
propertiesOrder: [],
|
|
232
229
|
icon: coolIconKeys[Math.floor(Math.random() * coolIconKeys.length)],
|
|
@@ -249,7 +246,6 @@ export function CollectionEditor(props: CollectionEditorDialogProps & {
|
|
|
249
246
|
includeTemplates={includeTemplates}
|
|
250
247
|
collection={collection}
|
|
251
248
|
setCollection={setCollection}
|
|
252
|
-
groups={groups}
|
|
253
249
|
propertyConfigs={propertyConfigs}/>
|
|
254
250
|
|
|
255
251
|
}
|
|
@@ -258,11 +254,10 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
258
254
|
isNewCollection,
|
|
259
255
|
configController,
|
|
260
256
|
editedCollectionId,
|
|
261
|
-
|
|
257
|
+
parentCollectionSlugs, parentEntityIds,
|
|
262
258
|
path,
|
|
263
259
|
collectionInference,
|
|
264
260
|
handleClose,
|
|
265
|
-
reservedGroups,
|
|
266
261
|
extraView,
|
|
267
262
|
handleCancel,
|
|
268
263
|
setFormDirty,
|
|
@@ -276,7 +271,6 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
276
271
|
setCollection,
|
|
277
272
|
initialValues,
|
|
278
273
|
propertyConfigs,
|
|
279
|
-
groups,
|
|
280
274
|
existingEntities,
|
|
281
275
|
initialView: initialViewProp,
|
|
282
276
|
expandKanban,
|
|
@@ -295,7 +289,6 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
295
289
|
collection: EntityCollection<M> | undefined,
|
|
296
290
|
setCollection: (collection: EntityCollection<M>) => void,
|
|
297
291
|
propertyConfigs: Record<string, PropertyConfig>,
|
|
298
|
-
groups: string[],
|
|
299
292
|
}
|
|
300
293
|
) {
|
|
301
294
|
|
|
@@ -321,7 +314,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
321
314
|
id,
|
|
322
315
|
collectionData: updatedCollection,
|
|
323
316
|
previousId: editedCollectionId,
|
|
324
|
-
|
|
317
|
+
parentCollectionSlugs
|
|
325
318
|
})
|
|
326
319
|
.then(() => {
|
|
327
320
|
setError(undefined);
|
|
@@ -532,7 +525,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
532
525
|
const usedPath = getTableName(values);
|
|
533
526
|
const pathError = validatePath(usedPath, isNewCollection, existingPaths, values.slug);
|
|
534
527
|
|
|
535
|
-
const parentPaths = !pathError &&
|
|
528
|
+
const parentPaths = !pathError && parentCollectionSlugs ? collectionRegistry.convertIdsToPaths(parentCollectionSlugs) : undefined;
|
|
536
529
|
|
|
537
530
|
const updatedFullPath = parentPaths && parentPaths.length > 0
|
|
538
531
|
? [...parentPaths, usedPath].join("/fake_id/")
|
|
@@ -615,11 +608,11 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
615
608
|
}
|
|
616
609
|
};
|
|
617
610
|
|
|
618
|
-
return <div className="h-full w-full flex flex-col bg-white dark:bg-surface-
|
|
611
|
+
return <div className="h-full w-full flex flex-col bg-white dark:bg-surface-950">
|
|
619
612
|
<Formex value={formController}>
|
|
620
613
|
|
|
621
614
|
<>
|
|
622
|
-
{!isNewCollection && <div className={cls("px-4 py-2 w-full flex shrink-0 items-center justify-between gap-4 bg-
|
|
615
|
+
{!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-950 border-b", defaultBorderMixin)}>
|
|
623
616
|
<div className="flex flex-1 items-center justify-end gap-4 min-w-0">
|
|
624
617
|
<Tabs value={currentView}
|
|
625
618
|
className="bg-transparent !w-fit max-w-full"
|
|
@@ -756,7 +749,6 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
756
749
|
<CollectionPropertiesEditorForm
|
|
757
750
|
showErrors={submitCount > 0}
|
|
758
751
|
isNewCollection={isNewCollection}
|
|
759
|
-
reservedGroups={reservedGroups}
|
|
760
752
|
onPropertyError={(propertyKey, namespace, error) => {
|
|
761
753
|
const current = removeUndefined({
|
|
762
754
|
...propertyErrorsRef.current,
|
|
@@ -780,7 +772,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
780
772
|
|
|
781
773
|
</div>
|
|
782
774
|
{(!fullScreen || isNewCollection || !!error) && (
|
|
783
|
-
<div className="shrink-0 w-full p-4 sm:px-6 sm:py-4 border-t border-surface-200 dark:border-surface-
|
|
775
|
+
<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-white dark:bg-surface-950">
|
|
784
776
|
{error && <ErrorView error={error}/>}
|
|
785
777
|
|
|
786
778
|
{isNewCollection && includeTemplates && currentView === "import_data_mapping" &&
|
|
@@ -858,7 +850,7 @@ function CollectionEditorInternal<M extends Record<string, unknown>>({
|
|
|
858
850
|
color="primary"
|
|
859
851
|
type="submit"
|
|
860
852
|
loading={isSubmitting}
|
|
861
|
-
disabled={isSubmitting || (currentView === "general" && !validValues)}
|
|
853
|
+
disabled={isSubmitting || (currentView === "general" && !validValues) || configController?.readOnly}
|
|
862
854
|
startIcon={currentView === "properties"
|
|
863
855
|
? <CheckIcon/>
|
|
864
856
|
: undefined}
|
|
@@ -27,7 +27,6 @@ type CollectionEditorFormProps = {
|
|
|
27
27
|
propertyErrorsRef?: React.MutableRefObject<any>;
|
|
28
28
|
onPropertyError: (propertyKey: string, namespace: string | undefined, error?: Record<string, any>) => void;
|
|
29
29
|
setDirty?: (dirty: boolean) => void;
|
|
30
|
-
reservedGroups?: string[];
|
|
31
30
|
extraIcon: React.ReactNode | any;
|
|
32
31
|
getUser?: (uid: string) => User | null;
|
|
33
32
|
getData?: () => Promise<object[]>;
|
|
@@ -42,7 +41,6 @@ export function CollectionPropertiesEditorForm({
|
|
|
42
41
|
propertyErrorsRef,
|
|
43
42
|
onPropertyError,
|
|
44
43
|
setDirty,
|
|
45
|
-
reservedGroups,
|
|
46
44
|
extraIcon,
|
|
47
45
|
getUser,
|
|
48
46
|
getData,
|
|
@@ -391,7 +389,7 @@ export function CollectionPropertiesEditorForm({
|
|
|
391
389
|
};
|
|
392
390
|
|
|
393
391
|
const body = (
|
|
394
|
-
<div className={"grid grid-cols-12 gap-2 h-full bg-
|
|
392
|
+
<div className={"grid grid-cols-12 gap-2 h-full bg-white dark:bg-surface-950"}>
|
|
395
393
|
<div className={cls(
|
|
396
394
|
"bg-surface-50 dark:bg-surface-900",
|
|
397
395
|
"p-4 md:p-8",
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
|
|
2
2
|
import { EntityCollection } from "@rebasepro/types";
|
|
3
3
|
import React, { useState, useEffect } from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Validates and double-quotes a SQL identifier to prevent injection.
|
|
7
|
+
* Only allows safe Postgres identifiers (letters, digits, underscores).
|
|
8
|
+
* Throws if the identifier contains unsafe characters.
|
|
9
|
+
*/
|
|
10
|
+
function sanitizeSqlIdentifier(name: string): string {
|
|
11
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
12
|
+
throw new Error(`Invalid SQL identifier: "${name}". Only letters, digits, and underscores are allowed.`);
|
|
13
|
+
}
|
|
14
|
+
return `"${name}"`;
|
|
15
|
+
}
|
|
4
16
|
import { Button, IconButton, Typography, cls, defaultBorderMixin, Chip, Paper, Container, Tooltip, CircularProgress, Dialog, DialogTitle, DialogContent, DialogActions, TextField, Select, SelectItem, MultiSelect, MultiSelectItem , iconSize } from "@rebasepro/ui";
|
|
5
17
|
import { KeyIcon, Trash2Icon } from "lucide-react";
|
|
6
18
|
import { useFormex } from "@rebasepro/formex";
|
|
@@ -51,10 +63,13 @@ export function CollectionRLSTab() {
|
|
|
51
63
|
|
|
52
64
|
setIsLoadingDb(true);
|
|
53
65
|
try {
|
|
66
|
+
const safeTableName = sanitizeSqlIdentifier(tableName);
|
|
67
|
+
// safeTableName is validated to be [a-zA-Z_][a-zA-Z0-9_]* — safe for string literal
|
|
68
|
+
const quotedName = safeTableName.slice(1, -1); // strip double quotes to get raw name
|
|
54
69
|
const sql = `
|
|
55
70
|
SELECT policyname, permissive, roles, cmd, qual, with_check
|
|
56
71
|
FROM pg_policies
|
|
57
|
-
WHERE tablename = '${
|
|
72
|
+
WHERE tablename = '${quotedName}' AND schemaname NOT IN ('information_schema', 'pg_catalog');
|
|
58
73
|
`;
|
|
59
74
|
const result = await databaseAdmin.executeSql(sql);
|
|
60
75
|
const extractRows = (res: unknown): Record<string, unknown>[] => {
|
|
@@ -280,7 +295,7 @@ function InlinePolicyEditor({
|
|
|
280
295
|
</div>
|
|
281
296
|
<div className="flex flex-col gap-1.5">
|
|
282
297
|
<Typography variant="caption" className="uppercase tracking-wider text-text-secondary">Behavior</Typography>
|
|
283
|
-
<Select value={behavior} onValueChange={(val: string) => setBehavior(val as
|
|
298
|
+
<Select value={behavior} onValueChange={(val: string) => setBehavior(val as "PERMISSIVE" | "RESTRICTIVE")} position="item-aligned">
|
|
284
299
|
<SelectItem value="PERMISSIVE">Permissive</SelectItem>
|
|
285
300
|
<SelectItem value="RESTRICTIVE">Restrictive</SelectItem>
|
|
286
301
|
</Select>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import React, { useState } from "react";
|
|
3
|
-
import { Button, IconButton, Typography, Table, TableHeader, TableCell, TableBody, TableRow, TextField, Select, SelectItem, Container, Dialog, DialogTitle, DialogContent, DialogActions } from "@rebasepro/ui";
|
|
3
|
+
import { Button, IconButton, Typography, Table, TableHeader, TableCell, TableBody, TableRow, TextField, Select, SelectItem, Container, Dialog, DialogTitle, DialogContent, DialogActions, cls, defaultBorderMixin } from "@rebasepro/ui";
|
|
4
4
|
import { Trash2Icon } from "lucide-react";
|
|
5
5
|
import { useFormex } from "@rebasepro/formex";
|
|
6
6
|
import { PostgresCollection, Relation } from "@rebasepro/types";
|
|
@@ -128,7 +128,7 @@ direction: "owning" });
|
|
|
128
128
|
<DialogTitle className="flex justify-between items-center w-full" variant="h6">
|
|
129
129
|
{editingRelationIndex === -1 ? "New Relation" : "Edit Relation"}
|
|
130
130
|
</DialogTitle>
|
|
131
|
-
<DialogContent includeMargin={false} className="p-4 md:p-6 border-t
|
|
131
|
+
<DialogContent includeMargin={false} className={cls("p-4 md:p-6 border-t bg-white dark:bg-surface-900", defaultBorderMixin)}>
|
|
132
132
|
<div className="flex flex-col gap-4 max-w-2xl mx-auto">
|
|
133
133
|
<TextField
|
|
134
134
|
label="Relation Name"
|
|
@@ -178,7 +178,7 @@ direction: val as Relation["direction"] } : null)}
|
|
|
178
178
|
</Select>
|
|
179
179
|
|
|
180
180
|
{editingRelationState.cardinality === "many" && editingRelationState.direction === "owning" && (
|
|
181
|
-
<div className="flex flex-col gap-4 mt-4 pt-4 border-t
|
|
181
|
+
<div className={cls("flex flex-col gap-4 mt-4 pt-4 border-t", defaultBorderMixin)}>
|
|
182
182
|
<Typography variant="subtitle2" className="text-text-primary">Intermediate Table</Typography>
|
|
183
183
|
<Typography variant="body2" className="text-text-secondary -mt-3">
|
|
184
184
|
Required for many-to-many relationships. This defines the junction table linking both collections.
|
|
@@ -42,7 +42,7 @@ export function CollectionStudioView({ collectionId, ...props }: CollectionStudi
|
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
return (
|
|
45
|
-
<div className="flex-grow flex flex-col h-full w-full bg-white dark:bg-surface-
|
|
45
|
+
<div className="flex-grow flex flex-col h-full w-full bg-white dark:bg-surface-950">
|
|
46
46
|
<AIModifiedPathsProvider>
|
|
47
47
|
{activeCollectionId ? (
|
|
48
48
|
<CollectionEditor
|
|
@@ -73,6 +73,7 @@ export function CollectionStudioView({ collectionId, ...props }: CollectionStudi
|
|
|
73
73
|
Select a collection or create a new one
|
|
74
74
|
</Typography>
|
|
75
75
|
<Button
|
|
76
|
+
disabled={props.configController?.readOnly}
|
|
76
77
|
onClick={() => navigate(urlController.buildAppUrlPath("schema/new"))}
|
|
77
78
|
>
|
|
78
79
|
<PlusIcon/>
|
|
@@ -4,7 +4,7 @@ import { IconForView } from "@rebasepro/core";
|
|
|
4
4
|
import { useUrlController } from "../../_cms_internals";
|
|
5
5
|
import React, { useState, useEffect } from "react";
|
|
6
6
|
import { useLocation, useNavigate } from "react-router-dom";
|
|
7
|
-
import { cls, defaultBorderMixin, ResizablePanels, Typography, IconButton, Button , iconSize } from "@rebasepro/ui";
|
|
7
|
+
import { cls, defaultBorderMixin, ResizablePanels, Typography, IconButton, Button , iconSize, Tooltip } from "@rebasepro/ui";
|
|
8
8
|
import { PlusIcon } from "lucide-react";
|
|
9
9
|
;
|
|
10
10
|
import { CollectionsConfigController } from "../../types/config_controller";
|
|
@@ -46,25 +46,30 @@ export function CollectionsStudioView({ configController }: CollectionsStudioVie
|
|
|
46
46
|
const collections = configController.collections || [];
|
|
47
47
|
|
|
48
48
|
return (
|
|
49
|
-
<div className="flex h-full w-full bg-white dark:bg-surface-
|
|
49
|
+
<div className="flex h-full w-full bg-white dark:bg-surface-950 overflow-hidden text-text-primary dark:text-text-primary-dark">
|
|
50
50
|
<ResizablePanels
|
|
51
51
|
orientation="horizontal"
|
|
52
52
|
panelSizePercent={sidebarSize}
|
|
53
53
|
onPanelSizeChange={setSidebarSize}
|
|
54
54
|
minPanelSizePx={220}
|
|
55
55
|
firstPanel={
|
|
56
|
-
<div className={cls("flex flex-col h-full w-full bg-white dark:bg-surface-
|
|
57
|
-
<div className={cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-
|
|
56
|
+
<div className={cls("flex flex-col h-full w-full bg-white dark:bg-surface-950 border-r", defaultBorderMixin)}>
|
|
57
|
+
<div className={cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin)}>
|
|
58
58
|
<Typography variant="caption" className="font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark">
|
|
59
59
|
Collections
|
|
60
60
|
</Typography>
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
<Tooltip title={configController.readOnly ? configController.readOnlyReason || "Read only" : "Add collection"}>
|
|
62
|
+
<div>
|
|
63
|
+
<IconButton
|
|
64
|
+
size="small"
|
|
65
|
+
disabled={configController.readOnly}
|
|
66
|
+
onClick={() => navigate(urlController.buildAppUrlPath("schema/new"))}
|
|
67
|
+
className={activeCollectionId === "new" ? "text-primary dark:text-primary-dark" : "text-text-secondary dark:text-text-secondary-dark"}
|
|
68
|
+
>
|
|
69
|
+
<PlusIcon size={iconSize.smallest}/>
|
|
70
|
+
</IconButton>
|
|
71
|
+
</div>
|
|
72
|
+
</Tooltip>
|
|
68
73
|
</div>
|
|
69
74
|
|
|
70
75
|
<div className="flex-grow overflow-y-auto w-full no-scrollbar p-2 space-y-0.5">
|
|
@@ -86,7 +91,7 @@ export function CollectionsStudioView({ configController }: CollectionsStudioVie
|
|
|
86
91
|
"flex items-center gap-3 px-3 py-2 cursor-pointer rounded-md text-sm transition-colors",
|
|
87
92
|
isSelected
|
|
88
93
|
? "bg-primary/10 text-primary dark:bg-primary/20 dark:text-primary-light"
|
|
89
|
-
: "hover:bg-surface-100 dark:hover:bg-surface-
|
|
94
|
+
: "hover:bg-surface-100 dark:hover:bg-surface-900 text-text-secondary dark:text-text-secondary-dark"
|
|
90
95
|
)}
|
|
91
96
|
>
|
|
92
97
|
<IconForView collectionOrView={collection} size={"small"} className={cls(
|
|
@@ -118,6 +123,7 @@ export function CollectionsStudioView({ configController }: CollectionsStudioVie
|
|
|
118
123
|
Select a collection or create a new one to start editing
|
|
119
124
|
</Typography>
|
|
120
125
|
<Button
|
|
126
|
+
disabled={configController.readOnly}
|
|
121
127
|
onClick={() => navigate(urlController.buildAppUrlPath("schema/new"))}
|
|
122
128
|
>
|
|
123
129
|
<PlusIcon/>
|
|
@@ -186,8 +186,7 @@ export function DisplaySettingsForm({
|
|
|
186
186
|
property={{
|
|
187
187
|
type: "string",
|
|
188
188
|
name: dialogPropertyName,
|
|
189
|
-
disabled: true,
|
|
190
|
-
hideFromCollection: true
|
|
189
|
+
ui: { disabled: true, hideFromCollection: true }
|
|
191
190
|
}}
|
|
192
191
|
propertyKey={dialogPropertyKey}
|
|
193
192
|
existingProperty={false}
|
|
@@ -123,8 +123,7 @@ function collectionToCode(collection: EntityCollection): object {
|
|
|
123
123
|
description: collection.description,
|
|
124
124
|
|
|
125
125
|
icon: collection.icon,
|
|
126
|
-
|
|
127
|
-
filter: collection.filter,
|
|
126
|
+
defaultFilter: collection.defaultFilter,
|
|
128
127
|
sort: collection.sort,
|
|
129
128
|
properties: Object.entries({
|
|
130
129
|
...(collection.properties ?? {})
|
|
@@ -39,10 +39,10 @@ export function PropertyFieldPreview({
|
|
|
39
39
|
<div onClick={onClick} className={onClick ? "cursor-pointer" : ""}>
|
|
40
40
|
<Paper
|
|
41
41
|
className={cls(
|
|
42
|
-
"w-full flex flex-row gap-3 items-center px-3 py-2 rounded-lg transition-all duration-200 border
|
|
42
|
+
"w-full flex flex-row gap-3 items-center px-3 py-2 rounded-lg transition-all duration-200 border bg-white dark:bg-surface-800 border-surface-200 dark:border-surface-700 shadow-xs",
|
|
43
43
|
selected
|
|
44
|
-
? "bg-primary/5 dark:bg-primary/10 ring-1 ring-inset ring-primary"
|
|
45
|
-
: "hover:bg-surface-50 dark:hover:bg-surface-
|
|
44
|
+
? "bg-primary/5 dark:bg-primary/10 ring-1 ring-inset ring-primary border-primary/30"
|
|
45
|
+
: "hover:bg-surface-50 dark:hover:bg-surface-750"
|
|
46
46
|
)}
|
|
47
47
|
>
|
|
48
48
|
<PropertyConfigBadge propertyConfig={propertyConfig} size="small"/>
|
|
@@ -105,10 +105,10 @@ export function NonEditablePropertyPreview({
|
|
|
105
105
|
<div onClick={onClick} className={onClick ? "cursor-pointer" : ""}>
|
|
106
106
|
<Paper
|
|
107
107
|
className={cls(
|
|
108
|
-
"w-full flex flex-row gap-3 items-center px-3 py-2 rounded-lg transition-all duration-200 border
|
|
108
|
+
"w-full flex flex-row gap-3 items-center px-3 py-2 rounded-lg transition-all duration-200 border bg-white dark:bg-surface-800 border-surface-200 dark:border-surface-700 shadow-xs",
|
|
109
109
|
selected
|
|
110
|
-
? "bg-primary/5 dark:bg-primary/10 ring-1 ring-inset ring-primary"
|
|
111
|
-
: "hover:bg-surface-50 dark:hover:bg-surface-
|
|
110
|
+
? "bg-primary/5 dark:bg-primary/10 ring-1 ring-inset ring-primary border-primary/30"
|
|
111
|
+
: "hover:bg-surface-50 dark:hover:bg-surface-750"
|
|
112
112
|
)}
|
|
113
113
|
>
|
|
114
114
|
<div className={"relative shrink-0"}>
|
|
@@ -21,14 +21,14 @@ export function SubcollectionsEditTab({
|
|
|
21
21
|
configController,
|
|
22
22
|
collectionInference,
|
|
23
23
|
getUser,
|
|
24
|
-
|
|
24
|
+
parentCollectionSlugs
|
|
25
25
|
}: {
|
|
26
26
|
collection: EntityCollection,
|
|
27
27
|
parentCollection?: EntityCollection,
|
|
28
28
|
configController: CollectionsConfigController;
|
|
29
29
|
collectionInference?: CollectionInference;
|
|
30
30
|
getUser?: (uid: string) => User | null;
|
|
31
|
-
|
|
31
|
+
parentCollectionSlugs?: string[], parentEntityIds?: string[];
|
|
32
32
|
}) {
|
|
33
33
|
|
|
34
34
|
const { entityViews: contextEntityViews } = useCustomizationController();
|
|
@@ -187,7 +187,7 @@ export function SubcollectionsEditTab({
|
|
|
187
187
|
onAccept={() => {
|
|
188
188
|
const props = {
|
|
189
189
|
id: subcollectionToDelete!,
|
|
190
|
-
|
|
190
|
+
parentCollectionSlugs: [...(parentCollectionSlugs ?? []), collection.slug]
|
|
191
191
|
};
|
|
192
192
|
console.debug("Deleting subcollection", props)
|
|
193
193
|
configController.deleteCollection(props).then(() => {
|
|
@@ -217,7 +217,7 @@ export function SubcollectionsEditTab({
|
|
|
217
217
|
configController={configController}
|
|
218
218
|
parentCollection={collection}
|
|
219
219
|
collectionInference={collectionInference}
|
|
220
|
-
|
|
220
|
+
parentCollectionSlugs={[...parentCollectionSlugs ?? [], values.slug]}
|
|
221
221
|
isNewCollection={false}
|
|
222
222
|
{...currentDialog}
|
|
223
223
|
getUser={getUser}
|
|
@@ -111,8 +111,8 @@ export function MapPropertyField({ disabled, getData, allowDataInference, proper
|
|
|
111
111
|
position={"start"}
|
|
112
112
|
size={"medium"}
|
|
113
113
|
label={t("spread_children_as_columns")}
|
|
114
|
-
onValueChange={(v) => setFieldValue("spreadChildren", v)}
|
|
115
|
-
value={values.spreadChildren ?? false}
|
|
114
|
+
onValueChange={(v) => setFieldValue("ui.spreadChildren", v)}
|
|
115
|
+
value={values.ui?.spreadChildren ?? false}
|
|
116
116
|
/>
|
|
117
117
|
<FieldCaption>
|
|
118
118
|
Set this flag to true if you want to display the children of this group as individual columns. This
|
|
@@ -4,7 +4,7 @@ import React from "react";
|
|
|
4
4
|
import { Field, getIn, useFormex } from "@rebasepro/formex";
|
|
5
5
|
;
|
|
6
6
|
import { NumberProperty, StringProperty } from "@rebasepro/types";
|
|
7
|
-
import { CircularProgress, Select,
|
|
7
|
+
import { CircularProgress, Select, SelectItem, Typography } from "@rebasepro/ui";
|
|
8
8
|
|
|
9
9
|
export function ReferencePropertyField({
|
|
10
10
|
existing,
|
|
@@ -81,12 +81,6 @@ export function CollectionsSelect({
|
|
|
81
81
|
|
|
82
82
|
const collections = collectionRegistry.collections ?? [];
|
|
83
83
|
|
|
84
|
-
const groups: string[] = Array.from(new Set(
|
|
85
|
-
Object.values(collections).map(e => e.group).filter(Boolean) as string[]
|
|
86
|
-
).values());
|
|
87
|
-
|
|
88
|
-
const ungroupedCollections = collections.filter((col) => !col.group);
|
|
89
|
-
|
|
90
84
|
return (
|
|
91
85
|
<>
|
|
92
86
|
<Select
|
|
@@ -113,48 +107,20 @@ export function CollectionsSelect({
|
|
|
113
107
|
}}
|
|
114
108
|
{...props}>
|
|
115
109
|
|
|
116
|
-
{
|
|
117
|
-
<
|
|
118
|
-
key={
|
|
119
|
-
{
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
{collection?.name.toUpperCase()}
|
|
131
|
-
</Typography>
|
|
132
|
-
</div>
|
|
133
|
-
</SelectItem>;
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
</SelectGroup>
|
|
138
|
-
))}
|
|
139
|
-
|
|
140
|
-
{ungroupedCollections && <SelectGroup label={"Views"}>
|
|
141
|
-
{ungroupedCollections
|
|
142
|
-
.map((collection) => {
|
|
143
|
-
return <SelectItem key={collection.slug}
|
|
144
|
-
value={collection.slug}>
|
|
145
|
-
<div className="flex flex-row">
|
|
146
|
-
<IconForView collectionOrView={collection}/>
|
|
147
|
-
<Typography
|
|
148
|
-
variant={"subtitle2"}
|
|
149
|
-
className="ml-4">
|
|
150
|
-
{collection?.name.toUpperCase()}
|
|
151
|
-
</Typography>
|
|
152
|
-
</div>
|
|
153
|
-
</SelectItem>;
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
</SelectGroup>}
|
|
110
|
+
{collections.map((collection) => {
|
|
111
|
+
return <SelectItem
|
|
112
|
+
key={collection.slug}
|
|
113
|
+
value={collection.slug}>
|
|
114
|
+
<div className="flex flex-row">
|
|
115
|
+
<IconForView collectionOrView={collection}/>
|
|
116
|
+
<Typography
|
|
117
|
+
variant={"subtitle2"}
|
|
118
|
+
className="ml-4">
|
|
119
|
+
{collection?.name.toUpperCase()}
|
|
120
|
+
</Typography>
|
|
121
|
+
</div>
|
|
122
|
+
</SelectItem>;
|
|
123
|
+
})}
|
|
158
124
|
|
|
159
125
|
</Select>
|
|
160
126
|
|