@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
@@ -1,12 +1,14 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import { slotted } from "../locale/slotted.js";
2
+ import { text } from "./messages.js";
3
+ import { jsx } from "react/jsx-runtime";
2
4
  //#region src/invitations/link-notice.tsx
3
5
  /** The invitation link to pass on, when the app cannot email it. */
4
- const LinkNotice = ({ link }) => link ? /* @__PURE__ */ jsxs("p", {
6
+ const LinkNotice = ({ link }) => link ? /* @__PURE__ */ jsx("p", {
5
7
  className: "mt-3 break-all rounded-md border bg-muted px-3 py-2 text-xs",
6
- children: ["This app cannot send email, so pass this link on yourself. It works once, until the invitation expires: ", /* @__PURE__ */ jsx("span", {
8
+ children: slotted(text("passLinkOn"), /* @__PURE__ */ jsx("span", {
7
9
  className: "font-mono",
8
10
  children: link
9
- })]
11
+ }))
10
12
  }) : null;
11
13
  //#endregion
12
14
  export { LinkNotice };
@@ -0,0 +1,24 @@
1
+ import { defineMessages } from "../locale/messages.js";
2
+ //#region src/invitations/messages.ts
3
+ const text = defineMessages({
4
+ en: {
5
+ email: "Email",
6
+ invite: "Invite",
7
+ expired: "Expired",
8
+ until: (date) => `Until ${date}`,
9
+ sendAgain: "Send again",
10
+ revoke: "Revoke",
11
+ passLinkOn: "This app cannot send email, so pass this link on yourself. It works once, until the invitation expires: {}"
12
+ },
13
+ nl: {
14
+ email: "E-mailadres",
15
+ invite: "Uitnodigen",
16
+ expired: "Verlopen",
17
+ until: (date) => `Tot ${date}`,
18
+ sendAgain: "Opnieuw sturen",
19
+ revoke: "Intrekken",
20
+ passLinkOn: "Deze app kan geen e-mail sturen, dus geef deze link zelf door. Die werkt één keer, tot de uitnodiging verloopt: {}"
21
+ }
22
+ });
23
+ //#endregion
24
+ export { text };
@@ -2,6 +2,7 @@ import { formatTag } from "../locale/active-locale.js";
2
2
  import { Button } from "../primitives/button.js";
3
3
  import { SectionError } from "../account/account-section.js";
4
4
  import { useAction } from "../organizations/use-action.js";
5
+ import { text } from "./messages.js";
5
6
  import { LinkNotice } from "./link-notice.js";
6
7
  import { useState } from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -27,7 +28,7 @@ const PendingInvitationRow = ({ email, gives, expiresAt, onResend, onRevoke }) =
27
28
  children: [
28
29
  gives,
29
30
  " · ",
30
- expired ? "Expired" : `Until ${new Date(expiresAt).toLocaleDateString(formatTag())}`
31
+ expired ? text("expired") : text("until", new Date(expiresAt).toLocaleDateString(formatTag()))
31
32
  ]
32
33
  })]
33
34
  }),
@@ -35,14 +36,14 @@ const PendingInvitationRow = ({ email, gives, expiresAt, onResend, onRevoke }) =
35
36
  size: "sm",
36
37
  loading: busy,
37
38
  onClick: () => void run(async () => setLink((await onResend()).link)),
38
- children: "Send again"
39
+ children: text("sendAgain")
39
40
  }),
40
41
  /* @__PURE__ */ jsx(Button, {
41
42
  size: "sm",
42
43
  variant: "danger",
43
44
  loading: busy,
44
45
  onClick: () => void run(onRevoke),
45
- children: "Revoke"
46
+ children: text("revoke")
46
47
  })
47
48
  ]
48
49
  }),
@@ -0,0 +1,8 @@
1
+ import { defineMessages } from "../locale/messages.js";
2
+ //#region src/lists/messages.ts
3
+ const text = defineMessages({
4
+ en: { showMore: "Show more" },
5
+ nl: { showMore: "Meer tonen" }
6
+ });
7
+ //#endregion
8
+ export { text };
@@ -1,6 +1,7 @@
1
1
  import { Input } from "../primitives/input.js";
