@protobase/ui 0.63.5 → 0.65.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 (277) 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/bottom-bar-from-meta.js +2 -3
  15. package/dist/app/change-confirm/messages.js +2 -13
  16. package/dist/app/change-confirm/use-change-confirm.js +1 -1
  17. package/dist/app/charts/chart-groups.js +3 -1
  18. package/dist/app/charts/group-bars.js +1 -1
  19. package/dist/app/charts/messages.js +2 -23
  20. package/dist/app/charts/period-chart.js +1 -1
  21. package/dist/app/comments/messages.js +2 -19
  22. package/dist/app/confirm-sign-in-messages.js +2 -19
  23. package/dist/app/confirm-sign-in.js +1 -1
  24. package/dist/app/create/create-page.js +3 -3
  25. package/dist/app/create/create-record-form.js +2 -2
  26. package/dist/app/create/create-route.js +1 -1
  27. package/dist/app/create/messages.js +2 -29
  28. package/dist/app/custom-section.js +1 -2
  29. package/dist/app/delete/blocked-delete.js +5 -2
  30. package/dist/app/delete/dialogs.js +21 -8
  31. package/dist/app/delete/messages.js +2 -63
  32. package/dist/app/delete/use-delete-flow.js +5 -4
  33. package/dist/app/displays/board-column.js +1 -1
  34. package/dist/app/displays/board-columns.js +1 -1
  35. package/dist/app/displays/board-display.js +21 -9
  36. package/dist/app/displays/calendar-display.js +15 -6
  37. package/dist/app/displays/cards-display.js +1 -1
  38. package/dist/app/displays/custom-display.js +1 -2
  39. package/dist/app/displays/list-cards.js +1 -1
  40. package/dist/app/displays/map-display.js +19 -6
  41. package/dist/app/displays/messages.js +2 -147
  42. package/dist/app/displays/period-controls.js +2 -2
  43. package/dist/app/displays/timeline-display.js +15 -6
  44. package/dist/app/displays/timeline-range.js +1 -1
  45. package/dist/app/displays/use-board-move.js +3 -3
  46. package/dist/app/displays/use-calendar-move.js +1 -1
  47. package/dist/app/document-title.js +1 -1
  48. package/dist/app/embedded-list/cut-off-note.js +7 -1
  49. package/dist/app/embedded-list/embedded-row-targets.js +3 -3
  50. package/dist/app/embedded-list/messages.js +2 -21
  51. package/dist/app/export/builder-port.js +1 -1
  52. package/dist/app/export/export-dialog.js +14 -8
  53. package/dist/app/export/messages.js +2 -75
  54. package/dist/app/export/use-export-flow.js +9 -3
  55. package/dist/app/field-editor.js +2 -2
  56. package/dist/app/field-errors.js +18 -7
  57. package/dist/app/field-messages.js +2 -45
  58. package/dist/app/field-types/members/messages.js +2 -15
  59. package/dist/app/field-types/messages.js +2 -5
  60. package/dist/app/field-types/widget-part.js +1 -1
  61. package/dist/app/file-field.js +3 -3
  62. package/dist/app/gallery/gallery-section.js +5 -2
  63. package/dist/app/gallery/messages.js +2 -27
  64. package/dist/app/gallery/photo-details.js +2 -2
  65. package/dist/app/hand-order/hand-sorted-list.js +1 -2
  66. package/dist/app/hand-order/messages.js +2 -29
  67. package/dist/app/hand-order/use-hand-order.js +1 -1
  68. package/dist/app/history/describe-change.js +1 -1
  69. package/dist/app/history/messages.js +2 -29
  70. package/dist/app/import/convert.js +19 -10
  71. package/dist/app/import/import-check-step.js +5 -5
  72. package/dist/app/import/import-dialog.js +5 -2
  73. package/dist/app/import/import-file-step.js +1 -1
  74. package/dist/app/import/import-mapping-step.js +3 -3
  75. package/dist/app/import/messages.js +2 -197
  76. package/dist/app/import/prepare-rows.js +11 -4
  77. package/dist/app/import/sheet-cell.js +1 -1
  78. package/dist/app/import/xlsx-reader.js +2 -2
  79. package/dist/app/import/zip-reader.js +4 -1
  80. package/dist/app/list-actions/use-list-actions.js +4 -1
  81. package/dist/app/list-edit/messages.js +2 -11
  82. package/dist/app/list-empty-state.js +7 -4
  83. package/dist/app/list-group-chart.js +1 -1
  84. package/dist/app/list-messages.js +2 -53
  85. package/dist/app/list-page.js +9 -9
  86. package/dist/app/live-update/messages.js +2 -11
  87. package/dist/app/map/messages.js +2 -11
  88. package/dist/app/menu-icons.js +10 -3
  89. package/dist/app/messages.js +2 -139
  90. package/dist/app/meta-gate-messages.js +2 -13
  91. package/dist/app/nav-from-meta.js +8 -9
  92. package/dist/app/new-version/messages.js +2 -21
  93. package/dist/app/new-version/new-version-banner.js +1 -2
  94. package/dist/app/pages/action-inputs/action-inputs-dialog.js +1 -1
  95. package/dist/app/pages/action-inputs/input-answers.js +1 -1
  96. package/dist/app/pages/blocks/modal-form.js +1 -1
  97. package/dist/app/pages/blocks/settings.js +1 -1
  98. package/dist/app/pages/blocks/tabs.js +1 -1
  99. package/dist/app/pages/composed-page.js +1 -2
  100. package/dist/app/pages/custom-boundary.js +1 -2
  101. package/dist/app/pages/messages.js +2 -79
  102. package/dist/app/pages/render-node.js +2 -3
  103. package/dist/app/pages/use-run-action.js +14 -6
  104. package/dist/app/rank-after/dependency-rule.js +8 -2
  105. package/dist/app/rank-after/messages.js +2 -5
  106. package/dist/app/rank-after/ranked-place.js +7 -1
  107. package/dist/app/record-chart/messages.js +2 -25
  108. package/dist/app/record-lines-cell.js +4 -1
  109. package/dist/app/record-lines.js +2 -2
  110. package/dist/app/record-messages.js +2 -83
  111. package/dist/app/record-page.js +3 -3
  112. package/dist/app/record-row/messages.js +2 -23
  113. package/dist/app/record-row/record-row-body.js +1 -1
  114. package/dist/app/record-row/record-row.js +2 -2
  115. package/dist/app/record-row/saved-record-row.js +2 -2
  116. package/dist/app/related-cards/messages.js +2 -15
  117. package/dist/app/related-dots/dots-summary.js +1 -1
  118. package/dist/app/related-dots/messages.js +2 -5
  119. package/dist/app/related-dots/related-dots.js +2 -3
  120. package/dist/app/relation-picker.js +1 -1
  121. package/dist/app/runtime/messages.js +2 -55
  122. package/dist/app/runtime/runtime-status.js +12 -3
  123. package/dist/app/saved/messages.js +2 -19
  124. package/dist/app/saved/saved-list.js +2 -2
  125. package/dist/app/search/messages.js +2 -19
  126. package/dist/app/search/navigation-hits.js +1 -1
  127. package/dist/app/search/search-model.js +9 -3
  128. package/dist/app/searches/messages.js +2 -93
  129. package/dist/app/searches/save-search-button.js +3 -3
  130. package/dist/app/searches/saved-search-rows.js +2 -2
  131. package/dist/app/searches/saved-search-section.js +3 -3
  132. package/dist/app/searches/saved-searches.js +13 -11
  133. package/dist/app/searches/search-controls.js +1 -1
  134. package/dist/app/searches/search-diff.js +8 -2
  135. package/dist/app/searches/update-search-dialog.js +9 -3
  136. package/dist/app/searches/use-save-search.js +1 -1
  137. package/dist/app/searches/use-search-row.js +2 -2
  138. package/dist/app/sensitive-field.js +3 -3
  139. package/dist/app/source-notice.js +3 -3
  140. package/dist/app/staff-banner.js +12 -8
  141. package/dist/app/use-live-save.js +2 -2
  142. package/dist/app/user-menu-from-meta.js +2 -3
  143. package/dist/app/value-badge.js +3 -4
  144. package/dist/app-shell/global-search.js +2 -2
  145. package/dist/app-shell/messages.js +2 -63
  146. package/dist/app-shell/sidebar-group.js +2 -2
  147. package/dist/app-shell/sidebar.js +1 -2
  148. package/dist/app-shell/top-bar.js +1 -1
  149. package/dist/assistant-dock/messages.js +2 -23
  150. package/dist/auth/auth-gate.js +1 -1
  151. package/dist/auth/auth-messages.js +9 -88
  152. package/dist/auth/email-code-form.js +2 -3
  153. package/dist/auth/forgot-password-form.js +2 -3
  154. package/dist/auth/messages.js +2 -203
  155. package/dist/auth/provider-sign-in-page.js +3 -3
  156. package/dist/auth/resend-code-button.js +1 -1
  157. package/dist/auth/reset-password-form.js +1 -1
  158. package/dist/auth/reset-password-page.js +1 -1
  159. package/dist/auth/sign-in-form.js +2 -2
  160. package/dist/auth/sign-up-code-form.js +2 -3
  161. package/dist/auth/sign-up-details-form.js +3 -4
  162. package/dist/auth/staff-sign-in-form.js +3 -3
  163. package/dist/calls/call-guests-panel.js +1 -1
  164. package/dist/calls/call-lobby-notice.js +1 -1
  165. package/dist/calls/call-mark.js +1 -1
  166. package/dist/calls/call-people.js +1 -1
  167. package/dist/calls/call-tile.js +2 -2
  168. package/dist/calls/messages.js +2 -139
  169. package/dist/carousel/carousel-controls.js +4 -1
  170. package/dist/carousel/messages.js +2 -13
  171. package/dist/chat/messages.js +2 -19
  172. package/dist/compact-table/compact-table.js +1 -1
  173. package/dist/compact-table/messages.js +2 -15
  174. package/dist/data-grid/cell-text.js +6 -5
  175. package/dist/data-grid/cells.js +7 -4
  176. package/dist/data-grid/grid-footer.js +1 -1
  177. package/dist/data-grid/grid-row.js +1 -1
  178. package/dist/data-grid/header-menu.js +1 -1
  179. package/dist/data-grid/messages.js +2 -49
  180. package/dist/data-grid/resize-handle.js +1 -1
  181. package/dist/data-grid/row-reorder.js +20 -5
  182. package/dist/filter-panel/active-filter-chips.js +1 -1
  183. package/dist/filter-panel/date-presets.js +2 -2
  184. package/dist/filter-panel/facet-combobox.js +1 -1
  185. package/dist/filter-panel/facet-group.js +1 -1
  186. package/dist/filter-panel/messages.js +2 -49
  187. package/dist/filter-panel/range-filter.js +1 -1
  188. package/dist/format/date.js +4 -4
  189. package/dist/format/messages.js +2 -21
  190. package/dist/format/money.js +1 -1
  191. package/dist/format/number.js +5 -2
  192. package/dist/forms/messages.js +2 -21
  193. package/dist/inline-child-table/inline-child-table.js +19 -4
  194. package/dist/inline-child-table/line-row.js +2 -2
  195. package/dist/inline-child-table/messages.js +2 -35
  196. package/dist/invitations/link-notice.js +2 -3
  197. package/dist/invitations/messages.js +2 -21
  198. package/dist/invitations/pending-invitation-row.js +1 -1
  199. package/dist/lists/messages.js +2 -5
  200. package/dist/live/columns-from-model.js +14 -31
  201. package/dist/live/display-value.js +1 -1
  202. package/dist/live/messages.js +2 -15
  203. package/dist/live/value-color.js +13 -3
  204. package/dist/live/view-fields.js +4 -2
  205. package/dist/locale/en.js +1399 -0
  206. package/dist/locale/messages.js +38 -7
  207. package/dist/locale/nl.js +1399 -0
  208. package/dist/markdown/messages.js +2 -13
  209. package/dist/mentions/messages.js +2 -13
  210. package/dist/notifications/bell/messages.js +2 -35
  211. package/dist/notifications/bell/unread-label.js +1 -1
  212. package/dist/organizations/invitation-page.js +31 -13
  213. package/dist/organizations/invitations-page.js +1 -1
  214. package/dist/organizations/members-page.js +2 -2
  215. package/dist/organizations/messages.js +2 -187
  216. package/dist/organizations/organization-page.js +4 -4
  217. package/dist/organizations/organizations-page.js +1 -1
  218. package/dist/package.js +1 -1
  219. package/dist/plugins/load-plugin.js +2 -2
  220. package/dist/plugins/messages.js +2 -33
  221. package/dist/plugins/plugin-notice.js +7 -5
  222. package/dist/primitives/badge.d.ts +2 -1
  223. package/dist/primitives/messages.js +2 -13
  224. package/dist/primitives/token.js +1 -1
  225. package/dist/record-view/field.js +2 -2
  226. package/dist/record-view/messages.js +2 -33
  227. package/dist/record-view/record-header.js +2 -2
  228. package/dist/roles/messages.js +2 -11
  229. package/dist/shell/assets/app-BOuBCV1m.js +8 -0
  230. package/dist/shell/assets/{calls-CPiQcC70.js → calls-C22bYKio.js} +2 -2
  231. package/dist/shell/assets/export-worker-ClXdfeuq.js +15 -0
  232. package/dist/shell/assets/{index-_ZpZ2ro0.js → index-G0fdUd70.js} +2 -2
  233. package/dist/shell/assets/{maplibre-CjNYwEqW.js → maplibre-CRmpQfDl.js} +3 -3
  234. package/dist/shell/assets/parse-worker-DxsmAjef.js +18 -0
  235. package/dist/shell/assets/preload-helper-BgLOXTzV.js +2 -0
  236. package/dist/shell/assets/{record-map-DjqQGqZ2.js → record-map-DsP4sXes.js} +2 -2
  237. package/dist/shell/assets/{records-map-DU29d6QK.js → records-map-BtWK38Kn.js} +2 -2
  238. package/dist/shell/assets/shared-protobase-ui-xqMMtr7u.js +2 -0
  239. package/dist/shell/assets/vendor-Kvdo8Jrw.js +73 -0
  240. package/dist/shell/index.html +5 -5
  241. package/dist/shell/protobase.shell.json +2 -2
  242. package/dist/shell/protobase.sw.js +2 -2
  243. package/dist/shell-source-maps/assets/app-BOuBCV1m.js.map +1 -0
  244. package/dist/shell-source-maps/assets/{calls-CPiQcC70.js.map → calls-C22bYKio.js.map} +1 -1
  245. package/dist/shell-source-maps/assets/export-worker-ClXdfeuq.js.map +1 -0
  246. package/dist/shell-source-maps/assets/{index-_ZpZ2ro0.js.map → index-G0fdUd70.js.map} +1 -1
  247. package/dist/shell-source-maps/assets/{maplibre-CjNYwEqW.js.map → maplibre-CRmpQfDl.js.map} +1 -1
  248. package/dist/shell-source-maps/assets/parse-worker-DxsmAjef.js.map +1 -0
  249. package/dist/shell-source-maps/assets/preload-helper-BgLOXTzV.js.map +1 -0
  250. package/dist/shell-source-maps/assets/{record-map-DjqQGqZ2.js.map → record-map-DsP4sXes.js.map} +1 -1
  251. package/dist/shell-source-maps/assets/{records-map-DU29d6QK.js.map → records-map-BtWK38Kn.js.map} +1 -1
  252. package/dist/shell-source-maps/assets/shared-protobase-ui-xqMMtr7u.js.map +1 -0
  253. package/dist/shell-source-maps/assets/vendor-Kvdo8Jrw.js.map +1 -0
  254. package/dist/side-panel/messages.js +2 -5
  255. package/dist/status/messages.js +2 -59
  256. package/dist/toasts/messages.js +2 -5
  257. package/dist/users/create-user-form.js +1 -1
  258. package/dist/users/messages.js +2 -49
  259. package/package.json +5 -4
  260. package/dist/app/icons.js +0 -27
  261. package/dist/app-shell/nav.js +0 -85
  262. package/dist/locale/slotted.js +0 -14
  263. package/dist/mocks/activity.js +0 -24
  264. package/dist/mocks/rng.js +0 -20
  265. package/dist/mocks/users.js +0 -63
  266. package/dist/shell/assets/app-BPv_SjnU.js +0 -9
  267. package/dist/shell/assets/export-worker-3e4Zsv0a.js +0 -3
  268. package/dist/shell/assets/parse-worker-UhbwEjS0.js +0 -6
  269. package/dist/shell/assets/preload-helper-SYSsmQ2O.js +0 -2
  270. package/dist/shell/assets/shared-protobase-ui-Cab5nqST.js +0 -2
  271. package/dist/shell/assets/vendor-iwLB0x-s.js +0 -63
  272. package/dist/shell-source-maps/assets/app-BPv_SjnU.js.map +0 -1
  273. package/dist/shell-source-maps/assets/export-worker-3e4Zsv0a.js.map +0 -1
  274. package/dist/shell-source-maps/assets/parse-worker-UhbwEjS0.js.map +0 -1
  275. package/dist/shell-source-maps/assets/preload-helper-SYSsmQ2O.js.map +0 -1
  276. package/dist/shell-source-maps/assets/shared-protobase-ui-Cab5nqST.js.map +0 -1
  277. package/dist/shell-source-maps/assets/vendor-iwLB0x-s.js.map +0 -1
