@rebasepro/admin 0.13.0 → 0.13.1-canary.g18cfeb7
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-CjXkWZ64.js → CollectionEditorDialog-CUFXevVg.js} +3 -3
- package/dist/{CollectionEditorDialog-CjXkWZ64.js.map → CollectionEditorDialog-CUFXevVg.js.map} +1 -1
- package/dist/{PropertyEditView-W8I3YV89.js → PropertyEditView-DDUC7giL.js} +2 -2
- package/dist/{PropertyEditView-W8I3YV89.js.map → PropertyEditView-DDUC7giL.js.map} +1 -1
- package/dist/{RouterCollectionsStudioView-BsLTNoqX.js → RouterCollectionsStudioView-vzS848Gf.js} +9 -13
- package/dist/RouterCollectionsStudioView-vzS848Gf.js.map +1 -0
- package/dist/collection_editor/serializable_types.d.ts +1 -0
- package/dist/collection_editor_ui.js +4 -4
- package/dist/components/AdditionalFieldValue.d.ts +25 -0
- package/dist/components/CollectionViewBinding/CollectionViewBinding.d.ts +16 -0
- package/dist/components/CollectionViewBinding/SlotValue.d.ts +63 -0
- package/dist/components/CollectionViewBinding/SplitListCloseButton.d.ts +17 -4
- package/dist/components/CollectionViewBinding/SplitListShowButton.d.ts +12 -0
- package/dist/components/CollectionViewBinding/usePreviewSlots.d.ts +55 -5
- package/dist/components/DetailViewBinding.d.ts +15 -0
- package/dist/components/DrawerNavigationGroup.d.ts +9 -6
- package/dist/components/DrawerNavigationItem.d.ts +16 -6
- package/dist/components/EditViewBinding.d.ts +30 -1
- package/dist/components/EntityDisplayHeader.d.ts +53 -0
- package/dist/components/EntityIdentityBar.d.ts +43 -1
- package/dist/components/EntityViewBinding.d.ts +60 -6
- package/dist/components/RebaseLayout.d.ts +1 -1
- package/dist/components/RebaseShell.d.ts +1 -1
- package/dist/components/RelationSelector.d.ts +8 -1
- package/dist/components/UserSelector.d.ts +8 -1
- package/dist/components/app/Scaffold.d.ts +9 -3
- package/dist/components/index.d.ts +2 -0
- package/dist/{export-J79rMoNj.js → export-5bl2EoSs.js} +2 -2
- package/dist/{export-J79rMoNj.js.map → export-5bl2EoSs.js.map} +1 -1
- package/dist/form/components/FieldBlock.d.ts +58 -4
- package/dist/form/components/FormRail.d.ts +13 -0
- package/dist/form/components/FormSections.d.ts +15 -1
- package/dist/form/components/useRailVisible.d.ts +5 -4
- package/dist/form/form_utils.d.ts +38 -1
- package/dist/{history-D7L_JlLO.js → history-BuKKAhoY.js} +4 -4
- package/dist/{history-D7L_JlLO.js.map → history-BuKKAhoY.js.map} +1 -1
- package/dist/hooks/useEntityDisplay.d.ts +102 -0
- package/dist/hooks/useEntityDisplayTitle.d.ts +18 -9
- package/dist/{import-BvYl--U4.js → import-BhdWs34H.js} +3 -3
- package/dist/{import-BvYl--U4.js.map → import-BhdWs34H.js.map} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +152 -57
- package/dist/index.js.map +1 -1
- package/dist/preview/compact_text.d.ts +23 -0
- package/dist/preview/components/BooleanPreview.d.ts +3 -1
- package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +1 -1
- package/dist/preview/property_previews/ArrayOneOfPreview.d.ts +1 -1
- package/dist/preview/property_previews/ArrayPropertyPreview.d.ts +1 -1
- package/dist/preview/property_previews/MapPropertyPreview.d.ts +1 -1
- package/dist/preview/property_previews/StringPropertyPreview.d.ts +1 -1
- package/dist/routes/RebaseRoute.d.ts +1 -1
- package/dist/types/components/PropertyPreviewProps.d.ts +19 -0
- package/dist/util/number_format.d.ts +14 -0
- package/dist/util/previews.d.ts +9 -2
- package/dist/{util-GiwPgxnL.js → util-DNG7iK0w.js} +3756 -2300
- package/dist/util-DNG7iK0w.js.map +1 -0
- package/package.json +9 -9
- package/src/collection_editor/serializable_types.ts +1 -0
- package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +9 -11
- package/src/components/AdditionalFieldValue.tsx +68 -0
- package/src/components/CollectionTableBinding/CollectionTableBinding.tsx +7 -8
- package/src/components/CollectionTableBinding/PropertyTableCell.tsx +2 -2
- package/src/components/CollectionTableBinding/column_utils.tsx +15 -6
- package/src/components/CollectionTableBinding/internal/popup_field/PopupFormField.tsx +2 -2
- package/src/components/CollectionViewBinding/BoardCardBinding.tsx +26 -27
- package/src/components/CollectionViewBinding/CollectionListViewBinding.tsx +723 -348
- package/src/components/CollectionViewBinding/CollectionViewActions.tsx +1 -1
- package/src/components/CollectionViewBinding/CollectionViewBinding.tsx +38 -8
- package/src/components/CollectionViewBinding/EntityCardBinding.tsx +23 -36
- package/src/components/CollectionViewBinding/SlotValue.tsx +156 -0
- package/src/components/CollectionViewBinding/SplitListCloseButton.tsx +23 -7
- package/src/components/CollectionViewBinding/SplitListShowButton.tsx +28 -0
- package/src/components/CollectionViewBinding/SplitListView.tsx +33 -2
- package/src/components/CollectionViewBinding/useBoardDataController.tsx +12 -3
- package/src/components/CollectionViewBinding/usePreviewSlots.ts +183 -64
- package/src/components/CollectionViewBinding/utils.ts +7 -4
- package/src/components/DefaultDrawer.tsx +19 -23
- package/src/components/DetailViewBinding.tsx +93 -56
- package/src/components/DrawerNavigationGroup.tsx +16 -39
- package/src/components/DrawerNavigationItem.tsx +44 -16
- package/src/components/EditViewBinding.tsx +215 -42
- package/src/components/EntityDisplayHeader.tsx +170 -0
- package/src/components/EntityIdentityBar.tsx +163 -23
- package/src/components/EntityInspector.tsx +24 -6
- package/src/components/EntityPreviewBinding.tsx +58 -18
- package/src/components/EntityViewBinding.tsx +342 -41
- package/src/components/InlineEntityPreview.tsx +10 -10
- package/src/components/RebaseLayout.tsx +2 -2
- package/src/components/RebaseShell.tsx +2 -2
- package/src/components/ReferenceTable/SelectionTableBinding.tsx +4 -2
- package/src/components/RelationSelector.tsx +15 -4
- package/src/components/SideDialogs.tsx +15 -3
- package/src/components/SidePanelBinding.tsx +122 -66
- package/src/components/UserSelector.tsx +15 -4
- package/src/components/app/Scaffold.tsx +112 -10
- package/src/components/history/LastEditedByIndicator.tsx +7 -12
- package/src/components/index.ts +3 -0
- package/src/data_import/utils/data.ts +9 -1
- package/src/form/EntityForm.tsx +64 -52
- package/src/form/EntityFormBinding.tsx +24 -11
- package/src/form/PropertyFieldBinding.tsx +2 -2
- package/src/form/components/FieldBlock.tsx +80 -10
- package/src/form/components/FormRail.tsx +19 -2
- package/src/form/components/FormSections.tsx +32 -5
- package/src/form/components/StorageUploadProgress.tsx +9 -3
- package/src/form/components/useRailVisible.tsx +5 -4
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +2 -2
- package/src/form/field_bindings/BinaryFieldBinding.tsx +10 -5
- package/src/form/field_bindings/BlockFieldBinding.tsx +3 -3
- package/src/form/field_bindings/GeopointFieldBinding.tsx +23 -16
- package/src/form/field_bindings/MapFieldBinding.tsx +2 -2
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +13 -7
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +7 -1
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +7 -1
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -1
- package/src/form/field_bindings/RelationFieldBinding.tsx +5 -2
- package/src/form/field_bindings/RepeatFieldBinding.tsx +3 -3
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +2 -2
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +4 -1
- package/src/form/field_bindings/VectorFieldBinding.tsx +6 -4
- package/src/form/form_utils.ts +78 -0
- package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +29 -5
- package/src/hooks/useEntityDisplay.tsx +262 -0
- package/src/hooks/useEntityDisplayTitle.tsx +27 -38
- package/src/index.ts +9 -1
- package/src/preview/PropertyPreview.tsx +25 -5
- package/src/preview/compact_text.ts +68 -0
- package/src/preview/components/BooleanPreview.tsx +5 -2
- package/src/preview/components/StorageThumbnail.tsx +5 -2
- package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +6 -3
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +26 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +10 -1
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +10 -1
- package/src/preview/property_previews/MapPropertyPreview.tsx +52 -1
- package/src/preview/property_previews/NumberPropertyPreview.tsx +9 -1
- package/src/preview/property_previews/StringPropertyPreview.tsx +8 -5
- package/src/routes/RebaseRoute.tsx +62 -4
- package/src/types/components/PropertyPreviewProps.tsx +21 -0
- package/src/util/number_format.ts +46 -0
- package/src/util/previews.ts +8 -55
- package/src/util/property_utils.tsx +6 -1
- package/dist/RouterCollectionsStudioView-BsLTNoqX.js.map +0 -1
- package/dist/util-GiwPgxnL.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/admin",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.13.
|
|
4
|
+
"version": "0.13.1-canary.g18cfeb7",
|
|
5
5
|
"description": "Rebase CMS — content management views, forms, and routing",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/rebaseco"
|
|
@@ -83,14 +83,14 @@
|
|
|
83
83
|
"react-dropzone": "^19.1.1",
|
|
84
84
|
"react-use-measure": "^2.1.7",
|
|
85
85
|
"zod": "^4.4.3",
|
|
86
|
-
"@rebasepro/admin-types": "0.13.
|
|
87
|
-
"@rebasepro/
|
|
88
|
-
"@rebasepro/
|
|
89
|
-
"@rebasepro/inference": "0.13.
|
|
90
|
-
"@rebasepro/
|
|
91
|
-
"@rebasepro/
|
|
92
|
-
"@rebasepro/types": "0.13.
|
|
93
|
-
"@rebasepro/
|
|
86
|
+
"@rebasepro/admin-types": "0.13.1-canary.g18cfeb7",
|
|
87
|
+
"@rebasepro/common": "0.13.1-canary.g18cfeb7",
|
|
88
|
+
"@rebasepro/forms": "0.13.1-canary.g18cfeb7",
|
|
89
|
+
"@rebasepro/inference": "0.13.1-canary.g18cfeb7",
|
|
90
|
+
"@rebasepro/app": "0.13.1-canary.g18cfeb7",
|
|
91
|
+
"@rebasepro/utils": "0.13.1-canary.g18cfeb7",
|
|
92
|
+
"@rebasepro/types": "0.13.1-canary.g18cfeb7",
|
|
93
|
+
"@rebasepro/ui": "0.13.1-canary.g18cfeb7"
|
|
94
94
|
},
|
|
95
95
|
"peerDependencies": {
|
|
96
96
|
"react": ">=19.2.7",
|
|
@@ -155,6 +155,7 @@ export interface SerializableAdminRelationOptions extends SerializableAdminBaseO
|
|
|
155
155
|
fixedFilter?: FilterValues<string>;
|
|
156
156
|
includeId?: boolean;
|
|
157
157
|
includeEntityLink?: boolean;
|
|
158
|
+
renderInForm?: boolean;
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
/** JSON-serializable version of `AdminArrayOptions`. */
|
|
@@ -17,6 +17,7 @@ import { CollectionsConfigController } from "../../types/config_controller";
|
|
|
17
17
|
import { CollectionStudioView } from "./CollectionStudioView";
|
|
18
18
|
import type { CollectionEditorExtensionProps } from "../../extensibility_types";
|
|
19
19
|
import type { AdminCollection } from "@rebasepro/admin-types";
|
|
20
|
+
import { readStoredString, writeStoredString } from "@rebasepro/utils";
|
|
20
21
|
|
|
21
22
|
export interface CollectionsStudioViewProps extends CollectionEditorExtensionProps {
|
|
22
23
|
configController: CollectionsConfigController;
|
|
@@ -77,21 +78,18 @@ export function CollectionsStudioView({
|
|
|
77
78
|
const collections = collectionsProp ?? configController.collections ?? [];
|
|
78
79
|
|
|
79
80
|
// ── Sidebar sizing ──────────────────────────────────────────────────
|
|
81
|
+
// Checked, not just parsed: `parseFloat` answers NaN for anything it cannot
|
|
82
|
+
// read, and a NaN pane size lays the sidebar out to nothing — with the bad
|
|
83
|
+
// value still in storage on reload. `SplitListView.getSavedPanelSize` is the
|
|
84
|
+
// same read, done this way.
|
|
80
85
|
const [sidebarSize, setSidebarSize] = useState(() => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
} catch (e) {
|
|
85
|
-
return 25;
|
|
86
|
-
}
|
|
86
|
+
const saved = readStoredString("rebase_collections_editor_sidebar_size");
|
|
87
|
+
const parsed = saved === null ? NaN : parseFloat(saved);
|
|
88
|
+
return Number.isFinite(parsed) && parsed > 0 && parsed < 100 ? parsed : 25;
|
|
87
89
|
});
|
|
88
90
|
|
|
89
91
|
useEffect(() => {
|
|
90
|
-
|
|
91
|
-
localStorage.setItem("rebase_collections_editor_sidebar_size", sidebarSize.toString());
|
|
92
|
-
} catch (e) {
|
|
93
|
-
// ignore local storage error
|
|
94
|
-
}
|
|
92
|
+
writeStoredString("rebase_collections_editor_sidebar_size", sidebarSize.toString());
|
|
95
93
|
}, [sidebarSize]);
|
|
96
94
|
|
|
97
95
|
return (
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { AdditionalFieldDelegate, RebaseContext } from "@rebasepro/admin-types";
|
|
2
|
+
import type { Entity } from "@rebasepro/types";
|
|
3
|
+
import React, { useEffect, useState } from "react";
|
|
4
|
+
|
|
5
|
+
export interface AdditionalFieldValueProps<M extends Record<string, unknown>> {
|
|
6
|
+
field: AdditionalFieldDelegate<M>;
|
|
7
|
+
entity: Entity<M>;
|
|
8
|
+
context: RebaseContext;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Renders an `additionalFields` entry that supplies a `value` rather than a
|
|
13
|
+
* `Builder`.
|
|
14
|
+
*
|
|
15
|
+
* `value` is typed `string | number | Promise<string | number>`, and the promise
|
|
16
|
+
* arm has been part of that type from the start — the CSV export awaits it
|
|
17
|
+
* correctly. Every *renderer* called `.toString()` on the result instead, so an
|
|
18
|
+
* async value drew the literal text `[object Promise]` in the cell: a shape the
|
|
19
|
+
* type promised, that worked in one of its two consumers, and failed silently in
|
|
20
|
+
* the other. That is what made the obvious port of a FireCMS column — one that
|
|
21
|
+
* fetches a title from a subcollection — look supported and not be.
|
|
22
|
+
*
|
|
23
|
+
* Three call sites had the same three lines copied between them (the table cell,
|
|
24
|
+
* the form and the read-only record), which is why the bug reached all three.
|
|
25
|
+
* Now there is one.
|
|
26
|
+
*/
|
|
27
|
+
export function AdditionalFieldValue<M extends Record<string, unknown>>({
|
|
28
|
+
field,
|
|
29
|
+
entity,
|
|
30
|
+
context
|
|
31
|
+
}: AdditionalFieldValueProps<M>) {
|
|
32
|
+
|
|
33
|
+
const [resolved, setResolved] = useState<string | number | undefined>(() => {
|
|
34
|
+
const value = field.value?.({ entity, context });
|
|
35
|
+
// A synchronous value is available on the first render, so it never
|
|
36
|
+
// flashes empty on its way in.
|
|
37
|
+
return isPromise(value) ? undefined : value;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
const value = field.value?.({ entity, context });
|
|
42
|
+
if (!isPromise(value)) {
|
|
43
|
+
setResolved(value);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// The row may scroll out, or the record change, before this lands.
|
|
48
|
+
let live = true;
|
|
49
|
+
value.then(
|
|
50
|
+
result => {
|
|
51
|
+
if (live) setResolved(result);
|
|
52
|
+
},
|
|
53
|
+
error => {
|
|
54
|
+
if (live) setResolved(undefined);
|
|
55
|
+
console.warn(`[rebase] Additional field "${field.key}" failed to resolve:`, error);
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
return () => {
|
|
59
|
+
live = false;
|
|
60
|
+
};
|
|
61
|
+
}, [field, entity, context]);
|
|
62
|
+
|
|
63
|
+
return <>{resolved === undefined || resolved === null ? null : String(resolved)}</>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function isPromise(value: unknown): value is Promise<string | number | undefined> {
|
|
67
|
+
return typeof (value as Promise<unknown> | undefined)?.then === "function";
|
|
68
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AdditionalFieldDelegate, AdminCollection } from "@rebasepro/admin-types";
|
|
2
|
+
import { AdditionalFieldValue } from "../AdditionalFieldValue";
|
|
2
3
|
import React, { useCallback, useMemo, useRef } from "react";
|
|
3
4
|
import { Entity, User, Property } from "@rebasepro/types";
|
|
4
5
|
import { CollectionSize, RebaseContext } from "@rebasepro/admin-types";
|
|
@@ -16,7 +17,7 @@ import { propertiesToColumns } from "./column_utils";
|
|
|
16
17
|
import { ErrorView } from "@rebasepro/app";
|
|
17
18
|
import { SelectableTable } from "../SelectableTable/SelectableTable";
|
|
18
19
|
import { cls } from "@rebasepro/ui";
|
|
19
|
-
import { getRowHeight } from "@rebasepro/app";
|
|
20
|
+
import { getRowHeight, isDisabled } from "@rebasepro/app";
|
|
20
21
|
import { getValueInPath } from "@rebasepro/utils";
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -146,7 +147,7 @@ export const CollectionTableBinding = function CollectionTableBinding<M extends
|
|
|
146
147
|
propertyKey,
|
|
147
148
|
entity
|
|
148
149
|
}) ?? columnCustom?.resolvedProperty;
|
|
149
|
-
if (!property
|
|
150
|
+
if (!property || !isDisabled(property)) {
|
|
150
151
|
disabled = false;
|
|
151
152
|
}
|
|
152
153
|
|
|
@@ -214,12 +215,10 @@ export const CollectionTableBinding = function CollectionTableBinding<M extends
|
|
|
214
215
|
|
|
215
216
|
const child: React.ReactNode = Builder
|
|
216
217
|
? <Builder entity={entity} context={context}/>
|
|
217
|
-
:
|
|
218
|
-
{additionalField
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
})?.toString()}
|
|
222
|
-
</>;
|
|
218
|
+
: <AdditionalFieldValue
|
|
219
|
+
field={additionalField}
|
|
220
|
+
entity={entity}
|
|
221
|
+
context={context as RebaseContext}/>;
|
|
223
222
|
|
|
224
223
|
return (
|
|
225
224
|
<EntityTableCell
|
|
@@ -18,7 +18,7 @@ import { EntityTableCellActions } from "./internal/EntityTableCellActions";
|
|
|
18
18
|
import { useSelectableTableController } from "../SelectableTable/SelectableTableContext";
|
|
19
19
|
import { useClearRestoreValue } from "../../form/useClearRestoreValue";
|
|
20
20
|
import { getRowHeight } from "@rebasepro/app";
|
|
21
|
-
import { isReadOnly } from "@rebasepro/app";
|
|
21
|
+
import { isDisabled, isReadOnly } from "@rebasepro/app";
|
|
22
22
|
import { TableRelationField } from "./fields/TableRelationField";
|
|
23
23
|
import { TableRelationSelectorField } from "./fields/TableRelationSelectorField";
|
|
24
24
|
|
|
@@ -95,7 +95,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
|
|
|
95
95
|
const customPreview = Boolean(property.admin?.Preview);
|
|
96
96
|
const readOnlyProperty = isReadOnly(property);
|
|
97
97
|
const disabledTooltip: string | undefined = typeof property.admin?.disabled === "object" ? property.admin?.disabled.disabledMessage : undefined;
|
|
98
|
-
const disabled = readonly || disabledProp ||
|
|
98
|
+
const disabled = readonly || disabledProp || isDisabled(property);
|
|
99
99
|
|
|
100
100
|
const validation = useMemo(() => mapPropertyToZod({
|
|
101
101
|
property,
|
|
@@ -39,15 +39,24 @@ export function propertiesToColumns<M extends Record<string, unknown>>({ propert
|
|
|
39
39
|
const disabledFilter = Boolean(fixedFilter);
|
|
40
40
|
return Object.entries<Property>(properties)
|
|
41
41
|
.flatMap(([key, property]) => getColumnKeysForProperty(property, key))
|
|
42
|
-
.
|
|
42
|
+
.flatMap(({
|
|
43
43
|
key,
|
|
44
44
|
disabled
|
|
45
45
|
}) => {
|
|
46
|
-
const property = getResolvedPropertyInPath(properties, key) as Property;
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
const property = getResolvedPropertyInPath(properties, key) as Property | undefined;
|
|
47
|
+
// One unresolvable key used to throw, and this runs inside the
|
|
48
|
+
// memo that builds the table's columns — so a single bad column
|
|
49
|
+
// took down the header, the rows and the empty state together,
|
|
50
|
+
// leaving a blank pane with nothing to attribute it to. A column
|
|
51
|
+
// that cannot be resolved is one column the table cannot offer;
|
|
52
|
+
// say so and carry the rest. Same choice, and now the same
|
|
53
|
+
// behaviour, as `getSortablePropertyOptions` below.
|
|
54
|
+
if (!property) {
|
|
55
|
+
console.warn(`No property found in path "${key}" — skipping that column.`);
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
49
58
|
const filterable = filterableProperty(property, false, engine);
|
|
50
|
-
return {
|
|
59
|
+
return [{
|
|
51
60
|
key: key as string,
|
|
52
61
|
align: getTableCellAlignment(property),
|
|
53
62
|
icon: getIconForProperty(property, "small"),
|
|
@@ -63,7 +72,7 @@ export function propertiesToColumns<M extends Record<string, unknown>>({ propert
|
|
|
63
72
|
AdditionalHeaderWidget: AdditionalHeaderWidget
|
|
64
73
|
? ({ onHover }: { onHover: boolean }) => <AdditionalHeaderWidget property={property} propertyKey={key} onHover={onHover}/>
|
|
65
74
|
: undefined
|
|
66
|
-
} satisfies VirtualTableColumn;
|
|
75
|
+
} satisfies VirtualTableColumn];
|
|
67
76
|
});
|
|
68
77
|
}
|
|
69
78
|
|
|
@@ -16,7 +16,7 @@ import { getPropertyInPath } from "../../../../util/property_utils";
|
|
|
16
16
|
import { PropertyFieldBinding, zodToFormErrors } from "../../../../form";
|
|
17
17
|
import { useAuthController, useCustomizationController, useData, useRebaseContext } from "@rebasepro/app";
|
|
18
18
|
import type { OnCellValueChangeParams } from "@rebasepro/app";
|
|
19
|
-
import { isReadOnly } from "@rebasepro/app";
|
|
19
|
+
import { isDisabled, isReadOnly } from "@rebasepro/app";
|
|
20
20
|
import type { AdminCollection } from "@rebasepro/admin-types";
|
|
21
21
|
|
|
22
22
|
interface PopupFormFieldProps<M extends Record<string, unknown>> {
|
|
@@ -295,7 +295,7 @@ export function PopupFormFieldInternal<M extends Record<string, unknown>>({
|
|
|
295
295
|
const fieldProps: PropertyFieldBindingProps<M> | undefined = propertyKey && property
|
|
296
296
|
? {
|
|
297
297
|
propertyKey: propertyKey as string,
|
|
298
|
-
disabled: isSubmitting || isReadOnly(property) ||
|
|
298
|
+
disabled: isSubmitting || isReadOnly(property) || isDisabled(property),
|
|
299
299
|
property,
|
|
300
300
|
includeDescription: false,
|
|
301
301
|
underlyingValueHasChanged: false,
|
|
@@ -6,7 +6,8 @@ import { PropertyPreview } from "../../preview";
|
|
|
6
6
|
import { useAuthController, useCustomizationController } from "@rebasepro/app";
|
|
7
7
|
import { IconForView } from "@rebasepro/app";
|
|
8
8
|
import { BoardItemViewProps } from "@rebasepro/ui";
|
|
9
|
-
import { useCollectionSlotKeys,
|
|
9
|
+
import { useCollectionSlotKeys, useEntitySlots } from "./usePreviewSlots";
|
|
10
|
+
import { SlotValue, TagChips } from "./SlotValue";
|
|
10
11
|
import type { AdminCollection } from "@rebasepro/admin-types";
|
|
11
12
|
|
|
12
13
|
export type BoardCardBindingProps<M extends Record<string, unknown> = Record<string, unknown>> = BoardItemViewProps<Entity<M>> & {
|
|
@@ -46,13 +47,10 @@ function BoardCardBindingInner<M extends Record<string, unknown> = Record<string
|
|
|
46
47
|
customizationController.propertyConfigs
|
|
47
48
|
);
|
|
48
49
|
|
|
49
|
-
const slots =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
slotKeys
|
|
54
|
-
),
|
|
55
|
-
[entity, collection, slotKeys]
|
|
50
|
+
const slots = useEntitySlots(
|
|
51
|
+
entity as Entity<Record<string, unknown>>,
|
|
52
|
+
collection as AdminCollection<Record<string, unknown>>,
|
|
53
|
+
slotKeys
|
|
56
54
|
);
|
|
57
55
|
|
|
58
56
|
const handleClick = useCallback((e: React.MouseEvent) => {
|
|
@@ -126,13 +124,7 @@ function BoardCardBindingInner<M extends Record<string, unknown> = Record<string
|
|
|
126
124
|
selectionEnabled && "group-hover/card:opacity-30",
|
|
127
125
|
selected && "opacity-0"
|
|
128
126
|
)}>
|
|
129
|
-
<
|
|
130
|
-
property={slots.image.property}
|
|
131
|
-
propertyKey={slots.image.propertyKey}
|
|
132
|
-
size="small"
|
|
133
|
-
value={slots.image.value}
|
|
134
|
-
fill={true}
|
|
135
|
-
/>
|
|
127
|
+
<SlotValue slot={slots.image} size="small" fill={true}/>
|
|
136
128
|
</div>
|
|
137
129
|
) : (
|
|
138
130
|
<div className={cls(
|
|
@@ -177,12 +169,7 @@ function BoardCardBindingInner<M extends Record<string, unknown> = Record<string
|
|
|
177
169
|
{/* Title slot */}
|
|
178
170
|
<div className="line-clamp-2 text-sm font-medium">
|
|
179
171
|
{slots.title ? (
|
|
180
|
-
<
|
|
181
|
-
propertyKey={slots.title.propertyKey}
|
|
182
|
-
value={slots.title.value}
|
|
183
|
-
property={slots.title.property}
|
|
184
|
-
size="small"
|
|
185
|
-
/>
|
|
172
|
+
<SlotValue slot={slots.title} size="small"/>
|
|
186
173
|
) : (
|
|
187
174
|
<span className="text-surface-500">{entity.id}</span>
|
|
188
175
|
)}
|
|
@@ -193,12 +180,7 @@ function BoardCardBindingInner<M extends Record<string, unknown> = Record<string
|
|
|
193
180
|
{typeof slots.subtitle.value === "string" ? (
|
|
194
181
|
<Markdown source={slots.subtitle.value} size="small" />
|
|
195
182
|
) : (
|
|
196
|
-
<
|
|
197
|
-
propertyKey={slots.subtitle.propertyKey}
|
|
198
|
-
value={slots.subtitle.value}
|
|
199
|
-
property={slots.subtitle.property}
|
|
200
|
-
size="small"
|
|
201
|
-
/>
|
|
183
|
+
<SlotValue slot={slots.subtitle} size="small"/>
|
|
202
184
|
)}
|
|
203
185
|
</div>
|
|
204
186
|
) : (
|
|
@@ -228,6 +210,23 @@ function BoardCardBindingInner<M extends Record<string, unknown> = Record<string
|
|
|
228
210
|
)}
|
|
229
211
|
</div>
|
|
230
212
|
)}
|
|
213
|
+
|
|
214
|
+
{/* Tags slot */}
|
|
215
|
+
{slots.tags && (
|
|
216
|
+
<div className="flex items-center gap-1 mt-1 flex-wrap">
|
|
217
|
+
<TagChips slot={slots.tags} max={3}/>
|
|
218
|
+
</div>
|
|
219
|
+
)}
|
|
220
|
+
|
|
221
|
+
{/* Date slot — a board card is a list row without the image, and
|
|
222
|
+
the row shows it. The status is deliberately not repeated
|
|
223
|
+
here: on a board grouped by it, the column header is already
|
|
224
|
+
saying it. */}
|
|
225
|
+
{slots.date && (
|
|
226
|
+
<div className="text-[10px] text-surface-500 dark:text-surface-400 mt-1">
|
|
227
|
+
{slots.date.formatted}
|
|
228
|
+
</div>
|
|
229
|
+
)}
|
|
231
230
|
</div>
|
|
232
231
|
</div>
|
|
233
232
|
</div>
|