@aiaiai-pt/design-system 0.46.0 → 0.46.2
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.
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
dateToDateOnly,
|
|
55
55
|
geoJsonPointToLonLat,
|
|
56
56
|
lonLatToGeoJsonPoint,
|
|
57
|
+
mapInitialCenter,
|
|
57
58
|
storedFileDescriptor,
|
|
58
59
|
widgetKind,
|
|
59
60
|
} from "./action-form-renderer-widgets";
|
|
@@ -1007,6 +1008,7 @@
|
|
|
1007
1008
|
{onoutofbounds}
|
|
1008
1009
|
error={fieldError ?? hydrated.error ?? geoError}
|
|
1009
1010
|
label={String(parameter.label ?? key)}
|
|
1011
|
+
center={mapInitialCenter(parameter)}
|
|
1010
1012
|
value={hydrated.coords ?? undefined}
|
|
1011
1013
|
onchange={(coords: [number, number]) => setValue(key, lonLatToGeoJsonPoint(coords))}
|
|
1012
1014
|
/>
|
|
@@ -1027,9 +1029,10 @@
|
|
|
1027
1029
|
{onoutofbounds}
|
|
1028
1030
|
error={fieldError ?? geoError}
|
|
1029
1031
|
label={String(parameter.label ?? key)}
|
|
1030
|
-
center={
|
|
1031
|
-
|
|
1032
|
-
|
|
1032
|
+
center={mapInitialCenter(parameter) ??
|
|
1033
|
+
(Array.isArray(parameter.default_value)
|
|
1034
|
+
? (parameter.default_value as [number, number])
|
|
1035
|
+
: undefined)}
|
|
1033
1036
|
value={Array.isArray(values[key])
|
|
1034
1037
|
? (values[key] as [number, number])
|
|
1035
1038
|
: undefined}
|
|
@@ -27,6 +27,17 @@ export declare function geoJsonPointToLonLat(value: unknown): {
|
|
|
27
27
|
};
|
|
28
28
|
/** #39 — serialize a placed pin back onto the GeoJSON wire shape. */
|
|
29
29
|
export declare function lonLatToGeoJsonPoint(coords: [number, number]): GeoJsonPoint;
|
|
30
|
+
/** #46 — the map picker's INITIAL CENTRE, from its declared home:
|
|
31
|
+
* `ui_schema.map.initial_center` ([lon, lat]). A viewport hint is
|
|
32
|
+
* presentation, not a value — it lives in ui_schema so `default_value`
|
|
33
|
+
* keeps its one meaning (the initial VALUE). Malformed/absent → undefined
|
|
34
|
+
* (the picker keeps its own default). Consumers still passing a bare
|
|
35
|
+
* [lon, lat] `default_value` on a legacy geo param keep working via the
|
|
36
|
+
* renderer's fallback (deprecated; removed next minor). */
|
|
37
|
+
export declare function mapInitialCenter(parameter: {
|
|
38
|
+
ui_schema?: unknown;
|
|
39
|
+
[key: string]: unknown;
|
|
40
|
+
}): [number, number] | undefined;
|
|
30
41
|
export type StoredFile = {
|
|
31
42
|
name: string;
|
|
32
43
|
url?: string;
|
|
@@ -95,6 +95,37 @@ export function lonLatToGeoJsonPoint(coords: [number, number]): GeoJsonPoint {
|
|
|
95
95
|
return { type: "Point", coordinates: [coords[0], coords[1]] };
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
/** #46 — the map picker's INITIAL CENTRE, from its declared home:
|
|
99
|
+
* `ui_schema.map.initial_center` ([lon, lat]). A viewport hint is
|
|
100
|
+
* presentation, not a value — it lives in ui_schema so `default_value`
|
|
101
|
+
* keeps its one meaning (the initial VALUE). Malformed/absent → undefined
|
|
102
|
+
* (the picker keeps its own default). Consumers still passing a bare
|
|
103
|
+
* [lon, lat] `default_value` on a legacy geo param keep working via the
|
|
104
|
+
* renderer's fallback (deprecated; removed next minor). */
|
|
105
|
+
export function mapInitialCenter(parameter: {
|
|
106
|
+
ui_schema?: unknown;
|
|
107
|
+
[key: string]: unknown;
|
|
108
|
+
}): [number, number] | undefined {
|
|
109
|
+
const ui =
|
|
110
|
+
parameter.ui_schema && typeof parameter.ui_schema === "object"
|
|
111
|
+
? (parameter.ui_schema as Record<string, unknown>)
|
|
112
|
+
: null;
|
|
113
|
+
const map =
|
|
114
|
+
ui?.map && typeof ui.map === "object"
|
|
115
|
+
? (ui.map as Record<string, unknown>)
|
|
116
|
+
: null;
|
|
117
|
+
const c = map?.initial_center;
|
|
118
|
+
if (
|
|
119
|
+
Array.isArray(c) &&
|
|
120
|
+
c.length >= 2 &&
|
|
121
|
+
typeof c[0] === "number" &&
|
|
122
|
+
typeof c[1] === "number"
|
|
123
|
+
) {
|
|
124
|
+
return [c[0], c[1]];
|
|
125
|
+
}
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
|
|
98
129
|
export type StoredFile = { name: string; url?: string };
|
|
99
130
|
|
|
100
131
|
/** #40 — normalize a file param's stored-current value (the edit form's
|
|
@@ -38,15 +38,27 @@ export declare function isIsoTimestamp(value: unknown): value is string;
|
|
|
38
38
|
/** Locale date for an ISO timestamp (date-only, UTC-stable so SSR == hydrate);
|
|
39
39
|
* the raw string when unparseable. */
|
|
40
40
|
export declare function formatTimestamp(value: string, locale: string): string;
|
|
41
|
+
/** Locale date+time for an ISO timestamp (UTC-stable so SSR == hydrate); the
|
|
42
|
+
* raw string when unparseable. Unlike `formatTimestamp` (date-only), this keeps
|
|
43
|
+
* the time — for a schema `datetime` field the staff admin renders the full
|
|
44
|
+
* instant (incl. 00:00), since a datetime's time is meaningful data (SLA
|
|
45
|
+
* stamps, acknowledgements). A `date`-typed field uses `formatTimestamp`. */
|
|
46
|
+
export declare function formatDateTime(value: string, locale: string): string;
|
|
41
47
|
/**
|
|
42
48
|
* The single display boundary for list cells / detail values. Formats a value
|
|
43
|
-
* as a locale date when it's a timestamp —
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
49
|
+
* as a locale date/datetime when it's a timestamp — the caller drives which
|
|
50
|
+
* from the schema FIELD TYPE (not a value-shape guess):
|
|
51
|
+
* - `treatAsDate` → date-only (a `date`-typed field)
|
|
52
|
+
* - `treatAsDateTime` → date+time (a `datetime`-typed field; time is data)
|
|
53
|
+
* - neither → value-shape: an ISO-timestamp STRING renders
|
|
54
|
+
* date-only (the portal, whose public schema strips
|
|
55
|
+
* typed created_at/updated_at). Unchanged.
|
|
56
|
+
* Everything else goes through `formatScalar` (with the host's object policy).
|
|
57
|
+
* `treatAsDate` wins if a caller mistakenly sets both.
|
|
47
58
|
*/
|
|
48
59
|
export declare function displayCell(value: unknown, locale: string, opts?: {
|
|
49
60
|
treatAsDate?: boolean;
|
|
61
|
+
treatAsDateTime?: boolean;
|
|
50
62
|
objectFallback?: ObjectFallback;
|
|
51
63
|
}): string;
|
|
52
64
|
/** Operator copy for a status value (falls back to the raw value). `labels` is
|
|
@@ -92,20 +92,49 @@ export function formatTimestamp(value: string, locale: string): string {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/** Locale date+time for an ISO timestamp (UTC-stable so SSR == hydrate); the
|
|
96
|
+
* raw string when unparseable. Unlike `formatTimestamp` (date-only), this keeps
|
|
97
|
+
* the time — for a schema `datetime` field the staff admin renders the full
|
|
98
|
+
* instant (incl. 00:00), since a datetime's time is meaningful data (SLA
|
|
99
|
+
* stamps, acknowledgements). A `date`-typed field uses `formatTimestamp`. */
|
|
100
|
+
export function formatDateTime(value: string, locale: string): string {
|
|
101
|
+
const parsed = new Date(value);
|
|
102
|
+
if (Number.isNaN(parsed.getTime())) return value;
|
|
103
|
+
try {
|
|
104
|
+
return new Intl.DateTimeFormat(locale || "en", {
|
|
105
|
+
dateStyle: "medium",
|
|
106
|
+
timeStyle: "short",
|
|
107
|
+
timeZone: "UTC",
|
|
108
|
+
}).format(parsed);
|
|
109
|
+
} catch {
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
95
114
|
/**
|
|
96
115
|
* The single display boundary for list cells / detail values. Formats a value
|
|
97
|
-
* as a locale date when it's a timestamp —
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
116
|
+
* as a locale date/datetime when it's a timestamp — the caller drives which
|
|
117
|
+
* from the schema FIELD TYPE (not a value-shape guess):
|
|
118
|
+
* - `treatAsDate` → date-only (a `date`-typed field)
|
|
119
|
+
* - `treatAsDateTime` → date+time (a `datetime`-typed field; time is data)
|
|
120
|
+
* - neither → value-shape: an ISO-timestamp STRING renders
|
|
121
|
+
* date-only (the portal, whose public schema strips
|
|
122
|
+
* typed created_at/updated_at). Unchanged.
|
|
123
|
+
* Everything else goes through `formatScalar` (with the host's object policy).
|
|
124
|
+
* `treatAsDate` wins if a caller mistakenly sets both.
|
|
101
125
|
*/
|
|
102
126
|
export function displayCell(
|
|
103
127
|
value: unknown,
|
|
104
128
|
locale: string,
|
|
105
|
-
opts: {
|
|
129
|
+
opts: {
|
|
130
|
+
treatAsDate?: boolean;
|
|
131
|
+
treatAsDateTime?: boolean;
|
|
132
|
+
objectFallback?: ObjectFallback;
|
|
133
|
+
} = {},
|
|
106
134
|
): string {
|
|
107
|
-
if (
|
|
108
|
-
return formatTimestamp(value, locale);
|
|
135
|
+
if (typeof value === "string" && value) {
|
|
136
|
+
if (opts.treatAsDate) return formatTimestamp(value, locale);
|
|
137
|
+
if (opts.treatAsDateTime) return formatDateTime(value, locale);
|
|
109
138
|
}
|
|
110
139
|
if (isIsoTimestamp(value)) return formatTimestamp(value, locale);
|
|
111
140
|
return formatScalar(value, { objectFallback: opts.objectFallback });
|