@protobase/ui 0.22.2 → 0.22.3
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/app/export/cells.js +4 -1
- package/dist/app/field-editor.js +1 -1
- package/dist/app/pages/field-value.js +1 -1
- package/dist/app/record-page.js +2 -2
- package/dist/data-grid/cell-text.js +2 -2
- package/dist/data-grid/cells.js +2 -1
- package/dist/filter-panel/filter-config.js +2 -0
- package/dist/format/date.js +5 -4
- package/dist/live/columns-from-model.js +1 -0
- package/dist/live/display-value.js +11 -6
- package/dist/live/filter-string.js +4 -0
- package/dist/package.js +1 -1
- package/dist/shell/assets/{app-ByxJVEUs.js → app-3MBLkJAB.js} +14 -14
- package/dist/shell/assets/export-worker-C1djGgjD.js +2 -0
- package/dist/shell/assets/{index-Dkcn0zHH.js → index-K4WBo5hS.js} +1 -1
- package/dist/shell/assets/{maplibre-CAXiHBgj.js → maplibre-CPwgBgXC.js} +1 -1
- package/dist/shell/assets/{markdown-content-B7XDhlLn.js → markdown-content-kdNPOEJy.js} +1 -1
- package/dist/shell/assets/{record-map-BcLvshZy.js → record-map-C57pIfol.js} +1 -1
- package/dist/shell/assets/{records-map-BYeO0Ega.js → records-map-B8_M8kjM.js} +1 -1
- package/dist/shell/assets/{shared-protobase-ui-CVanihMA.js → shared-protobase-ui-BRE7ZUBU.js} +1 -1
- package/dist/shell/index.html +3 -3
- package/dist/shell/protobase.shell.json +1 -1
- package/package.json +4 -4
- package/dist/shell/assets/export-worker-BoAr3vuF.js +0 -2
package/dist/app/export/cells.js
CHANGED
|
@@ -19,7 +19,10 @@ const csvText = (column, value, labels, mode) => {
|
|
|
19
19
|
const { field, hints } = column;
|
|
20
20
|
if (field.type === "file") return fileText(value, mode);
|
|
21
21
|
if (field.type === "relation") return mode === "shown" ? relationLabel(column, value, labels) : String(value);
|
|
22
|
-
if (mode === "shown") return displayValue(field, value,
|
|
22
|
+
if (mode === "shown") return displayValue(field, value, {
|
|
23
|
+
...hints,
|
|
24
|
+
format: void 0
|
|
25
|
+
});
|
|
23
26
|
if (typeof value === "object") return JSON.stringify(value);
|
|
24
27
|
return String(value);
|
|
25
28
|
};
|
package/dist/app/field-editor.js
CHANGED
|
@@ -106,7 +106,7 @@ const BuiltInEditor = ({ field, hints, value, stored, relationLabel, relationTo,
|
|
|
106
106
|
})
|
|
107
107
|
});
|
|
108
108
|
if (!isEditable(field) || locked) return /* @__PURE__ */ jsx("div", {
|
|
109
|
-
title: valueTitle(field, stored),
|
|
109
|
+
title: valueTitle(field, stored, void 0, hints),
|
|
110
110
|
className: cn("py-1.5 tabular-nums", field.type === "decimal" || field.type === "integer" ? "font-medium" : "text-muted-foreground", multiline && "whitespace-pre-line break-words"),
|
|
111
111
|
children: displayValue(field, stored, hints)
|
|
112
112
|
});
|
|
@@ -87,7 +87,7 @@ const BuiltInValue = ({ model, field, value, format, relationLabel }) => {
|
|
|
87
87
|
children: text
|
|
88
88
|
});
|
|
89
89
|
return /* @__PURE__ */ jsx("span", {
|
|
90
|
-
title: valueTitle(field, value),
|
|
90
|
+
title: valueTitle(field, value, void 0, hints),
|
|
91
91
|
className: cn(hints.format === "code" && "font-mono text-xs", (field.type === "decimal" || field.type === "integer") && "tabular-nums", hints.multiline && "whitespace-pre-line break-words"),
|
|
92
92
|
children: text
|
|
93
93
|
});
|
package/dist/app/record-page.js
CHANGED
|
@@ -303,7 +303,7 @@ const LoadedRecord = ({ model, recordKey, stored, preview }) => {
|
|
|
303
303
|
format: contact,
|
|
304
304
|
value: text
|
|
305
305
|
}) : /* @__PURE__ */ jsx("strong", {
|
|
306
|
-
title: valueTitle(field, value),
|
|
306
|
+
title: valueTitle(field, value, void 0, hint(name)),
|
|
307
307
|
className: hint(name)?.multiline ? "whitespace-pre-line break-words" : void 0,
|
|
308
308
|
children: text
|
|
309
309
|
});
|
|
@@ -524,7 +524,7 @@ const LoadedRecord = ({ model, recordKey, stored, preview }) => {
|
|
|
524
524
|
return [{
|
|
525
525
|
label: hint(name)?.label ?? humanize(name),
|
|
526
526
|
value: known(name) ? /* @__PURE__ */ jsx("span", {
|
|
527
|
-
title: valueTitle(field, stored.record[name]),
|
|
527
|
+
title: valueTitle(field, stored.record[name], void 0, hint(name)),
|
|
528
528
|
children: displayValue(field, stored.record[name], hint(name))
|
|
529
529
|
}) : /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-24" })
|
|
530
530
|
}];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { formatMoney } from "../format/money.js";
|
|
2
2
|
import { formatInt, formatPercent, formatSigned } from "../format/number.js";
|
|
3
|
-
import { formatDate, formatDateTime } from "../format/date.js";
|
|
3
|
+
import { formatDate, formatDateTime, formatRelativeTime } from "../format/date.js";
|
|
4
4
|
import { userById } from "../mocks/users.js";
|
|
5
5
|
import { fileShown } from "../live/file-values.js";
|
|
6
6
|
import { enumLabel } from "@protobase/schema";
|
|
@@ -15,7 +15,7 @@ const cellText = (spec, value) => {
|
|
|
15
15
|
case "id": return String(value);
|
|
16
16
|
case "money": return `${formatMoney(Number(value), spec.currency, spec.decimals)}${spec.suffix ?? ""}`;
|
|
17
17
|
case "date": return formatDate(Number(value));
|
|
18
|
-
case "datetime": return formatDateTime(Number(value));
|
|
18
|
+
case "datetime": return spec.relative ? formatRelativeTime(Math.round((Date.now() - Number(value)) / 1e3)) : formatDateTime(Number(value));
|
|
19
19
|
case "number": return `${formatInt(Number(value))}${spec.suffix ?? ""}`;
|
|
20
20
|
case "signed": return `${formatSigned(Number(value))}${spec.suffix ?? ""}`;
|
|
21
21
|
case "percent": return Number(value) === 0 ? "—" : formatPercent(Number(value));
|
package/dist/data-grid/cells.js
CHANGED
|
@@ -2,6 +2,7 @@ import { cn } from "../lib/cn.js";
|
|
|
2
2
|
import { Avatar } from "../primitives/avatar.js";
|
|
3
3
|
import { Badge } from "../primitives/badge.js";
|
|
4
4
|
import { viewerZone, zoneLabel } from "../format/zone.js";
|
|
5
|
+
import { formatDateTime } from "../format/date.js";
|
|
5
6
|
import { userById } from "../mocks/users.js";
|
|
6
7
|
import { fileShown, shownImage } from "../live/file-values.js";
|
|
7
8
|
import { cellText } from "./cell-text.js";
|
|
@@ -39,7 +40,7 @@ const renderCell = (spec, value) => {
|
|
|
39
40
|
});
|
|
40
41
|
case "datetime": return /* @__PURE__ */ jsx("span", {
|
|
41
42
|
className: "tabular-nums text-muted-foreground",
|
|
42
|
-
title: `Shown in ${zoneLabel(Number(value), viewerZone())}`,
|
|
43
|
+
title: spec.relative ? formatDateTime(Number(value)) : `Shown in ${zoneLabel(Number(value), viewerZone())}`,
|
|
43
44
|
children: text
|
|
44
45
|
});
|
|
45
46
|
case "number": return /* @__PURE__ */ jsx("span", {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//#region src/filter-panel/filter-config.ts
|
|
2
2
|
const defaultDatePresets = [
|
|
3
|
+
"today",
|
|
3
4
|
"7d",
|
|
4
5
|
"30d",
|
|
5
6
|
"year"
|
|
@@ -7,6 +8,7 @@ const defaultDatePresets = [
|
|
|
7
8
|
const datePresetLabels = {
|
|
8
9
|
today: "Today",
|
|
9
10
|
yesterday: "Yesterday",
|
|
11
|
+
"24h": "Last 24 hours",
|
|
10
12
|
"7d": "Last 7 days",
|
|
11
13
|
"30d": "Last 30 days",
|
|
12
14
|
"90d": "Last 90 days",
|
package/dist/format/date.js
CHANGED
|
@@ -79,11 +79,12 @@ const units = [
|
|
|
79
79
|
["hour", 3600],
|
|
80
80
|
["minute", 60]
|
|
81
81
|
];
|
|
82
|
-
/** "5 minutes ago", "yesterday", "3
|
|
82
|
+
/** "5 minutes ago", "yesterday", "in 3 hours"; `seconds` is how long ago it was, negative for a time to come. */
|
|
83
83
|
const formatRelativeTime = (seconds) => {
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
const away = Math.abs(seconds);
|
|
85
|
+
const [unit, size] = units.find(([, size]) => away >= size) ?? ["second", 1];
|
|
86
|
+
if (unit === "second" && away < 45) return "just now";
|
|
87
|
+
return relative.format(-Math.sign(seconds) * Math.floor(away / size), unit);
|
|
87
88
|
};
|
|
88
89
|
//#endregion
|
|
89
90
|
export { formatAgo, formatDate, formatDateTime, formatDayRange, formatDayShort, formatMonth, formatRelativeTime, formatTime, formatWeekday, formatWeekdayDate };
|
|
@@ -92,6 +92,7 @@ const columnsFromModel = (resource, view, highlight = [], names = listColumnName
|
|
|
92
92
|
...field.type === "enum" && viewField?.valueColors && { colors: viewField.valueColors },
|
|
93
93
|
...field.type === "enum" && viewField?.badgeShape && { shape: viewField.badgeShape },
|
|
94
94
|
...viewField?.suffix !== void 0 && { suffix: viewField.suffix },
|
|
95
|
+
...kind === "datetime" && viewField?.format === "relative" && { relative: true },
|
|
95
96
|
...kind === "money" && viewField?.decimals !== void 0 && { decimals: viewField.decimals },
|
|
96
97
|
...kind === "money" && {
|
|
97
98
|
currency: "EUR",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { viewerZone, zoneLabel } from "../format/zone.js";
|
|
2
|
-
import { formatDate, formatDateTime } from "../format/date.js";
|
|
2
|
+
import { formatDate, formatDateTime, formatRelativeTime } from "../format/date.js";
|
|
3
3
|
import { fileShown } from "./file-values.js";
|
|
4
4
|
import { enumLabel } from "@protobase/schema";
|
|
5
5
|
//#region src/live/display-value.ts
|
|
@@ -8,13 +8,16 @@ const affixed = (text, hints) => `${hints.prefix ?? ""}${text}${hints.suffix ??
|
|
|
8
8
|
* A read-only rendering of a stored value, following the view's prefix, suffix, decimals, format and value label hints; a
|
|
9
9
|
* timestamp on the clock of `zone`, the viewer's unless given.
|
|
10
10
|
*/
|
|
11
|
-
const displayValue = (field, value, hints = {}, zone = viewerZone()) => {
|
|
11
|
+
const displayValue = (field, value, hints = {}, zone = viewerZone(), now = Date.now()) => {
|
|
12
12
|
if (value === null || value === void 0 || value === "") return "—";
|
|
13
13
|
switch (field.type) {
|
|
14
14
|
case "boolean": return value ? "Yes" : "No";
|
|
15
15
|
case "file": return fileShown(value)?.name ?? "—";
|
|
16
16
|
case "enum": return enumLabel(String(value), hints.valueLabels);
|
|
17
|
-
case "timestamp":
|
|
17
|
+
case "timestamp": {
|
|
18
|
+
const ms = Date.parse(String(value));
|
|
19
|
+
return hints.format === "relative" ? formatRelativeTime(Math.round((now - ms) / 1e3)) : formatDateTime(ms, zone);
|
|
20
|
+
}
|
|
18
21
|
case "date": return formatDate(Date.parse(String(value)));
|
|
19
22
|
case "decimal": {
|
|
20
23
|
const text = hints.decimals === void 0 ? String(value) : Number(value).toFixed(hints.decimals);
|
|
@@ -29,11 +32,13 @@ const displayValue = (field, value, hints = {}, zone = viewerZone()) => {
|
|
|
29
32
|
default: return typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
30
33
|
}
|
|
31
34
|
};
|
|
32
|
-
/** The hover label of a shown value: the time zone a timestamp is shown in, nothing for other values. */
|
|
33
|
-
const valueTitle = (field, value, zone = viewerZone()) => {
|
|
35
|
+
/** The hover label of a shown value: the time zone a timestamp is shown in, or its exact time when shown relative; nothing for other values. */
|
|
36
|
+
const valueTitle = (field, value, zone = viewerZone(), hints = {}) => {
|
|
34
37
|
if (field.type !== "timestamp" || typeof value !== "string") return void 0;
|
|
35
38
|
const ms = Date.parse(value);
|
|
36
|
-
|
|
39
|
+
if (Number.isNaN(ms)) return void 0;
|
|
40
|
+
if (hints.format === "relative") return formatDateTime(ms, zone);
|
|
41
|
+
return `Shown in ${zoneLabel(ms, zone)}`;
|
|
37
42
|
};
|
|
38
43
|
//#endregion
|
|
39
44
|
export { displayValue, valueTitle };
|
package/dist/package.js
CHANGED