2
2
  import { Button } from "../primitives/button.js";
3
3
  import { AccountSection, SectionError } from "../account/account-section.js";
4
+ import { text } from "./messages.js";
4
5
  import { Search } from "lucide-react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  //#region src/lists/paged-search-list.tsx
@@ -34,7 +35,7 @@ const PagedSearchList = ({ title, description, searchLabel, placeholder, query,
34
35
  className: "mt-3",
35
36
  loading: list.loading,
36
37
  onClick: () => void list.more(),
37
- children: "Show more"
38
+ children: text("showMore")
38
39
  })
39
40
  ]
40
41
  });
@@ -0,0 +1,14 @@
1
+ import { Fragment } from "react";
2
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
3
+ //#region src/locale/slotted.tsx
4
+ /**
5
+ * A built-in text with a `{}` for each element that goes in it, such as a highlighted address, rendered with the
6
+ * elements in their places in order: each language puts them where its sentence needs them.
7
+ */
8
+ const slotted = (message, ...slots) => {
9
+ const parts = message.split("{}");
10
+ if (parts.length !== slots.length + 1) throw new Error(`The text "${message}" has ${parts.length - 1} places for ${slots.length} elements`);
11
+ return /* @__PURE__ */ jsx(Fragment$1, { children: parts.map((part, index) => /* @__PURE__ */ jsxs(Fragment, { children: [part, index < slots.length && slots[index]] }, index)) });
12
+ };
13
+ //#endregion
14
+ export { slotted };
@@ -1,15 +1,16 @@
1
1
  import { Segmented } from "../primitives/segmented.js";
2
2
  import { Textarea } from "../primitives/textarea.js";
3
3
  import { Markdown } from "./markdown.js";
4
+ import { text } from "./messages.js";
4
5
  import { useState } from "react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  //#region src/markdown/markdown-editor.tsx
7
- const modes = [{
8
+ const modes = () => [{
8
9
  value: "write",
9
- label: "Write"
10
+ label: text("write")
10
11
  }, {
11
12
  value: "preview",
12
- label: "Preview"
13
+ label: text("preview")
13
14
  }];
14
15
  /**
15
16
  * Markdown source in a box that grows with it, as GitHub edits a comment, and a switch to its rendered preview: the
@@ -23,7 +24,7 @@ const MarkdownEditor = ({ value, onChange, label, invalid, placeholder }) => {
23
24
  className: "self-start",
24
25
  children: /* @__PURE__ */ jsx(Segmented, {
25
26
  value: mode,
26
- options: modes,
27
+ options: modes(),
27
28
  onChange: setMode,
28
29
  label
29
30
  })
@@ -37,7 +38,7 @@ const MarkdownEditor = ({ value, onChange, label, invalid, placeholder }) => {
37
38
  className: "min-h-[7.5rem] rounded-md border border-border px-2.5 py-1.5",
38
39
  children: value.trim() === "" ? /* @__PURE__ */ jsx("span", {
39
40
  className: "text-faint-foreground",
40
- children: "Nothing to preview"
41
+ children: text("nothingToPreview")
41
42
  }) : /* @__PURE__ */ jsx(Markdown, { source: value })
42
43
  })]
43
44
  });
@@ -0,0 +1,16 @@
1
+ import { defineMessages } from "../locale/messages.js";
2
+ //#region src/markdown/messages.ts
3
+ const text = defineMessages({
4
+ en: {
5
+ write: "Write",
6
+ preview: "Preview",
7
+ nothingToPreview: "Nothing to preview"
8
+ },
9
+ nl: {
10
+ write: "Schrijven",
11
+ preview: "Voorbeeld",
12
+ nothingToPreview: "Niets om te tonen"
13
+ }
14
+ });
15
+ //#endregion
16
+ export { text };
@@ -1,4 +1,5 @@
1
1
  import { useAuth } from "../auth/auth-provider.js";
2
+ import { text } from "./messages.js";
2
3
  import { useAction } from "./use-action.js";
3
4
  import { PagedSearchList } from "../lists/paged-search-list.js";
4
5
  import { usePagedSearch } from "../lists/use-paged-search.js";
