@rebasepro/admin 0.2.3 → 0.3.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-CmGXXSY9.js → CollectionEditorDialog-D0VqpLPO.js} +70 -77
- package/dist/CollectionEditorDialog-D0VqpLPO.js.map +1 -0
- package/dist/{CollectionsStudioView-DcLHT5bU.js → CollectionsStudioView-Bc3Rxxc2.js} +5 -4
- package/dist/{CollectionsStudioView-DcLHT5bU.js.map → CollectionsStudioView-Bc3Rxxc2.js.map} +1 -1
- package/dist/{ExportCollectionAction-BfN34eWX.js → ExportCollectionAction-Ckc-09BQ.js} +4 -3
- package/dist/ExportCollectionAction-Ckc-09BQ.js.map +1 -0
- package/dist/{ImportCollectionAction-SZrInjhx.js → ImportCollectionAction-BqjIrC3Z.js} +3 -2
- package/dist/{ImportCollectionAction-SZrInjhx.js.map → ImportCollectionAction-BqjIrC3Z.js.map} +1 -1
- package/dist/{PropertyEditView-Cvryrb3B.js → PropertyEditView-CvRSV-A2.js} +128 -121
- package/dist/PropertyEditView-CvRSV-A2.js.map +1 -0
- package/dist/collection_editor/ConfigControllerProvider.d.ts +0 -5
- package/dist/collection_editor/index.d.ts +0 -1
- package/dist/collection_editor/types/collection_editor_controller.d.ts +0 -2
- package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +3 -3
- package/dist/collection_editor_ui.js +3 -3
- package/dist/components/ArrayContainer.d.ts +2 -2
- package/dist/components/DefaultAppBar.d.ts +18 -1
- package/dist/components/DefaultDrawer.d.ts +51 -3
- package/dist/components/EntityCollectionTable/fields/TableStorageUpload.d.ts +2 -2
- package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
- package/dist/components/EntityCollectionTable/table_bindings.d.ts +4 -3
- package/dist/components/EntityCollectionView/hooks/useKanbanDragAndDrop.d.ts +4 -3
- package/dist/components/EntityEditView.d.ts +2 -1
- package/dist/components/HomePage/HomePageDnD.d.ts +3 -3
- package/dist/components/PropertyCollectionView.d.ts +1 -1
- package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
- package/dist/components/SelectableTable/SelectionStore.d.ts +4 -1
- package/dist/components/SelectableTable/filters/BooleanFilterField.d.ts +2 -2
- package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +2 -2
- package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -2
- package/dist/components/SelectableTable/filters/StringNumberFilterField.d.ts +2 -2
- package/dist/components/admin/RolesView.d.ts +3 -3
- package/dist/components/admin/UsersView.d.ts +3 -3
- package/dist/components/app/Drawer.d.ts +8 -1
- package/dist/data_export/export/export.d.ts +3 -3
- package/dist/editor/components/editor-bubble.d.ts +5 -1
- package/dist/editor/components/image-bubble.d.ts +5 -1
- package/dist/editor/components/index.d.ts +3 -3
- package/dist/editor/components/table-bubble.d.ts +5 -1
- package/dist/editor/nodeViews/ReactNodeView.d.ts +4 -1
- package/dist/editor/useProseMirror.d.ts +2 -2
- package/dist/editor/utils/remove_classes.d.ts +1 -1
- package/dist/editor.js +15 -14
- package/dist/editor.js.map +1 -1
- package/dist/form/EntityForm.d.ts +2 -2
- package/dist/form/components/StorageUploadProgress.d.ts +2 -2
- package/dist/form/field_bindings/MultiSelectFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +1 -1
- package/dist/form/validation.d.ts +3 -3
- package/dist/hooks/navigation/useResolvedCollections.d.ts +6 -0
- package/dist/hooks/navigation/useResolvedViews.d.ts +3 -4
- package/dist/{index-PLIQXpTt.js → index-BCcLwgfe.js} +3 -2
- package/dist/{index-PLIQXpTt.js.map → index-BCcLwgfe.js.map} +1 -1
- package/dist/{index-DjduZG1T.js → index-DY2k5TtG.js} +3 -3
- package/dist/index-DY2k5TtG.js.map +1 -0
- package/dist/{index-MKPc70-v.js → index-UQOMHwt1.js} +3 -3
- package/dist/index-UQOMHwt1.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2813 -372
- package/dist/index.js.map +1 -1
- package/dist/{markdown-z2Ir7Cgo.js → markdown-DD2JDU1X.js} +2 -2
- package/dist/markdown-DD2JDU1X.js.map +1 -0
- package/dist/preview/components/UrlComponentPreview.d.ts +1 -0
- package/dist/types/components/EntityFormActionsProps.d.ts +1 -1
- package/dist/types/components/EntityFormProps.d.ts +2 -2
- package/dist/types/fields.d.ts +1 -1
- package/dist/{util-DbWax_sV.js → util-ZM9gQuCv.js} +2031 -2078
- package/dist/util-ZM9gQuCv.js.map +1 -0
- package/package.json +8 -8
- package/src/collection_editor/ConfigControllerProvider.tsx +3 -13
- package/src/collection_editor/index.ts +1 -3
- package/src/collection_editor/types/collection_editor_controller.tsx +0 -3
- package/src/collection_editor/ui/EditorCollectionAction.tsx +1 -6
- package/src/collection_editor/ui/EditorCollectionActionStart.tsx +1 -6
- package/src/collection_editor/ui/EditorEntityAction.tsx +1 -6
- package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +7 -14
- package/src/collection_editor/ui/NewCollectionCard.tsx +1 -5
- package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +3 -8
- package/src/collection_editor/ui/collection_editor/CollectionJsonImportDialog.tsx +8 -12
- package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +21 -21
- package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +4 -4
- package/src/collection_editor/ui/collection_editor/EnumForm.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/BlockPropertyField.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/properties/CommonPropertyFields.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/properties/DateTimePropertyField.tsx +8 -8
- package/src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx +5 -5
- package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/MarkdownPropertyField.tsx +5 -5
- package/src/collection_editor/ui/collection_editor/properties/NumberPropertyField.tsx +5 -5
- package/src/collection_editor/ui/collection_editor/properties/ReferencePropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/RepeatPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +8 -8
- package/src/collection_editor/ui/collection_editor/properties/StringPropertyField.tsx +5 -5
- package/src/collection_editor/ui/collection_editor/properties/UrlPropertyField.tsx +3 -2
- package/src/collection_editor/ui/collection_editor/properties/VectorPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +4 -7
- package/src/collection_editor/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +4 -4
- package/src/components/ArrayContainer.tsx +3 -3
- package/src/components/DefaultAppBar.tsx +52 -31
- package/src/components/DefaultDrawer.tsx +279 -66
- package/src/components/DrawerNavigationItem.tsx +1 -1
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +6 -5
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +9 -7
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -5
- package/src/components/EntityCollectionTable/fields/VirtualTableNumberInput.tsx +12 -9
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +2 -2
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +1 -1
- package/src/components/EntityCollectionTable/table_bindings.tsx +5 -4
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +6 -4
- package/src/components/EntityCollectionView/hooks/useCollectionInlineEditor.ts +1 -1
- package/src/components/EntityCollectionView/hooks/useKanbanDragAndDrop.ts +7 -6
- package/src/components/EntityDetailView.tsx +46 -24
- package/src/components/EntityEditView.tsx +51 -28
- package/src/components/EntityEditViewFormActions.tsx +4 -4
- package/src/components/EntityPreview.tsx +9 -4
- package/src/components/HomePage/HomePageDnD.tsx +3 -2
- package/src/components/PropertyCollectionView.tsx +1 -1
- package/src/components/PropertyIdCopyTooltip.tsx +1 -1
- package/src/components/RebaseLayout.tsx +5 -1
- package/src/components/RebaseNavigation.tsx +2 -2
- package/src/components/RebaseRouteDefs.tsx +4 -7
- package/src/components/RebaseShell.tsx +16 -13
- package/src/components/SearchIconsView.tsx +1 -8
- package/src/components/SelectableTable/SelectableTable.tsx +8 -11
- package/src/components/SelectableTable/SelectionStore.ts +1 -1
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +3 -3
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +3 -3
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +5 -5
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +3 -3
- package/src/components/SideEntityProvider.tsx +2 -1
- package/src/components/admin/RolesView.tsx +7 -2
- package/src/components/admin/UsersView.tsx +12 -6
- package/src/components/app/Drawer.tsx +9 -1
- package/src/components/app/Scaffold.tsx +5 -1
- package/src/data_export/export/export.ts +17 -17
- package/src/data_import/components/DataNewPropertiesMapping.tsx +1 -1
- package/src/editor/components/editor-bubble.tsx +32 -9
- package/src/editor/components/image-bubble.tsx +27 -11
- package/src/editor/components/index.ts +3 -3
- package/src/editor/components/table-bubble.tsx +79 -17
- package/src/editor/extensions/HighlightDecorationExtension.ts +3 -2
- package/src/editor/nodeViews/ReactNodeView.tsx +1 -1
- package/src/editor/nodeViews/TaskItemComponent.tsx +9 -8
- package/src/editor/schema.ts +135 -59
- package/src/editor/selectors/link-selector.tsx +8 -5
- package/src/editor/useProseMirror.ts +2 -2
- package/src/editor/utils/remove_classes.ts +6 -5
- package/src/form/EntityForm.tsx +15 -15
- package/src/form/EntityFormActions.tsx +2 -2
- package/src/form/PropertyFieldBinding.tsx +64 -64
- package/src/form/components/FieldHelperText.tsx +4 -4
- package/src/form/components/StorageUploadProgress.tsx +2 -2
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +1 -1
- package/src/form/field_bindings/BlockFieldBinding.tsx +54 -53
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +290 -289
- package/src/form/field_bindings/MapFieldBinding.tsx +2 -2
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +2 -2
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +8 -6
- package/src/form/field_bindings/RelationFieldBinding.tsx +4 -4
- package/src/form/field_bindings/RepeatFieldBinding.tsx +1 -1
- package/src/form/field_bindings/SelectFieldBinding.tsx +1 -1
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +84 -84
- package/src/form/field_bindings/SwitchFieldBinding.tsx +16 -16
- package/src/form/field_bindings/TextFieldBinding.tsx +77 -73
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +17 -17
- package/src/form/validation.ts +43 -43
- package/src/hooks/navigation/useBuildNavigationStateController.tsx +3 -5
- package/src/hooks/navigation/useResolvedCollections.ts +27 -7
- package/src/hooks/navigation/useResolvedViews.tsx +24 -44
- package/src/index.ts +2 -0
- package/src/preview/PropertyPreview.tsx +2 -2
- package/src/preview/components/ImagePreview.tsx +2 -1
- package/src/preview/components/UrlComponentPreview.tsx +11 -2
- package/src/preview/components/UserPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +2 -2
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -4
- package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +3 -3
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +3 -3
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +3 -2
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +6 -8
- package/src/preview/property_previews/ArrayPropertyEnumPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +3 -3
- package/src/preview/property_previews/MapPropertyPreview.tsx +4 -3
- package/src/preview/property_previews/NumberPropertyPreview.tsx +5 -3
- package/src/preview/property_previews/StringPropertyPreview.tsx +10 -8
- package/src/types/components/EntityFormActionsProps.tsx +1 -1
- package/src/types/components/EntityFormProps.tsx +2 -2
- package/src/types/fields.tsx +2 -2
- package/dist/CollectionEditorDialog-CmGXXSY9.js.map +0 -1
- package/dist/ContentHomePage-C7vFqKSe.js +0 -1784
- package/dist/ContentHomePage-C7vFqKSe.js.map +0 -1
- package/dist/ExportCollectionAction-BfN34eWX.js.map +0 -1
- package/dist/PropertyEditView-Cvryrb3B.js.map +0 -1
- package/dist/RoleChip-QtUFXeTp.js +0 -67
- package/dist/RoleChip-QtUFXeTp.js.map +0 -1
- package/dist/RolesView-BCb7qwWs.js +0 -437
- package/dist/RolesView-BCb7qwWs.js.map +0 -1
- package/dist/UsersView-Cex24r8H.js +0 -408
- package/dist/UsersView-Cex24r8H.js.map +0 -1
- package/dist/collection_editor/types/config_permissions.d.ts +0 -19
- package/dist/index-DjduZG1T.js.map +0 -1
- package/dist/index-MKPc70-v.js.map +0 -1
- package/dist/markdown-z2Ir7Cgo.js.map +0 -1
- package/dist/util-DbWax_sV.js.map +0 -1
- package/src/collection_editor/types/config_permissions.ts +0 -20
package/src/form/EntityForm.tsx
CHANGED
|
@@ -36,15 +36,15 @@ import { getValueInPath, isObject, mergeDeep } from "@rebasepro/utils";
|
|
|
36
36
|
import { useCollectionRegistryController, useSideEntityController, useCMSContext } from "../index";
|
|
37
37
|
|
|
38
38
|
// extract touched values for nested touched trees and map to current values
|
|
39
|
-
export function extractTouchedValues(values:
|
|
40
|
-
let acc: Record<string,
|
|
39
|
+
export function extractTouchedValues(values: unknown, touched: Record<string, boolean>): Record<string, unknown> {
|
|
40
|
+
let acc: Record<string, unknown> = {};
|
|
41
41
|
if (!touched || typeof touched !== "object") {
|
|
42
42
|
return acc;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
Object.entries(touched).forEach(([key, value]) => {
|
|
46
46
|
if (value) {
|
|
47
|
-
acc = setIn(acc, key, getIn(values, key))
|
|
47
|
+
acc = setIn(acc, key, getIn(values, key)) as Record<string, unknown>;
|
|
48
48
|
}
|
|
49
49
|
})
|
|
50
50
|
|
|
@@ -60,20 +60,20 @@ export function extractTouchedValues(values: any, touched: Record<string, boolea
|
|
|
60
60
|
/**
|
|
61
61
|
* CheckIcon if a value is semantically empty (null, undefined, or empty string).
|
|
62
62
|
*/
|
|
63
|
-
function isSemanticEmpty(v:
|
|
63
|
+
function isSemanticEmpty(v: unknown): boolean {
|
|
64
64
|
return v === null || v === undefined || v === "";
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
function removeEmptyContainers(obj:
|
|
67
|
+
function removeEmptyContainers(obj: unknown): unknown {
|
|
68
68
|
if (Array.isArray(obj)) {
|
|
69
69
|
const cleaned = obj.map(removeEmptyContainers);
|
|
70
70
|
// Keep arrays even if they contain only nulls/undefined — that's intentional data
|
|
71
71
|
return cleaned;
|
|
72
72
|
}
|
|
73
73
|
if (obj && typeof obj === "object" && Object.getPrototypeOf(obj) === Object.prototype) {
|
|
74
|
-
const result: Record<string,
|
|
74
|
+
const result: Record<string, unknown> = {};
|
|
75
75
|
for (const key of Object.keys(obj)) {
|
|
76
|
-
const cleaned = removeEmptyContainers(obj[key]);
|
|
76
|
+
const cleaned = removeEmptyContainers((obj as Record<string, unknown>)[key]);
|
|
77
77
|
// Skip empty plain objects
|
|
78
78
|
if (cleaned && typeof cleaned === "object" && !Array.isArray(cleaned)
|
|
79
79
|
&& Object.getPrototypeOf(cleaned) === Object.prototype
|
|
@@ -281,7 +281,7 @@ export function EntityForm<M extends Record<string, unknown>>({
|
|
|
281
281
|
return cleaned;
|
|
282
282
|
}, [localChangesDataRaw, initialValues]);
|
|
283
283
|
|
|
284
|
-
const hasLocalChanges = !localChangesCleared && localChangesData && Object.keys(localChangesData).length > 0;
|
|
284
|
+
const hasLocalChanges = !localChangesCleared && !!localChangesData && Object.keys(localChangesData as object).length > 0;
|
|
285
285
|
|
|
286
286
|
const internalFormex = useCreateFormex<M>({
|
|
287
287
|
initialValues: initialValues as M,
|
|
@@ -729,7 +729,7 @@ export function EntityForm<M extends Record<string, unknown>>({
|
|
|
729
729
|
throw Error("INTERNAL: Collection and path must be defined in form context");
|
|
730
730
|
}
|
|
731
731
|
|
|
732
|
-
const EntityFormActionsRender = EntityFormActionsComponent as React.FC<
|
|
732
|
+
const EntityFormActionsRender = EntityFormActionsComponent as React.FC<EntityFormActionsProps>;
|
|
733
733
|
|
|
734
734
|
const dialogActions = <EntityFormActionsRender
|
|
735
735
|
collection={collection}
|
|
@@ -737,14 +737,14 @@ export function EntityForm<M extends Record<string, unknown>>({
|
|
|
737
737
|
entity={entity}
|
|
738
738
|
layout={forceActionsAtTheBottom ? "bottom" : "responsive"}
|
|
739
739
|
savingError={savingError}
|
|
740
|
-
formex={formex}
|
|
740
|
+
formex={formex as any}
|
|
741
741
|
disabled={actionsDisabled}
|
|
742
742
|
status={status}
|
|
743
743
|
pluginActions={pluginFormActions ?? []}
|
|
744
744
|
openEntityMode={openEntityMode}
|
|
745
745
|
showDefaultActions={showDefaultActions}
|
|
746
746
|
navigateBack={navigateBack}
|
|
747
|
-
formContext={formContext}
|
|
747
|
+
formContext={formContext as any}
|
|
748
748
|
/>;
|
|
749
749
|
|
|
750
750
|
return (
|
|
@@ -844,18 +844,18 @@ export function getInitialEntityValues<M extends Record<string, unknown>>(
|
|
|
844
844
|
}
|
|
845
845
|
}
|
|
846
846
|
|
|
847
|
-
export function zodToFormErrors(zodError: z.ZodError): Record<string,
|
|
848
|
-
let errors: Record<string,
|
|
847
|
+
export function zodToFormErrors(zodError: z.ZodError): Record<string, string> {
|
|
848
|
+
let errors: Record<string, string> = {};
|
|
849
849
|
for (const issue of zodError.issues) {
|
|
850
850
|
const path = issue.path.join(".");
|
|
851
851
|
if (path && !getIn(errors, path)) {
|
|
852
|
-
errors = setIn(errors, path, issue.message)
|
|
852
|
+
errors = setIn(errors, path, issue.message) as Record<string, string>;
|
|
853
853
|
}
|
|
854
854
|
}
|
|
855
855
|
return errors;
|
|
856
856
|
}
|
|
857
857
|
|
|
858
|
-
function useOnAutoSave(autoSave: undefined | boolean, formex: FormexController<any>, lastSavedValues: any
|
|
858
|
+
function useOnAutoSave(autoSave: undefined | boolean, formex: FormexController<any>, lastSavedValues: React.MutableRefObject<any>, save: (values: EntityValues<any>) => Promise<Entity<any> | void>) {
|
|
859
859
|
useEffect(() => {
|
|
860
860
|
if (!autoSave) return;
|
|
861
861
|
if (formex.values && !equal(formex.values, lastSavedValues.current)) {
|
|
@@ -97,11 +97,11 @@ type ActionsViewProps<M extends Record<string, unknown>> = {
|
|
|
97
97
|
sideEntityController: SideEntityController,
|
|
98
98
|
disabled: boolean,
|
|
99
99
|
status: "new" | "existing" | "copy",
|
|
100
|
-
pluginActions?:
|
|
100
|
+
pluginActions?: React.ReactNode[],
|
|
101
101
|
openEntityMode: "side_panel" | "full_screen" | "split" | "dialog";
|
|
102
102
|
navigateBack: () => void;
|
|
103
103
|
formContext: FormContext,
|
|
104
|
-
formex: FormexController<
|
|
104
|
+
formex: FormexController<Record<string, unknown>>;
|
|
105
105
|
t: (key: string) => string;
|
|
106
106
|
className?: string;
|
|
107
107
|
};
|
|
@@ -6,7 +6,7 @@ import { deepEqual as equal } from "fast-equals"
|
|
|
6
6
|
|
|
7
7
|
import { resolveComponentRef } from "@rebasepro/core";
|
|
8
8
|
|
|
9
|
-
import { Field,
|
|
9
|
+
import { Field, FormexFieldProps, getIn } from "@rebasepro/formex";
|
|
10
10
|
|
|
11
11
|
;
|
|
12
12
|
import { ReadOnlyFieldBinding } from "./field_bindings/ReadOnlyFieldBinding";
|
|
@@ -42,7 +42,7 @@ import { ErrorBoundary } from "@rebasepro/ui";
|
|
|
42
42
|
* @param autoFocus
|
|
43
43
|
* @group Form custom fields
|
|
44
44
|
*/
|
|
45
|
-
export const PropertyFieldBinding = React.memo(PropertyFieldBindingInternal, (a: PropertyFieldBindingProps<
|
|
45
|
+
export const PropertyFieldBinding = React.memo(PropertyFieldBindingInternal, (a: PropertyFieldBindingProps<Record<string, unknown>>, b: PropertyFieldBindingProps<Record<string, unknown>>) => {
|
|
46
46
|
if (a.propertyKey !== b.propertyKey) {
|
|
47
47
|
return false;
|
|
48
48
|
}
|
|
@@ -70,21 +70,21 @@ export const PropertyFieldBinding = React.memo(PropertyFieldBindingInternal, (a:
|
|
|
70
70
|
}) as typeof PropertyFieldBindingInternal;
|
|
71
71
|
|
|
72
72
|
function PropertyFieldBindingInternal<M extends Record<string, unknown> = Record<string, unknown>>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
73
|
+
({
|
|
74
|
+
propertyKey,
|
|
75
|
+
property,
|
|
76
|
+
context,
|
|
77
|
+
includeDescription,
|
|
78
|
+
underlyingValueHasChanged,
|
|
79
|
+
disabled: disabledProp,
|
|
80
|
+
partOfArray,
|
|
81
|
+
partOfBlock,
|
|
82
|
+
minimalistView,
|
|
83
|
+
autoFocus,
|
|
84
|
+
index,
|
|
85
|
+
size,
|
|
86
|
+
onPropertyChange
|
|
87
|
+
}: PropertyFieldBindingProps<M>): ReactElement<PropertyFieldBindingProps<M>> {
|
|
88
88
|
|
|
89
89
|
const authController = useAuthController();
|
|
90
90
|
const customizationController = useCustomizationController();
|
|
@@ -96,7 +96,7 @@ function PropertyFieldBindingInternal<M extends Record<string, unknown> = Record
|
|
|
96
96
|
>
|
|
97
97
|
{(fieldProps) => {
|
|
98
98
|
|
|
99
|
-
let Component: ComponentType<FieldProps
|
|
99
|
+
let Component: ComponentType<FieldProps<Property, any, any>> | undefined;
|
|
100
100
|
const resolvedProperty = resolveProperty({
|
|
101
101
|
propertyKey,
|
|
102
102
|
property: property,
|
|
@@ -118,7 +118,7 @@ function PropertyFieldBindingInternal<M extends Record<string, unknown> = Record
|
|
|
118
118
|
} else if (resolvedProperty.ui?.Field) {
|
|
119
119
|
const resolved = resolveComponentRef(resolvedProperty.ui.Field);
|
|
120
120
|
if (resolved) {
|
|
121
|
-
Component = resolved as ComponentType<FieldProps<Property,
|
|
121
|
+
Component = resolved as ComponentType<FieldProps<Property, any, any>>;
|
|
122
122
|
}
|
|
123
123
|
} else {
|
|
124
124
|
const propertyConfig = getFieldConfig(resolvedProperty, customizationController.propertyConfigs);
|
|
@@ -135,7 +135,7 @@ function PropertyFieldBindingInternal<M extends Record<string, unknown> = Record
|
|
|
135
135
|
index,
|
|
136
136
|
authController
|
|
137
137
|
}) as Property | null;
|
|
138
|
-
Component = resolveComponentRef(configProperty?.ui?.Field) as ComponentType<FieldProps
|
|
138
|
+
Component = resolveComponentRef(configProperty?.ui?.Field) as ComponentType<FieldProps<Property, any, any>> | undefined;
|
|
139
139
|
}
|
|
140
140
|
if (!Component) {
|
|
141
141
|
console.warn(`No field component found for property ${propertyKey}`);
|
|
@@ -163,9 +163,9 @@ function PropertyFieldBindingInternal<M extends Record<string, unknown> = Record
|
|
|
163
163
|
};
|
|
164
164
|
|
|
165
165
|
return <FieldInternal
|
|
166
|
-
Component={Component as ComponentType<FieldProps
|
|
166
|
+
Component={Component as ComponentType<FieldProps<Property, any, any>>}
|
|
167
167
|
componentProps={componentProps}
|
|
168
|
-
formexFieldProps={fieldProps}/>;
|
|
168
|
+
formexFieldProps={fieldProps as FormexFieldProps<unknown, Record<string, unknown>>}/>;
|
|
169
169
|
}}
|
|
170
170
|
</Field>
|
|
171
171
|
);
|
|
@@ -175,68 +175,68 @@ function PropertyFieldBindingInternal<M extends Record<string, unknown> = Record
|
|
|
175
175
|
type ResolvedPropertyFieldBindingProps<M extends Record<string, unknown> = Record<string, unknown>> =
|
|
176
176
|
Omit<PropertyFieldBindingProps<M>, "property">
|
|
177
177
|
& {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
function FieldInternal<CustomProps, M extends Record<string,
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
178
|
+
property: Property
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
function FieldInternal<CustomProps, M extends Record<string, unknown>>
|
|
182
|
+
({
|
|
183
|
+
Component,
|
|
184
|
+
componentProps: {
|
|
185
|
+
propertyKey,
|
|
186
|
+
property,
|
|
187
|
+
includeDescription,
|
|
188
|
+
underlyingValueHasChanged,
|
|
189
|
+
partOfArray,
|
|
190
|
+
partOfBlock,
|
|
191
|
+
minimalistView,
|
|
192
|
+
autoFocus,
|
|
193
|
+
context,
|
|
194
|
+
disabled,
|
|
195
|
+
size,
|
|
196
|
+
onPropertyChange
|
|
197
|
+
},
|
|
198
|
+
formexFieldProps
|
|
199
|
+
}:
|
|
200
|
+
{
|
|
201
|
+
Component: ComponentType<FieldProps<Property, any, any>>,
|
|
202
|
+
componentProps: ResolvedPropertyFieldBindingProps<M>,
|
|
203
|
+
formexFieldProps: FormexFieldProps<unknown, Record<string, unknown>>
|
|
204
|
+
}) {
|
|
205
205
|
|
|
206
206
|
const { plugins } = useCustomizationController();
|
|
207
207
|
|
|
208
|
-
const customFieldProps:
|
|
208
|
+
const customFieldProps: unknown = property.ui?.customProps;
|
|
209
209
|
const value = formexFieldProps.field.value;
|
|
210
210
|
const error = getIn(formexFieldProps.form.errors, propertyKey) as string | string[] | undefined;
|
|
211
211
|
const touched = getIn(formexFieldProps.form.touched, propertyKey) as boolean | undefined;
|
|
212
212
|
|
|
213
213
|
const showError = Boolean(error &&
|
|
214
214
|
(formexFieldProps.form.submitCount > 0 || property.validation?.unique) &&
|
|
215
|
-
(!Array.isArray(error) || !!error.filter((e:
|
|
215
|
+
(!Array.isArray(error) || !!error.filter((e: unknown) => !!e).length));
|
|
216
216
|
|
|
217
|
-
const WrappedComponent: ComponentType<FieldProps<
|
|
217
|
+
const WrappedComponent: ComponentType<FieldProps<Property, any, any>> | null = useWrappedComponent<unknown, any>({
|
|
218
218
|
path: context.path,
|
|
219
219
|
collection: context.collection,
|
|
220
220
|
propertyKey: propertyKey,
|
|
221
221
|
property: property,
|
|
222
|
-
Component: Component,
|
|
222
|
+
Component: Component as any, // Cast component here since it is a generic component type
|
|
223
223
|
plugins: plugins
|
|
224
224
|
});
|
|
225
|
-
const UsedComponent: ComponentType<FieldProps
|
|
225
|
+
const UsedComponent: ComponentType<FieldProps<Property, any, any>> = WrappedComponent ?? Component;
|
|
226
226
|
|
|
227
227
|
const isSubmitting = formexFieldProps.form.isSubmitting;
|
|
228
228
|
|
|
229
|
-
const setValue = useCallback((value:
|
|
229
|
+
const setValue = useCallback((value: unknown | null, shouldValidate?: boolean) => {
|
|
230
230
|
formexFieldProps.form.setFieldTouched(propertyKey, true, false);
|
|
231
231
|
formexFieldProps.form.setFieldValue(propertyKey, value, shouldValidate);
|
|
232
232
|
}, []);
|
|
233
233
|
|
|
234
|
-
const setFieldValue = useCallback((otherPropertyKey: string, value:
|
|
234
|
+
const setFieldValue = useCallback((otherPropertyKey: string, value: unknown | null, shouldValidate?: boolean) => {
|
|
235
235
|
formexFieldProps.form.setFieldTouched(propertyKey, true, false);
|
|
236
236
|
formexFieldProps.form.setFieldValue(otherPropertyKey, value, shouldValidate);
|
|
237
237
|
}, []);
|
|
238
238
|
|
|
239
|
-
const cmsFieldProps: FieldProps<
|
|
239
|
+
const cmsFieldProps: FieldProps<Property, CustomProps, M> = {
|
|
240
240
|
propertyKey,
|
|
241
241
|
value,
|
|
242
242
|
setValue,
|
|
@@ -253,7 +253,7 @@ function FieldInternal<CustomProps, M extends Record<string, any>>
|
|
|
253
253
|
partOfBlock: partOfBlock ?? false,
|
|
254
254
|
minimalistView: minimalistView ?? false,
|
|
255
255
|
autoFocus: autoFocus ?? false,
|
|
256
|
-
customProps: customFieldProps,
|
|
256
|
+
customProps: customFieldProps as CustomProps,
|
|
257
257
|
context,
|
|
258
258
|
size,
|
|
259
259
|
onPropertyChange
|
|
@@ -295,11 +295,11 @@ interface UseWrappedComponentParams<M extends Record<string, unknown> = Record<s
|
|
|
295
295
|
collection?: EntityCollection<M>,
|
|
296
296
|
propertyKey: string,
|
|
297
297
|
property: Property,
|
|
298
|
-
Component: ComponentType<FieldProps<
|
|
298
|
+
Component: ComponentType<FieldProps<Property, unknown, M>>,
|
|
299
299
|
plugins?: RebasePlugin[]
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
-
function useWrappedComponent<T, M extends Record<string,
|
|
302
|
+
function useWrappedComponent<T, M extends Record<string, unknown> = Record<string, unknown>>(
|
|
303
303
|
{
|
|
304
304
|
path,
|
|
305
305
|
collection,
|
|
@@ -308,10 +308,10 @@ function useWrappedComponent<T, M extends Record<string, any> = any>(
|
|
|
308
308
|
Component,
|
|
309
309
|
plugins
|
|
310
310
|
}: UseWrappedComponentParams<M>
|
|
311
|
-
): ComponentType<FieldProps<
|
|
311
|
+
): ComponentType<FieldProps<Property, unknown, M>> | null {
|
|
312
312
|
|
|
313
|
-
const wrapperRef = useRef<ComponentType<FieldProps<
|
|
314
|
-
let Wrapper: ComponentType<FieldProps<
|
|
313
|
+
const wrapperRef = useRef<ComponentType<FieldProps<Property, unknown, M>> | null>((() => {
|
|
314
|
+
let Wrapper: ComponentType<FieldProps<Property, unknown, M>> | null = null;
|
|
315
315
|
if (plugins) {
|
|
316
316
|
plugins.forEach((plugin) => {
|
|
317
317
|
const fieldId = getFieldId(property);
|
|
@@ -327,7 +327,7 @@ function useWrappedComponent<T, M extends Record<string, any> = any>(
|
|
|
327
327
|
};
|
|
328
328
|
const enabled = plugin.fieldBuilder.enabled?.(params);
|
|
329
329
|
if (enabled === undefined || enabled)
|
|
330
|
-
Wrapper = (plugin.fieldBuilder.wrap(params) as unknown as ComponentType<FieldProps<
|
|
330
|
+
Wrapper = (plugin.fieldBuilder.wrap(params) as unknown as ComponentType<FieldProps<Property, unknown, M>> | null) ?? Wrapper;
|
|
331
331
|
}
|
|
332
332
|
if (!fieldId) {
|
|
333
333
|
console.warn("INTERNAL: Field id not found for property", property);
|
|
@@ -22,16 +22,16 @@ function normalizeError(error: unknown): string | undefined {
|
|
|
22
22
|
|
|
23
23
|
// Extract all string values from the object (e.g., nested validation errors)
|
|
24
24
|
const messages: string[] = [];
|
|
25
|
-
const extractMessages = (obj:
|
|
25
|
+
const extractMessages = (obj: Record<string, unknown>) => {
|
|
26
26
|
for (const key in obj) {
|
|
27
27
|
if (typeof obj[key] === "string") {
|
|
28
|
-
messages.push(obj[key]);
|
|
28
|
+
messages.push(obj[key] as string);
|
|
29
29
|
} else if (typeof obj[key] === "object" && obj[key] !== null) {
|
|
30
|
-
extractMessages(obj[key]);
|
|
30
|
+
extractMessages(obj[key] as Record<string, unknown>);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
|
-
extractMessages(error);
|
|
34
|
+
extractMessages(error as Record<string, unknown>);
|
|
35
35
|
if (messages.length > 0) {
|
|
36
36
|
return Array.from(new Set(messages)).join(", ");
|
|
37
37
|
}
|
|
@@ -7,11 +7,11 @@ import { cls, paperMixin, Skeleton } from "@rebasepro/ui";
|
|
|
7
7
|
|
|
8
8
|
export interface StorageUploadItemProps {
|
|
9
9
|
storagePath: string;
|
|
10
|
-
metadata?:
|
|
10
|
+
metadata?: Record<string, unknown>,
|
|
11
11
|
entry: StorageFieldItem,
|
|
12
12
|
onFileUploadComplete: (value: string,
|
|
13
13
|
entry: StorageFieldItem,
|
|
14
|
-
metadata?:
|
|
14
|
+
metadata?: Record<string, unknown>,
|
|
15
15
|
uploadedUrl?: string) => Promise<void>;
|
|
16
16
|
imageSize: number;
|
|
17
17
|
simple: boolean;
|
|
@@ -77,7 +77,7 @@ export function ArrayCustomShapedFieldBinding({
|
|
|
77
77
|
setValue,
|
|
78
78
|
setFieldValue,
|
|
79
79
|
customProps
|
|
80
|
-
} as FieldProps
|
|
80
|
+
} as FieldProps;
|
|
81
81
|
return <div key={`custom_shaped_array_${index}`} className="pb-4">
|
|
82
82
|
<PropertyFieldBinding {...fieldProps}/>
|
|
83
83
|
</div>;
|
|
@@ -64,7 +64,7 @@ export function ArrayOfReferencesFieldBinding({
|
|
|
64
64
|
throw Error(`Couldn't find the corresponding collection for the path: ${ofProperty.path}`);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const onMultipleEntitiesSelected = useCallback((entities: Entity<
|
|
67
|
+
const onMultipleEntitiesSelected = useCallback((entities: Entity<Record<string, unknown>>[]) => {
|
|
68
68
|
const refs = entities.map(e => getReferenceFrom(e));
|
|
69
69
|
setValue(refs);
|
|
70
70
|
}, [setValue]);
|
|
@@ -7,6 +7,7 @@ import { Field, useFormex } from "@rebasepro/formex";
|
|
|
7
7
|
import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
|
|
8
8
|
import { PropertyFieldBinding } from "../PropertyFieldBinding";
|
|
9
9
|
import { EnumValuesChip } from "../../preview";
|
|
10
|
+
|
|
10
11
|
;
|
|
11
12
|
import { DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE, getDefaultValueFor } from "@rebasepro/common";
|
|
12
13
|
import { getIconForProperty } from "../../util/property_utils";
|
|
@@ -25,20 +26,20 @@ import { mergeDeep } from "@rebasepro/utils";
|
|
|
25
26
|
* @group Form fields
|
|
26
27
|
*/
|
|
27
28
|
export function BlockFieldBinding({
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}: FieldProps<ArrayProperty>) {
|
|
29
|
+
propertyKey,
|
|
30
|
+
value,
|
|
31
|
+
error,
|
|
32
|
+
showError,
|
|
33
|
+
isSubmitting,
|
|
34
|
+
setValue,
|
|
35
|
+
setFieldValue,
|
|
36
|
+
minimalistView: minimalistViewProp,
|
|
37
|
+
property,
|
|
38
|
+
includeDescription,
|
|
39
|
+
underlyingValueHasChanged,
|
|
40
|
+
context,
|
|
41
|
+
disabled
|
|
42
|
+
}: FieldProps<ArrayProperty>) {
|
|
42
43
|
|
|
43
44
|
const minimalistView = minimalistViewProp || property.ui?.minimalistView;
|
|
44
45
|
const { t } = useTranslation();
|
|
@@ -56,11 +57,11 @@ export function BlockFieldBinding({
|
|
|
56
57
|
const [lastAddedId, setLastAddedId] = useState<number | undefined>();
|
|
57
58
|
|
|
58
59
|
const buildEntry = ({
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
index,
|
|
61
|
+
internalId,
|
|
62
|
+
storedProps,
|
|
63
|
+
storeProps
|
|
64
|
+
}: ArrayEntryParams) => {
|
|
64
65
|
|
|
65
66
|
return <BlockEntry
|
|
66
67
|
key={`array_one_of_${internalId}`}
|
|
@@ -87,18 +88,18 @@ export function BlockFieldBinding({
|
|
|
87
88
|
|
|
88
89
|
const firstOneOfKey = Object.keys(property.oneOf.properties)[0];
|
|
89
90
|
const body = <ArrayContainer value={value}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
91
|
+
className={"flex flex-col gap-3"}
|
|
92
|
+
droppableId={propertyKey}
|
|
93
|
+
addLabel={property.name ? t("add_to_field", { fieldName: property.name }) : t("add_entry")}
|
|
94
|
+
buildEntry={buildEntry}
|
|
95
|
+
onInternalIdAdded={setLastAddedId}
|
|
96
|
+
disabled={isSubmitting || Boolean(property.ui?.disabled)}
|
|
97
|
+
canAddElements={!property.ui?.disabled}
|
|
98
|
+
onValueChange={(value) => setFieldValue(propertyKey, value)}
|
|
99
|
+
newDefaultEntry={{
|
|
100
|
+
[property.oneOf!.typeField ?? DEFAULT_ONE_OF_TYPE]: firstOneOfKey,
|
|
101
|
+
[property.oneOf!.valueField ?? DEFAULT_ONE_OF_VALUE]: getDefaultValueFor(property.oneOf.properties[firstOneOfKey])
|
|
102
|
+
}}/>;
|
|
102
103
|
return (
|
|
103
104
|
|
|
104
105
|
<>
|
|
@@ -114,10 +115,10 @@ export function BlockFieldBinding({
|
|
|
114
115
|
{minimalistView && body}
|
|
115
116
|
|
|
116
117
|
<FieldHelperText includeDescription={includeDescription}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
showError={showError}
|
|
119
|
+
error={error}
|
|
120
|
+
disabled={disabled}
|
|
121
|
+
property={property}/>
|
|
121
122
|
|
|
122
123
|
</>
|
|
123
124
|
);
|
|
@@ -126,7 +127,7 @@ export function BlockFieldBinding({
|
|
|
126
127
|
interface BlockEntryProps {
|
|
127
128
|
name: string;
|
|
128
129
|
index: number;
|
|
129
|
-
value:
|
|
130
|
+
value: Record<string, unknown>;
|
|
130
131
|
/**
|
|
131
132
|
* Name of the field to use as the discriminator for type
|
|
132
133
|
* Defaults to `type`
|
|
@@ -148,7 +149,7 @@ interface BlockEntryProps {
|
|
|
148
149
|
/**
|
|
149
150
|
* Additional values related to the state of the form or the entity
|
|
150
151
|
*/
|
|
151
|
-
context: FormContext
|
|
152
|
+
context: FormContext;
|
|
152
153
|
|
|
153
154
|
storedProps?: object,
|
|
154
155
|
storeProps: (props: object) => void
|
|
@@ -156,19 +157,19 @@ interface BlockEntryProps {
|
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
function BlockEntry({
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}: BlockEntryProps) {
|
|
170
|
-
|
|
171
|
-
const type = value && value[typeField];
|
|
160
|
+
name,
|
|
161
|
+
index,
|
|
162
|
+
value,
|
|
163
|
+
typeField,
|
|
164
|
+
valueField,
|
|
165
|
+
properties,
|
|
166
|
+
autoFocus,
|
|
167
|
+
context,
|
|
168
|
+
storedProps,
|
|
169
|
+
storeProps
|
|
170
|
+
}: BlockEntryProps) {
|
|
171
|
+
|
|
172
|
+
const type = value && (value[typeField] as string | undefined);
|
|
172
173
|
const [typeInternal, setTypeInternal] = useState<string | undefined>(type ?? undefined);
|
|
173
174
|
|
|
174
175
|
const formex = useFormex();
|
|
@@ -218,7 +219,7 @@ function BlockEntry({
|
|
|
218
219
|
}
|
|
219
220
|
: undefined;
|
|
220
221
|
|
|
221
|
-
const updateType = (newType:
|
|
222
|
+
const updateType = (newType: string | undefined) => {
|
|
222
223
|
const newSelectedProperty = newType ? properties[newType] : undefined;
|
|
223
224
|
setTypeInternal(newType);
|
|
224
225
|
formex.setFieldTouched(typeFieldName, true);
|
|
@@ -239,12 +240,12 @@ function BlockEntry({
|
|
|
239
240
|
<Select
|
|
240
241
|
className="mb-2"
|
|
241
242
|
placeholder={<Typography variant={"caption"}
|
|
242
|
-
|
|
243
|
+
className={"px-4 py-2 font-medium"}>{t("type")}</Typography>}
|
|
243
244
|
size={"medium"}
|
|
244
245
|
fullWidth={true}
|
|
245
246
|
position={"item-aligned"}
|
|
246
247
|
value={value1}
|
|
247
|
-
renderValue={(enumKey:
|
|
248
|
+
renderValue={(enumKey: string) =>
|
|
248
249
|
<EnumValuesChip
|
|
249
250
|
enumKey={enumKey}
|
|
250
251
|
enumValues={enumValuesConfigs}
|