@@ -1,48 +1,5 @@
1
- import { defineMessages } from "../locale/messages.js";
1
+ import { messages } from "../locale/messages.js";
2
2
  //#region src/app/field-messages.ts
3
- const text = defineMessages({
4
- en: {
5
- atLeastCharacters: (label, count, n) => `${label} needs at least ${count} character${n === 1 ? "" : "s"}`,
6
- atMostCharacters: (label, count, n) => `${label} can have at most ${count} character${n === 1 ? "" : "s"}`,
7
- wholeNumberAtLeast: (min) => `Enter a whole number of at least ${min}`,
8
- wholeNumberAtMost: (max) => `Enter a whole number of at most ${max}`,
9
- wholeNumber: "Enter a whole number",
10
- number: "Enter a number",
11
- wholeNumberBelow: (below) => `Enter a whole number below ${below}`,
12
- decimalsBelow: (scale, below) => `Enter a number with at most ${scale} decimal${scale === 1 ? "" : "s"}, below ${below}`,
13
- date: "Enter a date",
14
- timestamp: "Enter a date and time",
15
- country: "Enter a two-letter country code, such as NL",
16
- currency: "Enter a three-letter currency code, such as EUR",
17
- uuid: "Enter a valid ID",
18
- enum: "Choose one of the options",
19
- relation: "Choose a record",
20
- json: "Enter valid JSON",
21
- required: (label) => `${label} is required`,
22
- checkField: "Check the marked field.",
23
- checkFields: (count) => `Check ${count} fields.`
24
- },
25
- nl: {
26
- atLeastCharacters: (label, count, n) => `${label} moet minstens ${count} ${n === 1 ? "teken" : "tekens"} hebben`,
27
- atMostCharacters: (label, count, n) => `${label} mag hoogstens ${count} ${n === 1 ? "teken" : "tekens"} hebben`,
28
- wholeNumberAtLeast: (min) => `Vul een geheel getal in van minstens ${min}`,
29
- wholeNumberAtMost: (max) => `Vul een geheel getal in van hoogstens ${max}`,
30
- wholeNumber: "Vul een geheel getal in",
31
- number: "Vul een getal in",
32
- wholeNumberBelow: (below) => `Vul een geheel getal in onder ${below}`,
33
- decimalsBelow: (scale, below) => `Vul een getal in met hoogstens ${scale} ${scale === 1 ? "decimaal" : "decimalen"}, onder ${below}`,
34
- date: "Vul een datum in",
35
- timestamp: "Vul een datum en tijd in",
36
- country: "Vul een landcode van twee letters in, zoals NL",
37
- currency: "Vul een valutacode van drie letters in, zoals EUR",
38
- uuid: "Vul een geldig ID in",
39
- enum: "Kies een van de opties",
40
- relation: "Kies een record",
41
- json: "Vul geldige JSON in",
42
- required: (label) => `${label} is verplicht`,
43
- checkField: "Controleer het gemarkeerde veld.",
44
- checkFields: (count) => `Controleer ${count} velden.`
45
- }
46
- });
3
+ const text = messages("app/field");
47
4
  //#endregion
