@protobase/ui 0.63.5 → 0.64.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.
Files changed (273) hide show
  1. package/dist/account/change-email-dialog.js +1 -1
  2. package/dist/account/devices-section.js +11 -5
  3. package/dist/account/messages.js +2 -333
  4. package/dist/account/passkeys-section.js +2 -2
  5. package/dist/account/password-change-dialog.js +3 -3
  6. package/dist/account/sign-in-policy-form.js +6 -3
  7. package/dist/account/sign-in-providers-section.js +1 -1
  8. package/dist/account/staff-sign-in-log.js +4 -4
  9. package/dist/action-card/messages.js +2 -5
  10. package/dist/activity-chart/activity-chart.js +4 -6
  11. package/dist/activity-chart/messages.js +2 -11
  12. package/dist/app/app.js +1 -2
  13. package/dist/app/batch-failure.js +5 -1
  14. package/dist/app/change-confirm/messages.js +2 -13
  15. package/dist/app/change-confirm/use-change-confirm.js +1 -1
  16. package/dist/app/charts/chart-groups.js +3 -1
  17. package/dist/app/charts/group-bars.js +1 -1
  18. package/dist/app/charts/messages.js +2 -23
  19. package/dist/app/charts/period-chart.js +1 -1
  20. package/dist/app/comments/messages.js +2 -19
  21. package/dist/app/confirm-sign-in-messages.js +2 -19
  22. package/dist/app/confirm-sign-in.js +1 -1
  23. package/dist/app/create/create-page.js +3 -3
  24. package/dist/app/create/create-record-form.js +2 -2
  25. package/dist/app/create/create-route.js +1 -1
  26. package/dist/app/create/messages.js +2 -29
  27. package/dist/app/custom-section.js +1 -2
  28. package/dist/app/delete/blocked-delete.js +5 -2
  29. package/dist/app/delete/dialogs.js +21 -8
  30. package/dist/app/delete/messages.js +2 -63
  31. package/dist/app/delete/use-delete-flow.js +5 -4
  32. package/dist/app/displays/board-column.js +1 -1
  33. package/dist/app/displays/board-columns.js +1 -1
  34. package/dist/app/displays/board-display.js +21 -9
  35. package/dist/app/displays/calendar-display.js +15 -6
  36. package/dist/app/displays/cards-display.js +1 -1
  37. package/dist/app/displays/custom-display.js +1 -2
  38. package/dist/app/displays/list-cards.js +1 -1
  39. package/dist/app/displays/map-display.js +19 -6
  40. package/dist/app/displays/messages.js +2 -147
  41. package/dist/app/displays/period-controls.js +2 -2
  42. package/dist/app/displays/timeline-display.js +15 -6
  43. package/dist/app/displays/timeline-range.js +1 -1
  44. package/dist/app/displays/use-board-move.js +3 -3
  45. package/dist/app/displays/use-calendar-move.js +1 -1
  46. package/dist/app/document-title.js +1 -1
  47. package/dist/app/embedded-list/cut-off-note.js +7 -1
  48. package/dist/app/embedded-list/embedded-row-targets.js +3 -3
  49. package/dist/app/embedded-list/messages.js +2 -21
  50. package/dist/app/export/builder-port.js +1 -1
  51. package/dist/app/export/export-dialog.js +14 -8
  52. package/dist/app/export/messages.js +2 -75
  53. package/dist/app/export/use-export-flow.js +9 -3
  54. package/dist/app/field-editor.js +2 -2
  55. package/dist/app/field-errors.js +18 -7
  56. package/dist/app/field-messages.js +2 -45
  57. package/dist/app/field-types/members/messages.js +2 -15
  58. package/dist/app/field-types/messages.js +2 -5
  59. package/dist/app/field-types/widget-part.js +1 -1
  60. package/dist/app/file-field.js +3 -3
  61. package/dist/app/gallery/gallery-section.js +5 -2
  62. package/dist/app/gallery/messages.js +2 -27
  63. package/dist/app/gallery/photo-details.js +2 -2
  64. package/dist/app/hand-order/hand-sorted-list.js +1 -2
  65. package/dist/app/hand-order/messages.js +2 -29
  66. package/dist/app/hand-order/use-hand-order.js +1 -1
  67. package/dist/app/history/describe-change.js +1 -1
  68. package/dist/app/history/messages.js +2 -29
  69. package/dist/app/import/convert.js +19 -10
  70. package/dist/app/import/import-check-step.js +5 -5
  71. package/dist/app/import/import-dialog.js +5 -2
  72. package/dist/app/import/import-file-step.js +1 -1
  73. package/dist/app/import/import-mapping-step.js +3 -3
  74. package/dist/app/import/messages.js +2 -197
  75. package/dist/app/import/prepare-rows.js +11 -4
  76. package/dist/app/import/sheet-cell.js +1 -1
  77. package/dist/app/import/xlsx-reader.js +2 -2
  78. package/dist/app/import/zip-reader.js +4 -1
  79. package/dist/app/list-actions/use-list-actions.js +4 -1
  80. package/dist/app/list-edit/messages.js +2 -11
  81. package/dist/app/list-empty-state.js +7 -4
  82. package/dist/app/list-group-chart.js +1 -1
  83. package/dist/app/list-messages.js +2 -53
  84. package/dist/app/list-page.js +9 -9
  85. package/dist/app/live-update/messages.js +2 -11
  86. package/dist/app/map/messages.js +2 -11
  87. package/dist/app/messages.js +2 -139
  88. package/dist/app/meta-gate-messages.js +2 -13
  89. package/dist/app/nav-from-meta.js +2 -2
  90. package/dist/app/new-version/messages.js +2 -21
  91. package/dist/app/new-version/new-version-banner.js +1 -2
  92. package/dist/app/pages/action-inputs/action-inputs-dialog.js +1 -1
  93. package/dist/app/pages/action-inputs/input-answers.js +1 -1
  94. package/dist/app/pages/blocks/modal-form.js +1 -1
  95. package/dist/app/pages/blocks/settings.js +1 -1
  96. package/dist/app/pages/blocks/tabs.js +1 -1
  97. package/dist/app/pages/composed-page.js +1 -2
  98. package/dist/app/pages/custom-boundary.js +1 -2
  99. package/dist/app/pages/messages.js +2 -79
  100. package/dist/app/pages/render-node.js +2 -3
  101. package/dist/app/pages/use-run-action.js +14 -6
  102. package/dist/app/rank-after/dependency-rule.js +8 -2
  103. package/dist/app/rank-after/messages.js +2 -5
  104. package/dist/app/rank-after/ranked-place.js +7 -1
  105. package/dist/app/record-chart/messages.js +2 -25
  106. package/dist/app/record-lines-cell.js +4 -1
  107. package/dist/app/record-lines.js +2 -2
  108. package/dist/app/record-messages.js +2 -83
  109. package/dist/app/record-page.js +3 -3
  110. package/dist/app/record-row/messages.js +2 -23
  111. package/dist/app/record-row/record-row-body.js +1 -1
  112. package/dist/app/record-row/record-row.js +2 -2
  113. package/dist/app/record-row/saved-record-row.js +2 -2
  114. package/dist/app/related-cards/messages.js +2 -15
  115. package/dist/app/related-dots/dots-summary.js +1 -1
  116. package/dist/app/related-dots/messages.js +2 -5
  117. package/dist/app/related-dots/related-dots.js +2 -3
  118. package/dist/app/relation-picker.js +1 -1
  119. package/dist/app/runtime/messages.js +2 -55
  120. package/dist/app/runtime/runtime-status.js +12 -3
  121. package/dist/app/saved/messages.js +2 -19
  122. package/dist/app/saved/saved-list.js +2 -2
  123. package/dist/app/search/messages.js +2 -19
  124. package/dist/app/search/navigation-hits.js +1 -1
  125. package/dist/app/search/search-model.js +9 -3
  126. package/dist/app/searches/messages.js +2 -93
  127. package/dist/app/searches/save-search-button.js +3 -3
  128. package/dist/app/searches/saved-search-rows.js +2 -2
  129. package/dist/app/searches/saved-search-section.js +3 -3
  130. package/dist/app/searches/saved-searches.js +13 -11
  131. package/dist/app/searches/search-controls.js +1 -1
  132. package/dist/app/searches/search-diff.js +8 -2
  133. package/dist/app/searches/update-search-dialog.js +9 -3
  134. package/dist/app/searches/use-save-search.js +1 -1
  135. package/dist/app/searches/use-search-row.js +2 -2
  136. package/dist/app/sensitive-field.js +3 -3
  137. package/dist/app/source-notice.js +3 -3
  138. package/dist/app/staff-banner.js +12 -8
  139. package/dist/app/use-live-save.js +2 -2
  140. package/dist/app/value-badge.js +3 -4
  141. package/dist/app-shell/global-search.js +2 -2
  142. package/dist/app-shell/messages.js +2 -63
  143. package/dist/app-shell/sidebar-group.js +2 -2
  144. package/dist/app-shell/sidebar.js +1 -2
  145. package/dist/app-shell/top-bar.js +1 -1
  146. package/dist/assistant-dock/messages.js +2 -23
  147. package/dist/auth/auth-gate.js +1 -1
  148. package/dist/auth/auth-messages.js +9 -88
  149. package/dist/auth/email-code-form.js +2 -3
  150. package/dist/auth/forgot-password-form.js +2 -3
  151. package/dist/auth/messages.js +2 -203
  152. package/dist/auth/provider-sign-in-page.js +3 -3
  153. package/dist/auth/resend-code-button.js +1 -1
  154. package/dist/auth/reset-password-form.js +1 -1
  155. package/dist/auth/reset-password-page.js +1 -1
  156. package/dist/auth/sign-in-form.js +2 -2
  157. package/dist/auth/sign-up-code-form.js +2 -3
  158. package/dist/auth/sign-up-details-form.js +3 -4
  159. package/dist/auth/staff-sign-in-form.js +3 -3
  160. package/dist/calls/call-guests-panel.js +1 -1
  161. package/dist/calls/call-lobby-notice.js +1 -1
  162. package/dist/calls/call-mark.js +1 -1
  163. package/dist/calls/call-people.js +1 -1
  164. package/dist/calls/call-tile.js +2 -2
  165. package/dist/calls/messages.js +2 -139
  166. package/dist/carousel/carousel-controls.js +4 -1
  167. package/dist/carousel/messages.js +2 -13
  168. package/dist/chat/messages.js +2 -19
  169. package/dist/compact-table/compact-table.js +1 -1
  170. package/dist/compact-table/messages.js +2 -15
  171. package/dist/data-grid/cell-text.js +6 -5
  172. package/dist/data-grid/cells.js +7 -4
  173. package/dist/data-grid/grid-footer.js +1 -1
  174. package/dist/data-grid/grid-row.js +1 -1
  175. package/dist/data-grid/header-menu.js +1 -1
  176. package/dist/data-grid/messages.js +2 -49
  177. package/dist/data-grid/resize-handle.js +1 -1
  178. package/dist/data-grid/row-reorder.js +20 -5
  179. package/dist/filter-panel/active-filter-chips.js +1 -1
  180. package/dist/filter-panel/date-presets.js +2 -2
  181. package/dist/filter-panel/facet-combobox.js +1 -1
  182. package/dist/filter-panel/facet-group.js +1 -1
  183. package/dist/filter-panel/messages.js +2 -49
  184. package/dist/filter-panel/range-filter.js +1 -1
  185. package/dist/format/date.js +4 -4
  186. package/dist/format/messages.js +2 -21
  187. package/dist/format/money.js +1 -1
  188. package/dist/format/number.js +5 -2
  189. package/dist/forms/messages.js +2 -21
  190. package/dist/inline-child-table/inline-child-table.js +19 -4
  191. package/dist/inline-child-table/line-row.js +2 -2
  192. package/dist/inline-child-table/messages.js +2 -35
  193. package/dist/invitations/link-notice.js +2 -3
  194. package/dist/invitations/messages.js +2 -21
  195. package/dist/invitations/pending-invitation-row.js +1 -1
  196. package/dist/lists/messages.js +2 -5
  197. package/dist/live/columns-from-model.js +14 -31
  198. package/dist/live/display-value.js +1 -1
  199. package/dist/live/messages.js +2 -15
  200. package/dist/live/value-color.js +13 -3
  201. package/dist/live/view-fields.js +4 -2
  202. package/dist/locale/en.js +1399 -0
  203. package/dist/locale/messages.js +38 -7
  204. package/dist/locale/nl.js +1399 -0
  205. package/dist/markdown/messages.js +2 -13
  206. package/dist/mentions/messages.js +2 -13
  207. package/dist/notifications/bell/messages.js +2 -35
  208. package/dist/notifications/bell/unread-label.js +1 -1
  209. package/dist/organizations/invitation-page.js +31 -13
  210. package/dist/organizations/invitations-page.js +1 -1
  211. package/dist/organizations/members-page.js +2 -2
  212. package/dist/organizations/messages.js +2 -187
  213. package/dist/organizations/organization-page.js +4 -4
  214. package/dist/organizations/organizations-page.js +1 -1
  215. package/dist/package.js +1 -1
  216. package/dist/plugins/load-plugin.js +2 -2
  217. package/dist/plugins/messages.js +2 -33
  218. package/dist/plugins/plugin-notice.js +7 -5
  219. package/dist/primitives/badge.d.ts +2 -1
  220. package/dist/primitives/messages.js +2 -13
  221. package/dist/primitives/token.js +1 -1
  222. package/dist/record-view/field.js +2 -2
  223. package/dist/record-view/messages.js +2 -33
  224. package/dist/record-view/record-header.js +2 -2
  225. package/dist/roles/messages.js +2 -11
  226. package/dist/shell/assets/app-CN_7en9q.js +8 -0
  227. package/dist/shell/assets/{calls-CPiQcC70.js → calls-D5RK7EJu.js} +2 -2
  228. package/dist/shell/assets/export-worker-ClXdfeuq.js +15 -0
  229. package/dist/shell/assets/{index-_ZpZ2ro0.js → index-DMaCBpbN.js} +2 -2
  230. package/dist/shell/assets/{maplibre-CjNYwEqW.js → maplibre-CRmpQfDl.js} +3 -3
  231. package/dist/shell/assets/parse-worker-DxsmAjef.js +18 -0
  232. package/dist/shell/assets/preload-helper-BgLOXTzV.js +2 -0
  233. package/dist/shell/assets/{record-map-DjqQGqZ2.js → record-map-DsP4sXes.js} +2 -2
  234. package/dist/shell/assets/{records-map-DU29d6QK.js → records-map-WFMHgKdf.js} +2 -2
  235. package/dist/shell/assets/shared-protobase-ui-CP2mMFbh.js +2 -0
  236. package/dist/shell/assets/vendor-Kvdo8Jrw.js +73 -0
  237. package/dist/shell/index.html +5 -5
  238. package/dist/shell/protobase.shell.json +2 -2
  239. package/dist/shell/protobase.sw.js +2 -2
  240. package/dist/shell-source-maps/assets/app-CN_7en9q.js.map +1 -0
  241. package/dist/shell-source-maps/assets/{calls-CPiQcC70.js.map → calls-D5RK7EJu.js.map} +1 -1
  242. package/dist/shell-source-maps/assets/export-worker-ClXdfeuq.js.map +1 -0
  243. package/dist/shell-source-maps/assets/{index-_ZpZ2ro0.js.map → index-DMaCBpbN.js.map} +1 -1
  244. package/dist/shell-source-maps/assets/{maplibre-CjNYwEqW.js.map → maplibre-CRmpQfDl.js.map} +1 -1
  245. package/dist/shell-source-maps/assets/parse-worker-DxsmAjef.js.map +1 -0
  246. package/dist/shell-source-maps/assets/preload-helper-BgLOXTzV.js.map +1 -0
  247. package/dist/shell-source-maps/assets/{record-map-DjqQGqZ2.js.map → record-map-DsP4sXes.js.map} +1 -1
  248. package/dist/shell-source-maps/assets/{records-map-DU29d6QK.js.map → records-map-WFMHgKdf.js.map} +1 -1
  249. package/dist/shell-source-maps/assets/shared-protobase-ui-CP2mMFbh.js.map +1 -0
  250. package/dist/shell-source-maps/assets/vendor-Kvdo8Jrw.js.map +1 -0
  251. package/dist/side-panel/messages.js +2 -5
  252. package/dist/status/messages.js +2 -59
  253. package/dist/toasts/messages.js +2 -5
  254. package/dist/users/create-user-form.js +1 -1
  255. package/dist/users/messages.js +2 -49
  256. package/package.json +5 -4
  257. package/dist/app-shell/nav.js +0 -85
  258. package/dist/locale/slotted.js +0 -14
  259. package/dist/mocks/activity.js +0 -24
  260. package/dist/mocks/rng.js +0 -20
  261. package/dist/mocks/users.js +0 -63
  262. package/dist/shell/assets/app-BPv_SjnU.js +0 -9
  263. package/dist/shell/assets/export-worker-3e4Zsv0a.js +0 -3
  264. package/dist/shell/assets/parse-worker-UhbwEjS0.js +0 -6
  265. package/dist/shell/assets/preload-helper-SYSsmQ2O.js +0 -2
  266. package/dist/shell/assets/shared-protobase-ui-Cab5nqST.js +0 -2
  267. package/dist/shell/assets/vendor-iwLB0x-s.js +0 -63
  268. package/dist/shell-source-maps/assets/app-BPv_SjnU.js.map +0 -1
  269. package/dist/shell-source-maps/assets/export-worker-3e4Zsv0a.js.map +0 -1
  270. package/dist/shell-source-maps/assets/parse-worker-UhbwEjS0.js.map +0 -1
  271. package/dist/shell-source-maps/assets/preload-helper-SYSsmQ2O.js.map +0 -1
  272. package/dist/shell-source-maps/assets/shared-protobase-ui-Cab5nqST.js.map +0 -1
  273. package/dist/shell-source-maps/assets/vendor-iwLB0x-s.js.map +0 -1