@@ -11,17 +12,17 @@ import { jsx } from "react/jsx-runtime";
11
12
  const AllOrganizations = ({ basePath, currentId }) => {
12
13
  const { session } = useAuth();
13
14
  const [query, setQuery] = useState("");
14
- const search = useCallback((text, offset) => session.organizations.search(text, offset).then((page) => ({
15
+ const search = useCallback((term, offset) => session.organizations.search(term, offset).then((page) => ({
15
16
  items: page.organizations,
16
17
  total: page.total
17
18
  })), [session]);
18
19
  const list = usePagedSearch(search, query);
19
20
  const { busy, error, run } = useAction();
20
21
  return /* @__PURE__ */ jsx(PagedSearchList, {
21
- title: "All organizations",
22
- description: "Every organization in the app. Your global roles let you work in any of them, with what those roles allow there. Opening one you are not a member of is written to the audit log.",
23
- searchLabel: "Find an organization",
24
- placeholder: "Name or slug",
22
+ title: text("allOrganizations"),
23
+ description: text("allOrganizationsDescription"),
24
+ searchLabel: text("findOrganization"),
25
+ placeholder: text("nameOrSlug"),
25
26
  query,
26
27
  onQuery: setQuery,
27
28
  list,
@@ -1,5 +1,6 @@
1
1
  import { cn } from "../lib/cn.js";
2
2
  import { Checkbox } from "../primitives/checkbox.js";
3
+ import { text } from "./messages.js";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region src/organizations/app-roles-picker.tsx
5
6
  /**
@@ -12,7 +13,7 @@ const AppRolesPicker = ({ roles, selected, grantable, disabled, onChange }) => /
12
13
  const held = selected.includes(role.name);
13
14
  const locked = disabled || !grantable.has(role.name);
14
15
  return /* @__PURE__ */ jsxs("label", {
15
- title: locked && !disabled ? "You cannot give or take away this role" : void 0,
16
+ title: locked && !disabled ? text("cannotChangeRole") : void 0,
16
17
  className: cn("inline-flex items-center gap-1.5", locked && "text-muted-foreground"),
17
18
  children: [/* @__PURE__ */ jsx(Checkbox, {
18
19
  checked: held,
@@ -6,7 +6,8 @@ import { authMessage } from "../auth/auth-messages.js";
6
6
  import { useAuth } from "../auth/auth-provider.js";
7
7
  import { Button, buttonClass } from "../primitives/button.js";
8
8
  import { AuthLayout } from "../auth/auth-layout.js";
9
- import { organizationRoleLabels, roleLabel } from "./organization-paths.js";
9
+ import { text } from "./messages.js";
10
+ import { organizationRoleLabel, roleLabel } from "./organization-paths.js";
10
11
  import { useAction } from "./use-action.js";
11
12
  import { useEffect, useState } from "react";
12
13
  import { AuthError } from "@protobase/client";
@@ -36,25 +37,25 @@ const SignUp = ({ token, preview, joins, onDone }) => {
36
37
  children: [
37
38
  /* @__PURE__ */ jsx("p", {
38
39
  className: "text-muted-foreground",
39
- children: joins ? `Make your account for ${preview.email} to join.` : `Make your account for ${preview.email}.`
40
+ children: joins ? text("makeAccountToJoin", preview.email) : text("makeAccount", preview.email)
40
41
  }),
41
42
  error && /* @__PURE__ */ jsx("p", {
42
43
  role: "alert",
43
- className: "text-xs font-medium text-danger-text",
44
+ className: "text-body font-medium text-danger-text",
44
45
  children: error
45
46
  }),
46
47
  /* @__PURE__ */ jsx(Input, {
47
- "aria-label": "Your name",
48
- placeholder: "Your name",
48
+ "aria-label": text("yourName"),
49
+ placeholder: text("yourName"),
49
50
  autoComplete: "name",
50
51
  value: name,
51
52
  onChange: (event) => setName(event.target.value)
52
53
  }),
53
54
  withPassword && /* @__PURE__ */ jsx(Input, {
54
- "aria-label": "Password",
55
+ "aria-label": text("password"),
55
56
  type: "password",
56
57
  autoComplete: "new-password",
57
- placeholder: passwordOptional ? `Password (optional, 12+ characters)` : `Password (12+ characters)`,
58
+ placeholder: passwordOptional ? text("passwordOptional", 12) : text("passwordRequired", 12),
58
59
  value: password,
59
60
  onChange: (event) => setPassword(event.target.value)
60
61
  }),
@@ -63,7 +64,7 @@ const SignUp = ({ token, preview, joins, onDone }) => {
63
64
  variant: "primary",
64
65
  loading: busy,
65
66
  disabled: !name.trim() || withPassword && !passwordOptional && password.length < 12,
66
- children: joins ? "Create account and join" : "Create your account"
67
+ children: joins ? text("createAndJoin") : text("createYourAccount")
67
68
  })
68
69
  ]
69
70
  });
@@ -79,61 +80,59 @@ const InvitationPage = ({ token, onDone, signIn }) => {
79
80
  const [invalid, setInvalid] = useState();
80
81
  const { busy, error, run } = useAction();
81
82
  useEffect(() => {
82
- session.organizations.invitation(token).then(setPreview, (failure) => setInvalid(failure instanceof AuthError ? authMessage(failure) : "This invitation link is not valid"));
83
+ session.organizations.invitation(token).then(setPreview, (failure) => setInvalid(failure instanceof AuthError ? authMessage(failure) : text("invalidLink")));
83
84
  }, [session, token]);
84
85
  if (invalid) return /* @__PURE__ */ jsx(AuthLayout, {
85
- title: "Invitation",
86
+ title: text("invitation"),
86
87
  description: invalid,
87
88
  children: /* @__PURE__ */ jsx(Button, {
88
89
  className: "w-full",
89
90
  onClick: onDone,
90
- children: "Go to the app"
91
+ children: text("goToApp")
91
92
  })
92
93
  });
93
94
  if (!preview) return /* @__PURE__ */ jsx(AuthLayout, {
94
- title: "Invitation",
95
+ title: text("invitation"),
95
96
  children: /* @__PURE__ */ jsxs("div", {
96
97
  className: "flex items-center justify-center gap-2 text-muted-foreground",
97
- children: [/* @__PURE__ */ jsx(Spinner, {}), " Loading"]
98
+ children: [
99
+ /* @__PURE__ */ jsx(Spinner, {}),
100
+ " ",
101
+ text("loading")
102
+ ]
98
103
  })
99
104
  });
100
105
  const user = state.kind === "signed-in" ? state.user : void 0;
101
106
  const sameAddress = user?.email.toLowerCase() === preview.email.toLowerCase();
102
107
  if (!preview.organization) {
103
108
  const app = preview.app?.name ?? "";
104
- const description = `${preview.inviter.name} invites you to join ${app}.`;
109
+ const description = text("invitesToApp", preview.inviter.name, app);
105
110
  return /* @__PURE__ */ jsx(AuthLayout, {
106
- title: `Join ${app}`,
111
+ title: text("join", app),
107
112
  description,
108
113
  children: preview.hasAccount ? user && sameAddress ? /* @__PURE__ */ jsx(Button, {
109
114
  variant: "primary",
110
115
  className: "w-full",
111
116
  onClick: onDone,
112
- children: "Go to the app"
113
- }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("p", {
117
+ children: text("goToApp")
118
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("p", {
114
119
  className: "mb-3 text-muted-foreground",
115
- children: [preview.email, " has an account already: sign in with it."]
120
+ children: text("hasAccount", preview.email)
116
121
  }), user ? /* @__PURE__ */ jsx(Button, {
117
122
  className: "w-full",
118
123
  onClick: () => void signOut(),
119
- children: "Sign out"
120
- }) : /* @__PURE__ */ jsxs(RouteLink, {
124
+ children: text("signOut")
125
+ }) : /* @__PURE__ */ jsx(RouteLink, {
121
126
  to: signIn,
122
127
  className: cn(buttonClass({ variant: "primary" }), "w-full"),
123
- children: ["Sign in as ", preview.email]
124
- })] }) : user ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("p", {
128
+ children: text("signInAs", preview.email)
129
+ })] }) : user ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("p", {
125
130
  className: "mb-3 text-muted-foreground",
126
- children: [
127
- "This invitation is for ",
128
- preview.email,
129
- ", and you are signed in as ",
130
- user.email,
131
- "."
132
- ]
131
+ children: text("otherAddress", preview.email, user.email)
133
132
  }), /* @__PURE__ */ jsx(Button, {
134
133
  className: "w-full",
135
134
  onClick: () => void signOut(),
136
- children: "Sign out to accept it"
135
+ children: text("signOutToAccept")
137
136
  })] }) : /* @__PURE__ */ jsx(SignUp, {
138
137
  token,
139
138
  preview,
@@ -144,35 +143,30 @@ const InvitationPage = ({ token, onDone, signIn }) => {
144
143
  }
145
144
  const organization = preview.organization;
146
145
  const roles = preview.appRoles.map((name) => roleLabel(organizations?.roles ?? [], name));
147
- const description = `${preview.inviter.name} invites you to ${organization.name} as ${organizationRoleLabels[preview.role].toLowerCase()}${roles.length > 0 ? `, with ${roles.join(", ")}` : ""}.`;
146
+ const role = organizationRoleLabel(preview.role).toLowerCase();
147
+ const description = roles.length > 0 ? text("invitesToWith", preview.inviter.name, organization.name, role, roles.join(", ")) : text("invitesTo", preview.inviter.name, organization.name, role);
148
148
  if (user && !sameAddress) return /* @__PURE__ */ jsxs(AuthLayout, {
149
- title: `Join ${organization.name}`,
149
+ title: text("join", organization.name),
150
150
  description,
151
- children: [/* @__PURE__ */ jsxs("p", {
151
+ children: [/* @__PURE__ */ jsx("p", {
152
152
  className: "mb-3 text-muted-foreground",
153
- children: [
154
- "This invitation is for ",
155
- preview.email,
156
- ", and you are signed in as ",
157
- user.email,
158
- "."
159
- ]
153
+ children: text("otherAddress", preview.email, user.email)
160
154
  }), /* @__PURE__ */ jsx(Button, {
161
155
  className: "w-full",
162
156
  onClick: () => void signOut(),
163
- children: "Sign out to accept it"
157
+ children: text("signOutToAccept")
164
158
  })]
165
159
  });
166
160
  return /* @__PURE__ */ jsx(AuthLayout, {
167
- title: `Join ${organization.name}`,
161
+ title: text("join", organization.name),
168
162
  description,
169
163
  children: user ? /* @__PURE__ */ jsxs("div", {
170
164
  className: "flex flex-col gap-3",
171
165
  children: [error && /* @__PURE__ */ jsx("p", {
172
166
  role: "alert",
173
- className: "text-xs font-medium text-danger-text",
167
+ className: "text-body font-medium text-danger-text",
174
168
  children: error
175
- }), /* @__PURE__ */ jsxs(Button, {
169
+ }), /* @__PURE__ */ jsx(Button, {
176
170
  variant: "primary",
177
171
  className: "w-full",
178
172
  loading: busy,
@@ -180,16 +174,12 @@ const InvitationPage = ({ token, onDone, signIn }) => {
180
174
  await session.organizations.accept(token);
181
175
  onDone();
182
176
  }),
183
- children: ["Join ", organization.name]
177
+ children: text("join", organization.name)
184
178
  })]
185
- }) : preview.hasAccount ? /* @__PURE__ */ jsxs(RouteLink, {
179
+ }) : preview.hasAccount ? /* @__PURE__ */ jsx(RouteLink, {
186
180
  to: signIn,
187
181
  className: cn(buttonClass({ variant: "primary" }), "w-full"),
188
- children: [
189
- "Sign in as ",
190
- preview.email,
191
- " to join"
192
- ]
182
+ children: text("signInAsToJoin", preview.email)
193
183
  }) : /* @__PURE__ */ jsx(SignUp, {
194
184
  token,
195
185
  preview,
@@ -1,7 +1,8 @@
1
1
  import { PageHeader } from "../app-shell/page-header.js";
2
2
  import { useAuth } from "../auth/auth-provider.js";
3
3
  import { AccountSection } from "../account/account-section.js";
4
- import { grantableRoles, organizationRoleLabels, roleLabel } from "./organization-paths.js";
4
+ import { text } from "./messages.js";
5
+ import { grantableRoles, organizationRoleLabel, roleLabel } from "./organization-paths.js";
5
6
  import { InviteForm } from "../invitations/invite-form.js";
6
7
  import { PendingInvitationRow } from "../invitations/pending-invitation-row.js";
7
8
  import { AppRolesPicker } from "./app-roles-picker.js";
@@ -25,17 +26,17 @@ const InviteToOrganization = ({ current, onSent }) => {
25
26
  return sent;
26
27
  };
27
28
  return /* @__PURE__ */ jsx(InviteForm, {
28
- title: "Invite someone",
29
- description: "They get an email with a link to join, or to make an account first. You can give the app roles you hold, and those your roles grant.",
29
+ title: text("inviteSomeone"),
30
+ description: text("inviteDescription"),
30
31
  onInvite: invite,
31
32
  beside: /* @__PURE__ */ jsx("select", {
32
- "aria-label": "Organization role",
33
+ "aria-label": text("organizationRole"),
33
34
  value: role,
34
35
  onChange: (event) => setRole(event.target.value),
35
36
  className: "h-8 rounded-md border border-border-strong bg-background px-2",
36
37
  children: assignableOrganizationRoles(current).map((option) => /* @__PURE__ */ jsx("option", {
37
38
  value: option,
38
- children: organizationRoleLabels[option]
39
+ children: organizationRoleLabel(option)
39
40
  }, option))
40
41
  }),
41
42
  children: /* @__PURE__ */ jsx(AppRolesPicker, {
@@ -51,7 +52,7 @@ const PendingRow = ({ invitation, organizationId, onChanged }) => {
51
52
  const appRoles = invitation.appRoles.map((name) => roleLabel(organizations?.roles ?? [], name));
52
53
  return /* @__PURE__ */ jsx(PendingInvitationRow, {
53
54
  email: invitation.email,
54
- gives: `${organizationRoleLabels[invitation.role]}${appRoles.length > 0 ? ` · ${appRoles.join(", ")}` : ""}`,
55
+ gives: `${organizationRoleLabel(invitation.role)}${appRoles.length > 0 ? ` · ${appRoles.join(", ")}` : ""}`,
55
56
  expiresAt: invitation.expiresAt,
56
57
  onResend: async () => {
57
58
  const sent = await session.organizations.resend(organizationId, invitation);
@@ -78,16 +79,16 @@ const InvitationsPage = ({ current }) => {
78
79
  className: "mx-auto flex w-full max-w-3xl flex-col gap-4 px-4 py-6 md:px-6",
79
80
  children: [
80
81
  /* @__PURE__ */ jsx(PageHeader, {
81
- title: "Invitations",
82
- subtitle: `People invited to ${current.organization.name}.`
82
+ title: text("invitations"),
83
+ subtitle: text("peopleInvited", current.organization.name)
83
84
  }),
84
85
  /* @__PURE__ */ jsx(InviteToOrganization, {
85
86
  current,
86
87
  onSent: load
87
88
  }),
88
89
  /* @__PURE__ */ jsx(AccountSection, {
89
- title: "Not accepted yet",
90
- description: invitations.length > 0 ? "Sending again gives a new link, which replaces the earlier one." : "Nobody is waiting.",
90
+ title: text("notAcceptedYet"),
91
+ description: invitations.length > 0 ? text("sendingAgain") : text("nobodyWaiting"),
91
92
  children: invitations.length > 0 && /* @__PURE__ */ jsx("ul", {
92
93
  className: "divide-y rounded-md border",
93
94
  children: invitations.map((invitation) => /* @__PURE__ */ jsx(PendingRow, {
@@ -4,7 +4,8 @@ import { authMessage } from "../auth/auth-messages.js";
4
4
  import { useAuth } from "../auth/auth-provider.js";
5
5
  import { Button } from "../primitives/button.js";
6
6
  import { AccountSection, SectionError } from "../account/account-section.js";
7
- import { grantableRoles, organizationRoleLabels } from "./organization-paths.js";
7
+ import { text } from "./messages.js";
8
+ import { grantableRoles, organizationRoleLabel } from "./organization-paths.js";
8
9
  import { useAction } from "./use-action.js";
9
10
  import { AppRolesPicker } from "./app-roles-picker.js";
10
11
  import { PersonRow } from "../people/person-row.js";
@@ -33,17 +34,17 @@ const MemberRow = ({ member, current, onChanged }) => {
33
34
  self,
34
35
  error,
35
36
  actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("select", {
36
- "aria-label": `Organization role of ${member.name}`,
37
+ "aria-label": text("roleOf", member.name),
37
38
  value: member.role,
38
39
  disabled: busy || roleLocked,
39
40
  onChange: (event) => void run(async () => {
40
41
  await session.organizations.setRole(organizationId, member.id, event.target.value);
41
42
  onChanged();
42
43
  }),
43
- className: "h-7 rounded-md border border-border-strong bg-background px-2 text-xs",
44
+ className: "h-7 rounded-md border border-border-strong bg-background px-2 text-body",
44
45
  children: (roleLocked ? [member.role] : organizationRoles).map((role) => /* @__PURE__ */ jsx("option", {
45
46
  value: role,
46
- children: organizationRoleLabels[role]
47
+ children: organizationRoleLabel(role)
47
48
  }, role))
48
49
  }), !self && /* @__PURE__ */ jsx(Button, {
49
50
  size: "sm",
@@ -54,7 +55,7 @@ const MemberRow = ({ member, current, onChanged }) => {
54
55
  await session.organizations.removeMember(organizationId, member.id);
55
56
  onChanged();
56
57
  }),
57
- children: "Remove"
58
+ children: text("remove")
58
59
  })] }),
59
60
  children: /* @__PURE__ */ jsx(AppRolesPicker, {
60
61
  roles: membershipRoles,
@@ -78,18 +79,18 @@ const MembersPage = ({ current }) => {
78
79
  const [error, setError] = useState();
79
80
  const organizationId = current?.organization?.id;
80
81
  const load = useCallback(() => {
81
- if (organizationId) session.organizations.members(organizationId).then(setMembers, (failure) => setError(failure instanceof AuthError ? authMessage(failure) : "Could not read the members"));
82
+ if (organizationId) session.organizations.members(organizationId).then(setMembers, (failure) => setError(failure instanceof AuthError ? authMessage(failure) : text("couldNotReadMembers")));
82
83
  }, [session, organizationId]);
83
84
  useEffect(load, [load]);
84
85
  if (!current?.organization) return null;
85
86
  return /* @__PURE__ */ jsxs("div", {
86
87
  className: "mx-auto flex w-full max-w-3xl flex-col gap-4 px-4 py-6 md:px-6",
87
88
  children: [/* @__PURE__ */ jsx(PageHeader, {
88
- title: "Members",
89
- subtitle: `Who works in ${current.organization.name}, and with which roles.`
89
+ title: text("members"),
90
+ subtitle: text("whoWorks", current.organization.name)
90
91
  }), /* @__PURE__ */ jsxs(AccountSection, {
91
- title: "Members",
92
- description: "Owners and admins manage the organization; app roles decide what each member sees and does in the app.",
92
+ title: text("members"),
93
+ description: text("membersDescription"),
93
94
  children: [/* @__PURE__ */ jsx(SectionError, { message: error }), members ? /* @__PURE__ */ jsx("ul", {
94
95
  className: "divide-y rounded-md border",
95
96
  children: members.map((member) => /* @__PURE__ */ jsx(MemberRow, {
@@ -99,7 +100,11 @@ const MembersPage = ({ current }) => {
99
100
  }, `${member.id}/${member.role}/${member.appRoles.join()}`))
100
101
  }) : !error && /* @__PURE__ */ jsxs("div", {
101
102
  className: "flex items-center gap-2 text-muted-foreground",
102
- children: [/* @__PURE__ */ jsx(Spinner, {}), " Loading"]
103
+ children: [
104
+ /* @__PURE__ */ jsx(Spinner, {}),
105
+ " ",
106
+ text("loading")
107
+ ]
103
108
  })]
104
109
  })]
105
110
  });