48
5
  export { text };
@@ -1,18 +1,5 @@
1
- import { defineMessages } from "../../../locale/messages.js";
1
+ import { messages } from "../../../locale/messages.js";
2
2
  //#region src/app/field-types/members/messages.ts
3
- const text = defineMessages({
4
- en: {
5
- needsOrganizations: "Choosing members needs organizations: turn them on in the auth config.",
6
- couldNotLoadMembers: "Could not load the members.",
7
- unknownMember: "Unknown member",
8
- searchMembers: "Search members"
9
- },
10
- nl: {
11
- needsOrganizations: "Leden kiezen vraagt om organisaties: zet ze aan in de auth-configuratie.",
12
- couldNotLoadMembers: "De leden konden niet worden geladen.",
13
- unknownMember: "Onbekend lid",
14
- searchMembers: "Leden zoeken"
15
- }
16
- });
3
+ const text = messages("app/field-types/members");
17
4
  //#endregion
18
5
  export { text };
@@ -1,8 +1,5 @@
1
- import { defineMessages } from "../../locale/messages.js";
1
+ import { messages } from "../../locale/messages.js";
2
2
  //#region src/app/field-types/messages.ts
3
- const text = defineMessages({
4
- en: { fieldType: (name) => `The field type ${name}` },
5
- nl: { fieldType: (name) => `Het veldtype ${name}` }
6
- });
3
+ const text = messages("app/field-types");
7
4
  //#endregion
