@asteby/metacore-runtime-react 18.1.0 → 18.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/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @asteby/metacore-runtime-react
2
2
 
3
+ ## 18.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - fc14b4f: Relation (one_to_many) cells now show the FK product image: when an FK column's backend-resolved sibling carries an `image`, the relation row renders a thumbnail + label instead of plain text. The nested line-item edit form drops server-managed/audit columns (`id`, `created_at`, `updated_at`, `deleted_at`, `created_by(_id)`, `updated_by(_id)`) so they no longer render as `[object Object]` inputs, and the nested `dynamic_select` is seeded with the existing value's label/image from the initial record so the trigger shows the name + thumbnail instead of a raw UUID. The image-url resolver context moved to its own `image-url-context` module to avoid a circular import.
8
+
9
+ ## 18.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 3cd35a1: Consolidate the record dialog into the SDK: tz-aware dates + FK image/label in
14
+ view & edit; ops consumes.
15
+
16
+ `DynamicRecordDialog` (the single, SDK-owned declarative record modal) absorbs
17
+ the improvements that had diverged into the ops fork and adds parity-plus:
18
+ - **tz-aware dates** — date/datetime/timestamp fields render via the SDK's
19
+ `formatDateCell(value, renderAs, locale, timeZone?)`; a new optional
20
+ `timeZone` prop pins instants to the org IANA zone (pure `date` to UTC) instead
21
+ of hand-rolled `toLocaleDateString`.
22
+ - **FK image/label** — relation fields (`ref`/`searchEndpoint`/`dynamic_select`
23
+ or any `*_id`) render a read-only `OptionLead` (thumbnail / icon / color dot) +
24
+ resolved label in **view** mode, and the searchable `DynamicSelectField` picker
25
+ in **edit** mode. Resolution prefers the table-served sibling object, falling
26
+ back to the canonical options endpoint.
27
+ - **resolved objects, nil-UUID, created_by avatar** — `{value,label}` / `{name}`
28
+ relation & user objects render their label (never raw JSON); the nil UUID
29
+ elides to an em-dash; `created_by`/avatar resolvers show name + avatar.
30
+ - **pro option badges** — enum/option fields render the served color/icon.
31
+ - **one_to_many child panels** — `DynamicRelations` (line items, etc.) below the
32
+ scalar fields in view (read-only) and edit (add/edit/delete), skipped on create.
33
+ - **instant render** via `initialRecord` seeding, `onOpenFullPage` footer link,
34
+ localized titles/messages, and `onSaved(record)` handing back the persisted row.
35
+
36
+ New optional props: `getImageUrl`, `timeZone`, `onOpenFullPage`, `initialRecord`.
37
+ `onSaved` now receives the persisted record. `ViewValue` and the `FieldDef` /
38
+ `FieldOption` / `GetImageUrl` types are exported so hosts can reuse the view
39
+ renderer (e.g. a full detail page). Fully backward compatible.
40
+
3
41
  ## 18.1.0
4
42
 
5
43
  ### Minor Changes
@@ -1,4 +1,51 @@
1
1
  import type { ModelSchema } from './types';
2
+ import { type GetImageUrl } from '../image-url-context';
3
+ export type { GetImageUrl };
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
- onSaved?: () => void;
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":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AA0F1C,MAAM,WAAW,wBAAwB;IACrC,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;QAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;IAClF;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;QAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;IACpG;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB;AA0DD,wBAAgB,mBAAmB,CAAC,EAChC,IAAI,EACJ,YAAY,EACZ,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,MAAM,GACT,EAAE,wBAAwB,+BAsP1B"}
1
+ {"version":3,"file":"dynamic-record.d.ts","sourceRoot":"","sources":["../../src/dialogs/dynamic-record.tsx"],"names":[],"mappings":"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"}