@@ -1,82 +1,5 @@
1
- import { defineMessages } from "../../locale/messages.js";
1
+ import { messages } from "../../locale/messages.js";
2
2
  //#region src/app/pages/messages.ts
3
- const text = defineMessages({
4
- en: {
5
- notFound: "Not found",
6
- noPage: "There is no page called {}.",
7
- tabs: "Tabs",
8
- noTab: (name) => `This page has no tab called ${name}.`,
9
- cancel: "Cancel",
10
- couldNotDraw: "{} could not be drawn.",
11
- noComponent: "No component is registered as {}. Export it from protobase.ui.tsx, or load the plugin that provides it.",
12
- unknownBlock: "{} is not a block this version of the app knows.",
13
- somethingWrong: "Something went wrong",
14
- needsRecord: "Needs a record",
15
- cannotChange: "You cannot change this record",
16
- cannotDelete: "You cannot delete this record",
17
- doesNotApply: "Does not apply to this record",
18
- noHandler: (name) => `The app has no handler for "${name}"`,
19
- noInputComponent: (component, input) => `The app has no component "${component}" for input "${input}"`,
20
- done: (label) => `${label}: done`,
21
- doneOn: (label, done, skipped, failed) => [
22
- `${label}: done on ${done}`,
23
- ...skipped > 0 ? [`skipped ${skipped} it does not apply to`] : [],
24
- ...failed > 0 ? [`failed on ${failed}`] : []
25
- ].join(", "),
26
- failed: (label) => `${label} failed`,
27
- noAction: (name) => `No action "${name}"`,
28
- couldNotLoad: "Could not load",
29
- nothingYet: "Nothing here yet.",
30
- saved: (label) => `${label}: saved`,
31
- create: "Create",
32
- save: "Save",
33
- notSaved: "Not saved",
34
- settings: "Settings",
35
- couldNotCount: "Could not count",
36
- required: "Required",
37
- wholeNumber: "A whole number",
38
- number: "A number",
39
- dateFormat: "A date as YYYY-MM-DD",
40
- atMost: (max) => `At most ${max} characters`
41
- },
42
- nl: {
43
- notFound: "Niet gevonden",
44
- noPage: "Er is geen pagina met de naam {}.",
45
- tabs: "Tabbladen",
46
- noTab: (name) => `Deze pagina heeft geen tabblad met de naam ${name}.`,
47
- cancel: "Annuleren",
48
- couldNotDraw: "{} kon niet worden getekend.",
49
- noComponent: "Er is geen component geregistreerd als {}. Exporteer die uit protobase.ui.tsx, of laad de plug-in die haar levert.",
50
- unknownBlock: "{} is geen blok dat deze versie van de app kent.",
51
- somethingWrong: "Er ging iets mis",
52
- needsRecord: "Vraagt een record",
53
- cannotChange: "Je kunt dit record niet wijzigen",
54
- cannotDelete: "Je kunt dit record niet verwijderen",
55
- doesNotApply: "Geldt niet voor dit record",
56
- noHandler: (name) => `De app heeft geen handler voor "${name}"`,
57
- noInputComponent: (component, input) => `De app heeft geen component "${component}" voor invoer "${input}"`,
58
- done: (label) => `${label}: klaar`,
59
- doneOn: (label, done, skipped, failed) => [
60
- `${label}: klaar voor ${done}`,
61
- ...skipped > 0 ? [`${skipped} overgeslagen waarvoor het niet geldt`] : [],
62
- ...failed > 0 ? [`mislukt voor ${failed}`] : []
63
- ].join(", "),
64
- failed: (label) => `${label} mislukt`,
65
- noAction: (name) => `Geen actie "${name}"`,
66
- couldNotLoad: "Kon niet laden",
67
- nothingYet: "Hier staat nog niets.",
68
- saved: (label) => `${label}: bewaard`,
69
- create: "Maken",
70
- save: "Bewaren",
71
- notSaved: "Niet bewaard",
72
- settings: "Instellingen",
73
- couldNotCount: "Kon niet tellen",
74
- required: "Verplicht",
75
- wholeNumber: "Een geheel getal",
76
- number: "Een getal",
77
- dateFormat: "Een datum als JJJJ-MM-DD",
78
- atMost: (max) => `Hoogstens ${max} tekens`
79
- }
80
- });
3
+ const text = messages("app/pages");
81
4
  //#endregion