8
5
  export { text };
@@ -25,7 +25,7 @@ const WidgetPart = ({ fallback, ...rest }) => {
25
25
  const element = partOf(rest);
26
26
  if (!element) return fallback;
27
27
  return /* @__PURE__ */ jsx(CustomBoundary, {
28
- name: text("fieldType", rest.shown.name),
28
+ name: text("fieldType", { name: rest.shown.name }),
29
29
  fallback,
30
30
  children: element
31
31
  });
@@ -98,7 +98,7 @@ const FileField = ({ field, hints, resource, value, locked, invalid, onChange })
98
98
  type: "file",
99
99
  hidden: true,
100
100
  accept: acceptOf(field),
101
- "aria-label": text("chooseFileFor", label),
101
+ "aria-label": text("chooseFileFor", { label }),
102
102
  onChange: (event) => choose(event.target.files)
103
103
  });
104
104
  const error = upload.error && /* @__PURE__ */ jsx("div", {
@@ -111,7 +111,7 @@ const FileField = ({ field, hints, resource, value, locked, invalid, onChange })
111
111
  if (upload.isPending) return /* @__PURE__ */ jsxs("div", {
112
112
  className: "py-1.5",
113
113
  role: "status",
114
- "aria-label": text("uploadingLabel", label),
114
+ "aria-label": text("uploadingLabel", { label }),
115
115
  children: [/* @__PURE__ */ jsx("div", {
116
116
  className: "h-1.5 overflow-hidden rounded-full bg-muted",
117
117
  children: /* @__PURE__ */ jsx("div", {
@@ -120,7 +120,7 @@ const FileField = ({ field, hints, resource, value, locked, invalid, onChange })
120
120
  })
121
121
  }), /* @__PURE__ */ jsx("span", {
122
122
  className: "text-xs text-muted-foreground",
123
- children: text("uploading", Math.round((progress ?? 0) * 100))
123
+ children: text("uploading", { percent: Math.round((progress ?? 0) * 100) })
124
124
  })]
125
125
  });
126
126
  if (fileShown(value)) return /* @__PURE__ */ jsxs("div", { children: [
@@ -92,7 +92,10 @@ const GallerySection = ({ item, record, recordKey }) => {
92
92
  const last = index === shown - 1 && more > 0;
93
93
  return /* @__PURE__ */ jsxs("button", {
94
94
  type: "button",
95
- "aria-label": last ? text("showAll", count) : text("showPhoto", index + 1, count),
95
+ "aria-label": last ? text("showAll", { count }) : text("showPhoto", {
96
+ index: index + 1,
97
+ count
98
+ }),
96
99
  onClick: () => setOpen(index),
97
100
  className: cn("group/tile relative overflow-hidden bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary", index === 0 ? "col-span-4 row-span-2" : "max-md:hidden", spans[shown][index]),
98
101
  children: [
@@ -120,7 +123,7 @@ const GallerySection = ({ item, record, recordKey }) => {
120
123
  onIndex: setOpen,
121
124
  onClose: () => setOpen(void 0),
122
125
  details,
123
- detailsTitle: holder && text("holderDetails", holderView?.names?.singular ?? humanize(holder.name))
126
+ detailsTitle: holder && text("holderDetails", { singular: holderView?.names?.singular ?? humanize(holder.name) })
124
127
  })]
125
128
  });
126
129
  };
@@ -1,30 +1,5 @@
1
- import { defineMessages } from "../../locale/messages.js";
1
+ import { messages } from "../../locale/messages.js";
2
2
  //#region src/app/gallery/messages.ts
3
- const text = defineMessages({
4
- en: {
5
- couldNotLoad: "Could not load the photos",
6
- showAll: (count) => `Show all ${count} photos`,
7
- showPhoto: (index, count) => `Show photo ${index} of ${count}`,
8
- details: "Details",
9
- holderDetails: (singular) => `${singular} details`,
10
- close: "Close",
11
- previousPhoto: "Previous photo",
12
- nextPhoto: "Next photo",
13
- couldNotLoadOne: (singular) => `Could not load the ${singular}`,
14
- open: (singular) => `Open ${singular}`
15
- },
16
- nl: {
17
- couldNotLoad: "Kon de foto’s niet laden",
18
- showAll: (count) => `Alle ${count} foto’s tonen`,
19
- showPhoto: (index, count) => `Foto ${index} van ${count} tonen`,
20
- details: "Gegevens",
21
- holderDetails: (singular) => `Gegevens van ${singular.toLowerCase()}`,
22
- close: "Sluiten",
23
- previousPhoto: "Vorige foto",
24
- nextPhoto: "Volgende foto",
25
- couldNotLoadOne: (singular) => `Kon ${singular} niet laden`,
26
- open: (singular) => `${singular} openen`
27
- }
28
- });
3
+ const text = messages("app/gallery");
29
4
  //#endregion
30
5
  export { text };
@@ -18,7 +18,7 @@ const PhotoDetails = ({ model, view, photoKey, fields }) => {
18
18
  const singular = (view?.names?.singular ?? humanize(model.name)).toLowerCase();
19
19
  if (record.isPending) return /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-48" });
20
20
  if (record.error) return /* @__PURE__ */ jsx(ErrorBanner, {
21
- title: text("couldNotLoadOne", singular),
21
+ title: text("couldNotLoadOne", { singular }),
22
22
  error: record.error
23
23
  });
24
24
  const shown = fields.filter((name) => fieldAccess(record.data.permissions, name) !== "hidden");
@@ -36,7 +36,7 @@ const PhotoDetails = ({ model, view, photoKey, fields }) => {
36
36
  key: photoKey
37
37
  },
38
38
  className: "mt-3 inline-block font-medium text-primary-text hover:underline",
39
- children: text("open", singular)
39
+ children: text("open", { singular })
40
40
  })] });
