@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
|
@@ -45,7 +45,7 @@ export function RelationFieldBinding({
|
|
|
45
45
|
const manyRelation = relation?.cardinality === "many";
|
|
46
46
|
|
|
47
47
|
// Inline selector mode
|
|
48
|
-
const widget = property.widget ?? "select";
|
|
48
|
+
const widget = property.ui?.widget ?? "select";
|
|
49
49
|
|
|
50
50
|
if (widget === "select" && relation) {
|
|
51
51
|
const normalizedSingle = (!manyRelation && value && !Array.isArray(value)) ? normalizeToEntityRelation(value) : null;
|
|
@@ -74,7 +74,7 @@ export function RelationFieldBinding({
|
|
|
74
74
|
}
|
|
75
75
|
}}
|
|
76
76
|
disabled={disabled || isSubmitting}
|
|
77
|
-
|
|
77
|
+
fixedFilter={property.fixedFilter}
|
|
78
78
|
size={selectorSize}
|
|
79
79
|
/>
|
|
80
80
|
|
|
@@ -123,7 +123,7 @@ export function RelationFieldBinding({
|
|
|
123
123
|
collection,
|
|
124
124
|
onSingleEntitySelected,
|
|
125
125
|
selectedEntityIds: validValue && normalizedValue ? [normalizedValue.id] : undefined,
|
|
126
|
-
|
|
126
|
+
fixedFilter: property.fixedFilter
|
|
127
127
|
}
|
|
128
128
|
);
|
|
129
129
|
|
|
@@ -149,7 +149,7 @@ export function RelationFieldBinding({
|
|
|
149
149
|
|
|
150
150
|
{usedRelation && <RelationPreview
|
|
151
151
|
disabled={!usedRelation}
|
|
152
|
-
previewProperties={property.previewProperties}
|
|
152
|
+
previewProperties={property.ui?.previewProperties}
|
|
153
153
|
hover={!disabled}
|
|
154
154
|
size={size}
|
|
155
155
|
onClick={disabled || isSubmitting ? undefined : onEntryClick}
|
|
@@ -43,7 +43,7 @@ export function RepeatFieldBinding({
|
|
|
43
43
|
throw Error("RepeatFieldBinding misconfiguration. Property `type` is not `array`");
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
const minimalistView = minimalistViewProp || property.minimalistView;
|
|
46
|
+
const minimalistView = minimalistViewProp || property.ui?.minimalistView;
|
|
47
47
|
|
|
48
48
|
if (!property.of)
|
|
49
49
|
throw Error("RepeatFieldBinding misconfiguration. Property `of` not set");
|
|
@@ -56,7 +56,7 @@ export function RepeatFieldBinding({
|
|
|
56
56
|
authController
|
|
57
57
|
})
|
|
58
58
|
|
|
59
|
-
const expanded = property.expanded === undefined ? true : property.expanded;
|
|
59
|
+
const expanded = property.ui?.expanded === undefined ? true : property.ui?.expanded;
|
|
60
60
|
const ofProperty = property.of;
|
|
61
61
|
|
|
62
62
|
const [lastAddedId, setLastAddedId] = useState<number | undefined>();
|
|
@@ -91,19 +91,19 @@ export function RepeatFieldBinding({
|
|
|
91
91
|
</ErrorBoundary>;
|
|
92
92
|
};
|
|
93
93
|
|
|
94
|
-
const canAddElements = !property.disabled && !isSubmitting && !disabled && (property.canAddElements || property.canAddElements === undefined);
|
|
94
|
+
const canAddElements = !property.ui?.disabled && !isSubmitting && !disabled && (property.canAddElements || property.canAddElements === undefined);
|
|
95
95
|
const sortable = property.sortable === undefined ? true : property.sortable;
|
|
96
96
|
const arrayContainer = <ArrayContainer droppableId={propertyKey}
|
|
97
97
|
addLabel={property.name ? t("add_to_field", { fieldName: property.name }) : t("add_entry")}
|
|
98
98
|
value={value ?? []}
|
|
99
99
|
buildEntry={buildEntry}
|
|
100
100
|
onInternalIdAdded={setLastAddedId}
|
|
101
|
-
disabled={isSubmitting || Boolean(property.disabled)}
|
|
101
|
+
disabled={isSubmitting || Boolean(property.ui?.disabled)}
|
|
102
102
|
canAddElements={canAddElements}
|
|
103
103
|
sortable={sortable}
|
|
104
104
|
newDefaultEntry={getDefaultValueFor(property.of)}
|
|
105
105
|
onValueChange={(value) => setFieldValue(propertyKey, value)}
|
|
106
|
-
className={property.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
106
|
+
className={property.ui?.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
107
107
|
/>;
|
|
108
108
|
|
|
109
109
|
const title = (<>
|
|
@@ -63,7 +63,7 @@ export function StorageUploadFieldBinding({
|
|
|
63
63
|
const authController = useAuthController();
|
|
64
64
|
|
|
65
65
|
const storageSource = useStorageSource(context.collection);
|
|
66
|
-
const disabled = isReadOnly(property) || !!property.disabled || isSubmitting || context.disabled;
|
|
66
|
+
const disabled = isReadOnly(property) || !!property.ui?.disabled || isSubmitting || context.disabled;
|
|
67
67
|
|
|
68
68
|
const {
|
|
69
69
|
internalValue,
|
|
@@ -43,7 +43,7 @@ export const SwitchFieldBinding = function SwitchFieldBinding({
|
|
|
43
43
|
value={value}
|
|
44
44
|
onValueChange={(v) => setValue(v)}
|
|
45
45
|
error={showError}
|
|
46
|
-
className={property.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
46
|
+
className={property.ui?.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
47
47
|
label={<LabelWithIcon
|
|
48
48
|
icon={getIconForProperty(property, "small")}
|
|
49
49
|
required={property.validation?.required}
|
|
@@ -33,8 +33,8 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
33
33
|
let multiline: boolean | undefined;
|
|
34
34
|
let url: boolean | PreviewType | undefined;
|
|
35
35
|
if (property.type === "string") {
|
|
36
|
-
multiline = property.multiline;
|
|
37
|
-
url = property.url;
|
|
36
|
+
multiline = property.ui?.multiline;
|
|
37
|
+
url = property.ui?.url;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
useClearRestoreValue({
|
|
@@ -71,7 +71,7 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
71
71
|
inputType = "number";
|
|
72
72
|
} else if (property.type === "string") {
|
|
73
73
|
if (property.email) inputType = "email";
|
|
74
|
-
else if (property.url) inputType = "url";
|
|
74
|
+
else if (property.ui?.url) inputType = "url";
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
const label = (
|
|
@@ -88,7 +88,7 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
88
88
|
fieldBackgroundMixin,
|
|
89
89
|
fieldBackgroundHoverMixin,
|
|
90
90
|
showError && error ? "border border-red-500 dark:border-red-600" : "",
|
|
91
|
-
property.widthPercentage !== undefined ? "mt-8" : undefined
|
|
91
|
+
property.ui?.widthPercentage !== undefined ? "mt-8" : undefined
|
|
92
92
|
)}>
|
|
93
93
|
<div className="pointer-events-none absolute top-1 text-xs font-medium px-3 text-text-secondary dark:text-text-secondary-dark">
|
|
94
94
|
{label}
|
|
@@ -104,7 +104,7 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
104
104
|
showError && error ? "text-red-500 dark:text-red-600" : ""
|
|
105
105
|
)}
|
|
106
106
|
/>
|
|
107
|
-
{property.clearable && (
|
|
107
|
+
{property.ui?.clearable && (
|
|
108
108
|
<div className="flex flex-row justify-center items-center absolute h-full right-0 top-0 mr-4">
|
|
109
109
|
<IconButton onClick={handleClearClick}>
|
|
110
110
|
<XIcon/>
|
|
@@ -118,7 +118,7 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
118
118
|
value={value ?? ""}
|
|
119
119
|
onChange={onChange}
|
|
120
120
|
autoFocus={autoFocus}
|
|
121
|
-
className={property.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
121
|
+
className={property.ui?.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
122
122
|
label={<LabelWithIcon
|
|
123
123
|
icon={getIconForProperty(property, "small")}
|
|
124
124
|
required={property.validation?.required || property.isId === true}
|
|
@@ -126,7 +126,7 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
126
126
|
type={inputType}
|
|
127
127
|
disabled={disabled}
|
|
128
128
|
endAdornment={
|
|
129
|
-
property.clearable && <IconButton
|
|
129
|
+
property.ui?.clearable && <IconButton
|
|
130
130
|
onClick={handleClearClick}>
|
|
131
131
|
<XIcon/>
|
|
132
132
|
</IconButton>
|
|
@@ -22,7 +22,7 @@ export function useClearRestoreValue<T>({
|
|
|
22
22
|
|
|
23
23
|
const clearedValueRef = useRef<T | null>(null);
|
|
24
24
|
useEffect(() => {
|
|
25
|
-
const shouldClearValueIfDisabled = typeof property.disabled === "object" && Boolean(property.disabled.clearOnDisabled);
|
|
25
|
+
const shouldClearValueIfDisabled = typeof property.ui?.disabled === "object" && Boolean(property.ui?.disabled.clearOnDisabled);
|
|
26
26
|
if (shouldClearValueIfDisabled) {
|
|
27
27
|
if (value != null) {
|
|
28
28
|
clearedValueRef.current = value;
|
package/src/form/validation.ts
CHANGED
|
@@ -187,7 +187,7 @@ function getZodStringSchema({
|
|
|
187
187
|
(value: any) => value == null || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value),
|
|
188
188
|
{ message: `${property.name} must be an email` }
|
|
189
189
|
);
|
|
190
|
-
if (property.url) {
|
|
190
|
+
if (property.ui?.url) {
|
|
191
191
|
if (!property.storage || property.storage?.storeUrl) {
|
|
192
192
|
schema = schema.refine(
|
|
193
193
|
(value: any) => {
|
|
@@ -6,7 +6,8 @@ export const CollectionRegistryContext = createContext<CollectionRegistryControl
|
|
|
6
6
|
getCollection: () => undefined,
|
|
7
7
|
getRawCollection: () => undefined,
|
|
8
8
|
getParentReferencesFromPath: () => [],
|
|
9
|
-
|
|
9
|
+
getParentCollectionSlugs: () => [],
|
|
10
|
+
getParentEntityIds: () => [],
|
|
10
11
|
convertIdsToPaths: () => [],
|
|
11
12
|
initialised: false
|
|
12
13
|
});
|
|
@@ -94,7 +94,7 @@ export function useBuildCollectionRegistryController(props: {
|
|
|
94
94
|
});
|
|
95
95
|
}, []);
|
|
96
96
|
|
|
97
|
-
const
|
|
97
|
+
const getParentCollectionSlugs = useCallback((path: string): string[] => {
|
|
98
98
|
const registry = collectionRegistryRef.current;
|
|
99
99
|
if (!registry) {
|
|
100
100
|
return [];
|
|
@@ -126,6 +126,16 @@ export function useBuildCollectionRegistryController(props: {
|
|
|
126
126
|
return result.map(r => getCollectionFromPaths(r)?.slug).filter(Boolean) as string[];
|
|
127
127
|
}, []);
|
|
128
128
|
|
|
129
|
+
const getParentEntityIds = useCallback((path: string): string[] => {
|
|
130
|
+
const cleanedPath = removeInitialAndTrailingSlashes(path);
|
|
131
|
+
const strings = cleanedPath.split("/");
|
|
132
|
+
const evenPathSegments = strings.filter((_, i) => i % 2 !== 0);
|
|
133
|
+
if (strings.length % 2 === 0) {
|
|
134
|
+
evenPathSegments.pop();
|
|
135
|
+
}
|
|
136
|
+
return evenPathSegments;
|
|
137
|
+
}, []);
|
|
138
|
+
|
|
129
139
|
const convertIdsToPaths = useCallback((ids: string[]): string[] => {
|
|
130
140
|
const registry = collectionRegistryRef.current;
|
|
131
141
|
if (!registry) return [];
|
|
@@ -156,7 +166,8 @@ export function useBuildCollectionRegistryController(props: {
|
|
|
156
166
|
getCollection,
|
|
157
167
|
getRawCollection,
|
|
158
168
|
getParentReferencesFromPath,
|
|
159
|
-
|
|
169
|
+
getParentCollectionSlugs,
|
|
170
|
+
getParentEntityIds,
|
|
160
171
|
convertIdsToPaths,
|
|
161
172
|
collectionRegistryRef
|
|
162
173
|
}), [
|
|
@@ -165,7 +176,8 @@ export function useBuildCollectionRegistryController(props: {
|
|
|
165
176
|
getCollection,
|
|
166
177
|
getRawCollection,
|
|
167
178
|
getParentReferencesFromPath,
|
|
168
|
-
|
|
179
|
+
getParentCollectionSlugs,
|
|
180
|
+
getParentEntityIds,
|
|
169
181
|
convertIdsToPaths
|
|
170
182
|
]);
|
|
171
183
|
}
|
|
@@ -104,7 +104,7 @@ export function useNavigationRegistry(userConfigPersistence?: UserConfigurationP
|
|
|
104
104
|
});
|
|
105
105
|
}, []);
|
|
106
106
|
|
|
107
|
-
const
|
|
107
|
+
const getParentCollectionSlugs = useCallback((path: string): string[] => {
|
|
108
108
|
const strings = path.split("/");
|
|
109
109
|
const oddPathSegments = strings.filter((_, i) => i % 2 === 0);
|
|
110
110
|
oddPathSegments.pop();
|
|
@@ -118,6 +118,15 @@ export function useNavigationRegistry(userConfigPersistence?: UserConfigurationP
|
|
|
118
118
|
return result.map(r => getCollectionFromPaths(r)?.slug).filter(Boolean) as string[];
|
|
119
119
|
}, [getAllParentReferencesForPath, getCollectionFromPaths]);
|
|
120
120
|
|
|
121
|
+
const getParentEntityIds = useCallback((path: string): string[] => {
|
|
122
|
+
const strings = path.split("/");
|
|
123
|
+
const evenPathSegments = strings.filter((_, i) => i % 2 !== 0);
|
|
124
|
+
if (strings.length % 2 === 0) {
|
|
125
|
+
evenPathSegments.pop();
|
|
126
|
+
}
|
|
127
|
+
return evenPathSegments;
|
|
128
|
+
}, []);
|
|
129
|
+
|
|
121
130
|
const convertIdsToPaths = useCallback((ids: string[]): string[] => {
|
|
122
131
|
const registry = collectionRegistryRef.current;
|
|
123
132
|
if (!registry) {
|
|
@@ -141,13 +150,15 @@ export function useNavigationRegistry(userConfigPersistence?: UserConfigurationP
|
|
|
141
150
|
getCollection,
|
|
142
151
|
getRawCollection,
|
|
143
152
|
getParentReferencesFromPath: getAllParentReferencesForPath,
|
|
144
|
-
|
|
153
|
+
getParentCollectionSlugs,
|
|
154
|
+
getParentEntityIds,
|
|
145
155
|
convertIdsToPaths
|
|
146
156
|
}), [
|
|
147
157
|
getCollection,
|
|
148
158
|
getRawCollection,
|
|
149
159
|
getAllParentReferencesForPath,
|
|
150
|
-
|
|
160
|
+
getParentCollectionSlugs,
|
|
161
|
+
getParentEntityIds,
|
|
151
162
|
convertIdsToPaths
|
|
152
163
|
]);
|
|
153
164
|
}
|
|
@@ -21,7 +21,7 @@ import { AuthController, RebaseData, User } from "@rebasepro/types";
|
|
|
21
21
|
import { UserManagementDelegate } from "@rebasepro/types";
|
|
22
22
|
|
|
23
23
|
import { resolveAppViews } from "./useNavigationResolution";
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
|
|
26
26
|
// Lazy-load admin views — only rendered when navigation reaches /users or /roles
|
|
27
27
|
const UsersView = lazy(() => import("../../components/admin/UsersView").then(m => ({ default: m.UsersView })));
|
|
@@ -128,7 +128,6 @@ export function useResolvedViews<USER extends User>(
|
|
|
128
128
|
views.push({
|
|
129
129
|
slug: "users",
|
|
130
130
|
name: "Users",
|
|
131
|
-
group: NAVIGATION_ADMIN_GROUP_NAME,
|
|
132
131
|
icon: "Headset",
|
|
133
132
|
view: usersViewElement
|
|
134
133
|
});
|
|
@@ -136,7 +135,6 @@ export function useResolvedViews<USER extends User>(
|
|
|
136
135
|
views.push({
|
|
137
136
|
slug: "roles",
|
|
138
137
|
name: "Roles",
|
|
139
|
-
group: NAVIGATION_ADMIN_GROUP_NAME,
|
|
140
138
|
icon: "Shield",
|
|
141
139
|
view: rolesViewElement
|
|
142
140
|
});
|
|
@@ -152,7 +152,7 @@ export function useTopLevelNavigation(
|
|
|
152
152
|
if (adminView.hideFromNavigation) return acc;
|
|
153
153
|
|
|
154
154
|
const pathKey = adminView.slug;
|
|
155
|
-
let groupName =
|
|
155
|
+
let groupName = NAVIGATION_ADMIN_GROUP_NAME;
|
|
156
156
|
|
|
157
157
|
if (finalNavigationGroupMappings) {
|
|
158
158
|
for (const pluginGroupDef of finalNavigationGroupMappings) {
|
|
@@ -11,7 +11,7 @@ export function getGroup(collectionOrView: EntityCollection<any, any> | AppView)
|
|
|
11
11
|
if (!trimmed || trimmed === "") {
|
|
12
12
|
return NAVIGATION_DEFAULT_GROUP_NAME;
|
|
13
13
|
}
|
|
14
|
-
return trimmed
|
|
14
|
+
return trimmed;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function computeNavigationGroups({
|
|
@@ -20,7 +20,7 @@ export interface UseEntityHistoryResult {
|
|
|
20
20
|
hasMore: boolean;
|
|
21
21
|
error?: Error;
|
|
22
22
|
loadMore: () => void;
|
|
23
|
-
revert: (historyId: string) => Promise<
|
|
23
|
+
revert: (historyId: string) => Promise<Record<string, unknown>>;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -129,7 +129,7 @@ signal });
|
|
|
129
129
|
}
|
|
130
130
|
}, [isLoading, hasMore, pageSize, offset, entries.length, total]);
|
|
131
131
|
|
|
132
|
-
const revert = useCallback(async (historyId: string) => {
|
|
132
|
+
const revert = useCallback(async (historyId: string): Promise<Record<string, unknown>> => {
|
|
133
133
|
if (!apiConfig?.apiUrl || !entityId) {
|
|
134
134
|
throw new Error("Cannot revert: missing API configuration or entity ID");
|
|
135
135
|
}
|
|
@@ -149,10 +149,15 @@ headers });
|
|
|
149
149
|
throw new Error(errorData.error?.message || `Failed to revert (${response.status})`);
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
const result = await response.json();
|
|
153
|
+
|
|
152
154
|
// Refresh the history list after revert by resetting the entity ref
|
|
153
155
|
// and triggering the effect.
|
|
154
156
|
currentEntityRef.current = undefined;
|
|
155
157
|
setRefreshTrigger(prev => prev + 1);
|
|
158
|
+
|
|
159
|
+
// Return the reverted entity data so callers can update the form
|
|
160
|
+
return result.data as Record<string, unknown>;
|
|
156
161
|
}, [apiConfig, slug, entityId]);
|
|
157
162
|
|
|
158
163
|
return useMemo(() => ({
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ArrayProperty, MapProperty, NumberProperty, Property, StringProperty } from "@rebasepro/types";
|
|
2
|
-
import React, { createElement } from "react";
|
|
2
|
+
import React, { createElement, Suspense } from "react";
|
|
3
3
|
import { deepEqual as equal } from "fast-equals"
|
|
4
4
|
|
|
5
5
|
import { EntityReference, EntityRelation } from "@rebasepro/types";
|
|
6
6
|
import type { PropertyPreviewProps } from "../types/components/PropertyPreviewProps";
|
|
7
7
|
import { resolveProperty, normalizeToEntityRelation } from "@rebasepro/common";
|
|
8
|
-
import { useAuthController, useCustomizationController } from "@rebasepro/core";
|
|
8
|
+
import { useAuthController, useCustomizationController, resolveComponentRef } from "@rebasepro/core";
|
|
9
9
|
import { EmptyValue } from "./components/EmptyValue";
|
|
10
10
|
import { UrlComponentPreview } from "./components/UrlComponentPreview";
|
|
11
11
|
import { StorageThumbnail } from "./components/StorageThumbnail";
|
|
@@ -56,18 +56,22 @@ export const PropertyPreview = React.memo(function PropertyPreview<P extends Pro
|
|
|
56
56
|
|
|
57
57
|
if (property === null) {
|
|
58
58
|
content = <EmptyValue/>;
|
|
59
|
-
} else if (property.Preview) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
59
|
+
} else if (property.ui?.Preview) {
|
|
60
|
+
const ResolvedPreview = resolveComponentRef(property.ui.Preview);
|
|
61
|
+
if (ResolvedPreview) {
|
|
62
|
+
content = <Suspense fallback={null}>
|
|
63
|
+
{createElement(ResolvedPreview,
|
|
64
|
+
{
|
|
65
|
+
propertyKey,
|
|
66
|
+
value,
|
|
67
|
+
property,
|
|
68
|
+
size,
|
|
69
|
+
height,
|
|
70
|
+
width,
|
|
71
|
+
customProps: property.ui?.customProps
|
|
72
|
+
})}
|
|
73
|
+
</Suspense>;
|
|
74
|
+
}
|
|
71
75
|
} else if (value === undefined || value === null) {
|
|
72
76
|
content = <EmptyValue/>;
|
|
73
77
|
} else if (property.type === "string") {
|
|
@@ -81,20 +85,20 @@ export const PropertyPreview = React.memo(function PropertyPreview<P extends Pro
|
|
|
81
85
|
size={props.size}
|
|
82
86
|
fill={fill}
|
|
83
87
|
storagePathOrDownloadUrl={filePath}/>;
|
|
84
|
-
} else if (stringProperty.url) {
|
|
85
|
-
if (typeof stringProperty.url === "boolean")
|
|
88
|
+
} else if (stringProperty.ui?.url) {
|
|
89
|
+
if (typeof stringProperty.ui?.url === "boolean")
|
|
86
90
|
content =
|
|
87
91
|
<UrlComponentPreview size={props.size}
|
|
88
92
|
url={value}
|
|
89
93
|
fill={fill}/>;
|
|
90
|
-
else if (typeof stringProperty.url === "string")
|
|
94
|
+
else if (typeof stringProperty.ui?.url === "string")
|
|
91
95
|
content =
|
|
92
96
|
<UrlComponentPreview size={props.size}
|
|
93
97
|
url={value}
|
|
94
98
|
interactive={interactive}
|
|
95
99
|
fill={fill}
|
|
96
|
-
previewType={stringProperty.url}/>;
|
|
97
|
-
} else if (stringProperty.markdown) {
|
|
100
|
+
previewType={stringProperty.ui?.url}/>;
|
|
101
|
+
} else if (stringProperty.ui?.markdown) {
|
|
98
102
|
content = <Markdown source={value} size={"small"}/>;
|
|
99
103
|
} else if (stringProperty.userSelect) {
|
|
100
104
|
content = <UserPreview
|
|
@@ -107,7 +111,7 @@ export const PropertyPreview = React.memo(function PropertyPreview<P extends Pro
|
|
|
107
111
|
if (typeof stringProperty.reference.path === "string") {
|
|
108
112
|
content = <ReferencePreview
|
|
109
113
|
disabled={!stringProperty.reference.path}
|
|
110
|
-
previewProperties={stringProperty.reference
|
|
114
|
+
previewProperties={(stringProperty as any).reference?.previewProperties}
|
|
111
115
|
includeId={stringProperty.reference.includeId}
|
|
112
116
|
includeEntityLink={stringProperty.reference.includeEntityLink}
|
|
113
117
|
size={props.size}
|
|
@@ -204,7 +208,7 @@ path: stringProperty.reference.path })}
|
|
|
204
208
|
if (typeof value === "object" && "isEntityReference" in value && value.isEntityReference()) {
|
|
205
209
|
content = <ReferencePreview
|
|
206
210
|
disabled={!property.path}
|
|
207
|
-
previewProperties={property.previewProperties}
|
|
211
|
+
previewProperties={property.ui?.previewProperties}
|
|
208
212
|
includeId={property.includeId}
|
|
209
213
|
includeEntityLink={property.includeEntityLink}
|
|
210
214
|
size={props.size}
|
|
@@ -232,7 +236,7 @@ path: stringProperty.reference.path })}
|
|
|
232
236
|
key={`preview_rel_${propertyKey}_${index}`}>
|
|
233
237
|
<RelationPreview
|
|
234
238
|
disabled={!property.relation}
|
|
235
|
-
previewProperties={property.previewProperties}
|
|
239
|
+
previewProperties={property.ui?.previewProperties}
|
|
236
240
|
includeId={property.includeId}
|
|
237
241
|
includeEntityLink={property.includeEntityLink}
|
|
238
242
|
size={"small"}
|
|
@@ -249,7 +253,7 @@ path: stringProperty.reference.path })}
|
|
|
249
253
|
if (relationValue) {
|
|
250
254
|
content = <RelationPreview
|
|
251
255
|
disabled={!property.relation}
|
|
252
|
-
previewProperties={property.previewProperties}
|
|
256
|
+
previewProperties={property.ui?.previewProperties}
|
|
253
257
|
includeId={property.includeId}
|
|
254
258
|
includeEntityLink={property.includeEntityLink}
|
|
255
259
|
size={props.size}
|
|
@@ -5,6 +5,7 @@ import { UrlComponentPreview } from "./UrlComponentPreview";
|
|
|
5
5
|
import { ErrorView, useStorageSource } from "@rebasepro/core";
|
|
6
6
|
import { DownloadConfig, FileType } from "@rebasepro/types";
|
|
7
7
|
import type { PreviewSize } from "../../types/components/PropertyPreviewProps";
|
|
8
|
+
import { Skeleton } from "@rebasepro/ui";
|
|
8
9
|
type StorageThumbnailProps = {
|
|
9
10
|
storagePathOrDownloadUrl: string;
|
|
10
11
|
storeUrl: boolean;
|
|
@@ -76,7 +77,9 @@ export function StorageThumbnailInternal({
|
|
|
76
77
|
size={size}
|
|
77
78
|
fill={fill}
|
|
78
79
|
hint={storagePathOrDownloadUrl}/>
|
|
79
|
-
:
|
|
80
|
+
: fill
|
|
81
|
+
? <Skeleton className="w-full h-full"/>
|
|
82
|
+
: renderSkeletonImageThumbnail(size);
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
function getFiletype(input: string): FileType {
|
|
@@ -28,7 +28,7 @@ export function ArrayOfMapsPreview({
|
|
|
28
28
|
throw Error(`You need to specify a 'properties' prop (or specify a custom field) in your map property ${propertyKey}`);
|
|
29
29
|
}
|
|
30
30
|
const values = value;
|
|
31
|
-
const previewProperties: string[] | undefined = mapProperty.previewProperties;
|
|
31
|
+
const previewProperties: string[] | undefined = (mapProperty.ui as any)?.previewProperties;
|
|
32
32
|
|
|
33
33
|
if (!values) return null;
|
|
34
34
|
|
|
@@ -30,7 +30,7 @@ export function ArrayOfReferencesPreview({
|
|
|
30
30
|
key={`preview_array_ref_${propertyKey}_${index}`}>
|
|
31
31
|
<ReferencePreview
|
|
32
32
|
disabled={!ofProperty.path}
|
|
33
|
-
previewProperties={ofProperty.previewProperties}
|
|
33
|
+
previewProperties={ofProperty.ui?.previewProperties}
|
|
34
34
|
size={childSize}
|
|
35
35
|
reference={reference}
|
|
36
36
|
includeId={ofProperty.includeId}
|
|
@@ -36,7 +36,7 @@ export function ArrayOfRelationsPreview({
|
|
|
36
36
|
key={`preview_array_rel_${propertyKey}_${index}`}>
|
|
37
37
|
<RelationPreview
|
|
38
38
|
disabled={!ofProperty.relation}
|
|
39
|
-
previewProperties={ofProperty.previewProperties}
|
|
39
|
+
previewProperties={ofProperty.ui?.previewProperties}
|
|
40
40
|
size={"small"}
|
|
41
41
|
relation={entityRelation}
|
|
42
42
|
includeId={ofProperty.includeId}
|
|
@@ -26,7 +26,7 @@ export function SkeletonPropertyComponent({
|
|
|
26
26
|
let content: React.ReactNode | any;
|
|
27
27
|
if (property.type === "string") {
|
|
28
28
|
const stringProperty = property as StringProperty;
|
|
29
|
-
if (stringProperty.url) {
|
|
29
|
+
if (stringProperty.ui?.url) {
|
|
30
30
|
content = renderUrlComponent(stringProperty, size);
|
|
31
31
|
} else if (stringProperty.storage) {
|
|
32
32
|
content = renderSkeletonImageThumbnail(size);
|
|
@@ -79,7 +79,7 @@ function renderMap<T extends Record<string, any>>(property: MapProperty, size: P
|
|
|
79
79
|
if (size === "large") {
|
|
80
80
|
mapPropertyKeys = Object.keys(property.properties);
|
|
81
81
|
} else {
|
|
82
|
-
mapPropertyKeys = (property.previewProperties || Object.keys(property.properties)) as string[];
|
|
82
|
+
mapPropertyKeys = ((property.ui as any)?.previewProperties || Object.keys(property.properties)) as string[];
|
|
83
83
|
if (size === "medium")
|
|
84
84
|
mapPropertyKeys = mapPropertyKeys.slice(0, 3);
|
|
85
85
|
else if (size === "small")
|
|
@@ -241,7 +241,7 @@ function renderReference() {
|
|
|
241
241
|
|
|
242
242
|
function renderUrlComponent(property: StringProperty, size: PreviewSize = "large") {
|
|
243
243
|
|
|
244
|
-
if (typeof property.url === "boolean") {
|
|
244
|
+
if (typeof property.ui?.url === "boolean") {
|
|
245
245
|
return <div style={{
|
|
246
246
|
display: "flex"
|
|
247
247
|
}}>
|
|
@@ -24,7 +24,7 @@ export function StringPropertyPreview({
|
|
|
24
24
|
enumKey={enumKey}
|
|
25
25
|
enumValues={property.enum}
|
|
26
26
|
size={size}/>;
|
|
27
|
-
} else if (property.previewAsTag) {
|
|
27
|
+
} else if (property.ui?.previewAsTag) {
|
|
28
28
|
const colorScheme = getColorSchemeForSeed(propertyKey ?? "");
|
|
29
29
|
return (
|
|
30
30
|
<ErrorBoundary>
|
|
@@ -34,11 +34,11 @@ export function StringPropertyPreview({
|
|
|
34
34
|
{value}
|
|
35
35
|
</Chip>
|
|
36
36
|
</ErrorBoundary>);
|
|
37
|
-
} else if (property.url) {
|
|
37
|
+
} else if (property.ui?.url) {
|
|
38
38
|
return (
|
|
39
39
|
<UrlComponentPreview size={size}
|
|
40
40
|
url={value}
|
|
41
|
-
previewType={typeof property.url === "string" ? property.url as PreviewType : undefined}/>
|
|
41
|
+
previewType={typeof property.ui?.url === "string" ? property.ui?.url as PreviewType : undefined}/>
|
|
42
42
|
);
|
|
43
43
|
} else {
|
|
44
44
|
if (!value) return <></>;
|