@asteby/metacore-runtime-react 18.1.0 → 18.2.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/CHANGELOG.md +32 -0
- package/dist/dialogs/dynamic-record.d.ts +86 -2
- package/dist/dialogs/dynamic-record.d.ts.map +1 -1
- package/dist/dialogs/dynamic-record.js +306 -88
- package/dist/dynamic-select-field.d.ts +21 -0
- package/dist/dynamic-select-field.d.ts.map +1 -1
- package/dist/dynamic-select-field.js +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/dialogs/dynamic-record.tsx +476 -114
- package/src/dynamic-select-field.tsx +2 -2
- package/src/index.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @asteby/metacore-runtime-react
|
|
2
2
|
|
|
3
|
+
## 18.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3cd35a1: Consolidate the record dialog into the SDK: tz-aware dates + FK image/label in
|
|
8
|
+
view & edit; ops consumes.
|
|
9
|
+
|
|
10
|
+
`DynamicRecordDialog` (the single, SDK-owned declarative record modal) absorbs
|
|
11
|
+
the improvements that had diverged into the ops fork and adds parity-plus:
|
|
12
|
+
- **tz-aware dates** — date/datetime/timestamp fields render via the SDK's
|
|
13
|
+
`formatDateCell(value, renderAs, locale, timeZone?)`; a new optional
|
|
14
|
+
`timeZone` prop pins instants to the org IANA zone (pure `date` to UTC) instead
|
|
15
|
+
of hand-rolled `toLocaleDateString`.
|
|
16
|
+
- **FK image/label** — relation fields (`ref`/`searchEndpoint`/`dynamic_select`
|
|
17
|
+
or any `*_id`) render a read-only `OptionLead` (thumbnail / icon / color dot) +
|
|
18
|
+
resolved label in **view** mode, and the searchable `DynamicSelectField` picker
|
|
19
|
+
in **edit** mode. Resolution prefers the table-served sibling object, falling
|
|
20
|
+
back to the canonical options endpoint.
|
|
21
|
+
- **resolved objects, nil-UUID, created_by avatar** — `{value,label}` / `{name}`
|
|
22
|
+
relation & user objects render their label (never raw JSON); the nil UUID
|
|
23
|
+
elides to an em-dash; `created_by`/avatar resolvers show name + avatar.
|
|
24
|
+
- **pro option badges** — enum/option fields render the served color/icon.
|
|
25
|
+
- **one_to_many child panels** — `DynamicRelations` (line items, etc.) below the
|
|
26
|
+
scalar fields in view (read-only) and edit (add/edit/delete), skipped on create.
|
|
27
|
+
- **instant render** via `initialRecord` seeding, `onOpenFullPage` footer link,
|
|
28
|
+
localized titles/messages, and `onSaved(record)` handing back the persisted row.
|
|
29
|
+
|
|
30
|
+
New optional props: `getImageUrl`, `timeZone`, `onOpenFullPage`, `initialRecord`.
|
|
31
|
+
`onSaved` now receives the persisted record. `ViewValue` and the `FieldDef` /
|
|
32
|
+
`FieldOption` / `GetImageUrl` types are exported so hosts can reuse the view
|
|
33
|
+
renderer (e.g. a full detail page). Fully backward compatible.
|
|
34
|
+
|
|
3
35
|
## 18.1.0
|
|
4
36
|
|
|
5
37
|
### Minor Changes
|
|
@@ -1,4 +1,51 @@
|
|
|
1
1
|
import type { ModelSchema } from './types';
|
|
2
|
+
/** Resolves a (possibly relative) storage path into a fetchable URL. */
|
|
3
|
+
export type GetImageUrl = (path: string | null | undefined) => string;
|
|
4
|
+
export interface FieldOption {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
/**
|
|
8
|
+
* Pro option metadata the backend serves for enum/option fields (e.g.
|
|
9
|
+
* `product_type`) so the view renders a colored/iconed badge instead of the
|
|
10
|
+
* raw value ("storable" → "Almacenable"). All optional and driven entirely
|
|
11
|
+
* by the served metadata — plain options stay plain.
|
|
12
|
+
*/
|
|
13
|
+
color?: string;
|
|
14
|
+
icon?: string;
|
|
15
|
+
image?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface FieldDef {
|
|
18
|
+
key: string;
|
|
19
|
+
label: string;
|
|
20
|
+
type: 'text' | 'textarea' | 'select' | 'search' | 'number' | 'date' | 'email' | 'url' | 'boolean' | 'image' | string;
|
|
21
|
+
required?: boolean;
|
|
22
|
+
options?: FieldOption[];
|
|
23
|
+
defaultValue?: any;
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
readonly?: boolean;
|
|
26
|
+
hidden?: boolean;
|
|
27
|
+
searchEndpoint?: string;
|
|
28
|
+
filterBy?: string;
|
|
29
|
+
/**
|
|
30
|
+
* FK target model the kernel auto-derives for a belongs_to column (>=
|
|
31
|
+
* v0.46.x serves it on modal fields, not just action fields). When present
|
|
32
|
+
* the native form renders an async searchable picker (`DynamicSelectField`)
|
|
33
|
+
* against `/api/options/<ref>?field=id` — with option thumbnails when the
|
|
34
|
+
* remote rows carry an `image` — instead of a raw FK text input. View mode
|
|
35
|
+
* shows the resolved thumbnail + label. Tolerates the snake_case
|
|
36
|
+
* `source`/`relation` aliases the manifest may serve.
|
|
37
|
+
*/
|
|
38
|
+
ref?: string;
|
|
39
|
+
source?: string;
|
|
40
|
+
relation?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Explicit renderer hint. Wins over the `type` switch: `dynamic_select`
|
|
43
|
+
* forces the searchable picker, `upload` forces the file dropzone. Lets the
|
|
44
|
+
* kernel opt a plain text/uuid column into a rich widget without changing
|
|
45
|
+
* its SQL type. Unknown values fall through to the `type`-based default.
|
|
46
|
+
*/
|
|
47
|
+
widget?: string;
|
|
48
|
+
}
|
|
2
49
|
export interface DynamicRecordDialogProps {
|
|
3
50
|
open: boolean;
|
|
4
51
|
onOpenChange: (open: boolean) => void;
|
|
@@ -6,7 +53,10 @@ export interface DynamicRecordDialogProps {
|
|
|
6
53
|
model: string;
|
|
7
54
|
recordId?: string | null;
|
|
8
55
|
endpoint?: string;
|
|
9
|
-
|
|
56
|
+
/** Fired after a successful save; receives the persisted record (when the
|
|
57
|
+
* backend returns it) so callers — e.g. the inline-create bridge behind a
|
|
58
|
+
* dynamic_select "+" — can auto-select the new row. */
|
|
59
|
+
onSaved?: (record?: any) => void;
|
|
10
60
|
/**
|
|
11
61
|
* Optional override invoked instead of the default `POST` when the dialog
|
|
12
62
|
* is in `create` mode. Hosts may use this to route writes through custom
|
|
@@ -43,6 +93,40 @@ export interface DynamicRecordDialogProps {
|
|
|
43
93
|
* the action.
|
|
44
94
|
*/
|
|
45
95
|
onEdit?: () => void;
|
|
96
|
+
/**
|
|
97
|
+
* Deliberate escape hatch: open the full `/m/:model/:id` detail page (with
|
|
98
|
+
* cross-module related records) for records too heavy for the modal.
|
|
99
|
+
* Rendered as a footer link in view mode when provided.
|
|
100
|
+
*/
|
|
101
|
+
onOpenFullPage?: () => void;
|
|
102
|
+
/**
|
|
103
|
+
* The row object the table already loaded. When provided, the dialog renders
|
|
104
|
+
* instantly from it (no spinner) and reuses the table's pro siblings — the
|
|
105
|
+
* resolved relation (`row.category = {value,label}`), served option lists and
|
|
106
|
+
* image urls. A background fetch only fills in fields the list row omitted.
|
|
107
|
+
*/
|
|
108
|
+
initialRecord?: Record<string, any> | null;
|
|
109
|
+
/**
|
|
110
|
+
* Host resolver turning a (possibly relative) storage path into a fetchable
|
|
111
|
+
* URL for images/avatars/thumbnails. Defaults to identity. Pass the host's
|
|
112
|
+
* `getImageUrl` so addon-served relative paths render.
|
|
113
|
+
*/
|
|
114
|
+
getImageUrl?: GetImageUrl;
|
|
115
|
+
/**
|
|
116
|
+
* Org IANA timezone (e.g. `America/Mexico_City`). Threaded into the tz-aware
|
|
117
|
+
* `formatDateCell` so datetime/timestamp instants render in the org zone
|
|
118
|
+
* regardless of the viewer's browser timezone. Pure `date` values pin to UTC.
|
|
119
|
+
*/
|
|
120
|
+
timeZone?: string;
|
|
46
121
|
}
|
|
47
|
-
export declare function DynamicRecordDialog({ open, onOpenChange, mode, model, recordId, endpoint, onSaved, onCreate, onUpdate, defaults, schema, onDelete, onEdit, }: DynamicRecordDialogProps): import("react").JSX.Element;
|
|
122
|
+
export declare function DynamicRecordDialog({ open, onOpenChange, mode, model, recordId, endpoint, onSaved, onCreate, onUpdate, defaults, schema, onDelete, onEdit, onOpenFullPage, initialRecord, getImageUrl, timeZone, }: DynamicRecordDialogProps): import("react").JSX.Element;
|
|
123
|
+
export declare function ViewValue({ field, value: rawValue, record, getImageUrl: getImageUrlProp, timeZone: timeZoneProp, }: {
|
|
124
|
+
field: FieldDef;
|
|
125
|
+
value: any;
|
|
126
|
+
record: any;
|
|
127
|
+
/** Optional override; when omitted falls back to the nearest provider/identity. */
|
|
128
|
+
getImageUrl?: GetImageUrl;
|
|
129
|
+
/** Optional override; when omitted falls back to the nearest provider. */
|
|
130
|
+
timeZone?: string;
|
|
131
|
+
}): import("react").JSX.Element;
|
|
48
132
|
//# sourceMappingURL=dynamic-record.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-record.d.ts","sourceRoot":"","sources":["../../src/dialogs/dynamic-record.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dynamic-record.d.ts","sourceRoot":"","sources":["../../src/dialogs/dynamic-record.tsx"],"names":[],"mappings":"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"}
|