41
41
  };
42
42
  //#endregion
@@ -6,7 +6,6 @@ import { useAppAddress } from "../use-app-address.js";
6
6
  import { ErrorBanner } from "../error-banner.js";
7
7
  import { useProjectUi } from "../pages/project-ui.js";
8
8
  import { Problem } from "../pages/problem.js";
9
- import { slotted } from "../../locale/slotted.js";
10
9
  import { DataGrid } from "../../data-grid/data-grid.js";
11
10
  import { text } from "./messages.js";
12
11
  import { embeddedColumns } from "../embedded-list/embedded-columns.js";
@@ -60,7 +59,7 @@ const HandSortedList = ({ model, view, field, filter, columns, sort }) => {
60
59
  total: rows.length,
61
60
  rowAt: (index) => rows[index]
62
61
  }, [rows]);
63
- if (ruleName !== void 0 && !rule) return /* @__PURE__ */ jsx(Problem, { children: slotted(text("noRule"), ruleName) });
62
+ if (ruleName !== void 0 && !rule) return /* @__PURE__ */ jsx(Problem, { children: text.rich("noRule", { rule: ruleName }) });
64
63
  if (order.loading) return /* @__PURE__ */ jsx("div", {
65
64
  className: "flex flex-col gap-2",
66
65
  children: Array.from({ length: 3 }, (_, index) => /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }, index))
