@asteby/metacore-runtime-react 18.0.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 CHANGED
@@ -1,5 +1,52 @@
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
+
35
+ ## 18.1.0
36
+
37
+ ### Minor Changes
38
+
39
+ - 4e601ec: Org-timezone-aware date display in dynamic tables.
40
+
41
+ `formatDateCell` and the column factory (`defaultGetDynamicColumns` /
42
+ `makeDefaultGetDynamicColumns`) now accept an optional IANA `timeZone`, and
43
+ `DynamicTable` exposes a matching `timeZone` prop. When provided, datetime /
44
+ timestamp(tz) cells are rendered in that zone via the native
45
+ `Intl.DateTimeFormat` (instead of the viewer's browser zone), so instants no
46
+ longer day-shift; pure `date` columns are pinned to UTC so they never roll to
47
+ the previous/next day. Omitting `timeZone` preserves the exact legacy date-fns
48
+ formatting (fully backward-compatible).
49
+
3
50
  ## 18.0.0
4
51
 
5
52
  ### Patch 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
- 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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"}