82
5
  export { text };
@@ -1,6 +1,5 @@
1
1
  import { useProjectUi } from "./project-ui.js";
2
2
  import { Problem } from "./problem.js";
3
- import { slotted } from "../../locale/slotted.js";
4
3
  import { text } from "./messages.js";
5
4
  import { CustomBoundary } from "./custom-boundary.js";
6
5
  import { ActionBlock } from "./blocks/action.js";
@@ -93,7 +92,7 @@ const RenderNode = ({ node }) => {
93
92
  const { components } = useProjectUi();
94
93
  if (node.custom) {
95
94
  const Custom = components?.[node.type];
96
- if (!Custom) return /* @__PURE__ */ jsx(Problem, { children: slotted(text("noComponent"), node.type) });
95
+ if (!Custom) return /* @__PURE__ */ jsx(Problem, { children: text.rich("noComponent", { component: node.type }) });
97
96
  return /* @__PURE__ */ jsx(CustomBoundary, {
98
97
  name: node.type,
99
98
  children: /* @__PURE__ */ jsx(Custom, {
@@ -103,7 +102,7 @@ const RenderNode = ({ node }) => {
103
102
  });
104
103
  }
105
104
  const Block = blocks[node.type];
106
- if (!Block) return /* @__PURE__ */ jsx(Problem, { children: slotted(text("unknownBlock"), node.type) });
105
+ if (!Block) return /* @__PURE__ */ jsx(Problem, { children: text.rich("unknownBlock", { type: node.type }) });
107
106
  return /* @__PURE__ */ jsx(Block, {
108
107
  node,
109
108
  slots: renderSlots(node),
@@ -40,9 +40,12 @@ const useActionRunner = (resource, scope, afterRun) => {
40
40
  if ((kind === "update" || kind === "ai") && (!can(permissions, "update") || on?.permissions?.update === false)) return text("cannotChange");
41
41
  if (action.run?.kind === "ai" && on?.permissions?.fields?.[action.run.writes] === "read") return text("cannotChange");
42
42
  if (kind === "delete" && (!can(permissions, "delete") || on?.permissions?.delete === false)) return text("cannotDelete");
43
- if (!action.run && !handlers?.[action.name]) return text("noHandler", action.name);
43
+ if (!action.run && !handlers?.[action.name]) return text("noHandler", { name: action.name });
44
44
  const custom = action.inputs?.find((input) => input.kind === "custom" && !components?.[input.component ?? ""]);
45
- if (custom) return text("noInputComponent", String(custom.component), custom.name);
45
+ if (custom) return text("noInputComponent", {
46
+ component: String(custom.component),
47
+ input: custom.name
48
+ });
46
49
  };
47
50
  const blocked = (action) => blockedOn(action, scope);
48
51
  const execute = async (action, on, values) => {
@@ -71,7 +74,7 @@ const useActionRunner = (resource, scope, afterRun) => {
71
74
  await refresh(resource);
72
75
  toast.show({
73
76
  state: "success",
74
- title: text("done", action.label)
77
+ title: text("done", { label: action.label })
75
78
  });
76
79
  afterRun?.(action);
77
80
  };
@@ -80,7 +83,7 @@ const useActionRunner = (resource, scope, afterRun) => {
80
83
  setRunning(action.name);
81
84
  await perform(action, on).catch((error) => toast.show({
82
85
  state: "error",
83
- title: text("failed", action.label),
86
+ title: text("failed", { label: action.label }),
84
87
  description: message(error)
85
88
  }));
86
89
  setRunning(void 0);
@@ -97,7 +100,12 @@ const useActionRunner = (resource, scope, afterRun) => {
97
100
  const outcome = await runEach(records, (on) => appliesOn(action, on), (on) => execute(action, on));
98
101
  setRunning(void 0);
99
102
  await refresh(resource);
100
- const title = text("doneOn", action.label, outcome.done, outcome.skipped + skipped, outcome.failed);
103
+ const title = text("doneOn", {
104
+ label: action.label,
105
+ done: outcome.done,
106
+ skipped: outcome.skipped + skipped,
107
+ failed: outcome.failed
108
+ });
101
109
  toast.show(outcome.failed > 0 ? {
102
110
  state: "error",
103
111
  title,
@@ -125,7 +133,7 @@ const useRunAction = (resource, name, scope) => {
125
133
  const action = runner.actions.find((entry) => entry.name === name);
126
134
  return {
127
135
  action,
128
- blocked: action ? runner.blocked(action) : text("noAction", name),
136
+ blocked: action ? runner.blocked(action) : text("noAction", { name }),
129
137
  running: runner.running === name,
130
138
  run: () => action ? runner.run(action) : Promise.resolve(),
131
139
  submit: (values) => action ? runner.submit(action, values) : Promise.resolve()
@@ -9,9 +9,15 @@ import { encodeKey } from "@protobase/schema/internal";
9
9
  const dependencyRule = (model, bounds, title) => ({ order, index }) => {
10
10
  const at = (key) => order.findIndex((entry) => encodeKey(recordKey(model, entry)) === key);
11
11
  const above = bounds.after.find((bound) => at(bound.key) > index);
12
- if (above) return text("dependsOn", title, above.title);
12
+ if (above) return text("dependsOn", {
13
+ record: title,
14
+ other: above.title
15
+ });
13
16
  const below = bounds.before.find((bound) => at(bound.key) !== -1 && at(bound.key) < index);
14
- return below ? text("dependsOn", below.title, title) : void 0;
17
+ return below ? text("dependsOn", {
18
+ record: below.title,
19
+ other: title
20
+ }) : void 0;
15
21
  };
16
22
  //#endregion
17
23
  export { dependencyRule };
@@ -1,8 +1,5 @@
1
- import { defineMessages } from "../../locale/messages.js";
1
+ import { messages } from "../../locale/messages.js";
2
2
  //#region src/app/rank-after/messages.ts
3
- const text = defineMessages({
4
- en: { dependsOn: (record, other) => `${record} depends on ${other}.` },
5
- nl: { dependsOn: (record, other) => `${record} hangt af van ${other}.` }
6
- });
3
+ const text = messages("app/rank-after");
7
4
  //#endregion
8
5
  export { text };
@@ -23,7 +23,13 @@ const rankedPlace = ({ model, rank, rows, row, index, bounds, title }) => {
23
23
  const mine = Number(ranked.get(encodeKey(recordKey(model, row.record))));
24
24
  const above = bounds.after.filter((bound) => isRank(rankOf(bound)) && Number(rankOf(bound)) >= mine);
25
25
  const below = bounds.before.find((bound) => isRank(rankOf(bound)) && Number(rankOf(bound)) <= mine);
26
- const refusal = below ? text("dependsOn", below.title, title) : above[0] && text("dependsOn", title, above[0].title);
26
+ const refusal = below ? text("dependsOn", {
27
+ record: below.title,
28
+ other: title
29
+ }) : above[0] && text("dependsOn", {
30
+ record: title,
31
+ other: above[0].title
32
+ });
27
33
  if (!refusal) return {
28
34
  place: { index: at },
29
35
  ...reason !== void 0 && { reason }
@@ -1,28 +1,5 @@
1
- import { defineMessages } from "../../locale/messages.js";
1
+ import { messages } from "../../locale/messages.js";
2
2
  //#region src/app/record-chart/messages.ts
3
- const text = defineMessages({
4
- en: {
5
- range: "Range",
6
- hour: "Hour",
7
- day: "Day",
8
- week: "Week",
9
- measure: "Per bucket",
10
- average: "Average",
11
- maximum: "Maximum",
12
- noSamples: "No samples in this range.",
13
- couldNotLoad: "Could not load the chart."
14
- },
15
- nl: {
16
- range: "Periode",
17
- hour: "Uur",
18
- day: "Dag",
19
- week: "Week",
20
- measure: "Per interval",
21
- average: "Gemiddelde",
22
- maximum: "Maximum",
23
- noSamples: "Geen metingen in deze periode.",
24
- couldNotLoad: "Kon de grafiek niet laden."
25
- }
26
- });
3
+ const text = messages("app/record-chart");
27
4
  //#endregion
28
5
  export { text };
@@ -20,7 +20,10 @@ const LineCell = ({ field, hints, label, lineNumber, resource, value, stored, re
20
20
  /* @__PURE__ */ jsx("label", {
21
21
  htmlFor: id,
22
22
  className: "sr-only",
23
- children: text("lineField", label, lineNumber)
23
+ children: text("lineField", {
24
+ label,
25
+ place: lineNumber
26
+ })
24
27
  }),
25
28
  /* @__PURE__ */ jsx(FieldEditor, {
26
29
  field,
@@ -93,7 +93,7 @@ const RecordLines = ({ lines, editable, saving }) => {
93
93
  help: text("linesHelp"),
94
94
  children: [!data.complete && /* @__PURE__ */ jsx("p", {
95
95
  className: "mb-2 text-muted-foreground",
96
- children: text("tooManyLines", formatInt(1e3))
96
+ children: text("tooManyLines", { limit: formatInt(1e3) })
97
97
  }), /* @__PURE__ */ jsx("div", {
98
98
  className: "-mx-4 overflow-x-auto px-4 [-webkit-overflow-scrolling:touch] md:mx-0 md:px-0",
99
99
  children: /* @__PURE__ */ jsx("div", {
@@ -101,7 +101,7 @@ const RecordLines = ({ lines, editable, saving }) => {
101
101
  children: /* @__PURE__ */ jsx(InlineChildTable, {
102
102
  lines: draft.shown,
103
103
  columns: tableColumns,
104
- lineName: (line) => recordTitle(model, view, line.stored ?? {}, "") || text("lineNumber", placeOf(line)),
104
+ lineName: (line) => recordTitle(model, view, line.stored ?? {}, "") || text("lineNumber", { place: placeOf(line) }),
105
105
  onReorder: (next) => draft.setOrder(next.map((line) => line.id)),
106
106
  reorderable: canUpdate,
107
107
  onAdd: canCreate ? () => void draft.add() : void 0,
@@ -1,86 +1,5 @@
1
- import { defineMessages } from "../locale/messages.js";
1
+ import { messages } from "../locale/messages.js";
2
2
  //#region src/app/record-messages.ts
3
- const text = defineMessages({
4
- en: {
5
- details: "Details",
6
- history: "History",
7
- comments: "Comments",
8
- summary: "Summary",
9
- loading: "Loading",
10
- fetching: "Fetching the record.",
11
- noRecord: "This record does not exist, or you cannot see it.",
12
- openingElsewhere: "Opening the record in its organization.",
13
- couldNotLoad: "Could not load the record",
14
- someoneElse: "Someone else",
15
- justNow: "just now",
16
- saved: "Saved",
17
- save: "Save",
18
- cancel: "Cancel",
19
- unsavedChanges: "Unsaved changes",
20
- notSaved: "Not saved",
21
- linesChanged: "The lines were changed by someone else",
22
- linesReloaded: "The lines were reloaded. Your new order is kept: Save again to apply it.",
23
- unsavedKept: "You have unsaved changes to this record.",
24
- continueEditing: "Continue editing",
25
- discard: "Discard",
26
- unsavedRestored: "Your unsaved changes were restored.",
27
- keep: "Keep",
28
- savingSubject: (subject) => `Saving ${subject}...`,
29
- subjectSaved: (subject) => `${subject} saved`,
30
- changedBySomeoneElse: "Changed by someone else",
31
- couldNotSave: "Could not save",
32
- recordActions: "Record actions",
33
- edit: "Edit",
34
- delete: "Delete",
35
- nothingYet: "Nothing here yet.",
36
- couldNotLoadRelated: "Could not load",
37
- relatedRecords: "Related records",
38
- lines: "Lines",
39
- linesHelp: "What the document bills for. Edit a line in place, add one, or drag the handle to change the order; Save applies it all.",
40
- lineNumber: (place) => `Line ${place}`,
41
- lineField: (label, place) => `${label}, line ${place}`,
42
- tooManyLines: (limit) => `This record has more than ${limit} lines, so they show here read-only.`
43
- },
44
- nl: {
45
- details: "Details",
46
- history: "Geschiedenis",
47
- comments: "Opmerkingen",
48
- summary: "Overzicht",
49
- loading: "Laden",
50
- fetching: "Het record wordt opgehaald.",
51
- noRecord: "Dit record bestaat niet, of je mag het niet zien.",
52
- openingElsewhere: "Het record wordt in zijn organisatie geopend.",
53
- couldNotLoad: "Kon het record niet laden",
54
- someoneElse: "Iemand anders",
55
- justNow: "zojuist",
56
- saved: "Bewaard",
57
- save: "Bewaren",
58
- cancel: "Annuleren",
59
- unsavedChanges: "Niet bewaarde wijzigingen",
60
- notSaved: "Niet bewaard",
61
- linesChanged: "De regels zijn door iemand anders gewijzigd",
62
- linesReloaded: "De regels zijn opnieuw geladen. Je nieuwe volgorde is behouden: bewaar opnieuw om hem toe te passen.",
63
- unsavedKept: "Je hebt niet bewaarde wijzigingen in dit record.",
64
- continueEditing: "Verder bewerken",
65
- discard: "Weggooien",
66
- unsavedRestored: "Je niet bewaarde wijzigingen zijn teruggezet.",
67
- keep: "Houden",
68
- savingSubject: (subject) => `${subject} bewaren...`,
69
- subjectSaved: (subject) => `${subject} bewaard`,
70
- changedBySomeoneElse: "Gewijzigd door iemand anders",
71
- couldNotSave: "Kon niet bewaren",
72
- recordActions: "Recordacties",
73
- edit: "Bewerken",
74
- delete: "Verwijderen",
75
- nothingYet: "Hier staat nog niets.",
76
- couldNotLoadRelated: "Kon niet laden",
77
- relatedRecords: "Gerelateerde records",
78
- lines: "Regels",
79
- linesHelp: "Waar het document voor factureert. Wijzig een regel ter plekke, voeg er een toe, of sleep de greep om de volgorde te wijzigen; Bewaren past alles toe.",
80
- lineNumber: (place) => `Regel ${place}`,
81
- lineField: (label, place) => `${label}, regel ${place}`,
82
- tooManyLines: (limit) => `Dit record heeft meer dan ${limit} regels, dus ze staan hier alleen ter inzage.`
83
- }
84
- });
3
+ const text = messages("app/record");
85
4
  //#endregion
86
5
  export { text };
@@ -11,7 +11,7 @@ import { humanize } from "../live/naming.js";
11
11
  import { markdownExcerpt } from "../markdown/markdown-excerpt.js";
12
12
  import { isMarkdown } from "../markdown/markdown-hint.js";
13
13
  import { contactFormat } from "../live/contact-links.js";
14
- import { toneFor } from "../live/columns-from-model.js";
14
+ import { valueTone } from "../live/value-color.js";
15
15
  import { displayValue, valueTitle } from "../live/display-value.js";
16
16
  import { filledFields } from "./filled-fields.js";
17
17
  import { Skeleton } from "../primitives/skeleton.js";
@@ -107,7 +107,7 @@ const RecordPage = ({ resource, recordKey }) => {
107
107
  const record = useOpenedRecord(resource, recordKey);
108
108
  if (!model) return /* @__PURE__ */ jsx(Notice, {
109
109
  title: text("notFound"),
110
- children: text("noResource", resource)
110
+ children: text("noResource", { name: resource })
111
111
  });
112
112
  if (record.isPending) return /* @__PURE__ */ jsx(Notice, {
113
113
  title: text$1("loading"),
@@ -484,7 +484,7 @@ const LoadedRecord = ({ model, recordKey, stored, preview }) => {
484
484
  title,
485
485
  status: status ? {
486
486
  label: enumLabel(status, hint("status")?.valueLabels),
487
- tone: toneFor(status)
487
+ tone: valueTone(hint("status")?.valueColors, status)
488
488
  } : void 0
489
489
  }),
490
490
  editor.message && /* @__PURE__ */ jsx("div", {
@@ -1,26 +1,5 @@
1
- import { defineMessages } from "../../locale/messages.js";
1
+ import { messages } from "../../locale/messages.js";
2
2
  //#region src/app/record-row/messages.ts
3
- const text = defineMessages({
4
- en: {
5
- couldNotLoad: "Could not load",
6
- noneMatch: (plural) => `No ${plural} match.`,
7
- viewAll: "View all",
8
- new: "New",
9
- previous: (label) => `Previous ${label}`,
10
- next: (label) => `Next ${label}`,
11
- couldNotLoadYour: (plural) => `Could not load your ${plural}`,
12
- noneYet: (plural) => `No ${plural} yet.`
13
- },
14
- nl: {
15
- couldNotLoad: "Kon niet laden",
16
- noneMatch: (plural) => `Geen ${plural} gevonden.`,
17
- viewAll: "Alles bekijken",
18
- new: "Nieuw",
19
- previous: (label) => `Terug in ${label}`,
20
- next: (label) => `Verder in ${label}`,
21
- couldNotLoadYour: (plural) => `Kon je ${plural} niet laden`,
22
- noneYet: (plural) => `Nog geen ${plural}.`
23
- }
24
- });
3
+ const text = messages("app/record-row");
25
4
  //#endregion
26
5
  export { text };
@@ -82,7 +82,7 @@ const RecordRowBody = ({ model, view, filter, sort = "", display: named, limit,
82
82
  error: rows.error
83
83
  }) : !source || source.total === 0 ? /* @__PURE__ */ jsx("p", {
84
84
  className: "text-muted-foreground",
85
- children: empty ?? text("noneMatch", plural.toLowerCase())
85
+ children: empty ?? text("noneMatch", { plural: plural.toLowerCase() })
86
86
  }) : /* @__PURE__ */ jsx(RecordRow, {
87
87
  model,
88
88
  view,
@@ -70,7 +70,7 @@ const RecordRow = ({ model, view, display, source, label, isNew }) => {
70
70
  }),
71
71
  scroll.back && /* @__PURE__ */ jsx("button", {
72
72
  type: "button",
73
- "aria-label": text("previous", label.toLowerCase()),
73
+ "aria-label": text("previous", { label: label.toLowerCase() }),
74
74
  onClick: () => scroll.page(-1),
75
75
  className: `${arrowClass} -left-3`,
76
76
  children: /* @__PURE__ */ jsx(ChevronLeft, {
@@ -80,7 +80,7 @@ const RecordRow = ({ model, view, display, source, label, isNew }) => {
80
80
  }),
81
81
  scroll.on && /* @__PURE__ */ jsx("button", {
82
82
  type: "button",
83
- "aria-label": text("next", label.toLowerCase()),
83
+ "aria-label": text("next", { label: label.toLowerCase() }),
84
84
  onClick: () => scroll.page(1),
85
85
  className: `${arrowClass} -right-3`,
86
86
  children: /* @__PURE__ */ jsx(ChevronRight, {
@@ -20,14 +20,14 @@ const SavedRecordRow = ({ model, view, empty, ...props }) => {
20
20
  const plural = (view.names?.plural ?? humanize(model.name)).toLowerCase();
21
21
  if (!listed.listOf) return null;
22
22
  if (saved.error) return /* @__PURE__ */ jsx(ErrorBanner, {
23
- title: text("couldNotLoadYour", plural),
23
+ title: text("couldNotLoadYour", { plural }),
24
24
  error: saved.error
25
25
  });
26
26
  if (!saved.data) return /* @__PURE__ */ jsx(Skeleton, { className: "h-24" });
27
27
  const scope = savedScope(listed.model, saved.data);
28
28
  if (!scope) return /* @__PURE__ */ jsx("p", {
29
29
  className: "text-muted-foreground",
30
- children: empty ?? text("noneYet", plural)
30
+ children: empty ?? text("noneYet", { plural })
31
31
  });
32
32
  return /* @__PURE__ */ jsx(RecordRowBody, {
33
33
  ...props,
@@ -1,18 +1,5 @@
1
- import { defineMessages } from "../../locale/messages.js";
1
+ import { messages } from "../../locale/messages.js";
2
2
  //#region src/app/related-cards/messages.ts
3
- const text = defineMessages({
4
- en: {
5
- showMore: "Show more",
6
- showLess: "Show less",
7
- couldNotLoad: "Could not load",
8
- nothingYet: "Nothing here yet."
9
- },
10
- nl: {
11
- showMore: "Meer tonen",
12
- showLess: "Minder tonen",
13
- couldNotLoad: "Kon niet laden",
14
- nothingYet: "Hier staat nog niets."
15
- }
16
- });
3
+ const text = messages("app/related-cards");
17
4
  //#endregion
18
5
  export { text };
@@ -5,7 +5,7 @@ import { text } from "./messages.js";
5
5
  * of the status's values, such as "4 tasks: 1 To do, 3 Done". "No tasks" without any.
6
6
  */
7
7
  const dotsSummary = (statuses, { values, label, singular, plural }) => {
8
- if (statuses.length === 0) return text("none", plural);
8
+ if (statuses.length === 0) return text("none", { plural });
9
9
  const counts = /* @__PURE__ */ new Map();
10
10
  for (const status of statuses) if (status !== null && status !== void 0) counts.set(String(status), (counts.get(String(status)) ?? 0) + 1);
11
11
  const parts = [...values, ...[...counts.keys()].filter((value) => !values.includes(value))].filter((value) => counts.has(value)).map((value) => `${counts.get(value)} ${label(value)}`);
@@ -1,8 +1,5 @@
1
- import { defineMessages } from "../../locale/messages.js";
1
+ import { messages } from "../../locale/messages.js";
2
2
  //#region src/app/related-dots/messages.ts
3
- const text = defineMessages({
4
- en: { none: (plural) => `No ${plural}` },
5
- nl: { none: (plural) => `Geen ${plural}` }
6
- });
3
+ const text = messages("app/related-dots");
7
4
  //#endregion
8
5
  export { text };
@@ -2,11 +2,10 @@ import { cn } from "../../lib/cn.js";
2
2
  import { toneDots } from "../../primitives/badge.js";
3
3
  import { humanize } from "../../live/naming.js";
4
4
  import { recordTitleField } from "../../live/model-helpers.js";
5
- import { toneFor } from "../../live/columns-from-model.js";
5
+ import { valueColor, valueTone } from "../../live/value-color.js";
6
6
  import { displayValue } from "../../live/display-value.js";
7
7
  import { displayRow } from "../displays/list-displays.js";
8
8
  import { AppLink } from "../use-app-address.js";
9
- import { valueColor } from "../../live/value-color.js";
10
9
  import { placeCard } from "./card-place.js";
11
10
  import { dotCard } from "./dot-card.js";
12
11
  import { dotsSummary } from "./dots-summary.js";
@@ -153,7 +152,7 @@ const RelatedDots = ({ column, records, target, view, wrap = false, Card }) => {
153
152
  children: /* @__PURE__ */ jsx("span", {
154
153
  "aria-hidden": true,
155
154
  style: color === void 0 ? void 0 : { backgroundColor: color },
156
- className: cn(dotMark, color === void 0 && toneDots[toneFor(String(value))], shown?.key === row.key && "ring-2 ring-foreground/30")
155
+ className: cn(dotMark, color === void 0 && toneDots[valueTone(hints?.valueColors, value)], shown?.key === row.key && "ring-2 ring-foreground/30")
157
156
  })
158
157
  }, row.key);
159
158
  }),
@@ -47,7 +47,7 @@ const RelationPicker = ({ target, view, value, label, chosen = [value], several
47
47
  chosen,
48
48
  several,
49
49
  closedText: label ?? value,
50
- placeholder: text("searchPlural", (view?.names?.plural ?? humanize(target.name)).toLowerCase()),
50
+ placeholder: text("searchPlural", { plural: (view?.names?.plural ?? humanize(target.name)).toLowerCase() }),
51
51
  invalid,
52
52
  paging: {
53
53
  more: Boolean(rows.hasNextPage),
@@ -1,58 +1,5 @@
1
- import { defineMessages } from "../../locale/messages.js";
1
+ import { messages } from "../../locale/messages.js";
2
2
  //#region src/app/runtime/messages.ts
3
- const text = defineMessages({
4
- en: {
5
- immediate: "Updates as soon as a release is out",
6
- weekly: "Updates at a set time every week",
7
- scheduled: "Updates at the time set for this release",
8
- manual: "Updates only when asked to",
9
- job: "Preparing the update",
10
- build: "Building",
11
- updatingNow: "Updating now",
12
- started: (stage, ago) => `${stage}, started ${ago}`,
13
- nextOn: (policy, when) => `${policy}: next on ${when}`,
14
- succeeded: (version, when) => `Updated to ${version} on ${when}`,
15
- unchanged: (version, when) => `The update to ${version} on ${when} changed nothing`,
16
- failed: (version, when) => `The update to ${version} failed on ${when}`,
17
- alreadyLatest: "Already on the latest version, or an update is running.",
18
- onlyAdmin: "Only an admin can update the runtime.",
19
- couldNotStart: "The update could not be started. Try again later.",
20
- runtimeUpdate: "Runtime update",
21
- close: "Close",
22
- updating: "Updating…",
23
- updateNow: "Update now",
24
- currentVersion: "Current version",
25
- latestVersion: "Latest version",
26
- checkFailed: "The status could not be checked again; this is the last one read.",
27
- updateAvailable: "Update available",
28
- update: "Update"
29
- },
30
- nl: {
31
- immediate: "Werkt bij zodra er een release is",
32
- weekly: "Werkt elke week op een vast moment bij",
33
- scheduled: "Werkt bij op het moment dat voor deze release is ingesteld",
34
- manual: "Werkt alleen bij als erom wordt gevraagd",
35
- job: "De update voorbereiden",
36
- build: "Bouwen",
37
- updatingNow: "Nu aan het bijwerken",
38
- started: (stage, ago) => `${stage}, begonnen ${ago}`,
39
- nextOn: (policy, when) => `${policy}: volgende op ${when}`,
40
- succeeded: (version, when) => `Bijgewerkt naar ${version} op ${when}`,
41
- unchanged: (version, when) => `De update naar ${version} op ${when} veranderde niets`,
42
- failed: (version, when) => `De update naar ${version} mislukte op ${when}`,
43
- alreadyLatest: "Al op de nieuwste versie, of er loopt een update.",
44
- onlyAdmin: "Alleen een beheerder kan de runtime bijwerken.",
45
- couldNotStart: "De update kon niet worden gestart. Probeer het later opnieuw.",
46
- runtimeUpdate: "Runtime-update",
47
- close: "Sluiten",
48
- updating: "Bijwerken…",
49
- updateNow: "Nu bijwerken",
50
- currentVersion: "Huidige versie",
51
- latestVersion: "Nieuwste versie",
52
- checkFailed: "De status kon niet opnieuw worden gecontroleerd; dit is de laatst gelezen.",
53
- updateAvailable: "Update beschikbaar",
54
- update: "Bijwerken"
55
- }
56
- });
3
+ const text = messages("app/runtime");
57
4
  //#endregion
58
5
  export { text };
@@ -12,18 +12,27 @@ const runningText = (status, now) => {
12
12
  const label = text(status.updateStage);
13
13
  if (!status.updateStartedAt) return label;
14
14
  const seconds = Math.max(0, Math.floor((now - Date.parse(status.updateStartedAt)) / 1e3));
15
- return text("started", label, formatAgo(seconds));
15
+ return text("started", {
16
+ stage: label,
17
+ ago: formatAgo(seconds)
18
+ });
16
19
  };
17
20
  /** How far the running update is, or when the latest version will be applied on its own, in words; `now` in ms. */
18
21
  const nextUpdateText = (status, now = Date.now(), zone = viewerZone()) => {
19
22
  if (status.updating) return runningText(status, now);
20
- if (status.nextUpdateAt) return text("nextOn", text(status.policy), formatDateTime(Date.parse(status.nextUpdateAt), zone));
23
+ if (status.nextUpdateAt) return text("nextOn", {
24
+ policy: text(status.policy),
25
+ when: formatDateTime(Date.parse(status.nextUpdateAt), zone)
26
+ });
21
27
  return text(status.policy);
22
28
  };
23
29
  /** How the last update ended, in words, with the endpoint's message for the owner when it has one. */
24
30
  const lastUpdateText = (last, zone = viewerZone()) => {
25
31
  const when = formatDateTime(Date.parse(last.finishedAt), zone);
26
- const headline = text(last.outcome, last.toVersion, when);
32
+ const headline = text(last.outcome, {
33
+ version: last.toVersion,
34
+ when
35
+ });
27
36
  return last.message ? `${headline}: ${last.message}` : `${headline}.`;
28
37
  };
29
38
  /** Why "Update now" failed, in words: the endpoint's own message for a refusal, when it sends one. */