@@ -1,32 +1,5 @@
1
- import { defineMessages } from "../../locale/messages.js";
1
+ import { messages } from "../../locale/messages.js";
2
2
  //#region src/app/hand-order/messages.ts
3
- const text = defineMessages({
4
- en: {
5
- done: "Done",
6
- reorder: "Reorder",
7
- couldNotLoad: "Could not load",
8
- nothingYet: "Nothing here yet.",
9
- couldNotChange: "Could not change the order",
10
- orderChanged: "Order changed",
11
- undo: "Undo",
12
- couldNotUndo: "Could not undo",
13
- movedToPlace: (place) => `Moved to place ${place}`,
14
- notMoved: "Left in its place",
15
- noRule: "No drop rule is registered as {}. Give it in dropRules in protobase.ui.tsx, or load the plugin that provides it."
16
- },
17
- nl: {
18
- done: "Klaar",
19
- reorder: "Volgorde wijzigen",
20
- couldNotLoad: "Kon niet laden",
21
- nothingYet: "Hier staat nog niets.",
22
- couldNotChange: "Kon de volgorde niet wijzigen",
23
- orderChanged: "Volgorde gewijzigd",
24
- undo: "Ongedaan maken",
25
- couldNotUndo: "Kon niet ongedaan maken",
26
- movedToPlace: (place) => `Verplaatst naar plaats ${place}`,
27
- notMoved: "Op zijn plaats gelaten",
28
- noRule: "Er is geen sleepregel geregistreerd als {}. Geef die in dropRules in protobase.ui.tsx, of laad de plug-in die haar levert."
29
- }
30
- });
3
+ const text = messages("app/hand-order");
31
4
  //#endregion
32
5
  export { text };
