@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,80 +1,81 @@
1
+ import { text } from "./messages.js";
1
2
  //#region src/account/sign-in-policy-labels.ts
2
- const onOff = [{
3
+ const onOff = () => [{
3
4
  value: "allowed",
4
- label: "On"
5
+ label: text("on")
5
6
  }, {
6
7
  value: "forbidden",
7
- label: "Off"
8
+ label: text("off")
8
9
  }];
9
- const optionalRequiredOff = [
10
+ const optionalRequiredOff = () => [
10
11
  {
11
12
  value: "allowed",
12
- label: "Optional"
13
+ label: text("optional")
13
14
  },
14
15
  {
15
16
  value: "required",
16
- label: "Required"
17
+ label: text("required")
17
18
  },
18
19
  {
19
20
  value: "forbidden",
20
- label: "Off"
21
+ label: text("off")
21
22
  }
22
23
  ];
23
24
  /** The rows of the sign-in policy page, in order, with the rules each method takes and their words. */
24
- const policyRows = [
25
+ const policyRows = () => [
25
26
  {
26
27
  method: "password",
27
- label: "Password",
28
- description: "Sign in with the email address and a password.",
29
- rules: onOff
28
+ label: text("password"),
29
+ description: text("passwordDescription"),
30
+ rules: onOff()
30
31
  },
31
32
  {
32
33
  method: "emailCode",
33
- label: "Emailed sign-in code",
34
- description: "Sign in with a one-time code mailed to the account's address.",
35
- rules: onOff
34
+ label: text("emailedSignInCode"),
35
+ description: text("emailedSignInCodeDescription"),
36
+ rules: onOff()
36
37
  },
37
38
  {
38
39
  method: "passkey",
39
- label: "Passkeys",
40
- description: "Sign in with Face ID, Touch ID, Windows Hello, a phone or a security key. Required: everyone adds one after signing in.",
41
- rules: optionalRequiredOff
40
+ label: text("passkeys"),
41
+ description: text("passkeysPolicyDescription"),
42
+ rules: optionalRequiredOff()
42
43
  },
43
44
  {
44
45
  method: "twoFactor",
45
- label: "Two-factor authentication",
46
- description: "A code from an authenticator app, or an emailed one, after a password or an emailed sign-in code. Required: everyone turns it on after signing in.",
47
- rules: optionalRequiredOff
46
+ label: text("twoFactor"),
47
+ description: text("twoFactorPolicyDescription"),
48
+ rules: optionalRequiredOff()
48
49
  },
49
50
  {
50
51
  method: "staffAccess",
51
- label: "Staff sign-in as a person",
52
- description: "The team that runs this app signs in as someone to help them, with a reason, for a short session. Each time is in the log below; with \"Email the person\" they are told too.",
52
+ label: text("staffAccess"),
53
+ description: text("staffAccessDescription"),
53
54
  rules: [
54
55
  {
55
56
  value: "allowed",
56
- label: "On"
57
+ label: text("on")
57
58
  },
58
59
  {
59
60
  value: "notify",
60
- label: "Email the person"
61
+ label: text("emailThePerson")
61
62
  },
62
63
  {
63
64
  value: "forbidden",
64
- label: "Off"
65
+ label: text("off")
65
66
  }
66
67
  ]
67
68
  },
68
69
  {
69
70
  method: "platformSignIn",
70
- label: "Sign-in through the platform",
71
- description: "The sign-in provider the platform that runs this app adds, for people who have an account here already. It never creates accounts.",
72
- rules: onOff
71
+ label: text("platformSignIn"),
72
+ description: text("platformSignInDescription"),
73
+ rules: onOff()
73
74
  }
74
75
  ];
75
76
  /** The word for `rule` in `method`'s row, for example "Optional" for an allowed passkey. Every rule the server stores has one. */
76
77
  const ruleLabel = (method, rule) => {
77
- const label = policyRows.find((row) => row.method === method)?.rules.find((option) => option.value === rule)?.label;
78
+ const label = policyRows().find((row) => row.method === method)?.rules.find((option) => option.value === rule)?.label;
78
79
  if (label === void 0) throw new Error(`No label for the ${rule} rule of ${method}`);
79
80
  return label;
80
81
  };
@@ -1,3 +1,4 @@
1
+ import { text } from "./messages.js";
1
2
  import { Spinner } from "../primitives/spinner.js";
2
3
  import { PageHeader } from "../app-shell/page-header.js";
3
4
  import { authMessage } from "../auth/auth-messages.js";
@@ -13,7 +14,7 @@ const StaffSignIns = ({ operator }) => {
13
14
  const [signIns, setSignIns] = useState();
14
15
  const [error, setError] = useState();
15
16
  useEffect(() => {
16
- session.staff.log().then(setSignIns, (failure) => setError(failure instanceof AuthError ? authMessage(failure) : "Could not read the staff sign-ins"));
17
+ session.staff.log().then(setSignIns, (failure) => setError(failure instanceof AuthError ? authMessage(failure) : text("couldNotReadStaffSignIns")));
17
18
  }, [session]);
18
19
  return /* @__PURE__ */ jsx(StaffSignInLog, {
19
20
  operator,
@@ -32,7 +33,7 @@ const SignInPolicyPage = () => {
32
33
  const [error, setError] = useState();
33
34
  const [notice, setNotice] = useState();
34
35
  useEffect(() => {
35
- session.signInPolicy.read().then(setState, (failure) => setError(failure instanceof AuthError ? authMessage(failure) : "Could not read the sign-in policy"));
36
+ session.signInPolicy.read().then(setState, (failure) => setError(failure instanceof AuthError ? authMessage(failure) : text("couldNotReadPolicy")));
36
37
  }, [session]);
37
38
  const save = async (policy) => {
38
39
  setBusy(true);
@@ -40,7 +41,7 @@ const SignInPolicyPage = () => {
40
41
  setNotice(void 0);
41
42
  try {
42
43
  setState(await session.signInPolicy.save(policy));
43
- setNotice("Saved. It applies to every sign-in from now on.");
44
+ setNotice(text("policySaved"));
44
45
  } catch (failure) {
45
46
  if (!(failure instanceof AuthError)) throw failure;
46
47
  setError(authMessage(failure));
@@ -50,8 +51,8 @@ const SignInPolicyPage = () => {
50
51
  return /* @__PURE__ */ jsxs("div", {
51
52
  className: "mx-auto flex w-full max-w-3xl flex-col gap-4 px-4 py-6 md:px-6",
52
53
  children: [/* @__PURE__ */ jsx(PageHeader, {
53
- title: "Sign-in policy",
54
- subtitle: "How people sign in to this app. Signed-in people keep their session, and are asked for what is newly required within 15 minutes."
54
+ title: text("signInPolicy"),
55
+ subtitle: text("policySubtitle")
55
56
  }), state ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(SignInPolicyForm, {
56
57
  state,
57
58
  busy,
@@ -64,7 +65,11 @@ const SignInPolicyPage = () => {
64
65
  children: error
65
66
  }) : /* @__PURE__ */ jsxs("div", {
66
67
  className: "flex items-center gap-2 text-muted-foreground",
67
- children: [/* @__PURE__ */ jsx(Spinner, {}), " Loading"]
68
+ children: [
69
+ /* @__PURE__ */ jsx(Spinner, {}),
70
+ " ",
71
+ text("loading")
72
+ ]
68
73
  })]
69
74
  });
70
75
  };
@@ -1,3 +1,4 @@
1
+ import { text } from "./messages.js";
1
2
  import { Badge } from "../primitives/badge.js";
2
3
  import { authMessage } from "../auth/auth-messages.js";
3
4
  import { Button } from "../primitives/button.js";
@@ -23,8 +24,8 @@ const SignInProvidersSection = ({ providers, linked, onConnect, error: returned
23
24
  }
24
25
  };
25
26
  return /* @__PURE__ */ jsxs(AccountSection, {
26
- title: "Connected accounts",
27
- description: "Sign in with these instead of your password. Connecting one asks you to sign in there; its address may differ from yours here.",
27
+ title: text("connectedAccounts"),
28
+ description: text("connectedAccountsDescription"),
28
29
  children: [/* @__PURE__ */ jsx(SectionError, { message: error }), /* @__PURE__ */ jsx("ul", {
29
30
  className: "divide-y rounded-md border",
30
31
  children: providers.map((provider) => /* @__PURE__ */ jsxs("li", {
@@ -37,13 +38,13 @@ const SignInProvidersSection = ({ providers, linked, onConnect, error: returned
37
38
  }),
38
39
  linked.includes(provider.id) ? /* @__PURE__ */ jsx(Badge, {
39
40
  tone: "green",
40
- children: "Connected"
41
- }) : /* @__PURE__ */ jsxs(Button, {
41
+ children: text("connected")
42
+ }) : /* @__PURE__ */ jsx(Button, {
42
43
  size: "sm",
43
44
  loading: busy === provider.id,
44
45
  disabled: busy !== void 0,
45
46
  onClick: () => void connect(provider.id),
46
- children: ["Connect ", provider.name]
47
+ children: text("connect", provider.name)
47
48
  })
48
49
  ]
49
50
  }, provider.id))
@@ -1,27 +1,28 @@
1
+ import { text } from "./messages.js";
1
2
  import { Badge } from "../primitives/badge.js";
2
3
  import { formatDateTime } from "../format/date.js";
3
4
  import { AccountSection, SectionError } from "./account-section.js";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  //#region src/account/staff-sign-in-log.tsx
6
- const stateOf = (entry, now) => entry.endedAt ? /* @__PURE__ */ jsxs(Badge, {
7
+ const stateOf = (entry, now) => entry.endedAt ? /* @__PURE__ */ jsx(Badge, {
7
8
  tone: "neutral",
8
- children: ["Stopped ", formatDateTime(Date.parse(entry.endedAt))]
9
- }) : Date.parse(entry.expiresAt) <= now ? /* @__PURE__ */ jsxs(Badge, {
9
+ children: text("stopped", formatDateTime(Date.parse(entry.endedAt)))
10
+ }) : Date.parse(entry.expiresAt) <= now ? /* @__PURE__ */ jsx(Badge, {
10
11
  tone: "neutral",
11
- children: ["Ended ", formatDateTime(Date.parse(entry.expiresAt))]
12
- }) : /* @__PURE__ */ jsxs(Badge, {
12
+ children: text("ended", formatDateTime(Date.parse(entry.expiresAt)))
13
+ }) : /* @__PURE__ */ jsx(Badge, {
13
14
  tone: "amber",
14
- children: ["Signed in until ", formatDateTime(Date.parse(entry.expiresAt))]
15
+ children: text("signedInUntil", formatDateTime(Date.parse(entry.expiresAt)))
15
16
  });
16
17
  /** The app's log of staff sign-ins, for admins: who signed in as whom, why, and when. */
17
18
  const StaffSignInLog = ({ signIns, operator, error, now = Date.now() }) => /* @__PURE__ */ jsxs(AccountSection, {
18
- title: "Staff sign-ins",
19
- description: `Each time staff of ${operator} signed in as someone here, newest first.`,
19
+ title: text("staffSignIns"),
20
+ description: text("staffSignInsDescription", operator),
20
21
  children: [
21
22
  /* @__PURE__ */ jsx(SectionError, { message: error }),
22
23
  signIns && signIns.length === 0 && /* @__PURE__ */ jsx("p", {
23
24
  className: "text-muted-foreground",
24
- children: "No staff has signed in as anyone yet."
25
+ children: text("noStaffSignIns")
25
26
  }),
26
27
  signIns && signIns.length > 0 && /* @__PURE__ */ jsx("ul", {
27
28
  className: "divide-y rounded-md border",
@@ -37,7 +38,7 @@ const StaffSignInLog = ({ signIns, operator, error, now = Date.now() }) => /* @_
37
38
  }),
38
39
  /* @__PURE__ */ jsx("span", {
39
40
  className: "text-muted-foreground",
40
- children: "as"
41
+ children: text("as")
41
42
  }),
42
43
  /* @__PURE__ */ jsx("span", {
43
44
  className: "font-medium break-all",
@@ -1,3 +1,4 @@
1
+ import { text } from "./messages.js";
1
2
  import { useMemo } from "react";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
4
  import { encode } from "uqr";
@@ -18,7 +19,7 @@ const TotpQr = ({ uri, className }) => {
18
19
  return /* @__PURE__ */ jsxs("svg", {
19
20
  viewBox: `0 0 ${size} ${size}`,
20
21
  role: "img",
21
- "aria-label": "QR code for your authenticator app",
22
+ "aria-label": text("qrCode"),
22
23
  shapeRendering: "crispEdges",
23
24
  className,
24
25
  children: [/* @__PURE__ */ jsx("rect", {
@@ -1,3 +1,4 @@
1
+ import { text } from "./messages.js";
1
2
  import { Badge } from "../primitives/badge.js";
2
3
  import { Button } from "../primitives/button.js";
3
4
  import { Dialog } from "../primitives/dialog.js";
@@ -9,9 +10,9 @@ import { useState } from "react";
9
10
  import { jsx, jsxs } from "react/jsx-runtime";
10
11
  //#region src/account/two-factor-section.tsx
11
12
  const offDescriptions = {
12
- allowed: "Ask for a second step after your password or an emailed sign-in code: a code from an authenticator app, or one emailed to you. A passkey needs no second step.",
13
- required: "This app requires two-factor authentication for every account. Turn it on to keep using the app.",
14
- forbidden: "Your admin turned two-factor authentication off for this app."
13
+ allowed: "twoFactorAllowed",
14
+ required: "twoFactorRequired",
15
+ forbidden: "twoFactorForbidden"
15
16
  };
16
17
  const TwoFactorSection = (props) => {
17
18
  const { rule, enabled, authenticatorApp, mail, needsPassword, onTurnOff, onNewBackupCodes, onChanged } = props;
@@ -19,14 +20,14 @@ const TwoFactorSection = (props) => {
19
20
  const close = () => setOpen(void 0);
20
21
  const status = enabled ? /* @__PURE__ */ jsx(Badge, {
21
22
  tone: "green",
22
- children: "On"
23
+ children: text("on")
23
24
  }) : rule === "required" ? /* @__PURE__ */ jsx(Badge, {
24
25
  tone: "amber",
25
- children: "Required"
26
- }) : /* @__PURE__ */ jsx(Badge, { children: "Off" });
27
- const description = !enabled ? offDescriptions[rule] : authenticatorApp ? `Signing in with a password or an emailed sign-in code also asks for a code from your authenticator app${mail ? ", or one emailed to you" : ""}. Backup codes work when you do not have the app.` : "Signing in with a password or an emailed sign-in code also asks for a code emailed to you.";
26
+ children: text("required")
27
+ }) : /* @__PURE__ */ jsx(Badge, { children: text("off") });
28
+ const description = !enabled ? text(offDescriptions[rule]) : authenticatorApp ? text(mail ? "twoFactorOnWithAppOrMail" : "twoFactorOnWithApp") : text("twoFactorOnWithMail");
28
29
  if (open?.kind === "setup") return /* @__PURE__ */ jsx(AccountSection, {
29
- title: "Two-factor authentication",
30
+ title: text("twoFactor"),
30
31
  status,
31
32
  description,
32
33
  children: /* @__PURE__ */ jsx("div", {
@@ -46,7 +47,7 @@ const TwoFactorSection = (props) => {
46
47
  })
47
48
  });
48
49
  return /* @__PURE__ */ jsxs(AccountSection, {
49
- title: "Two-factor authentication",
50
+ title: text("twoFactor"),
50
51
  status,
51
52
  description,
52
53
  children: [
@@ -59,32 +60,32 @@ const TwoFactorSection = (props) => {
59
60
  kind: "setup",
60
61
  appOnly: false
61
62
  }),
62
- children: "Turn on"
63
+ children: text("turnOn")
63
64
  }),
64
65
  enabled && !authenticatorApp && rule !== "forbidden" && /* @__PURE__ */ jsx(Button, {
65
66
  onClick: () => setOpen({
66
67
  kind: "setup",
67
68
  appOnly: true
68
69
  }),
69
- children: "Add an authenticator app"
70
+ children: text("addAuthenticator")
70
71
  }),
71
72
  enabled && authenticatorApp && /* @__PURE__ */ jsx(Button, {
72
73
  onClick: () => setOpen({ kind: "new-codes" }),
73
- children: "New backup codes"
74
+ children: text("newBackupCodes")
74
75
  }),
75
76
  enabled && /* @__PURE__ */ jsx(Button, {
76
77
  variant: "danger",
77
78
  disabled: rule === "required",
78
- title: rule === "required" ? "This app requires two-factor authentication." : void 0,
79
+ title: rule === "required" ? text("twoFactorIsRequired") : void 0,
79
80
  onClick: () => setOpen({ kind: "turn-off" }),
80
- children: "Turn off"
81
+ children: text("turnOff")
81
82
  })
82
83
  ]
83
84
  }),
84
85
  open?.kind === "turn-off" && /* @__PURE__ */ jsx(PasswordDialog, {
85
- title: "Turn off two-factor authentication?",
86
- description: "Signing in then needs only your password or an emailed code. Your backup codes stop working.",
87
- confirmLabel: "Turn off",
86
+ title: text("turnOffTitle"),
87
+ description: text("turnOffDescription"),
88
+ confirmLabel: text("turnOff"),
88
89
  danger: true,
89
90
  needsPassword,
90
91
  onClose: close,
@@ -95,9 +96,9 @@ const TwoFactorSection = (props) => {
95
96
  }
96
97
  }),
97
98
  open?.kind === "new-codes" && /* @__PURE__ */ jsx(PasswordDialog, {
98
- title: "Make new backup codes?",
99
- description: "Your current backup codes stop working, and you get ten new ones.",
100
- confirmLabel: "Make new codes",
99
+ title: text("newCodesTitle"),
100
+ description: text("newCodesDescription"),
101
+ confirmLabel: text("makeNewCodes"),
101
102
  needsPassword,
102
103
  onClose: close,
103
104
  onConfirm: async (password) => setOpen({
@@ -106,13 +107,13 @@ const TwoFactorSection = (props) => {
106
107
  })
107
108
  }),
108
109
  open?.kind === "codes" && /* @__PURE__ */ jsx(Dialog, {
109
- title: "Your new backup codes",
110
- description: "Keep them somewhere safe: each one signs you in once if you lose your phone. They are not shown again.",
110
+ title: text("yourNewCodes"),
111
+ description: text("keepCodesSafe"),
111
112
  onClose: close,
112
113
  actions: /* @__PURE__ */ jsx(Button, {
113
114
  variant: "primary",
114
115
  onClick: close,
115
- children: "I saved my backup codes"
116
+ children: text("savedCodes")
116
117
  }),
117
118
  children: /* @__PURE__ */ jsx(BackupCodes, { codes: open.codes })
118
119
  })
@@ -1,3 +1,4 @@
1
+ import { text } from "./messages.js";
1
2
  import { cn } from "../lib/cn.js";
2
3
  import { Input } from "../primitives/input.js";
3
4
  import { authMessage } from "../auth/auth-messages.js";
@@ -9,14 +10,14 @@ import { useState } from "react";
9
10
  import { AuthError } from "@protobase/client";
10
11
  import { jsx, jsxs } from "react/jsx-runtime";
11
12
  //#region src/account/two-factor-setup.tsx
12
- const choices = [{
13
+ const choices = () => [{
13
14
  value: "app",
14
- label: "Authenticator app",
15
- description: "A code from an app such as Google Authenticator, Microsoft Authenticator or 1Password. Comes with backup codes."
15
+ label: text("authenticatorApp"),
16
+ description: text("authenticatorAppDescription")
16
17
  }, {
17
18
  value: "email",
18
- label: "Emailed code",
19
- description: "A code mailed to your address each time you sign in with a password or an emailed sign-in code."
19
+ label: text("emailedCode"),
20
+ description: text("emailedCodeDescription")
20
21
  }];
21
22
  /** Turns on two-factor authentication: choose the app or emailed codes, confirm the password, scan, and keep the backup codes. */
22
23
  const TwoFactorSetup = ({ offerEmailedCodes, needsPassword, onStartApp, onConfirmApp, onEmailedCodes, onDone, onCancel }) => {
@@ -26,7 +27,7 @@ const TwoFactorSetup = ({ offerEmailedCodes, needsPassword, onStartApp, onConfir
26
27
  const [code, setCode] = useState("");
27
28
  const [busy, setBusy] = useState(false);
28
29
  const [error, setError] = useState();
29
- const offered = offerEmailedCodes ? choices : choices.filter((option) => option.value === "app");
30
+ const offered = offerEmailedCodes ? choices() : choices().filter((option) => option.value === "app");
30
31
  const attempt = async (action) => {
31
32
  setBusy(true);
32
33
  setError(void 0);
@@ -58,7 +59,7 @@ const TwoFactorSetup = ({ offerEmailedCodes, needsPassword, onStartApp, onConfir
58
59
  });
59
60
  const errorLine = error && /* @__PURE__ */ jsx("p", {
60
61
  role: "alert",
61
- className: "text-xs font-medium text-danger-text",
62
+ className: "text-body font-medium text-danger-text",
62
63
  children: error
63
64
  });
64
65
  if (step.kind === "backup-codes") return /* @__PURE__ */ jsxs("div", {
@@ -66,14 +67,14 @@ const TwoFactorSetup = ({ offerEmailedCodes, needsPassword, onStartApp, onConfir
66
67
  children: [
67
68
  /* @__PURE__ */ jsx("p", {
68
69
  className: "text-muted-foreground",
69
- children: "Two-factor authentication is on. Keep these backup codes somewhere safe: each one signs you in once if you lose your phone. They are not shown again."
70
+ children: text("twoFactorIsOn")
70
71
  }),
71
72
  /* @__PURE__ */ jsx(BackupCodes, { codes: step.codes }),
72
73
  /* @__PURE__ */ jsx(Button, {
73
74
  variant: "primary",
74
75
  onClick: onDone,
75
76
  className: "min-h-10",
76
- children: "I saved my backup codes"
77
+ children: text("savedCodes")
77
78
  })
78
79
  ]
79
80
  });
@@ -86,7 +87,7 @@ const TwoFactorSetup = ({ offerEmailedCodes, needsPassword, onStartApp, onConfir
86
87
  children: [
87
88
  /* @__PURE__ */ jsx("p", {
88
89
  className: "text-muted-foreground",
89
- children: "Scan this code with your authenticator app, then enter the 6-digit code it shows."
90
+ children: text("scanCode")
90
91
  }),
91
92
  /* @__PURE__ */ jsxs("div", {
92
93
  className: "flex flex-col items-center gap-2",
@@ -95,7 +96,7 @@ const TwoFactorSetup = ({ offerEmailedCodes, needsPassword, onStartApp, onConfir
95
96
  className: "size-44 rounded-md border"
96
97
  }), /* @__PURE__ */ jsxs("p", {
97
98
  className: "text-center text-xs text-muted-foreground",
98
- children: ["Can't scan it? Enter this key in the app:", /* @__PURE__ */ jsx("span", {
99
+ children: [text("cannotScan"), /* @__PURE__ */ jsx("span", {
99
100
  className: "mt-1 block break-all font-mono text-body text-foreground",
100
101
  children: totpKey(step.setup.totpURI)
101
102
  })]
@@ -103,7 +104,7 @@ const TwoFactorSetup = ({ offerEmailedCodes, needsPassword, onStartApp, onConfir
103
104
  }),
104
105
  /* @__PURE__ */ jsxs("label", {
105
106
  className: "flex flex-col gap-1.5 font-medium",
106
- children: ["Code from the app", /* @__PURE__ */ jsx(OtpInput, {
107
+ children: [text("codeFromApp"), /* @__PURE__ */ jsx(OtpInput, {
107
108
  name: "code",
108
109
  required: true,
109
110
  autoFocus: true,
@@ -119,13 +120,13 @@ const TwoFactorSetup = ({ offerEmailedCodes, needsPassword, onStartApp, onConfir
119
120
  type: "submit",
120
121
  loading: busy,
121
122
  className: "min-h-10",
122
- children: "Turn on"
123
+ children: text("turnOn")
123
124
  }),
124
125
  onCancel && /* @__PURE__ */ jsx(Button, {
125
126
  variant: "ghost",
126
127
  onClick: onCancel,
127
128
  className: "min-h-10",
128
- children: "Cancel"
129
+ children: text("cancel")
129
130
  })
130
131
  ]
131
132
  });
@@ -138,7 +139,7 @@ const TwoFactorSetup = ({ offerEmailedCodes, needsPassword, onStartApp, onConfir
138
139
  children: [
139
140
  /* @__PURE__ */ jsx("div", {
140
141
  role: "radiogroup",
141
- "aria-label": "Second step",
142
+ "aria-label": text("secondStep"),
142
143
  className: "flex flex-col gap-2",
143
144
  children: offered.map((option) => /* @__PURE__ */ jsxs("button", {
144
145
  type: "button",
@@ -157,7 +158,7 @@ const TwoFactorSetup = ({ offerEmailedCodes, needsPassword, onStartApp, onConfir
157
158
  }),
158
159
  needsPassword && /* @__PURE__ */ jsxs("label", {
159
160
  className: "flex flex-col gap-1.5 font-medium",
160
- children: ["Your password", /* @__PURE__ */ jsx(Input, {
161
+ children: [text("yourPassword"), /* @__PURE__ */ jsx(Input, {
161
162
  type: "password",
162
163
  name: "password",
163
164
  autoComplete: "current-password",
@@ -174,13 +175,13 @@ const TwoFactorSetup = ({ offerEmailedCodes, needsPassword, onStartApp, onConfir
174
175
  type: "submit",
175
176
  loading: busy,
176
177
  className: "min-h-10",
177
- children: "Continue"
178
+ children: text("continue")
178
179
  }),
179
180
  onCancel && /* @__PURE__ */ jsx(Button, {
180
181
  variant: "ghost",
181
182
  onClick: onCancel,
182
183
  className: "min-h-10",
183
- children: "Cancel"
184
+ children: text("cancel")
184
185
  })
185
186
  ]
186
187
  });
@@ -1,6 +1,7 @@
1
1
  import { cn } from "../lib/cn.js";
2
2
  import { Button } from "../primitives/button.js";
3
3
  import { Dialog } from "../primitives/dialog.js";
4
+ import { text } from "./messages.js";
4
5
  import { useState } from "react";
5
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
7
  //#region src/action-card/action-card.tsx
@@ -76,7 +77,7 @@ const ActionCard = ({ title, tone = "neutral", badge, note, actions = [], onActi
76
77
  onClose: () => setConfirming(void 0),
77
78
  actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button, {
78
79
  onClick: () => setConfirming(void 0),
79
- children: "Cancel"
80
+ children: text("cancel")
80
81
  }), /* @__PURE__ */ jsx(Button, {
81
82
  variant: confirming.style === "danger" ? "danger" : "primary",
82
83
  onClick: () => {
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  //#region src/action-card/field-list.tsx
3
3
  /** Labelled values, one per row, inside a card. */
4
4
  const FieldList = ({ fields }) => /* @__PURE__ */ jsx("dl", {
5
- className: "grid grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-1 text-xs",
5
+ className: "grid grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-1 text-body",
6
6
  children: fields.map((field, index) => /* @__PURE__ */ jsxs("div", {
7
7
  className: "contents",
8
8
  children: [/* @__PURE__ */ jsx("dt", {
@@ -0,0 +1,8 @@
1
+ import { defineMessages } from "../locale/messages.js";
2
+ //#region src/action-card/messages.ts
3
+ const text = defineMessages({
4
+ en: { cancel: "Cancel" },
5
+ nl: { cancel: "Annuleren" }
6
+ });
7
+ //#endregion
8
+ export { text };
@@ -6,6 +6,7 @@ import { formatDayShort } from "../format/date.js";
6
6
  import { activitySeries } from "../mocks/activity.js";
7
7
  import { halfOverHalfDelta, totalCount } from "./activity-math.js";
8
8
  import { ActivityTooltip } from "./activity-tooltip.js";
9
+ import { text } from "./messages.js";
9
10
  import { useState } from "react";
10
11
  import { jsx, jsxs } from "react/jsx-runtime";
11
12
  import { Bar, BarChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
@@ -54,10 +55,10 @@ const ActivityChart = ({ title = "Orders created", noun = "orders", defaultGranu
54
55
  onChange: setGranularity,
55
56
  options: [{
56
57
  value: "day",
57
- label: "Day"
58
+ label: text("day")
58
59
  }, {
59
60
  value: "week",
60
- label: "Week"
61
+ label: text("week")
61
62
  }]
62
63
  })]
63
64
  }), /* @__PURE__ */ jsx("div", {
@@ -0,0 +1,14 @@
1
+ import { defineMessages } from "../locale/messages.js";
2
+ //#region src/activity-chart/messages.ts
3
+ const text = defineMessages({
4
+ en: {
5
+ day: "Day",
6
+ week: "Week"
7
+ },
8
+ nl: {
9
+ day: "Dag",
10
+ week: "Week"
11
+ }
12
+ });
13
+ //#endregion
14
+ export { text };
package/dist/app/app.d.ts CHANGED
@@ -2,8 +2,8 @@ import { SidebarMode } from "../app-shell/sidebar-mode.js";
2
2
  import "../app-shell/index.js";
3
3
  import { ProjectUi } from "./pages/project-ui.js";
4
4
  import { PluginLoader } from "../plugins/load-plugin.js";
5
- import { AssistantClient, AuthSession, Client, RuntimeClient } from "@protobase/client";
6
5
  import { Locale } from "@protobase/schema/internal";
6
+ import { AssistantClient, AuthSession, Client, RuntimeClient } from "@protobase/client";
7
7
  //#region src/app/app.d.ts
8
8
  export type AppProps = {
9
9
  /** Where `/api/v1` lives. Defaults to the current origin. */