@protobase/ui 0.25.2 → 0.25.4

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 (271) hide show
  1. package/dist/account/account-pages.js +3 -2
  2. package/dist/account/account-section.js +1 -1
  3. package/dist/account/account-security-page.js +9 -4
  4. package/dist/account/backup-codes.js +7 -6
  5. package/dist/account/messages.js +214 -0
  6. package/dist/account/passkeys-section.js +23 -22
  7. package/dist/account/password-dialog.js +4 -3
  8. package/dist/account/sign-in-policy-form.js +14 -13
  9. package/dist/account/sign-in-policy-labels.js +30 -29
  10. package/dist/account/sign-in-policy-page.js +11 -6
  11. package/dist/account/sign-in-providers-section.js +6 -5
  12. package/dist/account/staff-sign-in-log.js +11 -10
  13. package/dist/account/totp-qr.js +2 -1
  14. package/dist/account/two-factor-section.js +24 -23
  15. package/dist/account/two-factor-setup.js +19 -18
  16. package/dist/action-card/action-card.js +2 -1
  17. package/dist/action-card/field-list.js +1 -1
  18. package/dist/action-card/messages.js +8 -0
  19. package/dist/activity-chart/activity-chart.js +3 -2
  20. package/dist/activity-chart/messages.js +14 -0
  21. package/dist/app/app.d.ts +1 -1
  22. package/dist/app/app.js +20 -21
  23. package/dist/app/assistant-shell.js +2 -1
  24. package/dist/app/batch-failure.js +2 -1
  25. package/dist/app/breadcrumb-for.js +4 -3
  26. package/dist/app/charts/chart-groups.js +3 -2
  27. package/dist/app/charts/chart-view.js +3 -2
  28. package/dist/app/charts/group-bars.js +2 -1
  29. package/dist/app/charts/messages.js +26 -0
  30. package/dist/app/charts/period-chart.js +3 -2
  31. package/dist/app/charts/split-points.js +2 -1
  32. package/dist/app/comments/comment-composer.js +19 -18
  33. package/dist/app/comments/comments-section.js +4 -3
  34. package/dist/app/comments/messages.js +26 -0
  35. package/dist/app/create/create-page.js +11 -18
  36. package/dist/app/custom-section.js +4 -6
  37. package/dist/app/displays/board-column.js +7 -6
  38. package/dist/app/displays/board-columns.js +3 -2
  39. package/dist/app/displays/board-display.js +13 -15
  40. package/dist/app/displays/calendar-controls.js +3 -2
  41. package/dist/app/displays/calendar-display.js +12 -17
  42. package/dist/app/displays/card-carousel.js +4 -3
  43. package/dist/app/displays/cards-display.js +2 -1
  44. package/dist/app/displays/custom-display.js +4 -6
  45. package/dist/app/displays/display-frame.js +3 -2
  46. package/dist/app/displays/list-cards.js +5 -8
  47. package/dist/app/displays/list-displays.js +3 -3
  48. package/dist/app/displays/map-display.js +15 -14
  49. package/dist/app/displays/messages.js +128 -2
  50. package/dist/app/displays/period-controls.js +4 -3
  51. package/dist/app/displays/record-card.js +7 -6
  52. package/dist/app/displays/timeline-display.js +17 -26
  53. package/dist/app/displays/timeline-range.js +2 -1
  54. package/dist/app/displays/timeline-row.js +1 -1
  55. package/dist/app/displays/use-board-move.js +2 -2
  56. package/dist/app/displays/use-calendar-move.js +2 -1
  57. package/dist/app/document-title.js +2 -1
  58. package/dist/app/error-banner.js +1 -1
  59. package/dist/app/export/builder-port.js +2 -1
  60. package/dist/app/export/export-dialog.js +39 -43
  61. package/dist/app/export/export-worker.js +2 -0
  62. package/dist/app/export/messages.js +78 -0
  63. package/dist/app/export/run-export.js +5 -2
  64. package/dist/app/export/sink.js +4 -3
  65. package/dist/app/export/use-export-flow.js +4 -3
  66. package/dist/app/field-editor.js +4 -3
  67. package/dist/app/field-types/messages.js +8 -0
  68. package/dist/app/field-types/widget-part.js +2 -1
  69. package/dist/app/file-field.js +11 -14
  70. package/dist/app/gallery/gallery-section.js +4 -3
  71. package/dist/app/gallery/lightbox.js +5 -4
  72. package/dist/app/gallery/messages.js +30 -0
  73. package/dist/app/gallery/photo-details.js +3 -2
  74. package/dist/app/hand-order/hand-sorted-list.js +3 -6
  75. package/dist/app/hand-order/messages.js +4 -2
  76. package/dist/app/history/describe-change.js +3 -8
  77. package/dist/app/history/messages.js +32 -0
  78. package/dist/app/import/convert.js +20 -19
  79. package/dist/app/import/failed-rows.js +3 -2
  80. package/dist/app/import/import-button.js +2 -1
  81. package/dist/app/import/import-check-step.js +21 -37
  82. package/dist/app/import/import-dialog.js +13 -17
  83. package/dist/app/import/import-file-step.js +5 -9
  84. package/dist/app/import/import-mapping-step.js +32 -35
  85. package/dist/app/import/import-result-step.js +13 -12
  86. package/dist/app/import/messages.js +200 -0
  87. package/dist/app/import/parse-worker.js +2 -0
  88. package/dist/app/import/prepare-rows.js +5 -4
  89. package/dist/app/import/sheet-cell.js +2 -1
  90. package/dist/app/import/sheet-file.js +3 -2
  91. package/dist/app/import/sheet-source.js +7 -3
  92. package/dist/app/import/xlsx-reader.js +4 -3
  93. package/dist/app/import/xlsx-xml.js +2 -1
  94. package/dist/app/import/zip-reader.js +4 -3
  95. package/dist/app/list-edit/use-list-edits.js +1 -1
  96. package/dist/app/list-group-chart.js +2 -1
  97. package/dist/app/list-page.js +1 -1
  98. package/dist/app/map/map-layer-switch.js +3 -2
  99. package/dist/app/map/messages.js +14 -0
  100. package/dist/app/messages.js +116 -2
  101. package/dist/app/meta-gate.js +1 -1
  102. package/dist/app/nav-from-meta.js +11 -10
  103. package/dist/app/pages/action-inputs/action-inputs-dialog.js +3 -2
  104. package/dist/app/pages/action-inputs/input-answers.js +6 -5
  105. package/dist/app/pages/blocks/card-row.js +3 -2
  106. package/dist/app/pages/blocks/field.js +1 -1
  107. package/dist/app/pages/blocks/modal-form.js +5 -4
  108. package/dist/app/pages/blocks/progress.js +1 -1
  109. package/dist/app/pages/blocks/record-card.js +3 -2
  110. package/dist/app/pages/blocks/stat.js +2 -1
  111. package/dist/app/pages/composed-page.js +6 -8
  112. package/dist/app/pages/confirm-action.js +2 -1
  113. package/dist/app/pages/custom-boundary.js +4 -2
  114. package/dist/app/pages/messages.js +64 -0
  115. package/dist/app/pages/render-node.js +5 -7
  116. package/dist/app/pages/use-run-action.js +11 -10
  117. package/dist/app/record-page.js +1 -1
  118. package/dist/app/record-row/messages.js +26 -0
  119. package/dist/app/record-row/record-row-body.js +12 -7
  120. package/dist/app/record-row/record-row.js +4 -3
  121. package/dist/app/record-row/saved-record-row.js +3 -2
  122. package/dist/app/related-dots/dots-summary.js +2 -1
  123. package/dist/app/related-dots/messages.js +8 -0
  124. package/dist/app/relation-picker.js +9 -8
  125. package/dist/app/router.js +5 -4
  126. package/dist/app/runtime/messages.js +58 -0
  127. package/dist/app/runtime/runtime-status.js +10 -23
  128. package/dist/app/runtime/runtime-update-dialog.js +7 -6
  129. package/dist/app/runtime/runtime-update.js +4 -3
  130. package/dist/app/saved/favorite-button.js +2 -1
  131. package/dist/app/saved/messages.js +22 -0
  132. package/dist/app/saved/saved-list.js +4 -7
  133. package/dist/app/saved/use-favorite.js +3 -2
  134. package/dist/app/search/messages.js +6 -2
  135. package/dist/app/search/navigation-hits.js +9 -7
  136. package/dist/app/searches/filter-chip-list.js +2 -1
  137. package/dist/app/searches/messages.js +96 -0
  138. package/dist/app/searches/save-search-button.js +5 -4
  139. package/dist/app/searches/saved-search-rows.js +3 -2
  140. package/dist/app/searches/saved-search-section.js +6 -5
  141. package/dist/app/searches/saved-search.js +4 -3
  142. package/dist/app/searches/saved-searches.js +15 -25
  143. package/dist/app/searches/search-controls.js +5 -4
  144. package/dist/app/searches/search-diff.js +4 -2
  145. package/dist/app/searches/search-name-dialog.js +4 -3
  146. package/dist/app/searches/update-search-dialog.js +15 -30
  147. package/dist/app/searches/use-save-search.js +8 -7
  148. package/dist/app/searches/use-search-row.js +4 -3
  149. package/dist/app/sensitive-field.js +5 -4
  150. package/dist/app/source-notice.js +13 -8
  151. package/dist/app/staff-banner.js +13 -20
  152. package/dist/app-shell/global-search.js +2 -2
  153. package/dist/app-shell/messages.js +4 -2
  154. package/dist/app-shell/sidebar-group.js +1 -1
  155. package/dist/app-shell/sidebar-item.js +1 -1
  156. package/dist/app-shell/sidebar.js +1 -1
  157. package/dist/assistant-dock/assistant-dock.js +6 -6
  158. package/dist/assistant-dock/messages.js +26 -0
  159. package/dist/assistant-dock/use-assistant.js +2 -1
  160. package/dist/assistant-dock/use-backend-data.js +2 -1
  161. package/dist/assistant-dock/widget-view.js +3 -2
  162. package/dist/auth/auth-gate.js +10 -5
  163. package/dist/auth/auth-locale.js +14 -0
  164. package/dist/auth/auth-messages.js +122 -43
  165. package/dist/auth/auth-provider.js +6 -1
  166. package/dist/auth/code-form.js +4 -3
  167. package/dist/auth/email-code-form.js +11 -13
  168. package/dist/auth/email-code-page.js +2 -1
  169. package/dist/auth/first-run-page.js +6 -5
  170. package/dist/auth/forgot-password-form.js +15 -17
  171. package/dist/auth/forgot-password-page.js +2 -1
  172. package/dist/auth/messages.js +200 -0
  173. package/dist/auth/provider-sign-in-page.js +5 -5
  174. package/dist/auth/resend-code-button.js +2 -1
  175. package/dist/auth/reset-password-form.js +12 -11
  176. package/dist/auth/reset-password-page.js +4 -3
  177. package/dist/auth/setup-required-form.js +8 -10
  178. package/dist/auth/setup-required-page.js +7 -2
  179. package/dist/auth/sign-in-form.js +18 -21
  180. package/dist/auth/sign-in-prompt.js +4 -3
  181. package/dist/auth/sign-up-code-form.js +11 -13
  182. package/dist/auth/sign-up-details-form.js +15 -22
  183. package/dist/auth/sign-up-email-form.js +9 -8
  184. package/dist/auth/sign-up-page.js +2 -1
  185. package/dist/auth/staff-sign-in-form.js +16 -19
  186. package/dist/auth/two-factor-form.js +19 -18
  187. package/dist/auth/user-to-shell.js +2 -1
  188. package/dist/chat/composer.js +8 -7
  189. package/dist/chat/messages.js +14 -0
  190. package/dist/compact-table/compact-table.js +4 -8
  191. package/dist/compact-table/messages.js +18 -0
  192. package/dist/data/meta-data.d.ts +1 -1
  193. package/dist/data/use-update-record.js +1 -1
  194. package/dist/data-grid/grid-header.js +1 -1
  195. package/dist/filter-panel/date-presets.js +1 -1
  196. package/dist/forms/public-form-page.js +1 -1
  197. package/dist/inline-child-table/inline-child-table.js +12 -12
  198. package/dist/inline-child-table/line-row.js +10 -9
  199. package/dist/inline-child-table/messages.js +52 -0
  200. package/dist/inline-child-table/totals-footer.js +5 -8
  201. package/dist/invitations/invite-form.js +3 -2
  202. package/dist/invitations/link-notice.js +6 -4
  203. package/dist/invitations/messages.js +24 -0
  204. package/dist/invitations/pending-invitation-row.js +4 -3
  205. package/dist/lists/messages.js +8 -0
  206. package/dist/lists/paged-search-list.js +2 -1
  207. package/dist/locale/slotted.js +14 -0
  208. package/dist/markdown/markdown-editor.js +6 -5
  209. package/dist/markdown/messages.js +16 -0
  210. package/dist/organizations/all-organizations.js +6 -5
  211. package/dist/organizations/app-roles-picker.js +2 -1
  212. package/dist/organizations/invitation-page.js +41 -51
  213. package/dist/organizations/invitations-page.js +11 -10
  214. package/dist/organizations/members-page.js +16 -11
  215. package/dist/organizations/messages.js +180 -0
  216. package/dist/organizations/organization-page.js +27 -26
  217. package/dist/organizations/organization-paths.js +16 -13
  218. package/dist/organizations/organization-row.js +3 -2
  219. package/dist/organizations/organizations-page.js +17 -16
  220. package/dist/organizations/use-organizations.js +2 -1
  221. package/dist/package.js +1 -1
  222. package/dist/plugins/before-sign-in.js +6 -1
  223. package/dist/plugins/load-plugin.d.ts +1 -1
  224. package/dist/plugins/load-plugin.js +3 -2
  225. package/dist/plugins/messages.js +36 -0
  226. package/dist/plugins/plugin-gate.js +6 -1
  227. package/dist/plugins/plugin-manifest.js +8 -7
  228. package/dist/plugins/plugin-notice.js +8 -12
  229. package/dist/primitives/button.js +1 -1
  230. package/dist/primitives/messages.js +16 -0
  231. package/dist/primitives/segmented.js +1 -1
  232. package/dist/primitives/sheet.js +2 -1
  233. package/dist/primitives/spinner.js +2 -1
  234. package/dist/primitives/token.js +2 -1
  235. package/dist/record-view/field.js +2 -2
  236. package/dist/record-view/messages.js +4 -2
  237. package/dist/record-view/record-tabs.js +2 -1
  238. package/dist/roles/messages.js +14 -0
  239. package/dist/roles/use-active-role.js +3 -2
  240. package/dist/shell/assets/app-yCMYvqMX.js +69 -0
  241. package/dist/shell/assets/cn-Bi0ZEjD9.js +1 -0
  242. package/dist/shell/assets/export-worker-ClACk00b.js +2 -0
  243. package/dist/shell/assets/{index-BRkDA5KD.css → index-Bkc7w8I4.css} +1 -1
  244. package/dist/shell/assets/{index-xY0Mvv6V.js → index-HkjqX_O-.js} +2 -2
  245. package/dist/shell/assets/maplibre-DUTS_eJM.js +814 -0
  246. package/dist/shell/assets/{markdown-content-ukDTCu6u.js → markdown-content-CtGUP4W6.js} +1 -1
  247. package/dist/shell/assets/parse-worker-UhbwEjS0.js +5 -0
  248. package/dist/shell/assets/preload-helper-BZ3hrQDD.js +1 -0
  249. package/dist/shell/assets/{record-map-BJmYZ7kQ.js → record-map-DFy7sJEU.js} +1 -1
  250. package/dist/shell/assets/records-map-MfQEuiFB.js +1 -0
  251. package/dist/shell/assets/shared-protobase-ui-Bfa59vx6.js +1 -0
  252. package/dist/shell/index.html +6 -4
  253. package/dist/shell/protobase.shell.json +1 -1
  254. package/dist/shell/protobase.sw.js +2 -2
  255. package/dist/side-panel/messages.js +8 -0
  256. package/dist/side-panel/side-panel.js +2 -1
  257. package/dist/toasts/messages.js +8 -0
  258. package/dist/toasts/toast.js +2 -1
  259. package/dist/users/app-invitations.js +5 -4
  260. package/dist/users/create-user-form.js +9 -8
  261. package/dist/users/messages.js +52 -0
  262. package/dist/users/use-user-roles.js +2 -1
  263. package/dist/users/user-list.js +6 -5
  264. package/dist/users/user-row.js +5 -4
  265. package/package.json +4 -4
  266. package/dist/shell/assets/app-C-OLrsRR.js +0 -69
  267. package/dist/shell/assets/export-worker-Bz57Pf5g.js +0 -2
  268. package/dist/shell/assets/maplibre-Dov6nhPX.js +0 -814
  269. package/dist/shell/assets/parse-worker-BtcY0dQw.js +0 -5
  270. package/dist/shell/assets/records-map-C1_gDKHR.js +0 -1
  271. package/dist/shell/assets/shared-protobase-ui-CFYJAbMR.js +0 -1