@@ -156,7 +156,7 @@ const useHandOrder = ({ model, view, field, filter, fields, rule }) => {
156
156
  const allowed = allowedDrop(rows.map((row) => displayRow(model, row).record), from, dropped, rule);
157
157
  if (allowed.reason !== void 0) toast.show({
158
158
  state: "warning",
159
- title: allowed.to === from ? text("notMoved") : text("movedToPlace", allowed.to + 1),
159
+ title: allowed.to === from ? text("notMoved") : text("movedToPlace", { place: allowed.to + 1 }),
160
160
  description: allowed.reason
161
161
  });
162
162
  return allowed.to;
@@ -5,7 +5,7 @@ import { text } from "./messages.js";
5
5
  /** Who made a change: their name, else their id; a write from outside the app names the database role. */
6
6
  const changedBy = (change) => {
7
7
  if (change.actor) return change.actor.name ?? change.actor.id;
8
- return change.databaseRole ? text("databaseRole", change.databaseRole) : text("database");
8
+ return change.databaseRole ? text("databaseRole", { role: change.databaseRole }) : text("database");
9
9
  };
10
10
  /**
11
11
  * A change as the record page tells it: who, what they did, and for an update each changed field the model still has,
@@ -1,32 +1,5 @@
1
- import { defineMessages } from "../../locale/messages.js";
1
+ import { messages } from "../../locale/messages.js";
2
2
  //#region src/app/history/messages.ts
3
- const text = defineMessages({
4
- en: {
5
- create: "created this",
6
- update: "changed",
7
- delete: "deleted this",
8
- undelete: "restored this",
9
- database: "Database",
10
- databaseRole: (role) => `Database (${role})`,
11
- changed: "changed",
12
- changedThis: "changed this",
13
- couldNotLoad: "Could not load the history",
14
- noChanges: "No changes kept yet.",
15
- showMore: "Show more"
16
- },
17
- nl: {
18
- create: "maakte dit",
19
- update: "wijzigde",
20
- delete: "verwijderde dit",
21
- undelete: "zette dit terug",
22
- database: "Database",
23
- databaseRole: (role) => `Database (${role})`,
24
- changed: "gewijzigd",
25
- changedThis: "wijzigde dit",
26
- couldNotLoad: "Kon de geschiedenis niet laden",
27
- noChanges: "Nog geen wijzigingen bewaard.",
28
- showMore: "Meer tonen"
29
- }
30
- });
3
+ const text = messages("app/history");
31
4
  //#endregion
32
5
  export { text };
@@ -18,16 +18,16 @@ const toNumberText = (cell, options) => {
18
18
  };
19
19
  const integerValue = (field, cell, options) => {
20
20
  const text$1 = toNumberText(cell, options);
21
- if (text$1 === void 0) return problem(text("notNumber", quoted(cell)));
21
+ if (text$1 === void 0) return problem(text("notNumber", { cell: quoted(cell) }));
22
22
  const [whole, fraction = ""] = text$1.split(".");
23
- if (/[1-9]/.test(fraction) || /e/i.test(text$1)) return problem(text("notWholeNumber", quoted(cell)));
23
+ if (/[1-9]/.test(fraction) || /e/i.test(text$1)) return problem(text("notWholeNumber", { cell: quoted(cell) }));
24
24
  if (field.type === "bigint") return ok(String(BigInt(whole)));
25
25
  const value = Number(whole);
26
- return Number.isSafeInteger(value) ? ok(value) : problem(text("tooLarge", quoted(cell)));
26
+ return Number.isSafeInteger(value) ? ok(value) : problem(text("tooLarge", { cell: quoted(cell) }));
27
27
  };
28
28
  const decimalValue = (cell, options) => {
29
29
  const text$2 = toNumberText(cell, options);
30
- return text$2 === void 0 ? problem(text("notNumber", quoted(cell))) : ok(text$2);
30
+ return text$2 === void 0 ? problem(text("notNumber", { cell: quoted(cell) })) : ok(text$2);
31
31
  };
32
32
  const trueWords = /* @__PURE__ */ new Set([
33
33
  "true",
@@ -44,7 +44,7 @@ const booleanValue = (cell) => {
44
44
  const text$3 = typeof cell === "string" || typeof cell === "number" ? String(cell).trim().toLowerCase() : "";
45
45
  if (trueWords.has(text$3)) return ok(true);
46
46
  if (falseWords.has(text$3)) return ok(false);
47
- return problem(text("notBoolean", quoted(cell)));
47
+ return problem(text("notBoolean", { cell: quoted(cell) }));
48
48
  };
49
49
  const pad = (value) => String(value).padStart(2, "0");
50
50
  const calendarDate = (year, month, day) => {
@@ -91,11 +91,14 @@ const wallTimeOf = (cell, options) => {
91
91
  }
92
92
  return typeof cell === "string" ? readWallTime(cell, options.dateOrder) : void 0;
93
93
  };
94
- const notDate = (cell, options) => problem(text("notDate", quoted(cell), options.dateOrder === "dmy"));
94
+ const notDate = (cell, options) => problem(text("notDate", {
95
+ cell: quoted(cell),
96
+ dayFirst: options.dateOrder === "dmy"
97
+ }));
95
98
  const dateValue = (cell, options) => {
96
99
  const at = wallTimeOf(cell, options);
97
100
  if (!at) return notDate(cell, options);
98
- if (at.time && at.time !== "00:00:00") return problem(text("hasTime", quoted(cell)));
101
+ if (at.time && at.time !== "00:00:00") return problem(text("hasTime", { cell: quoted(cell) }));
99
102
  return ok(at.date);
100
103
  };
101
104
  const timestampValue = (cell, options) => {
@@ -112,10 +115,16 @@ const enumValue = (field, hints, cell) => {
112
115
  const text$4 = normalized(cellText(cell));
113
116
  const matches = values.filter((value) => normalized(value) === text$4 || normalized(enumLabel(value, hints?.valueLabels)) === text$4);
114
117
  if (matches.length === 1) return ok(matches[0]);
115
- if (matches.length > 1) return problem(text("severalValues", quoted(cell), matches.map((value) => enumLabel(value, hints?.valueLabels)).join(", ")));
116
- return problem(text("notOneOf", quoted(cell), values.map((value) => enumLabel(value, hints?.valueLabels)).join(", ")));
118
+ if (matches.length > 1) return problem(text("severalValues", {
119
+ cell: quoted(cell),
120
+ values: matches.map((value) => enumLabel(value, hints?.valueLabels)).join(", ")
121
+ }));
122
+ return problem(text("notOneOf", {
123
+ cell: quoted(cell),
124
+ values: values.map((value) => enumLabel(value, hints?.valueLabels)).join(", ")
125
+ }));
117
126
  };
118
- const textValue = (cell) => typeof cell === "boolean" ? problem(text("notText", quoted(cell))) : ok(cellText(cell));
127
+ const textValue = (cell) => typeof cell === "boolean" ? problem(text("notText", { cell: quoted(cell) })) : ok(cellText(cell));
119
128
  /**
120
129
  * The value a cell gives a field, as the API takes it, or the problem that keeps it from being one: never a guess, and an
121
130
  * empty cell is null, never a default. A relation's cell is the value of the field its records are found by, so it
@@ -13,7 +13,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
13
13
  /** How many rows with problems the check lists; the file of them holds every one. */
14
14
  const listedProblems = 50;
15
15
  /** Saves the rows with their problems as a CSV named after the imported file. */
16
- const downloadRows = (fileName, headers, rows) => saveFile(failedRowsCsv(headers, rows), text("notImportedFile", (fileName ?? "import").replace(/\.[^.]+$/, "")), "text/csv");
16
+ const downloadRows = (fileName, headers, rows) => saveFile(failedRowsCsv(headers, rows), text("notImportedFile", { name: (fileName ?? "import").replace(/\.[^.]+$/, "") }), "text/csv");
17
17
  /** The rows with what keeps each from being imported, at most `listedProblems` of them. */
18
18
  const ProblemList = ({ rows }) => /* @__PURE__ */ jsxs("ul", {
19
19
  "aria-label": text("rowsNotImported"),
@@ -21,19 +21,19 @@ const ProblemList = ({ rows }) => /* @__PURE__ */ jsxs("ul", {
21
21
  children: [rows.slice(0, listedProblems).map((row) => /* @__PURE__ */ jsxs("li", { children: [
22
22
  /* @__PURE__ */ jsx("span", {
23
23
  className: "font-medium",
24
- children: text("rowProblems", row.line)
24
+ children: text("rowProblems", { line: row.line })
25
25
  }),
26
26
  " ",
27
27
  row.problems.join("; ")
28
28
  ] }, row.line)), rows.length > listedProblems && /* @__PURE__ */ jsx("li", {
29
29
  className: "text-muted-foreground",
30
- children: text("andMore", (rows.length - listedProblems).toLocaleString(formatTag()))
30
+ children: text("andMore", { count: (rows.length - listedProblems).toLocaleString(formatTag()) })
31
31
  })]
32
32
  });
33
33
  const ImportChecking = ({ rows }) => /* @__PURE__ */ jsxs("p", {
34
34
  className: "flex items-center gap-2 text-muted-foreground",
35
35
  role: "status",
36
- children: [/* @__PURE__ */ jsx(Spinner, { className: "size-3.5" }), text("checkingRows", rows.toLocaleString(formatTag()))]
36
+ children: [/* @__PURE__ */ jsx(Spinner, { className: "size-3.5" }), text("checkingRows", { count: rows.toLocaleString(formatTag()) })]
37
37
  });
38
38
  /**
39
39
  * What the import would do, before it writes anything: how many rows create or update a record, the first rows as they
@@ -99,7 +99,7 @@ const ImportCheckStep = ({ check, model, resources, views, columns, headers, fil
99
99
  }),
100
100
  /* @__PURE__ */ jsx("p", {
101
101
  className: "text-xs text-muted-foreground",
102
- children: text("batches", 100)
102
+ children: text("batches", { size: 100 })
103
103
  })
104
104
  ]
105
105
  });
@@ -73,7 +73,10 @@ const ImportDialog = ({ model, resources, views, canUpdate, onClose, sourceFor }
73
73
  variant: "primary",
74
74
  disabled: rows === 0,
75
75
  onClick: () => flow.start(rows),
76
- children: text("importRows", rows.toLocaleString(formatTag()), rows)
76
+ children: text("importRows", {
77
+ count: rows.toLocaleString(formatTag()),
78
+ rows
79
+ })
77
80
  })] });
