@rebasepro/admin 0.12.1-canary.gf5f1d39 → 0.13.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/README.md +1 -1
- package/dist/{CollectionEditorDialog-Dpc75wIZ.js → CollectionEditorDialog-CjXkWZ64.js} +75 -62
- package/dist/{CollectionEditorDialog-Dpc75wIZ.js.map → CollectionEditorDialog-CjXkWZ64.js.map} +1 -1
- package/dist/{PropertyEditView-DH3XZC2x.js → PropertyEditView-W8I3YV89.js} +36 -16
- package/dist/{PropertyEditView-DH3XZC2x.js.map → PropertyEditView-W8I3YV89.js.map} +1 -1
- package/dist/{RouterCollectionsStudioView-BZLq4MGp.js → RouterCollectionsStudioView-BsLTNoqX.js} +5 -5
- package/dist/{RouterCollectionsStudioView-BZLq4MGp.js.map → RouterCollectionsStudioView-BsLTNoqX.js.map} +1 -1
- package/dist/collection_editor/serializable_types.d.ts +4 -1
- package/dist/collection_editor/ui/collection_editor/CollectionRelationsTab.d.ts +1 -0
- package/dist/collection_editor/useLocalCollectionsConfigController.d.ts +8 -0
- package/dist/collection_editor_ui.js +5 -5
- package/dist/collection_editor_ui.js.map +1 -1
- package/dist/components/CollectionTableBinding/column_utils.d.ts +17 -0
- package/dist/components/CollectionViewBinding/CollectionViewStartActions.d.ts +7 -2
- package/dist/components/CollectionViewBinding/SortButton.d.ts +24 -0
- package/dist/components/CollectionViewBinding/SplitListCloseButton.d.ts +10 -0
- package/dist/components/CollectionViewBinding/SplitViewContext.d.ts +23 -0
- package/dist/components/CollectionViewBinding/hooks/useKanbanDragAndDrop.d.ts +26 -0
- package/dist/components/DetailViewBinding.d.ts +5 -0
- package/dist/components/EditFormActions.d.ts +12 -1
- package/dist/components/EditViewBinding.d.ts +6 -1
- package/dist/components/EntityIdentityBar.d.ts +53 -0
- package/dist/components/EntityInspector.d.ts +35 -0
- package/dist/components/EntityPreviewNesting.d.ts +25 -0
- package/dist/components/EntityViewBinding.d.ts +9 -0
- package/dist/components/InlineEntityPreview.d.ts +47 -0
- package/dist/components/history/EntityHistoryView.d.ts +4 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/editor.js +18 -10
- package/dist/editor.js.map +1 -1
- package/dist/{export-BzIpUdSK.js → export-J79rMoNj.js} +2 -2
- package/dist/{export-BzIpUdSK.js.map → export-J79rMoNj.js.map} +1 -1
- package/dist/form/EntityForm.d.ts +1 -1
- package/dist/form/EntityFormActions.d.ts +11 -1
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/form/components/FieldBlock.d.ts +30 -0
- package/dist/form/components/FormRail.d.ts +18 -0
- package/dist/form/components/FormSections.d.ts +16 -0
- package/dist/form/components/index.d.ts +3 -2
- package/dist/form/components/useRailVisible.d.ts +24 -0
- package/dist/form/field_bindings/BinaryFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/DateTimeFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/GeopointFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MultiSelectFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/UserSelectFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/VectorFieldBinding.d.ts +1 -1
- package/dist/{history-g9688IaK.js → history-D7L_JlLO.js} +35 -33
- package/dist/history-D7L_JlLO.js.map +1 -0
- package/dist/hooks/navigation/utils.d.ts +16 -0
- package/dist/hooks/useBuildSidePanel.d.ts +14 -0
- package/dist/hooks/useEntityDisplayTitle.d.ts +18 -0
- package/dist/hooks/useHistory.d.ts +7 -0
- package/dist/hooks/useRecordActions.d.ts +17 -0
- package/dist/{import-BjUG-cIY.js → import-BvYl--U4.js} +2 -2
- package/dist/{import-BjUG-cIY.js.map → import-BvYl--U4.js.map} +1 -1
- package/dist/index.js +106 -35
- package/dist/index.js.map +1 -1
- package/dist/markdown-CklalUUk.js.map +1 -1
- package/dist/preview/components/InlineEntityListPreview.d.ts +15 -0
- package/dist/preview/index.d.ts +1 -0
- package/dist/preview/property_previews/ArrayOfReferencesPreview.d.ts +1 -1
- package/dist/preview/property_previews/ArrayOfRelationsPreview.d.ts +1 -1
- package/dist/types/components/EntityFormActionsProps.d.ts +0 -1
- package/dist/types/components/EntityFormProps.d.ts +0 -5
- package/dist/types/fields.d.ts +24 -0
- package/dist/{util-B5fJm1FA.js → util-GiwPgxnL.js} +2106 -1117
- package/dist/util-GiwPgxnL.js.map +1 -0
- package/package.json +32 -34
- package/src/collection_editor/ConfigControllerProvider.tsx +1 -1
- package/src/collection_editor/serializable_types.ts +4 -3
- package/src/collection_editor/serializable_utils.ts +51 -17
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +65 -22
- package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +38 -30
- package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +3 -1
- package/src/collection_editor/ui/collection_editor/RouterCollectionStudioView.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/RouterCollectionsStudioView.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx +16 -0
- package/src/collection_editor/useLocalCollectionsConfigController.tsx +127 -15
- package/src/collection_editor/validateCollectionJson.ts +3 -3
- package/src/components/AdminModeSyncer.tsx +1 -1
- package/src/components/CollectionTableBinding/PropertyTableCell.tsx +10 -2
- package/src/components/CollectionTableBinding/column_utils.tsx +59 -2
- package/src/components/CollectionTableBinding/table_bindings.tsx +2 -1
- package/src/components/CollectionViewBinding/CollectionBoardViewBinding.tsx +23 -16
- package/src/components/CollectionViewBinding/CollectionViewActions.tsx +7 -1
- package/src/components/CollectionViewBinding/CollectionViewBinding.tsx +9 -2
- package/src/components/CollectionViewBinding/CollectionViewStartActions.tsx +47 -12
- package/src/components/CollectionViewBinding/SortButton.tsx +189 -0
- package/src/components/CollectionViewBinding/SplitListCloseButton.tsx +33 -0
- package/src/components/CollectionViewBinding/SplitListView.tsx +18 -3
- package/src/components/CollectionViewBinding/SplitViewContext.tsx +34 -0
- package/src/components/CollectionViewBinding/hooks/useKanbanDragAndDrop.ts +48 -9
- package/src/components/CollectionViewBinding/useBoardDataController.tsx +80 -25
- package/src/components/CollectionViewBinding/usePreviewSlots.ts +18 -6
- package/src/components/DefaultAppBar.tsx +1 -1
- package/src/components/DefaultDrawer.tsx +1 -1
- package/src/components/DetailViewBinding.tsx +112 -148
- package/src/components/DrawerNavigationItem.tsx +1 -1
- package/src/components/EditFormActions.tsx +54 -129
- package/src/components/EditViewBinding.tsx +202 -99
- package/src/components/EntityIdentityBar.tsx +288 -0
- package/src/components/EntityInspector.tsx +137 -0
- package/src/components/EntityPreviewBinding.tsx +6 -2
- package/src/components/EntityPreviewNesting.tsx +50 -0
- package/src/components/EntityViewBinding.tsx +35 -32
- package/src/components/HomePage/FavouritesView.tsx +1 -1
- package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
- package/src/components/HomePage/SmallNavigationCard.tsx +1 -1
- package/src/components/InlineEntityPreview.tsx +149 -0
- package/src/components/RebaseLayout.tsx +1 -1
- package/src/components/RebaseNavigation.tsx +45 -5
- package/src/components/RebaseRouteDefs.tsx +1 -1
- package/src/components/SelectableTable/SelectableTable.tsx +2 -2
- package/src/components/SidePanelBinding.tsx +19 -13
- package/src/components/UserSelector.tsx +12 -6
- package/src/components/common/default_entity_actions.tsx +4 -3
- package/src/components/history/EntityHistoryEntry.tsx +28 -7
- package/src/components/history/EntityHistoryView.tsx +29 -24
- package/src/components/history/LastEditedByIndicator.tsx +4 -3
- package/src/components/index.ts +2 -0
- package/src/data_import/utils/get_import_inference_type.ts +6 -0
- package/src/form/EntityForm.tsx +267 -179
- package/src/form/EntityFormActions.tsx +50 -99
- package/src/form/EntityFormBinding.tsx +4 -2
- package/src/form/PropertyFieldBinding.tsx +4 -0
- package/src/form/components/FieldBlock.tsx +119 -0
- package/src/form/components/FormRail.tsx +125 -0
- package/src/form/components/FormSections.tsx +118 -0
- package/src/form/components/index.tsx +3 -2
- package/src/form/components/useRailVisible.tsx +46 -0
- package/src/form/field_bindings/BinaryFieldBinding.tsx +3 -2
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +3 -2
- package/src/form/field_bindings/GeopointFieldBinding.tsx +3 -2
- package/src/form/field_bindings/MapFieldBinding.tsx +1 -2
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +3 -2
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +2 -1
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -1
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +2 -1
- package/src/form/field_bindings/RelationFieldBinding.tsx +6 -4
- package/src/form/field_bindings/RepeatFieldBinding.tsx +4 -1
- package/src/form/field_bindings/SelectFieldBinding.tsx +3 -2
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +31 -8
- package/src/form/field_bindings/SwitchFieldBinding.tsx +7 -3
- package/src/form/field_bindings/TextFieldBinding.tsx +18 -16
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +3 -2
- package/src/form/field_bindings/VectorFieldBinding.tsx +2 -1
- package/src/hooks/navigation/useBuildUrlController.tsx +1 -1
- package/src/hooks/navigation/useTopLevelNavigation.ts +18 -7
- package/src/hooks/navigation/utils.ts +20 -0
- package/src/hooks/useBuildSideDialogsController.tsx +2 -2
- package/src/hooks/useBuildSidePanel.tsx +22 -61
- package/src/hooks/useEntityDisplayTitle.tsx +60 -0
- package/src/hooks/useHistory.ts +20 -10
- package/src/hooks/useRecordActions.tsx +69 -0
- package/src/hooks/useResolvedUsers.ts +10 -5
- package/src/preview/PropertyPreview.tsx +48 -22
- package/src/preview/components/InlineEntityListPreview.tsx +42 -0
- package/src/preview/components/ReferencePreview.tsx +34 -14
- package/src/preview/components/RelationPreview.tsx +34 -14
- package/src/preview/index.ts +1 -0
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +24 -1
- package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +25 -1
- package/src/routes/RebaseRoute.tsx +2 -2
- package/src/types/components/EntityFormActionsProps.tsx +0 -1
- package/src/types/components/EntityFormProps.tsx +0 -6
- package/src/types/fields.tsx +27 -0
- package/dist/form/components/FormEntry.d.ts +0 -6
- package/dist/form/components/FormLayout.d.ts +0 -5
- package/dist/history-g9688IaK.js.map +0 -1
- package/dist/util-B5fJm1FA.js.map +0 -1
- package/src/form/components/FormEntry.tsx +0 -22
- package/src/form/components/FormLayout.tsx +0 -16
|
@@ -6,9 +6,13 @@ import type { PreviewSize } from "../../types/components/PropertyPreviewProps";
|
|
|
6
6
|
import { useCustomizationController, useFetch, ErrorView, useComponentOverride, CollectionScopeProvider } from "@rebasepro/app";
|
|
7
7
|
import { Skeleton } from "@rebasepro/ui";
|
|
8
8
|
import { EntityPreviewBinding, EntityPreviewContainer } from "../../components/EntityPreviewBinding";
|
|
9
|
+
import {
|
|
10
|
+
InlineEntityPreview,
|
|
11
|
+
InlineEntityPreviewMissing,
|
|
12
|
+
InlineEntityPreviewSkeleton
|
|
13
|
+
} from "../../components/InlineEntityPreview";
|
|
14
|
+
import { useIsNestedEntityPreview } from "../../components/EntityPreviewNesting";
|
|
9
15
|
import { useCollectionRegistryController } from "../../hooks/navigation/contexts/CollectionRegistryContext";
|
|
10
|
-
import { getEntityTitlePropertyKeyForEntity } from "../../util/previews";
|
|
11
|
-
import { getValueInPath } from "@rebasepro/utils";
|
|
12
16
|
import type { AdminCollection } from "@rebasepro/admin-types";
|
|
13
17
|
|
|
14
18
|
export type RelationPreviewProps = {
|
|
@@ -64,9 +68,10 @@ function extractDisplayFromPlainObject(obj: unknown): string {
|
|
|
64
68
|
*/
|
|
65
69
|
export const RelationPreview = function RelationPreview(props: RelationPreviewProps) {
|
|
66
70
|
const relation = props.relation;
|
|
71
|
+
const nested = useIsNestedEntityPreview();
|
|
67
72
|
if (!(typeof relation === "object" && "isEntityRelation" in relation && relation.isEntityRelation())) {
|
|
68
73
|
console.warn("Relation preview received value of type", typeof relation);
|
|
69
|
-
if (props.textOnly) {
|
|
74
|
+
if (props.textOnly || nested) {
|
|
70
75
|
const display = extractDisplayFromPlainObject(relation);
|
|
71
76
|
return <span className="truncate">{display}</span>;
|
|
72
77
|
}
|
|
@@ -95,6 +100,7 @@ function RelationPreviewInternalInner({
|
|
|
95
100
|
collection
|
|
96
101
|
}: RelationPreviewProps & { collection?: AdminCollection }) {
|
|
97
102
|
const ResolvedMissingReference = useComponentOverride("Entity.MissingReference", DefaultMissingReference);
|
|
103
|
+
const nested = useIsNestedEntityPreview();
|
|
98
104
|
|
|
99
105
|
if (!collection) {
|
|
100
106
|
if (ResolvedMissingReference !== DefaultMissingReference) {
|
|
@@ -103,6 +109,10 @@ function RelationPreviewInternalInner({
|
|
|
103
109
|
if (textOnly) {
|
|
104
110
|
return <span>{relation.path}</span>;
|
|
105
111
|
}
|
|
112
|
+
if (nested) {
|
|
113
|
+
return <InlineEntityPreviewMissing label={String(relation.id)}
|
|
114
|
+
tooltip={`Collection not found: ${relation.path}`}/>;
|
|
115
|
+
}
|
|
106
116
|
return <EntityPreviewContainer size={size}>
|
|
107
117
|
<ErrorView error={`Collection not found: ${relation.path}`}/>
|
|
108
118
|
</EntityPreviewContainer>;
|
|
@@ -162,6 +172,11 @@ function RelationPreviewExisting<M extends Record<string, unknown> = Record<stri
|
|
|
162
172
|
const passedEntity = relation.data as Entity<M> | undefined;
|
|
163
173
|
const ResolvedEntityPreview = useComponentOverride("EntityPreview", EntityPreviewBinding);
|
|
164
174
|
const customizationController = useCustomizationController();
|
|
175
|
+
const nested = useIsNestedEntityPreview();
|
|
176
|
+
|
|
177
|
+
// Nested inside another preview, or filling a title slot: one line of text,
|
|
178
|
+
// not a second card. See {@link InlineEntityPreview}.
|
|
179
|
+
const inline = nested || Boolean(textOnly);
|
|
165
180
|
|
|
166
181
|
const {
|
|
167
182
|
entity,
|
|
@@ -190,8 +205,9 @@ function RelationPreviewExisting<M extends Record<string, unknown> = Record<stri
|
|
|
190
205
|
}
|
|
191
206
|
|
|
192
207
|
if (body) {
|
|
193
|
-
if (
|
|
194
|
-
return <
|
|
208
|
+
if (inline) {
|
|
209
|
+
return <InlineEntityPreviewMissing label={String(relation.id)}
|
|
210
|
+
tooltip={relation.pathWithId}/>;
|
|
195
211
|
}
|
|
196
212
|
return (
|
|
197
213
|
<EntityPreviewContainer onClick={disabled ? undefined : onClick}
|
|
@@ -203,8 +219,8 @@ function RelationPreviewExisting<M extends Record<string, unknown> = Record<stri
|
|
|
203
219
|
}
|
|
204
220
|
|
|
205
221
|
if (dataLoading && !usedEntity) {
|
|
206
|
-
if (
|
|
207
|
-
return <
|
|
222
|
+
if (inline) {
|
|
223
|
+
return <InlineEntityPreviewSkeleton/>;
|
|
208
224
|
}
|
|
209
225
|
return (
|
|
210
226
|
<EntityPreviewContainer onClick={disabled ? undefined : onClick}
|
|
@@ -216,8 +232,9 @@ function RelationPreviewExisting<M extends Record<string, unknown> = Record<stri
|
|
|
216
232
|
}
|
|
217
233
|
|
|
218
234
|
if (!usedEntity) {
|
|
219
|
-
if (
|
|
220
|
-
return <
|
|
235
|
+
if (inline) {
|
|
236
|
+
return <InlineEntityPreviewMissing label={String(relation.id)}
|
|
237
|
+
tooltip={"Entity not found"}/>;
|
|
221
238
|
}
|
|
222
239
|
return (
|
|
223
240
|
<EntityPreviewContainer onClick={disabled ? undefined : onClick}
|
|
@@ -228,11 +245,14 @@ function RelationPreviewExisting<M extends Record<string, unknown> = Record<stri
|
|
|
228
245
|
);
|
|
229
246
|
}
|
|
230
247
|
|
|
231
|
-
if (
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
248
|
+
if (inline) {
|
|
249
|
+
return <InlineEntityPreview entity={usedEntity}
|
|
250
|
+
collection={collection}
|
|
251
|
+
disabled={disabled}
|
|
252
|
+
onClick={onClick}
|
|
253
|
+
// In a title slot the row itself is the click target; only a
|
|
254
|
+
// preview nested inside a card opens its own side panel.
|
|
255
|
+
includeEntityLink={!textOnly && includeEntityLink !== false}/>;
|
|
236
256
|
}
|
|
237
257
|
|
|
238
258
|
return <ResolvedEntityPreview size={size}
|
package/src/preview/index.ts
CHANGED
|
@@ -22,4 +22,5 @@ export * from "./components/EmptyValue";
|
|
|
22
22
|
export * from "./components/ImagePreview";
|
|
23
23
|
export * from "./components/ReferencePreview";
|
|
24
24
|
export * from "./components/RelationPreview";
|
|
25
|
+
export * from "./components/InlineEntityListPreview";
|
|
25
26
|
export * from "./components/UserPreview";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ArrayProperty, ReferenceProperty, EntityReference } from "@rebasepro/types";
|
|
2
2
|
import type { PropertyPreviewProps, PreviewSize } from "../../types/components/PropertyPreviewProps";
|
|
3
3
|
import { ReferencePreview } from "../components/ReferencePreview";
|
|
4
|
+
import { useIsNestedEntityPreview } from "../../components/EntityPreviewNesting";
|
|
5
|
+
import { InlineEntityListPreview } from "../components/InlineEntityListPreview";
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* @group Preview components
|
|
@@ -9,9 +11,12 @@ export function ArrayOfReferencesPreview({
|
|
|
9
11
|
propertyKey,
|
|
10
12
|
value,
|
|
11
13
|
property: property,
|
|
12
|
-
size
|
|
14
|
+
size,
|
|
15
|
+
textOnly
|
|
13
16
|
}: PropertyPreviewProps<ArrayProperty>) {
|
|
14
17
|
|
|
18
|
+
const nested = useIsNestedEntityPreview();
|
|
19
|
+
|
|
15
20
|
if (Array.isArray(property?.of)) {
|
|
16
21
|
throw Error("Using array properties instead of single one in `of` in ArrayProperty");
|
|
17
22
|
}
|
|
@@ -20,6 +25,24 @@ export function ArrayOfReferencesPreview({
|
|
|
20
25
|
throw Error("Picked wrong preview component ArrayOfReferencesPreview");
|
|
21
26
|
|
|
22
27
|
const childSize: PreviewSize = size === "medium" ? "medium" : "small";
|
|
28
|
+
const ofProperty = property.of as ReferenceProperty;
|
|
29
|
+
|
|
30
|
+
// Stacked cards inside another preview (or a title slot) turn a list into a
|
|
31
|
+
// wall of boxes: keep it to one wrapping line of links.
|
|
32
|
+
if (nested || textOnly) {
|
|
33
|
+
return <InlineEntityListPreview
|
|
34
|
+
items={(value ?? []) as EntityReference[]}
|
|
35
|
+
renderItem={(reference, index) => <ReferencePreview
|
|
36
|
+
key={`preview_array_ref_${propertyKey}_${index}`}
|
|
37
|
+
disabled={!ofProperty.path}
|
|
38
|
+
previewProperties={ofProperty.admin?.previewProperties}
|
|
39
|
+
size={childSize}
|
|
40
|
+
reference={reference}
|
|
41
|
+
textOnly={textOnly}
|
|
42
|
+
includeId={ofProperty.admin?.includeId}
|
|
43
|
+
includeEntityLink={ofProperty.admin?.includeEntityLink}
|
|
44
|
+
/>}/>;
|
|
45
|
+
}
|
|
23
46
|
|
|
24
47
|
return (
|
|
25
48
|
<div className="flex flex-col w-full">
|
|
@@ -3,6 +3,8 @@ import { EntityRelation } from "@rebasepro/types";
|
|
|
3
3
|
import type { PropertyPreviewProps } from "../../types/components/PropertyPreviewProps";
|
|
4
4
|
import { normalizeToEntityRelation } from "@rebasepro/common";
|
|
5
5
|
import { RelationPreview } from "../components/RelationPreview";
|
|
6
|
+
import { useIsNestedEntityPreview } from "../../components/EntityPreviewNesting";
|
|
7
|
+
import { InlineEntityListPreview } from "../components/InlineEntityListPreview";
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* @group Preview components
|
|
@@ -11,9 +13,12 @@ export function ArrayOfRelationsPreview({
|
|
|
11
13
|
propertyKey,
|
|
12
14
|
value,
|
|
13
15
|
property,
|
|
14
|
-
size
|
|
16
|
+
size,
|
|
17
|
+
textOnly
|
|
15
18
|
}: PropertyPreviewProps<ArrayProperty>) {
|
|
16
19
|
|
|
20
|
+
const nested = useIsNestedEntityPreview();
|
|
21
|
+
|
|
17
22
|
if (Array.isArray(property?.of)) {
|
|
18
23
|
throw Error("Using array properties instead of single one in `of` in ArrayProperty");
|
|
19
24
|
}
|
|
@@ -23,6 +28,25 @@ export function ArrayOfRelationsPreview({
|
|
|
23
28
|
|
|
24
29
|
const ofProperty = property.of as RelationProperty;
|
|
25
30
|
|
|
31
|
+
// See ArrayOfReferencesPreview: nested lists stay on one wrapping line.
|
|
32
|
+
if (nested || textOnly) {
|
|
33
|
+
const relations = ((value ?? []) as unknown[])
|
|
34
|
+
.map(relation => normalizeToEntityRelation(relation))
|
|
35
|
+
.filter((relation): relation is EntityRelation => Boolean(relation));
|
|
36
|
+
return <InlineEntityListPreview
|
|
37
|
+
items={relations}
|
|
38
|
+
renderItem={(relation, index) => <RelationPreview
|
|
39
|
+
key={`preview_array_rel_${propertyKey}_${index}`}
|
|
40
|
+
disabled={!ofProperty.relation}
|
|
41
|
+
previewProperties={ofProperty.admin?.previewProperties}
|
|
42
|
+
size={"small"}
|
|
43
|
+
relation={relation}
|
|
44
|
+
textOnly={textOnly}
|
|
45
|
+
includeId={ofProperty.admin?.includeId}
|
|
46
|
+
includeEntityLink={ofProperty.admin?.includeEntityLink}
|
|
47
|
+
/>}/>;
|
|
48
|
+
}
|
|
49
|
+
|
|
26
50
|
return (
|
|
27
51
|
<div className="flex flex-col w-full gap-0.5">
|
|
28
52
|
{value ?
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
import type { ViewMode, AdminCollection } from "@rebasepro/admin-types";
|
|
3
|
-
import { useLocation } from "react-router
|
|
3
|
+
import { useLocation } from "react-router";
|
|
4
4
|
import { EditViewBinding } from "../components/EditViewBinding";
|
|
5
5
|
import { DetailViewBinding } from "../components/DetailViewBinding";
|
|
6
6
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
7
|
-
import { useNavigate } from "react-router
|
|
7
|
+
import { useNavigate } from "react-router";
|
|
8
8
|
import { CollectionViewBinding } from "../components/CollectionViewBinding/CollectionViewBinding";
|
|
9
9
|
import { NotFoundPage, useUserConfigurationPersistence, useComponentOverride, useNavigationBlocker } from "@rebasepro/app";
|
|
10
10
|
import { resolveOpenEntityMode, resolveViewMode } from "../util/view_mode";
|
|
@@ -22,7 +22,6 @@ export type EntityFormProps<M extends Record<string, unknown>> = {
|
|
|
22
22
|
onSaved?: (params: OnUpdateParams) => void;
|
|
23
23
|
initialDirtyValues?: Partial<M>; // dirty cached entity in memory
|
|
24
24
|
onFormContextReady?: (formContext: FormContext<M>) => void;
|
|
25
|
-
forceActionsAtTheBottom?: boolean;
|
|
26
25
|
className?: string;
|
|
27
26
|
initialStatus: EntityStatus;
|
|
28
27
|
onStatusChange?: (status: EntityStatus) => void;
|
|
@@ -38,11 +37,6 @@ export type EntityFormProps<M extends Record<string, unknown>> = {
|
|
|
38
37
|
*/
|
|
39
38
|
showDefaultActions?: boolean;
|
|
40
39
|
|
|
41
|
-
/**
|
|
42
|
-
* Display the entity path in the form
|
|
43
|
-
*/
|
|
44
|
-
showEntityPath?: boolean;
|
|
45
|
-
|
|
46
40
|
EntityFormActionsComponent?: React.FC<EntityFormActionsProps>;
|
|
47
41
|
|
|
48
42
|
navigateBack?: () => void;
|
package/src/types/fields.tsx
CHANGED
|
@@ -99,6 +99,21 @@ export interface FieldProps<
|
|
|
99
99
|
*/
|
|
100
100
|
includeDescription?: boolean;
|
|
101
101
|
|
|
102
|
+
/**
|
|
103
|
+
* The container is rendering the label and the description itself, so this
|
|
104
|
+
* field should render only its control.
|
|
105
|
+
*
|
|
106
|
+
* This is what the generated form sets. Field types used to disagree about
|
|
107
|
+
* where a label goes — text and number put it inside the input, select,
|
|
108
|
+
* array, storage and read-only put it above — which read as two design
|
|
109
|
+
* systems in one column. The label now belongs to the form, and the binding
|
|
110
|
+
* to the control.
|
|
111
|
+
*
|
|
112
|
+
* A custom field that ignores this still renders its own label, so it
|
|
113
|
+
* degrades to the old look rather than losing its label.
|
|
114
|
+
*/
|
|
115
|
+
hideLabel?: boolean;
|
|
116
|
+
|
|
102
117
|
/**
|
|
103
118
|
* Flag to indicate that the underlying value has been updated in the
|
|
104
119
|
* driver
|
|
@@ -222,6 +237,12 @@ export interface FormContext<M extends Record<string, unknown> = Record<string,
|
|
|
222
237
|
|
|
223
238
|
disabled: boolean;
|
|
224
239
|
|
|
240
|
+
/**
|
|
241
|
+
* A save is in flight, including the autosave debounce, which `formex`
|
|
242
|
+
* cannot report because it never goes through `handleSubmit`.
|
|
243
|
+
*/
|
|
244
|
+
isSaving?: boolean;
|
|
245
|
+
|
|
225
246
|
/**
|
|
226
247
|
* Whether the form context is in read-only detail view mode.
|
|
227
248
|
* Custom entity views can use this to adjust their rendering.
|
|
@@ -258,6 +279,12 @@ export interface PropertyFieldBindingProps<M extends Record<string, unknown> = R
|
|
|
258
279
|
*/
|
|
259
280
|
includeDescription?: boolean;
|
|
260
281
|
|
|
282
|
+
/**
|
|
283
|
+
* The container renders the label and description; render only the control.
|
|
284
|
+
* See the note on {@link FieldProps.hideLabel}.
|
|
285
|
+
*/
|
|
286
|
+
hideLabel?: boolean;
|
|
287
|
+
|
|
261
288
|
/**
|
|
262
289
|
* Has the value of this property been updated in the database while this
|
|
263
290
|
* field is being edited
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"history-g9688IaK.js","names":[],"sources":["../src/components/history/UserChip.tsx","../src/components/history/EntityHistoryEntry.tsx","../src/components/history/EntityHistoryView.tsx"],"sourcesContent":["import { User } from \"@rebasepro/types\";\nimport { Chip, Tooltip } from \"@rebasepro/ui\";\n\nexport function UserChip({ user }: { user: User }) {\n return (\n <Tooltip title={user.email ?? user.uid}>\n <Chip size={\"small\"} className={\"flex items-center\"}>\n {user.photoURL && <img\n className={\"rounded-full w-6 h-6 mr-2\"}\n src={user.photoURL} alt={user.displayName ?? \"User picture\"}/>}\n <span>{user.displayName ?? user.email ?? user.uid}</span>\n </Chip>\n </Tooltip>\n );\n}\n","\nimport type { Property } from \"@rebasepro/types\";\nimport * as React from \"react\";\n\nimport { ArrowLeftIcon, Chip, cls, defaultBorderMixin, iconSize, Tooltip, Typography } from \"@rebasepro/ui\";\nimport { PreviewSize } from \"../../types/components/PropertyPreviewProps\";\nimport { getPropertyInPath } from \"../../util/property_utils\";\nimport { PropertyPreview } from \"../../preview/PropertyPreview\";\nimport { SkeletonPropertyComponent } from \"../../preview/property_previews/SkeletonPropertyComponent\";\nimport { useAuthController } from \"@rebasepro/app\";\nimport { UserChip } from \"./UserChip\";\nimport { HistoryEntryData } from \"../../hooks\";\nimport { getValueInPath } from \"@rebasepro/utils\";\nimport type { AdminCollection } from \"@rebasepro/admin-types\";\n\n/**\n * Recursive deep equality for primitives, arrays and plain objects.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a == null || b == null) return a === b;\n if (typeof a !== typeof b) return false;\n if (typeof a !== \"object\") return false;\n\n if (Array.isArray(a)) {\n if (!Array.isArray(b) || a.length !== (b as unknown[]).length) return false;\n return a.every((item, i) => deepEqual(item, (b as unknown[])[i]));\n }\n\n if (Array.isArray(b)) return false;\n\n const aObj = a as Record<string, unknown>;\n const bObj = b as Record<string, unknown>;\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n if (aKeys.length !== bKeys.length) return false;\n return aKeys.every(key => key in bObj && deepEqual(aObj[key], bObj[key]));\n}\n\nexport type EntityHistoryEntryProps = {\n size: PreviewSize;\n actions?: React.ReactNode;\n collection?: AdminCollection;\n hover?: boolean;\n entry: HistoryEntryData;\n onClick?: (e: React.SyntheticEvent) => void;\n};\n\nfunction PreviousValueView({\n previousValueInPath,\n childProperty,\n propertyKey\n}: {\n previousValueInPath: unknown;\n childProperty: Property;\n propertyKey: string;\n}) {\n if (typeof previousValueInPath === \"string\" || typeof previousValueInPath === \"number\") {\n return <Typography variant={\"caption\"} color={\"secondary\"} className=\"line-through\">\n {previousValueInPath}\n </Typography>;\n } else if (typeof previousValueInPath === \"boolean\") {\n return <Typography variant={\"caption\"} color={\"secondary\"} className=\"line-through\">\n {previousValueInPath ? \"true\" : \"false\"}\n </Typography>;\n } else {\n return <Tooltip\n side={\"left\"}\n title={<div className={\"flex flex-col gap-2\"}>\n <Typography variant={\"caption\"} color={\"secondary\"}>\n Previous value\n </Typography>\n <PropertyPreview\n propertyKey={propertyKey as string}\n value={previousValueInPath as never}\n property={childProperty as Property}\n size={\"small\"}/>\n </div>}>\n <ArrowLeftIcon size={iconSize.smallest} color={\"disabled\"} className={\"mb-1\"}/>\n </Tooltip>\n }\n}\n\n/**\n * Displays a single entity history revision entry.\n * Adapted from the entity_history plugin — now reads from backend API data.\n */\nexport function EntityHistoryEntry({\n actions,\n hover,\n collection,\n size,\n entry\n}: EntityHistoryEntryProps) {\n\n const authController = useAuthController();\n\n const changedFields = entry.changed_fields;\n const previousValues = entry.previous_values;\n const updatedOn = new Date(entry.updated_at);\n const updatedBy = entry.updated_by;\n\n // Resolve user display\n const currentUser = authController.user;\n const userDisplay = updatedBy === currentUser?.uid\n ? currentUser\n : undefined;\n\n return <div className={\"w-full flex flex-col gap-2 mt-4\"}>\n <div className={\"ml-4 flex items-center gap-4\"}>\n <Typography variant={\"body2\"} color={\"secondary\"}>\n {updatedOn.toLocaleString()}\n </Typography>\n <Chip size={\"small\"}>\n {entry.action}\n </Chip>\n {!userDisplay && updatedBy && <Chip size={\"small\"}>{updatedBy}</Chip>}\n {userDisplay && <UserChip user={userDisplay}/>}\n </div>\n <div\n className={cls(\n \"bg-white dark:bg-surface-900\",\n \"min-h-[44px]\",\n \"w-full\",\n \"items-center\",\n hover ? \"hover:bg-surface-accent-50 dark:hover:bg-surface-800\" : \"\",\n size === \"small\" ? \"p-1\" : \"px-2 py-1\",\n \"flex border rounded-lg\",\n defaultBorderMixin\n )}>\n\n {actions}\n\n <div className={\"flex flex-col grow w-full m-1 shrink min-w-0\"}>\n\n {changedFields && collection && changedFields.map((key: string) => {\n const childProperty = getPropertyInPath(collection.properties, key);\n const valueInPath = entry.values ? getValueInPath(entry.values, key) : undefined;\n const previousValueInPath = previousValues ? getValueInPath(previousValues, key) : undefined;\n\n const element = childProperty\n ? <PropertyPreview\n propertyKey={key}\n value={valueInPath as never}\n property={childProperty as Property}\n size={\"small\"}/>\n : <Typography variant={\"body2\"}>\n {typeof valueInPath === \"string\" ? valueInPath : JSON.stringify(valueInPath)}\n </Typography>;\n\n return (\n <div key={\"ref_prev_\" + key}\n className=\"flex w-full my-1 items-center\">\n <Typography variant={\"caption\"}\n color={\"secondary\"}\n className=\"min-w-[140px] md:min-w-[200px] w-1/5 pr-8 overflow-hidden text-ellipsis text-right\">\n {key}\n </Typography>\n <div className=\"w-4/5\">\n {previousValueInPath !== undefined && !deepEqual(previousValueInPath, valueInPath) &&\n <PreviousValueView previousValueInPath={previousValueInPath}\n childProperty={childProperty as Property}\n propertyKey={key}/>\n }\n {element}\n </div>\n </div>\n );\n })}\n\n {(!changedFields || changedFields.length === 0) && (\n <Typography variant={\"caption\"} color={\"secondary\"} className=\"ml-4\">\n {entry.action === \"create\" ? \"Entity created\" :\n entry.action === \"delete\" ? \"Entity deleted\" : \"No field changes recorded\"}\n </Typography>\n )}\n\n </div>\n\n </div>\n </div>;\n}\n","\nimport type { EntityCustomViewParams } from \"@rebasepro/admin-types\";\nimport { useRef, useEffect } from \"react\";\nimport { cls, IconButton, Label, Tooltip, Typography } from \"@rebasepro/ui\";\nimport { ErrorBoundary, HistoryIcon } from \"@rebasepro/ui\";\nimport { EntityHistoryEntry } from \"./EntityHistoryEntry\";\nimport { useSnackbarController, useAuthController } from \"@rebasepro/app\";\nimport { ConfirmationDialog } from \"@rebasepro/app\";\nimport { useState } from \"react\";\nimport { useHistory } from \"../../hooks/useHistory\";\n\n/**\n * Entity history tab view. Shows a paginated list of entity revisions\n * fetched from the backend API. Supports infinite scroll and revert.\n */\nexport function EntityHistoryView<M extends Record<string, unknown>>({\n entity,\n collection,\n formContext\n}: EntityCustomViewParams<M>) {\n\n const snackbarController = useSnackbarController();\n const authController = useAuthController();\n const dirty = formContext?.formex.dirty;\n\n const slug = collection.slug;\n const entityId = entity?.id;\n\n const {\n entries,\n isLoading,\n hasMore,\n loadMore,\n revert\n } = useHistory({\n slug,\n entityId,\n enabled: !!entityId,\n pageSize: 10\n });\n\n const [revertHistoryId, setRevertHistoryId] = useState<string | undefined>();\n const [isReverting, setIsReverting] = useState(false);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const loadMoreRef = useRef<HTMLDivElement>(null);\n\n // Intersection observer for infinite scroll\n useEffect(() => {\n const currentContainer = containerRef.current;\n const currentLoadMore = loadMoreRef.current;\n\n if (!currentContainer || !currentLoadMore || !hasMore || isLoading) return;\n\n const observer = new IntersectionObserver(\n (observerEntries) => {\n if (observerEntries[0].isIntersecting && hasMore && !isLoading) {\n loadMore();\n }\n },\n {\n root: currentContainer,\n rootMargin: \"0px 0px 200px 0px\",\n threshold: 0.01\n }\n );\n\n observer.observe(currentLoadMore);\n\n return () => observer.disconnect();\n }, [hasMore, isLoading, entries.length, loadMore]);\n\n if (!entity) {\n return <div className=\"flex items-center justify-center h-full\">\n <Label>History is only available for existing entities</Label>\n </div>;\n }\n\n async function doRevert(historyId: string) {\n setIsReverting(true);\n try {\n const revertedValues = await revert(historyId);\n setRevertHistoryId(undefined);\n\n // Reset the form with the reverted values so the UI updates\n // immediately without requiring a page refresh.\n if (formContext?.formex?.resetForm && revertedValues) {\n formContext.formex.resetForm({\n values: revertedValues as M,\n submitCount: 0,\n touched: {}\n });\n }\n\n snackbarController.open({\n message: \"Reverted to selected version\",\n type: \"info\"\n });\n } catch (error) {\n console.error(\"Error reverting entity:\", error);\n snackbarController.open({\n message: \"Error reverting entity\",\n type: \"error\"\n });\n } finally {\n setIsReverting(false);\n }\n }\n\n const revertEntry = revertHistoryId\n ? entries.find(e => e.id === revertHistoryId)\n : undefined;\n\n return <div\n ref={containerRef}\n className={cls(\"relative flex-1 h-full overflow-auto w-full flex flex-col gap-4 p-8\")}>\n <div className=\"flex flex-col gap-2 max-w-6xl mx-auto w-full\">\n\n <Typography variant={\"h5\"} className={\"mt-24 ml-4\"}>\n History\n </Typography>\n\n {isLoading && entries.length === 0 && (\n <div className=\"flex flex-col gap-4 mt-8 ml-4\">\n {[1, 2, 3].map(i => (\n <div key={i} className=\"flex flex-col gap-2 animate-pulse\">\n <div className=\"h-4 w-48 bg-surface-200 dark:bg-surface-700 rounded\"/>\n <div className=\"h-12 w-full bg-surface-100 dark:bg-surface-900 rounded-lg border border-surface-200 dark:border-surface-700\"/>\n </div>\n ))}\n </div>\n )}\n\n {!isLoading && entries.length === 0 && <>\n <Label className={\"ml-4 mt-8\"}>\n No history available\n </Label>\n <Typography variant={\"caption\"} className={\"ml-4\"}>\n When you save a entity, a new version is created and stored in the history.\n </Typography>\n </>}\n\n {entries.map((entry) => (\n <div key={entry.id} className=\"flex flex-cols gap-2 w-full\">\n <EntityHistoryEntry\n entry={entry}\n collection={collection}\n size={\"medium\"}\n actions={\n <Tooltip title={\"Revert to this version\"}\n className={\"m-2 grow-0 self-start\"}>\n <IconButton\n onClick={() => {\n if (dirty) {\n snackbarController.open({\n message: \"Please save or discard your changes before reverting\",\n type: \"warning\"\n });\n } else {\n setRevertHistoryId(entry.id);\n }\n }}>\n <HistoryIcon/>\n </IconButton>\n </Tooltip>\n }\n />\n </div>\n ))}\n\n {/* Load more sentinel */}\n {entries.length > 0 && (\n <div ref={loadMoreRef} className=\"py-4 text-center\">\n {isLoading && <Label>Loading more...</Label>}\n {!hasMore && entries.length > 10 && <Label>No more history available</Label>}\n </div>\n )}\n </div>\n\n <ErrorBoundary>\n <ConfirmationDialog\n open={Boolean(revertHistoryId)}\n onAccept={() => {\n if (revertHistoryId) doRevert(revertHistoryId);\n }}\n onCancel={() => setRevertHistoryId(undefined)}\n title={<Typography variant={\"subtitle2\"}>Revert data to this version?</Typography>}\n body={revertEntry\n ? <div className=\"p-4\">\n <Typography variant={\"caption\"} color={\"secondary\"}>\n This will save the entity with the values from{\" \"}\n {new Date(revertEntry.updated_at).toLocaleString()}.\n A new history entry will be created for the revert.\n </Typography>\n </div>\n : null\n }\n />\n </ErrorBoundary>\n </div>;\n}\n"],"mappings":"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"}
|