@@ -2,6 +2,7 @@ import { Skeleton } from "../../primitives/skeleton.js";
2
2
  import { dayIn, viewerZone } from "../../format/zone.js";
3
3
  import { formatDate } from "../../format/date.js";
4
4
  import { humanize } from "../../live/naming.js";
5
+ import { text } from "./messages.js";
5
6
  import { usePermissions } from "../meta-gate.js";
6
7
  import { ErrorBanner } from "../error-banner.js";
7
8
  import { can, rowAllows } from "../permissions.js";
@@ -17,18 +18,18 @@ import { useRef, useState } from "react";
17
18
  import { jsx, jsxs } from "react/jsx-runtime";
18
19
  import { DndContext, DragOverlay, KeyboardSensor, MouseSensor, TouchSensor, useSensor, useSensors } from "@dnd-kit/core";
19
20
  //#region src/app/displays/timeline-display.tsx
20
- const scales = [
21
+ const scales = () => [
21
22
  {
22
23
  scale: "week",
23
- label: "Week"
24
+ label: text("week")
24
25
  },
25
26
  {
26
27
  scale: "month",
27
- label: "Month"
28
+ label: text("month")
28
29
  },
29
30
  {
30
31
  scale: "quarter",
31
- label: "Quarter"
32
+ label: text("quarter")
32
33
  }
33
34
  ];
34
35
  /**
@@ -90,11 +91,11 @@ const TimelineDisplay = ({ model, view, display, fields, filter, at, linkTo, now
90
91
  const title = (picked) => eventTitle(model, view, display, picked.row);
91
92
  const startText = (picked) => formatDate(Date.parse(`${addDays(picked.day, shift.current)}T00:00:00Z`));
92
93
  const announcements = {
93
- onDragStart: ({ active: picked }) => `Picked up ${title(picked.data.current)}.`,
94
- onDragMove: ({ active: picked }) => `${title(picked.data.current)} starts on ${startText(picked.data.current)}.`,
94
+ onDragStart: ({ active: picked }) => text("pickedUp", title(picked.data.current)),
95
+ onDragMove: ({ active: picked }) => text("startsOn", title(picked.data.current), startText(picked.data.current)),
95
96
  onDragOver: () => void 0,
96
- onDragEnd: ({ active: picked }) => shift.current === 0 ? `${title(picked.data.current)} was put back.` : `${title(picked.data.current)} was moved to ${startText(picked.data.current)}.`,
97
- onDragCancel: ({ active: picked }) => `Moving ${title(picked.data.current)} was cancelled.`
97
+ onDragEnd: ({ active: picked }) => shift.current === 0 ? text("putBack", title(picked.data.current)) : text("wasMovedTo", title(picked.data.current), startText(picked.data.current)),
98
+ onDragCancel: ({ active: picked }) => text("cancelled", title(picked.data.current))
98
99
  };
99
100
  const release = () => {
100
101
  setActive(void 0);
@@ -127,28 +128,22 @@ const TimelineDisplay = ({ model, view, display, fields, filter, at, linkTo, now
127
128
  day: today
128
129
  }, now),
129
130
  next: stepTimeline(shown, 1),
130
- scales: scales.map(({ scale, label }) => ({
131
+ scales: scales().map(({ scale, label }) => ({
131
132
  view: scaledTimeline(shown, scale, now),
132
133
  label,
133
134
  current: shown.scale === scale
134
135
  })),
135
- scalesLabel: "Timeline scale",
136
+ scalesLabel: text("timelineScale"),
136
137
  linkTo,
137
138
  onView: setLocal
138
139
  }),
139
140
  list.error && /* @__PURE__ */ jsx(ErrorBanner, {
140
- title: "Could not load rows",
141
+ title: text("couldNotLoadRows"),
141
142
  error: list.error
142
143
  }),
143
- list.capped && /* @__PURE__ */ jsxs("p", {
144
+ list.capped && /* @__PURE__ */ jsx("p", {
144
145
  className: "text-xs text-muted-foreground",
145
- children: [
146
- "Showing the first ",
147
- 500,
148
- " records of this ",
149
- shown.scale,
150
- ". Narrow the filter to see the rest."
151
- ]
146
+ children: text("capped", 500, shown.scale)
152
147
  }),
153
148
  /* @__PURE__ */ jsxs(DndContext, {
154
149
  sensors,
@@ -159,7 +154,7 @@ const TimelineDisplay = ({ model, view, display, fields, filter, at, linkTo, now
159
154
  onDragCancel: release,
160
155
  accessibility: {
161
156
  announcements,
162
- screenReaderInstructions: { draggable: "To move a bar to other days, press Space, move it a day with the left and right arrow keys, and press Space again to drop it there. Escape puts it back." }
157
+ screenReaderInstructions: { draggable: text("timelineInstructions") }
163
158
  },
164
159
  children: [/* @__PURE__ */ jsxs("div", {
165
160
  className: "overflow-hidden rounded-lg border border-border",
@@ -181,13 +176,9 @@ const TimelineDisplay = ({ model, view, display, fields, filter, at, linkTo, now
181
176
  className: "relative flex flex-col gap-2 p-2",
182
177
  children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-4" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-4" })]
183
178
  }),
184
- empty && /* @__PURE__ */ jsxs("p", {
179
+ empty && /* @__PURE__ */ jsx("p", {
185
180
  className: "relative px-2 py-3 text-xs text-muted-foreground",
186
- children: [
187
- "Nothing in this ",
188
- shown.scale,
189
- "."
190
- ]
181
+ children: text("nothingIn", shown.scale)
191
182
  }),
192
183
  !list.loading && lanes.map((lane) => /* @__PURE__ */ jsxs("section", {
193
184
  "aria-label": lane.label,
@@ -2,6 +2,7 @@ import { dayIn, viewerZone } from "../../format/zone.js";
2
2
  import { formatDayRange, formatMonth, formatMonthName, formatMonthRange, formatWeekday } from "../../format/date.js";
3
3
  import { humanize } from "../../live/naming.js";
4
4
  import { displayValue } from "../../live/display-value.js";
5
+ import { text } from "./messages.js";
5
6
  import { addDays, monday, monthOf, recordDays } from "./calendar-range.js";
6
7
  //#region src/app/displays/timeline-range.ts
7
8
  const dayMs = 864e5;
@@ -114,7 +115,7 @@ const timelineLanes = (rows, model, view, display) => {
114
115
  const value = row.record[group];
115
116
  const empty = value === null || value === void 0 || value === "";
116
117
  const key = empty ? noValue : `value:${String(value)}`;
117
- const label = empty ? `No ${(hints?.label ?? humanize(group)).toLowerCase()}` : row.labels[group] ?? displayValue(field, value, hints);
118
+ const label = empty ? text("noValue", hints?.label ?? humanize(group)) : row.labels[group] ?? displayValue(field, value, hints);
118
119
  const known = lanes.get(key) ?? {
119
120
  value: empty ? void 0 : value,
120
121
  lane: {
@@ -14,7 +14,7 @@ const TimelineRow = ({ model, view, display, row, days, movable, dragged }) => {
14
14
  className: cn(timelineGrid, "relative border-b border-border last:border-b-0"),
15
15
  children: [/* @__PURE__ */ jsx("span", {
16
16
  "aria-hidden": true,
17
- className: "truncate px-2 pt-1 text-xs sm:py-1.5",
17
+ className: "truncate px-2 pt-1 text-body sm:py-1.5",
18
18
  children: eventTitle(model, view, display, row)
19
19
  }), /* @__PURE__ */ jsx("div", {
20
20
  className: "relative h-7",
@@ -1,8 +1,8 @@
1
1
  import { useClient } from "../../data/api-provider.js";
2
2
  import { useToast } from "../../toasts/toast-provider.js";
3
3
  import { recordKey } from "../../live/model-helpers.js";
4
- import { refusalReason } from "./board-columns.js";
5
4
  import { text } from "./messages.js";
5
+ import { refusalReason } from "./board-columns.js";
6
6
  import { useRefreshResource } from "../pages/use-layout-data.js";
7
7
  import { dropWrite } from "./board-drop.js";
8
8
  import { boardWrites, placeOps } from "./board-place.js";
@@ -115,7 +115,7 @@ const useBoardMove = ({ model, by, rank, drop, labelOf }) => {
115
115
  },
116
116
  onError: (error, { row, to }) => {
117
117
  settle(row.key);
118
- const title = (row.record[by] ?? null) === to.value ? "Could not change the order" : `Could not move it to ${to.label}`;
118
+ const title = (row.record[by] ?? null) === to.value ? text("couldNotReorder") : text("couldNotMoveTo", to.label);
119
119
  toast.show({
120
120
  state: "error",
121
121
  title,
@@ -2,6 +2,7 @@ import { formatDate } from "../../format/date.js";
2
2
  import { useClient } from "../../data/api-provider.js";
3
3
  import { useToast } from "../../toasts/toast-provider.js";
4
4
  import { recordKey } from "../../live/model-helpers.js";
5
+ import { text } from "./messages.js";
5
6
  import { refusalReason } from "./board-columns.js";
6
7
  import { useRefreshResource } from "../pages/use-layout-data.js";
7
8
  import { movedPatch } from "./calendar-range.js";
@@ -44,7 +45,7 @@ const useCalendarMove = (model, display) => {
44
45
  settle(row.key);
45
46
  toast.show({
46
47
  state: "error",
47
- title: `Could not move it to ${formatDate(Date.parse(`${to}T00:00:00Z`))}`,
48
+ title: text("couldNotMoveTo", formatDate(Date.parse(`${to}T00:00:00Z`))),
48
49
  description: refusalReason(error)
49
50
  });
50
51
  },
@@ -1,3 +1,4 @@
1
+ import { text } from "./create/messages.js";
1
2
  import { useEffect } from "react";
2
3
  //#region src/app/document-title.ts
3
4
  /** What a tab names, most specific first: the record and its list, the new record and its list, the list, or the page. */
@@ -7,7 +8,7 @@ const titleParts = ({ address, page, accountPage, resourceLabel, singular, recor
7
8
  if (!address || address.kind === "page") return [];
8
9
  const list = resourceLabel ? [resourceLabel] : [];
9
10
  if (address.kind === "list") return list;
10
- if (address.kind === "create") return [...singular ? [`New ${singular.toLowerCase()}`] : [], ...list];
11
+ if (address.kind === "create") return [...singular ? [text("title", singular)] : [], ...list];
11
12
  const record = recordTitle ?? (recordLoading ? void 0 : address.key);
12
13
  return [...record ? [record] : [], ...list];
13
14
  };
@@ -18,7 +18,7 @@ const ErrorBanner = ({ error, title }) => /* @__PURE__ */ jsxs("div", {
18
18
  className: "font-medium",
19
19
  children: title
20
20
  }), describe(error).map((detail) => /* @__PURE__ */ jsxs("p", {
21
- className: "text-xs",
21
+ className: "text-body",
22
22
  children: [detail.message, detail.hint && /* @__PURE__ */ jsxs("span", {
23
23
  className: "text-muted-foreground",
24
24
  children: [" ", detail.hint]
@@ -1,3 +1,4 @@
1
+ import { text } from "./messages.js";
1
2
  import { createExportBuilder } from "./builder.js";
2
3
  //#region src/app/export/builder-port.ts
3
4
  const joined = (chunks) => {
@@ -36,7 +37,7 @@ const createWorkerPort = () => {
36
37
  worker.onmessage = (event) => waiting.shift()?.resolve(event.data.bytes);
37
38
  worker.onerror = (event) => {
38
39
  event.preventDefault();
39
- const error = /* @__PURE__ */ new Error(`The export could not be built: ${event.message}`);
40
+ const error = new Error(text("couldNotBuild", event.message));
40
41
  for (const entry of waiting.splice(0)) entry.reject(error);
41
42
  };
42
43
  return {
@@ -3,33 +3,34 @@ import { formatApproxRows, formatInt } from "../../format/number.js";
3
3
  import { Button } from "../../primitives/button.js";
4
4
  import { Checkbox } from "../../primitives/checkbox.js";
5
5
  import { ResponsiveDialog } from "../../primitives/responsive-dialog.js";
6
+ import { text } from "./messages.js";
6
7
  import { exportLimit } from "./export-options.js";
7
8
  import { useState } from "react";
8
9
  import { ArrowDown, ArrowUp } from "lucide-react";
9
10
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
11
  //#region src/app/export/export-dialog.tsx
11
- const formatOptions = [{
12
+ const formatOptions = () => [{
12
13
  value: "xlsx",
13
- label: "Excel (.xlsx)"
14
+ label: text("excel")
14
15
  }, {
15
16
  value: "csv",
16
- label: "CSV"
17
+ label: text("csv")
17
18
  }];
18
- const modeOptions = [{
19
+ const modeOptions = () => [{
19
20
  value: "shown",
20
- label: "As shown"
21
+ label: text("asShown")
21
22
  }, {
22
23
  value: "raw",
23
- label: "Raw values"
24
+ label: text("rawValues")
24
25
  }];
25
26
  const modeHelp = {
26
- shown: "Labels, dates and numbers as the list shows them.",
27
- raw: "Values as they are stored, such as keys and codes."
27
+ shown: "shownHint",
28
+ raw: "rawHint"
28
29
  };
29
30
  const countText = (count) => {
30
- if (count.kind === "counting") return "Counting rows…";
31
+ if (count.kind === "counting") return text("counting");
31
32
  if (count.kind === "exact") return formatApproxRows(count.rows);
32
- return count.rows > 1e4 ? formatApproxRows(count.rows) : "more than 10,000 rows";
33
+ return count.rows > 1e4 ? formatApproxRows(count.rows) : text("moreThan");
33
34
  };
34
35
  /** The fewest rows the list finds, as far as the count tells: an estimate stands only above 10,000. */
35
36
  const countedRows = (count) => {
@@ -40,7 +41,7 @@ const Setting = ({ label, help, children }) => /* @__PURE__ */ jsxs("div", {
40
41
  className: "flex flex-col items-start gap-1.5",
41
42
  children: [
42
43
  /* @__PURE__ */ jsx("span", {
43
- className: "text-[13px] font-medium",
44
+ className: "text-body font-medium",
44
45
  children: label
45
46
  }),
46
47
  children,
@@ -66,7 +67,7 @@ const ColumnPicker = ({ fields, columns, onChange }) => {
66
67
  const ordered = [...columns, ...fields.map((field) => field.name).filter((name) => !columns.includes(name))];
67
68
  return /* @__PURE__ */ jsx("ul", {
68
69
  className: "divide-y self-stretch rounded-md border",
69
- "aria-label": "Columns",
70
+ "aria-label": text("columns"),
70
71
  children: ordered.map((name) => {
71
72
  const chosen = columns.includes(name);
72
73
  const index = columns.indexOf(name);
@@ -88,7 +89,7 @@ const ColumnPicker = ({ fields, columns, onChange }) => {
88
89
  size: "sm",
89
90
  variant: "ghost",
90
91
  className: "min-h-8 px-2",
91
- "aria-label": `Move ${labels[name]} up`,
92
+ "aria-label": text("moveUp", labels[name]),
92
93
  disabled: index === 0,
93
94
  onClick: () => onChange(move(columns, name, -1)),
94
95
  children: /* @__PURE__ */ jsx(ArrowUp, { className: "size-3.5" })
@@ -96,7 +97,7 @@ const ColumnPicker = ({ fields, columns, onChange }) => {
96
97
  size: "sm",
97
98
  variant: "ghost",
98
99
  className: "min-h-8 px-2",
99
- "aria-label": `Move ${labels[name]} down`,
100
+ "aria-label": text("moveDown", labels[name]),
100
101
  disabled: index === columns.length - 1,
101
102
  onClick: () => onChange(move(columns, name, 1)),
102
103
  children: /* @__PURE__ */ jsx(ArrowDown, { className: "size-3.5" })
@@ -116,22 +117,22 @@ const ExportDialog = ({ plural, view, fields, initialColumns, count, selected, o
116
117
  const [columns, setColumns] = useState(initialColumns);
117
118
  const [mode, setMode] = useState("shown");
118
119
  const limit = exportLimit(view, format);
119
- const rows = scope === "selected" ? `${formatInt(selected ?? 0)} selected ${selected === 1 ? "row" : "rows"}` : countText(count);
120
+ const rows = scope === "selected" ? text("selectedRows", formatInt(selected ?? 0), selected ?? 0) : countText(count);
120
121
  const overLimit = (scope === "selected" ? selected ?? 0 : countedRows(count) ?? 0) > limit;
121
122
  const scopeOptions = [{
122
123
  value: "list",
123
- label: "Rows in the list"
124
+ label: text("rowsInList")
124
125
  }, {
125
126
  value: "selected",
126
- label: `Selected (${formatInt(selected ?? 0)})`
127
+ label: text("selected", formatInt(selected ?? 0))
127
128
  }];
128
129
  return /* @__PURE__ */ jsx(ResponsiveDialog, {
129
- title: `Export ${plural.toLowerCase()}`,
130
+ title: text("exportPlural", plural),
130
131
  open,
131
132
  onClose,
132
133
  actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button, {
133
134
  onClick: onClose,
134
- children: "Cancel"
135
+ children: text("cancel")
135
136
  }), /* @__PURE__ */ jsx(Button, {
136
137
  variant: "primary",
137
138
  disabled: columns.length === 0,
@@ -141,45 +142,45 @@ const ExportDialog = ({ plural, view, fields, initialColumns, count, selected, o
141
142
  columns,
142
143
  mode
143
144
  }),
144
- children: "Export"
145
+ children: text("export")
145
146
  })] }),
146
147
  children: /* @__PURE__ */ jsxs("div", {
147
- className: "flex flex-col gap-4 text-[13px]",
148
+ className: "flex flex-col gap-4 text-body",
148
149
  children: [
149
150
  /* @__PURE__ */ jsx(Setting, {
150
- label: "Format",
151
+ label: text("format"),
151
152
  children: /* @__PURE__ */ jsx(Segmented, {
152
153
  size: "md",
153
- label: "Format",
154
+ label: text("format"),
154
155
  value: format,
155
- options: formatOptions,
156
+ options: formatOptions(),
156
157
  onChange: setFormat
157
158
  })
158
159
  }),
159
160
  selected !== void 0 && selected > 0 && /* @__PURE__ */ jsx(Setting, {
160
- label: "Rows",
161
- help: scope === "list" ? "With the list’s filters, search and sort." : void 0,
161
+ label: text("rows"),
162
+ help: scope === "list" ? text("listHint") : void 0,
162
163
  children: /* @__PURE__ */ jsx(Segmented, {
163
164
  size: "md",
164
- label: "Rows",
165
+ label: text("rows"),
165
166
  value: scope,
166
167
  options: scopeOptions,
167
168
  onChange: setScope
168
169
  })
169
170
  }),
170
171
  /* @__PURE__ */ jsx(Setting, {
171
- label: "Values",
172
- help: modeHelp[mode],
172
+ label: text("values"),
173
+ help: text(modeHelp[mode]),
173
174
  children: /* @__PURE__ */ jsx(Segmented, {
174
175
  size: "md",
175
- label: "Values",
176
+ label: text("values"),
176
177
  value: mode,
177
- options: modeOptions,
178
+ options: modeOptions(),
178
179
  onChange: setMode
179
180
  })
180
181
  }),
181
182
  /* @__PURE__ */ jsx(Setting, {
182
- label: "Columns",
183
+ label: text("columns"),
183
184
  children: /* @__PURE__ */ jsx(ColumnPicker, {
184
185
  fields,
185
186
  columns,
@@ -189,12 +190,7 @@ const ExportDialog = ({ plural, view, fields, initialColumns, count, selected, o
189
190
  /* @__PURE__ */ jsxs("p", {
190
191
  role: "status",
191
192
  className: "text-muted-foreground",
192
- children: [
193
- "Exports ",
194
- rows,
195
- ".",
196
- overLimit && ` A file holds at most ${formatInt(limit)} rows; the rest are left out.`
197
- ]
193
+ children: [text("exports", rows), overLimit && text("overLimit", formatInt(limit))]
198
194
  })
199
195
  ]
200
196
  })
@@ -204,18 +200,18 @@ const ExportDialog = ({ plural, view, fields, initialColumns, count, selected, o
204
200
  const ExportProgressDialog = ({ plural, done, total, onCancel }) => {
205
201
  const share = total ? Math.min(1, done / total) : void 0;
206
202
  return /* @__PURE__ */ jsx(ResponsiveDialog, {
207
- title: `Exporting ${plural.toLowerCase()}`,
203
+ title: text("exporting", plural),
208
204
  open: true,
209
205
  onClose: onCancel,
210
206
  actions: /* @__PURE__ */ jsx(Button, {
211
207
  onClick: onCancel,
212
- children: "Cancel"
208
+ children: text("cancel")
213
209
  }),
214
210
  children: /* @__PURE__ */ jsxs("div", {
215
- className: "flex flex-col gap-2 text-[13px]",
211
+ className: "flex flex-col gap-2 text-body",
216
212
  children: [/* @__PURE__ */ jsx("div", {
217
213
  role: "progressbar",
218
- "aria-label": "Rows exported",
214
+ "aria-label": text("rowsExported"),
219
215
  "aria-valuemin": 0,
220
216
  "aria-valuemax": total,
221
217
  "aria-valuenow": done,
@@ -226,7 +222,7 @@ const ExportProgressDialog = ({ plural, done, total, onCancel }) => {
226
222
  })
227
223
  }), /* @__PURE__ */ jsx("p", {
228
224
  className: "text-muted-foreground",
229
- children: total ? `${formatInt(done)} of ${formatInt(total)} rows` : `${formatInt(done)} rows`
225
+ children: total ? text("doneOf", formatInt(done), formatInt(total)) : text("done", formatInt(done))
230
226
  })]
231
227
  })
232
228
  });
@@ -1,8 +1,10 @@
1
+ import { setFallbackLocale } from "../../locale/active-locale.js";
1
2
  import { createBuilderHandler } from "./builder-port.js";
2
3
  //#region src/app/export/export-worker.ts
3
4
  const handle = createBuilderHandler();
4
5
  const scope = self;
5
6
  scope.onmessage = (event) => {
7
+ if (event.data.kind === "start") setFallbackLocale(event.data.locale);
6
8
  const bytes = handle(event.data);
7
9
  scope.postMessage({ bytes }, [bytes.buffer]);
8
10
  };
@@ -0,0 +1,78 @@
1
+ import { defineMessages } from "../../locale/messages.js";
2
+ //#region src/app/export/messages.ts
3
+ const text = defineMessages({
4
+ en: {
5
+ excel: "Excel (.xlsx)",
6
+ csv: "CSV",
7
+ asShown: "As shown",
8
+ rawValues: "Raw values",
9
+ shownHint: "Labels, dates and numbers as the list shows them.",
10
+ rawHint: "Values as they are stored, such as keys and codes.",
11
+ counting: "Counting rows…",
12
+ moreThan: "more than 10,000 rows",
13
+ columns: "Columns",
14
+ moveUp: (label) => `Move ${label} up`,
15
+ moveDown: (label) => `Move ${label} down`,
16
+ selectedRows: (count, rows) => `${count} selected ${rows === 1 ? "row" : "rows"}`,
17
+ rowsInList: "Rows in the list",
18
+ selected: (count) => `Selected (${count})`,
19
+ exportPlural: (plural) => `Export ${plural.toLowerCase()}`,
20
+ cancel: "Cancel",
21
+ export: "Export",
22
+ format: "Format",
23
+ rows: "Rows",
24
+ listHint: "With the list’s filters, search and sort.",
25
+ values: "Values",
26
+ exports: (rows) => `Exports ${rows}.`,
27
+ overLimit: (limit) => ` A file holds at most ${limit} rows; the rest are left out.`,
28
+ exporting: (plural) => `Exporting ${plural.toLowerCase()}`,
29
+ rowsExported: "Rows exported",
30
+ doneOf: (done, total) => `${done} of ${total} rows`,
31
+ done: (done) => `${done} rows`,
32
+ exported: (count, plural) => `Exported ${count} ${plural.toLowerCase()}`,
33
+ truncated: (name, count) => `${name}: the first ${count} rows, as many as a file holds.`,
34
+ couldNotExport: (plural) => `Could not export ${plural.toLowerCase()}`,
35
+ cancelled: "The export was cancelled",
36
+ couldNotBuild: (message) => `The export could not be built: ${message}`,
37
+ workbook: "Excel workbook",
38
+ csvFile: "CSV file"
39
+ },
40
+ nl: {
41
+ excel: "Excel (.xlsx)",
42
+ csv: "CSV",
43
+ asShown: "Zoals getoond",
44
+ rawValues: "Ruwe waarden",
45
+ shownHint: "Labels, datums en getallen zoals de lijst ze toont.",
46
+ rawHint: "Waarden zoals ze zijn opgeslagen, zoals sleutels en codes.",
47
+ counting: "Rijen tellen…",
48
+ moreThan: "meer dan 10.000 rijen",
49
+ columns: "Kolommen",
50
+ moveUp: (label) => `${label} omhoog`,
51
+ moveDown: (label) => `${label} omlaag`,
52
+ selectedRows: (count, rows) => `${count} geselecteerde ${rows === 1 ? "rij" : "rijen"}`,
53
+ rowsInList: "Rijen in de lijst",
54
+ selected: (count) => `Geselecteerd (${count})`,
55
+ exportPlural: (plural) => `${plural} exporteren`,
56
+ cancel: "Annuleren",
57
+ export: "Exporteren",
58
+ format: "Formaat",
59
+ rows: "Rijen",
60
+ listHint: "Met de filters, zoekopdracht en sortering van de lijst.",
61
+ values: "Waarden",
62
+ exports: (rows) => `Exporteert ${rows}.`,
63
+ overLimit: (limit) => ` Een bestand bevat hoogstens ${limit} rijen; de rest blijft weg.`,
64
+ exporting: (plural) => `${plural} exporteren`,
65
+ rowsExported: "Geëxporteerde rijen",
66
+ doneOf: (done, total) => `${done} van ${total} rijen`,
67
+ done: (done) => `${done} rijen`,
68
+ exported: (count, plural) => `${count} ${plural.toLowerCase()} geëxporteerd`,
69
+ truncated: (name, count) => `${name}: de eerste ${count} rijen, zoveel als een bestand bevat.`,
70
+ couldNotExport: (plural) => `Kon ${plural.toLowerCase()} niet exporteren`,
71
+ cancelled: "De export is geannuleerd",
72
+ couldNotBuild: (message) => `De export kon niet worden gemaakt: ${message}`,
73
+ workbook: "Excel-werkmap",
74
+ csvFile: "CSV-bestand"
75
+ }
76
+ });
77
+ //#endregion
78
+ export { text };
@@ -1,4 +1,6 @@
1
- const aborted = () => new DOMException("The export was cancelled", "AbortError");
1
+ import { activeLocale } from "../../locale/active-locale.js";
2
+ import { text } from "./messages.js";
3
+ const aborted = () => new DOMException(text("cancelled"), "AbortError");
2
4
  /**
3
5
  * Reads the rows through the list API, page by page with its page tokens, and has the port build the file from each;
4
6
  * each piece is written to the sink as it is built, so only a page is held at a time. A cancel stops at the next page
@@ -10,7 +12,8 @@ const runExport = async ({ client, resource, filters, orderBy, plan, labels, lim
10
12
  try {
11
13
  await sink.write(await port.send({
12
14
  kind: "start",
13
- plan
15
+ plan,
16
+ locale: activeLocale()
14
17
  }));
15
18
  for (const [index, filter] of filters.entries()) {
16
19
  let pageToken = "";
@@ -1,14 +1,15 @@
1
+ import { text } from "./messages.js";
1
2
  //#region src/app/export/sink.ts
2
3
  const types = {
3
4
  xlsx: {
4
5
  mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
5
6
  extension: ".xlsx",
6
- description: "Excel workbook"
7
+ description: "workbook"
7
8
  },
8
9
  csv: {
9
10
  mime: "text/csv",
10
11
  extension: ".csv",
11
- description: "CSV file"
12
+ description: "csvFile"
12
13
  }
13
14
  };
14
15
  const unsafeName = /[\\/:*?"<>|\u0000-\u001f]/g;
@@ -70,7 +71,7 @@ const pickFileSink = async (name, format) => {
70
71
  handle = await pick({
71
72
  suggestedName: name,
72
73
  types: [{
73
- description: type.description,
74
+ description: text(type.description),
74
75
  accept: { [type.mime]: [type.extension] }
75
76
  }]
76
77
  });
@@ -3,6 +3,7 @@ import { keys } from "../../data/query-keys.js";
3
3
  import { useClient } from "../../data/api-provider.js";
4
4
  import { useToast } from "../../toasts/toast-provider.js";
5
5
  import { listLabels } from "../../live/relation-labels.js";
6
+ import { text } from "./messages.js";
6
7
  import { runExport } from "./run-export.js";
7
8
  import { defaultExportColumns, exportColumns, exportHeaders, exportLimit, exportableFields, exportsSelection, selectionFilters } from "./export-options.js";
8
9
  import { createWorkerPort } from "./builder-port.js";
@@ -90,15 +91,15 @@ const useExportFlow = ({ model, view, resources, views, plural, filter, orderBy,
90
91
  });
91
92
  toast.show({
92
93
  state: "success",
93
- title: `Exported ${formatInt(result.rows)} ${plural.toLowerCase()}`,
94
- description: result.truncated ? `${name}: the first ${formatInt(result.rows)} rows, as many as a file holds.` : name
94
+ title: text("exported", formatInt(result.rows), plural),
95
+ description: result.truncated ? text("truncated", name, formatInt(result.rows)) : name
95
96
  });
96
97
  } catch (error) {
97
98
  if (error instanceof DOMException && error.name === "AbortError") return;
98
99
  if (!isApiError(error)) throw error;
99
100
  toast.show({
100
101
  state: "error",
101
- title: `Could not export ${plural.toLowerCase()}`,
102
+ title: text("couldNotExport", plural),
102
103
  description: error.message
103
104
  });
104
105
  } finally {
@@ -2,6 +2,7 @@ import { cn } from "../lib/cn.js";
2
2
  import { useFieldControl } from "../primitives/field-control.js";
3
3
  import { Input } from "../primitives/input.js";
4
4
  import { buttonClass } from "../primitives/button.js";
5
+ import { text } from "./messages.js";
5
6
  import { humanize } from "../live/naming.js";
6
7
  import { isMarkdown } from "../markdown/markdown-hint.js";
7
8
  import { contactFormat, contactInputProps } from "../live/contact-links.js";
@@ -64,8 +65,8 @@ const BuiltInEditor = ({ field, hints, value, stored, relationLabel, relationTo,
64
65
  children: picker
65
66
  }), /* @__PURE__ */ jsx(AppLink, {
66
67
  to: relationTo,
67
- "aria-label": `Open ${relationLabel ?? String(value)}`,
68
- title: "Open",
68
+ "aria-label": text("openLabel", relationLabel ?? String(value)),
69
+ title: text("open"),
69
70
  className: cn(buttonClass({ variant: "ghost" }), "w-8 px-0"),
70
71
  children: /* @__PURE__ */ jsx(ArrowUpRight, { className: "size-4" })
71
72
  })]
@@ -118,7 +119,7 @@ const BuiltInEditor = ({ field, hints, value, stored, relationLabel, relationTo,
118
119
  className: "h-8 w-full rounded-md border border-border-strong bg-background px-2 shadow-sm focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20",
119
120
  children: [value === "" && /* @__PURE__ */ jsx("option", {
120
121
  value: "",
121
- children: "Choose..."
122
+ children: text("choose")
122
123
  }), (field.enumValues ?? []).map((option) => /* @__PURE__ */ jsx("option", {
123
124
  value: option,
124
125
  children: enumLabel(option, hints?.valueLabels)
@@ -0,0 +1,8 @@
1
+ import { defineMessages } from "../../locale/messages.js";
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
+ });
7
+ //#endregion
8
+ export { text };
@@ -1,4 +1,5 @@
1
1
  import { CustomBoundary } from "../pages/custom-boundary.js";
2
+ import { text } from "./messages.js";
2
3
  import { jsx } from "react/jsx-runtime";
3
4
  //#region src/app/field-types/widget-part.tsx
4
5
  const partOf = ({ shown, part, field, value, onChange, invalid = false }) => {
@@ -24,7 +25,7 @@ const WidgetPart = ({ fallback, ...rest }) => {
24
25
  const element = partOf(rest);
25
26
  if (!element) return fallback;
26
27
  return /* @__PURE__ */ jsx(CustomBoundary, {
27
- name: `The field type ${rest.shown.name}`,
28
+ name: text("fieldType", rest.shown.name),
28
29
  fallback,
29
30
  children: element
30
31
  });