78
81
  }
79
82
  case "importing": return /* @__PURE__ */ jsx(Button, {
@@ -132,7 +135,7 @@ const ImportDialog = ({ model, resources, views, canUpdate, onClose, sourceFor }
132
135
  return /* @__PURE__ */ jsx(ResponsiveDialog, {
133
136
  open: true,
134
137
  wide: true,
135
- title: text("importPlural", plural),
138
+ title: text("importPlural", { plural }),
136
139
  description: flow.file && step.kind !== "file" ? flow.file.name : void 0,
137
140
  onClose: close,
138
141
  actions: actions(),
@@ -39,7 +39,7 @@ const ImportFileStep = ({ file, sheets, sheet, reading, onChoose, onSheet }) =>
39
39
  reading && /* @__PURE__ */ jsxs("p", {
40
40
  className: "flex items-center gap-2 text-muted-foreground",
41
41
  role: "status",
42
- children: [/* @__PURE__ */ jsx(Spinner, { className: "size-3.5" }), text("reading", file?.name ?? text("theFile"))]
42
+ children: [/* @__PURE__ */ jsx(Spinner, { className: "size-3.5" }), text("reading", { name: file?.name ?? text("theFile") })]
43
43
  }),
44
44
  !reading && sheets.length > 1 && /* @__PURE__ */ jsxs("div", {
45
45
  className: "flex items-end gap-3",
@@ -162,13 +162,13 @@ const ImportMappingStep = ({ flow, model, resources, views, canUpdate }) => {
162
162
  className: "flex min-w-0 flex-col gap-2",
163
163
  children: [/* @__PURE__ */ jsx(ImportSelect, {
164
164
  label: text("field"),
165
- name: text("fieldFor", name),
165
+ name: text("fieldFor", { name }),
166
166
  value: mapped?.field ?? skip,
167
167
  options: fieldOptions,
168
168
  onChange: (next) => flow.mapColumn(column, next || void 0)
169
169
  }), target && /* @__PURE__ */ jsx(ImportSelect, {
170
170
  label: text("foundBy"),
171
- name: text("pluralFoundBy", views[target.name]?.names?.plural ?? fieldLabel(view, field.name)),
171
+ name: text("pluralFoundBy", { plural: views[target.name]?.names?.plural ?? fieldLabel(view, field.name) }),
172
172
  value: mapped.matchBy ?? target.primaryKey[0],
173
173
  options: matchFields(target).map((candidate) => ({
174
174
  value: candidate.name,
@@ -183,7 +183,7 @@ const ImportMappingStep = ({ flow, model, resources, views, canUpdate }) => {
183
183
  missing.length > 0 && /* @__PURE__ */ jsxs("p", {
184
184
  role: "alert",
185
185
  className: "flex gap-2 rounded-lg border border-warning/30 bg-warning-soft px-3 py-2 text-warning-text",
186
- children: [/* @__PURE__ */ jsx(TriangleAlert, { className: "mt-0.5 size-4 shrink-0" }), /* @__PURE__ */ jsx("span", { children: text("noColumnFills", missing.map((field) => fieldLabel(view, field.name)).join(", ")) })]
186
+ children: [/* @__PURE__ */ jsx(TriangleAlert, { className: "mt-0.5 size-4 shrink-0" }), /* @__PURE__ */ jsx("span", { children: text("noColumnFills", { fields: missing.map((field) => fieldLabel(view, field.name)).join(", ") }) })]
187
187
  })
188
188
  ]
189
189
  });