@protobase/ui 0.25.1 → 0.25.3
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.
- package/dist/account/account-pages.js +3 -2
- package/dist/account/account-security-page.js +9 -4
- package/dist/account/backup-codes.js +7 -6
- package/dist/account/messages.js +214 -0
- package/dist/account/passkeys-section.js +23 -22
- package/dist/account/password-dialog.js +3 -2
- package/dist/account/sign-in-policy-form.js +11 -10
- package/dist/account/sign-in-policy-labels.js +30 -29
- package/dist/account/sign-in-policy-page.js +11 -6
- package/dist/account/sign-in-providers-section.js +6 -5
- package/dist/account/staff-sign-in-log.js +11 -10
- package/dist/account/totp-qr.js +2 -1
- package/dist/account/two-factor-section.js +24 -23
- package/dist/account/two-factor-setup.js +18 -17
- package/dist/action-card/action-card.js +2 -1
- package/dist/action-card/messages.js +8 -0
- package/dist/activity-chart/activity-chart.js +3 -2
- package/dist/activity-chart/messages.js +14 -0
- package/dist/app/app.d.ts +1 -1
- package/dist/app/app.js +20 -21
- package/dist/app/assistant-shell.js +2 -1
- package/dist/app/batch-failure.js +2 -1
- package/dist/app/breadcrumb-for.js +4 -3
- package/dist/app/charts/chart-groups.js +3 -2
- package/dist/app/charts/chart-view.js +3 -2
- package/dist/app/charts/group-bars.js +2 -1
- package/dist/app/charts/messages.js +26 -0
- package/dist/app/charts/period-chart.js +3 -2
- package/dist/app/charts/split-points.js +2 -1
- package/dist/app/comments/comment-composer.js +19 -18
- package/dist/app/comments/comments-section.js +4 -3
- package/dist/app/comments/messages.js +26 -0
- package/dist/app/create/create-page.js +11 -18
- package/dist/app/custom-section.js +4 -6
- package/dist/app/displays/board-column.js +6 -5
- package/dist/app/displays/board-columns.js +3 -2
- package/dist/app/displays/board-display.js +13 -15
- package/dist/app/displays/calendar-controls.js +3 -2
- package/dist/app/displays/calendar-display.js +12 -17
- package/dist/app/displays/card-carousel.js +4 -3
- package/dist/app/displays/cards-display.js +2 -1
- package/dist/app/displays/custom-display.js +4 -6
- package/dist/app/displays/display-frame.js +3 -2
- package/dist/app/displays/list-cards.js +5 -8
- package/dist/app/displays/list-displays.js +3 -3
- package/dist/app/displays/map-display.js +15 -14
- package/dist/app/displays/messages.js +128 -2
- package/dist/app/displays/period-controls.js +4 -3
- package/dist/app/displays/record-card.js +7 -6
- package/dist/app/displays/timeline-display.js +17 -26
- package/dist/app/displays/timeline-range.js +2 -1
- package/dist/app/displays/use-board-move.js +2 -2
- package/dist/app/displays/use-calendar-move.js +2 -1
- package/dist/app/document-title.js +2 -1
- package/dist/app/export/builder-port.js +2 -1
- package/dist/app/export/export-dialog.js +36 -40
- package/dist/app/export/export-worker.js +2 -0
- package/dist/app/export/messages.js +78 -0
- package/dist/app/export/run-export.js +5 -2
- package/dist/app/export/sink.js +4 -3
- package/dist/app/export/use-export-flow.js +4 -3
- package/dist/app/field-editor.js +4 -3
- package/dist/app/field-types/messages.js +8 -0
- package/dist/app/field-types/widget-part.js +2 -1
- package/dist/app/file-field.js +11 -14
- package/dist/app/gallery/gallery-section.js +4 -3
- package/dist/app/gallery/lightbox.js +5 -4
- package/dist/app/gallery/messages.js +30 -0
- package/dist/app/gallery/photo-details.js +3 -2
- package/dist/app/hand-order/hand-sorted-list.js +3 -6
- package/dist/app/hand-order/messages.js +4 -2
- package/dist/app/history/describe-change.js +3 -8
- package/dist/app/history/messages.js +32 -0
- package/dist/app/import/convert.js +20 -19
- package/dist/app/import/failed-rows.js +3 -2
- package/dist/app/import/import-button.js +2 -1
- package/dist/app/import/import-check-step.js +19 -35
- package/dist/app/import/import-dialog.js +13 -17
- package/dist/app/import/import-file-step.js +5 -9
- package/dist/app/import/import-mapping-step.js +32 -35
- package/dist/app/import/import-result-step.js +13 -12
- package/dist/app/import/messages.js +200 -0
- package/dist/app/import/parse-worker.js +2 -0
- package/dist/app/import/prepare-rows.js +5 -4
- package/dist/app/import/sheet-cell.js +2 -1
- package/dist/app/import/sheet-file.js +3 -2
- package/dist/app/import/sheet-source.js +7 -3
- package/dist/app/import/xlsx-reader.js +4 -3
- package/dist/app/import/xlsx-xml.js +2 -1
- package/dist/app/import/zip-reader.js +4 -3
- package/dist/app/list-edit/use-list-edits.js +1 -1
- package/dist/app/list-group-chart.js +2 -1
- package/dist/app/list-page.js +1 -1
- package/dist/app/map/map-layer-switch.js +3 -2
- package/dist/app/map/messages.js +14 -0
- package/dist/app/messages.js +116 -2
- package/dist/app/meta-gate.js +1 -1
- package/dist/app/nav-from-meta.js +11 -10
- package/dist/app/pages/action-inputs/action-inputs-dialog.js +3 -2
- package/dist/app/pages/action-inputs/input-answers.js +6 -5
- package/dist/app/pages/blocks/card-row.js +3 -2
- package/dist/app/pages/blocks/modal-form.js +5 -4
- package/dist/app/pages/blocks/record-card.js +3 -2
- package/dist/app/pages/blocks/stat.js +2 -1
- package/dist/app/pages/composed-page.js +6 -8
- package/dist/app/pages/confirm-action.js +2 -1
- package/dist/app/pages/custom-boundary.js +4 -2
- package/dist/app/pages/messages.js +64 -0
- package/dist/app/pages/render-node.js +5 -7
- package/dist/app/pages/use-run-action.js +11 -10
- package/dist/app/record-page.js +1 -1
- package/dist/app/record-row/messages.js +26 -0
- package/dist/app/record-row/record-row-body.js +12 -7
- package/dist/app/record-row/record-row.js +4 -3
- package/dist/app/record-row/saved-record-row.js +3 -2
- package/dist/app/related-dots/dots-summary.js +2 -1
- package/dist/app/related-dots/messages.js +8 -0
- package/dist/app/relation-picker.js +9 -8
- package/dist/app/router.js +5 -4
- package/dist/app/runtime/messages.js +58 -0
- package/dist/app/runtime/runtime-status.js +10 -23
- package/dist/app/runtime/runtime-update-dialog.js +7 -6
- package/dist/app/runtime/runtime-update.js +4 -3
- package/dist/app/saved/favorite-button.js +2 -1
- package/dist/app/saved/messages.js +22 -0
- package/dist/app/saved/saved-list.js +4 -7
- package/dist/app/saved/use-favorite.js +3 -2
- package/dist/app/search/messages.js +6 -2
- package/dist/app/search/navigation-hits.js +9 -7
- package/dist/app/searches/filter-chip-list.js +2 -1
- package/dist/app/searches/messages.js +96 -0
- package/dist/app/searches/save-search-button.js +5 -4
- package/dist/app/searches/saved-search-rows.js +3 -2
- package/dist/app/searches/saved-search-section.js +6 -5
- package/dist/app/searches/saved-search.js +4 -3
- package/dist/app/searches/saved-searches.js +15 -25
- package/dist/app/searches/search-controls.js +5 -4
- package/dist/app/searches/search-diff.js +4 -2
- package/dist/app/searches/search-name-dialog.js +4 -3
- package/dist/app/searches/update-search-dialog.js +15 -30
- package/dist/app/searches/use-save-search.js +8 -7
- package/dist/app/searches/use-search-row.js +4 -3
- package/dist/app/sensitive-field.js +5 -4
- package/dist/app/source-notice.js +13 -8
- package/dist/app/staff-banner.js +12 -19
- package/dist/app-shell/global-search.js +2 -2
- package/dist/app-shell/messages.js +4 -2
- package/dist/assistant-dock/assistant-dock.js +5 -5
- package/dist/assistant-dock/messages.js +26 -0
- package/dist/assistant-dock/use-assistant.js +2 -1
- package/dist/assistant-dock/use-backend-data.js +2 -1
- package/dist/assistant-dock/widget-view.js +3 -2
- package/dist/auth/auth-gate.js +10 -5
- package/dist/auth/auth-locale.js +14 -0
- package/dist/auth/auth-messages.js +122 -43
- package/dist/auth/auth-provider.js +6 -1
- package/dist/auth/code-form.js +2 -1
- package/dist/auth/email-code-form.js +11 -13
- package/dist/auth/email-code-page.js +2 -1
- package/dist/auth/first-run-page.js +6 -5
- package/dist/auth/forgot-password-form.js +14 -16
- package/dist/auth/forgot-password-page.js +2 -1
- package/dist/auth/messages.js +200 -0
- package/dist/auth/provider-sign-in-page.js +5 -5
- package/dist/auth/resend-code-button.js +2 -1
- package/dist/auth/reset-password-form.js +11 -10
- package/dist/auth/reset-password-page.js +4 -3
- package/dist/auth/setup-required-form.js +7 -9
- package/dist/auth/setup-required-page.js +7 -2
- package/dist/auth/sign-in-form.js +15 -18
- package/dist/auth/sign-in-prompt.js +4 -3
- package/dist/auth/sign-up-code-form.js +11 -13
- package/dist/auth/sign-up-details-form.js +14 -21
- package/dist/auth/sign-up-email-form.js +8 -7
- package/dist/auth/sign-up-page.js +2 -1
- package/dist/auth/staff-sign-in-form.js +14 -17
- package/dist/auth/two-factor-form.js +17 -16
- package/dist/auth/user-to-shell.js +2 -1
- package/dist/chat/composer.js +8 -7
- package/dist/chat/messages.js +14 -0
- package/dist/compact-table/compact-table.js +4 -8
- package/dist/compact-table/messages.js +18 -0
- package/dist/data/meta-data.d.ts +1 -1
- package/dist/data/use-update-record.js +1 -1
- package/dist/inline-child-table/inline-child-table.js +12 -12
- package/dist/inline-child-table/line-row.js +10 -9
- package/dist/inline-child-table/messages.js +52 -0
- package/dist/inline-child-table/totals-footer.js +5 -8
- package/dist/invitations/invite-form.js +3 -2
- package/dist/invitations/link-notice.js +6 -4
- package/dist/invitations/messages.js +24 -0
- package/dist/invitations/pending-invitation-row.js +4 -3
- package/dist/lists/messages.js +8 -0
- package/dist/lists/paged-search-list.js +2 -1
- package/dist/locale/slotted.js +14 -0
- package/dist/markdown/markdown-editor.js +6 -5
- package/dist/markdown/messages.js +16 -0
- package/dist/organizations/all-organizations.js +6 -5
- package/dist/organizations/app-roles-picker.js +2 -1
- package/dist/organizations/invitation-page.js +39 -49
- package/dist/organizations/invitations-page.js +11 -10
- package/dist/organizations/members-page.js +15 -10
- package/dist/organizations/messages.js +180 -0
- package/dist/organizations/organization-page.js +27 -26
- package/dist/organizations/organization-paths.js +16 -13
- package/dist/organizations/organization-row.js +3 -2
- package/dist/organizations/organizations-page.js +17 -16
- package/dist/organizations/use-organizations.js +2 -1
- package/dist/package.js +1 -1
- package/dist/plugins/before-sign-in.js +6 -1
- package/dist/plugins/load-plugin.d.ts +1 -1
- package/dist/plugins/load-plugin.js +3 -2
- package/dist/plugins/messages.js +36 -0
- package/dist/plugins/plugin-gate.js +6 -1
- package/dist/plugins/plugin-manifest.js +8 -7
- package/dist/plugins/plugin-notice.js +8 -12
- package/dist/primitives/messages.js +16 -0
- package/dist/primitives/sheet.js +2 -1
- package/dist/primitives/spinner.js +2 -1
- package/dist/primitives/token.js +2 -1
- package/dist/record-view/messages.js +4 -2
- package/dist/record-view/record-tabs.js +2 -1
- package/dist/roles/messages.js +14 -0
- package/dist/roles/use-active-role.js +3 -2
- package/dist/shell/assets/app-CW3U56yM.js +69 -0
- package/dist/shell/assets/cn-Bi0ZEjD9.js +1 -0
- package/dist/shell/assets/export-worker-ClACk00b.js +2 -0
- package/dist/shell/assets/{index-BuKnJ48y.js → index-B7cIjCuz.js} +2 -2
- package/dist/shell/assets/maplibre-CVG5L9FD.js +814 -0
- package/dist/shell/assets/{markdown-content-CvNiaqsy.js → markdown-content-CtGUP4W6.js} +1 -1
- package/dist/shell/assets/parse-worker-UhbwEjS0.js +5 -0
- package/dist/shell/assets/preload-helper-BX9CcZkY.js +1 -0
- package/dist/shell/assets/{record-map-BmPHHEMK.js → record-map-Cw3_NcUl.js} +1 -1
- package/dist/shell/assets/records-map-D4f3ZeDL.js +1 -0
- package/dist/shell/assets/shared-protobase-ui-CB_i50NP.js +1 -0
- package/dist/shell/index.html +5 -3
- package/dist/shell/protobase.shell.json +1 -1
- package/dist/shell/protobase.sw.js +2 -2
- package/dist/side-panel/messages.js +8 -0
- package/dist/side-panel/side-panel.js +2 -1
- package/dist/toasts/messages.js +8 -0
- package/dist/toasts/toast.js +2 -1
- package/dist/users/app-invitations.js +5 -4
- package/dist/users/create-user-form.js +9 -8
- package/dist/users/messages.js +52 -0
- package/dist/users/use-user-roles.js +2 -1
- package/dist/users/user-list.js +6 -5
- package/dist/users/user-row.js +5 -4
- package/package.json +4 -4
- package/dist/shell/assets/app-BPHSSo4E.js +0 -69
- package/dist/shell/assets/export-worker-Bz57Pf5g.js +0 -2
- package/dist/shell/assets/maplibre-C2VkKdp3.js +0 -814
- package/dist/shell/assets/parse-worker-BtcY0dQw.js +0 -5
- package/dist/shell/assets/records-map-BvUD1Fqc.js +0 -1
- package/dist/shell/assets/shared-protobase-ui-B-pEBDQf.js +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { cn } from "../lib/cn.js";
|
|
2
2
|
import { Input } from "../primitives/input.js";
|
|
3
3
|
import { Button } from "../primitives/button.js";
|
|
4
|
+
import { text } from "./messages.js";
|
|
4
5
|
import { humanize } from "../live/naming.js";
|
|
5
6
|
import { displayValue } from "../live/display-value.js";
|
|
6
7
|
import { toDraft } from "../live/field-values.js";
|
|
@@ -28,7 +29,7 @@ const SensitiveField = ({ field, hints, value, reveal, locked, invalid, placehol
|
|
|
28
29
|
variant: "ghost",
|
|
29
30
|
size: "sm",
|
|
30
31
|
className: "-mr-1.5 px-1.5",
|
|
31
|
-
"aria-label":
|
|
32
|
+
"aria-label": shown ? text("hide", label) : text("show", label),
|
|
32
33
|
"aria-pressed": shown,
|
|
33
34
|
loading: stored.isPending,
|
|
34
35
|
onClick: toggle,
|
|
@@ -37,7 +38,7 @@ const SensitiveField = ({ field, hints, value, reveal, locked, invalid, placehol
|
|
|
37
38
|
const error = stored.error && /* @__PURE__ */ jsx("div", {
|
|
38
39
|
className: "mt-2",
|
|
39
40
|
children: /* @__PURE__ */ jsx(ErrorBanner, {
|
|
40
|
-
title:
|
|
41
|
+
title: text("couldNotShow", label),
|
|
41
42
|
error: stored.error
|
|
42
43
|
})
|
|
43
44
|
});
|
|
@@ -48,7 +49,7 @@ const SensitiveField = ({ field, hints, value, reveal, locked, invalid, placehol
|
|
|
48
49
|
children: shown ? displayValue(field, stored.data, hints) : mask
|
|
49
50
|
}), reveal && eye]
|
|
50
51
|
}), error] });
|
|
51
|
-
const text = typed ? toDraft(value) : shown && stored.isSuccess ? toDraft(stored.data) : "";
|
|
52
|
+
const text$1 = typed ? toDraft(value) : shown && stored.isSuccess ? toDraft(stored.data) : "";
|
|
52
53
|
return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Input, {
|
|
53
54
|
type: shown ? "text" : "password",
|
|
54
55
|
autoComplete: "off",
|
|
@@ -56,7 +57,7 @@ const SensitiveField = ({ field, hints, value, reveal, locked, invalid, placehol
|
|
|
56
57
|
"aria-label": label,
|
|
57
58
|
className: cn(hints?.format === "code" && "font-mono text-xs"),
|
|
58
59
|
placeholder: typed || !reveal ? placeholder : mask,
|
|
59
|
-
value: text,
|
|
60
|
+
value: text$1,
|
|
60
61
|
trailing: eye,
|
|
61
62
|
onChange: (event) => onChange(event.target.value)
|
|
62
63
|
}), error] });
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { Spinner } from "../primitives/spinner.js";
|
|
2
2
|
import { Button } from "../primitives/button.js";
|
|
3
3
|
import { keys } from "../data/query-keys.js";
|
|
4
|
+
import { text } from "./messages.js";
|
|
4
5
|
import { isApiError } from "@protobase/client";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
import { useQueryClient } from "@tanstack/react-query";
|
|
7
8
|
//#region src/app/source-notice.tsx
|
|
8
9
|
const reason = (error) => {
|
|
9
|
-
if (!isApiError(error)) return "
|
|
10
|
-
if (error.status === 401 || error.status === 403) return
|
|
10
|
+
if (!isApiError(error)) return text("noAnswer");
|
|
11
|
+
if (error.status === 401 || error.status === 403) return text("signInRefused", error.message);
|
|
11
12
|
return error.message;
|
|
12
13
|
};
|
|
13
14
|
/** Where a resource drawn from another API would be while that API's `/meta` loads, or when it cannot be read. */
|
|
@@ -17,8 +18,8 @@ const SourceNotice = ({ status }) => {
|
|
|
17
18
|
className: "flex h-full min-h-48 flex-1 items-center justify-center gap-2 text-muted-foreground",
|
|
18
19
|
children: [
|
|
19
20
|
/* @__PURE__ */ jsx(Spinner, {}),
|
|
20
|
-
"
|
|
21
|
-
status.source.label
|
|
21
|
+
" ",
|
|
22
|
+
text("loadingFrom", status.source.label)
|
|
22
23
|
]
|
|
23
24
|
});
|
|
24
25
|
return /* @__PURE__ */ jsx("div", {
|
|
@@ -26,18 +27,22 @@ const SourceNotice = ({ status }) => {
|
|
|
26
27
|
children: /* @__PURE__ */ jsxs("div", {
|
|
27
28
|
className: "max-w-md text-center",
|
|
28
29
|
children: [
|
|
29
|
-
/* @__PURE__ */
|
|
30
|
+
/* @__PURE__ */ jsx("h1", {
|
|
30
31
|
className: "text-[16px] font-semibold",
|
|
31
|
-
children:
|
|
32
|
+
children: text("cannotReach", status.source.label)
|
|
32
33
|
}),
|
|
33
34
|
/* @__PURE__ */ jsxs("p", {
|
|
34
35
|
className: "mt-1 text-muted-foreground",
|
|
35
|
-
children: [
|
|
36
|
+
children: [
|
|
37
|
+
reason(status.error),
|
|
38
|
+
" ",
|
|
39
|
+
text("restWorks")
|
|
40
|
+
]
|
|
36
41
|
}),
|
|
37
42
|
/* @__PURE__ */ jsx(Button, {
|
|
38
43
|
className: "mt-3",
|
|
39
44
|
onClick: () => void queryClient.refetchQueries({ queryKey: keys.sourceMetas(status.source.url) }),
|
|
40
|
-
children: "
|
|
45
|
+
children: text("tryAgain")
|
|
41
46
|
})
|
|
42
47
|
]
|
|
43
48
|
})
|
package/dist/app/staff-banner.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { authMessage } from "../auth/auth-messages.js";
|
|
2
2
|
import { formatDateTime } from "../format/date.js";
|
|
3
3
|
import { Button } from "../primitives/button.js";
|
|
4
|
+
import { text } from "./messages.js";
|
|
5
|
+
import { slotted } from "../locale/slotted.js";
|
|
4
6
|
import { useState } from "react";
|
|
5
7
|
import { UserRoundCog } from "lucide-react";
|
|
6
8
|
import { AuthError } from "@protobase/client";
|
|
@@ -23,31 +25,22 @@ const StaffBanner = ({ signIn, onStop }) => {
|
|
|
23
25
|
};
|
|
24
26
|
return /* @__PURE__ */ jsxs("div", {
|
|
25
27
|
role: "region",
|
|
26
|
-
"aria-label": "
|
|
28
|
+
"aria-label": text("staffSession"),
|
|
27
29
|
className: "flex flex-wrap items-center gap-x-3 gap-y-2 border-b border-warning/40 bg-warning-soft px-4 py-2 text-warning-text",
|
|
28
30
|
children: [
|
|
29
31
|
/* @__PURE__ */ jsx(UserRoundCog, {
|
|
30
32
|
"aria-hidden": true,
|
|
31
33
|
className: "size-4 shrink-0"
|
|
32
34
|
}),
|
|
33
|
-
/* @__PURE__ */
|
|
35
|
+
/* @__PURE__ */ jsx("p", {
|
|
34
36
|
className: "min-w-64 flex-1 break-words",
|
|
35
|
-
children:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
className: "font-semibold",
|
|
43
|
-
children: signIn.user
|
|
44
|
-
}),
|
|
45
|
-
" until",
|
|
46
|
-
" ",
|
|
47
|
-
formatDateTime(Date.parse(signIn.expiresAt)),
|
|
48
|
-
". Reason: ",
|
|
49
|
-
signIn.reason
|
|
50
|
-
]
|
|
37
|
+
children: slotted(text("staffSignedIn"), /* @__PURE__ */ jsx("span", {
|
|
38
|
+
className: "font-semibold",
|
|
39
|
+
children: signIn.staffName ?? signIn.staff
|
|
40
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
41
|
+
className: "font-semibold",
|
|
42
|
+
children: signIn.user
|
|
43
|
+
}), formatDateTime(Date.parse(signIn.expiresAt)), signIn.reason)
|
|
51
44
|
}),
|
|
52
45
|
error && /* @__PURE__ */ jsx("p", {
|
|
53
46
|
role: "alert",
|
|
@@ -58,7 +51,7 @@ const StaffBanner = ({ signIn, onStop }) => {
|
|
|
58
51
|
size: "sm",
|
|
59
52
|
loading: stopping,
|
|
60
53
|
onClick: () => void stop(),
|
|
61
|
-
children: "
|
|
54
|
+
children: text("stopStaffSession")
|
|
62
55
|
})
|
|
63
56
|
]
|
|
64
57
|
});
|
|
@@ -107,9 +107,9 @@ const GlobalSearch = ({ search, className = "w-96", autoFocus, showShortcut = tr
|
|
|
107
107
|
className: "px-3 pb-1 pt-2 text-[11px] font-medium uppercase tracking-wide text-faint-foreground",
|
|
108
108
|
children: group.label
|
|
109
109
|
}),
|
|
110
|
-
group.failed && /* @__PURE__ */
|
|
110
|
+
group.failed && /* @__PURE__ */ jsx("p", {
|
|
111
111
|
className: "px-3 py-1.5 text-danger-text",
|
|
112
|
-
children:
|
|
112
|
+
children: text("couldNotSearch", group.label)
|
|
113
113
|
}),
|
|
114
114
|
group.hits.map((hit) => {
|
|
115
115
|
position += 1;
|
|
@@ -28,7 +28,8 @@ const text = defineMessages({
|
|
|
28
28
|
recent: (plural) => `Recent ${plural}`,
|
|
29
29
|
loading: "Loading...",
|
|
30
30
|
couldNotLoad: "Could not load",
|
|
31
|
-
viewAll: "View all"
|
|
31
|
+
viewAll: "View all",
|
|
32
|
+
couldNotSearch: (label) => `Could not search ${label.toLowerCase()}`
|
|
32
33
|
},
|
|
33
34
|
nl: {
|
|
34
35
|
navigation: "Navigatie",
|
|
@@ -57,7 +58,8 @@ const text = defineMessages({
|
|
|
57
58
|
recent: (plural) => `Recente ${plural}`,
|
|
58
59
|
loading: "Laden...",
|
|
59
60
|
couldNotLoad: "Kon niet laden",
|
|
60
|
-
viewAll: "Alles bekijken"
|
|
61
|
+
viewAll: "Alles bekijken",
|
|
62
|
+
couldNotSearch: (label) => `Kon niet zoeken in ${label.toLowerCase()}`
|
|
61
63
|
}
|
|
62
64
|
});
|
|
63
65
|
//#endregion
|
|
@@ -2,13 +2,13 @@ import { ChatMessage } from "../chat/chat-message.js";
|
|
|
2
2
|
import { ChatThread } from "../chat/chat-thread.js";
|
|
3
3
|
import { Composer } from "../chat/composer.js";
|
|
4
4
|
import { SidePanel } from "../side-panel/side-panel.js";
|
|
5
|
+
import { text } from "./messages.js";
|
|
5
6
|
import { PartView } from "./part-view.js";
|
|
6
7
|
import { AssistantBackendContext } from "./use-backend-data.js";
|
|
7
8
|
import { useEffect, useRef } from "react";
|
|
8
9
|
import { Sparkles } from "lucide-react";
|
|
9
10
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
11
|
//#region src/assistant-dock/assistant-dock.tsx
|
|
11
|
-
const defaultPlaceholder = "Ask a question...";
|
|
12
12
|
/**
|
|
13
13
|
* The assistant beside the app: renders a backend's chat, its cards, the app's widgets and status line, and sends
|
|
14
14
|
* messages and clicks back.
|
|
@@ -19,9 +19,9 @@ const AssistantDock = ({ state, offline, error, onSend, onAction, onClose, clien
|
|
|
19
19
|
if (state.placeholder) input.current?.focus();
|
|
20
20
|
}, [state.placeholder]);
|
|
21
21
|
return /* @__PURE__ */ jsx(SidePanel, {
|
|
22
|
-
title: "
|
|
22
|
+
title: text("assistant"),
|
|
23
23
|
icon: /* @__PURE__ */ jsx(Sparkles, { className: "size-4 text-primary" }),
|
|
24
|
-
status: offline ? "
|
|
24
|
+
status: offline ? text("reconnecting") : state.status,
|
|
25
25
|
onClose,
|
|
26
26
|
footer: /* @__PURE__ */ jsxs(Fragment$1, { children: [error && /* @__PURE__ */ jsx("p", {
|
|
27
27
|
role: "alert",
|
|
@@ -31,13 +31,13 @@ const AssistantDock = ({ state, offline, error, onSend, onAction, onClose, clien
|
|
|
31
31
|
inputRef: input,
|
|
32
32
|
onSend,
|
|
33
33
|
busy: state.replying,
|
|
34
|
-
placeholder: state.placeholder ??
|
|
34
|
+
placeholder: state.placeholder ?? text("askQuestion")
|
|
35
35
|
})] }),
|
|
36
36
|
children: /* @__PURE__ */ jsx(AssistantBackendContext.Provider, {
|
|
37
37
|
value: client,
|
|
38
38
|
children: /* @__PURE__ */ jsx(ChatThread, {
|
|
39
39
|
length: state.messages.reduce((sum, message) => sum + message.parts.length, 0),
|
|
40
|
-
empty: "
|
|
40
|
+
empty: text("empty"),
|
|
41
41
|
children: state.messages.map((message) => /* @__PURE__ */ jsx(ChatMessage, {
|
|
42
42
|
from: message.from,
|
|
43
43
|
children: message.parts.map((part) => /* @__PURE__ */ jsx(PartView, {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { defineMessages } from "../locale/messages.js";
|
|
2
|
+
//#region src/assistant-dock/messages.ts
|
|
3
|
+
const text = defineMessages({
|
|
4
|
+
en: {
|
|
5
|
+
askQuestion: "Ask a question...",
|
|
6
|
+
assistant: "Assistant",
|
|
7
|
+
reconnecting: "Reconnecting...",
|
|
8
|
+
empty: "Ask a question about this app or its data.",
|
|
9
|
+
noAnswer: "The assistant did not answer",
|
|
10
|
+
backendNoAnswer: "The assistant backend did not answer",
|
|
11
|
+
couldNotDraw: "It could not be drawn.",
|
|
12
|
+
cannotShowLive: "This version of the app cannot show it live."
|
|
13
|
+
},
|
|
14
|
+
nl: {
|
|
15
|
+
askQuestion: "Stel een vraag...",
|
|
16
|
+
assistant: "Assistent",
|
|
17
|
+
reconnecting: "Opnieuw verbinden...",
|
|
18
|
+
empty: "Stel een vraag over deze app of de gegevens ervan.",
|
|
19
|
+
noAnswer: "De assistent antwoordde niet",
|
|
20
|
+
backendNoAnswer: "De backend van de assistent antwoordde niet",
|
|
21
|
+
couldNotDraw: "Dit kon niet worden getekend.",
|
|
22
|
+
cannotShowLive: "Deze versie van de app kan dit niet live tonen."
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
//#endregion
|
|
26
|
+
export { text };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { text } from "./messages.js";
|
|
1
2
|
import { useEffect, useState } from "react";
|
|
2
3
|
import { applyAssistantEvent, emptyAssistantState } from "@protobase/schema/internal";
|
|
3
4
|
//#region src/assistant-dock/use-assistant.ts
|
|
4
|
-
const messageOf = (error) => error instanceof Error ? error.message : "
|
|
5
|
+
const messageOf = (error) => error instanceof Error ? error.message : text("noAnswer");
|
|
5
6
|
/** Follows an assistant backend's event stream into state, with its two requests; `undefined` client means not yet. */
|
|
6
7
|
const useAssistant = (client) => {
|
|
7
8
|
const [state, setState] = useState(emptyAssistantState);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { text } from "./messages.js";
|
|
1
2
|
import { createContext, useContext, useEffect, useRef, useState } from "react";
|
|
2
3
|
//#region src/assistant-dock/use-backend-data.ts
|
|
3
4
|
/** The assistant backend the dock talks to, for the widgets it draws; `AssistantDock` provides it from its `client`. */
|
|
4
5
|
const AssistantBackendContext = createContext(void 0);
|
|
5
|
-
const asError = (reason) => reason instanceof Error ? reason :
|
|
6
|
+
const asError = (reason) => reason instanceof Error ? reason : new Error(text("backendNoAnswer"));
|
|
6
7
|
const refreshOf = (refresh, data) => typeof refresh === "function" ? refresh(data) : refresh;
|
|
7
8
|
/**
|
|
8
9
|
* JSON from the assistant backend at `path` (see `AssistantClient.fetch`), read as the signed-in user each time the
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { reportRenderError } from "../app/error-reporting.js";
|
|
2
2
|
import { useProjectUi } from "../app/pages/project-ui.js";
|
|
3
3
|
import { ActionCard } from "../action-card/action-card.js";
|
|
4
|
+
import { text } from "./messages.js";
|
|
4
5
|
import { Component } from "react";
|
|
5
6
|
import { jsx } from "react/jsx-runtime";
|
|
6
7
|
//#region src/assistant-dock/widget-view.tsx
|
|
@@ -24,7 +25,7 @@ var WidgetBoundary = class extends Component {
|
|
|
24
25
|
render() {
|
|
25
26
|
return this.state.failed ? /* @__PURE__ */ jsx(Fallback, {
|
|
26
27
|
part: this.props.part,
|
|
27
|
-
note: "
|
|
28
|
+
note: text("couldNotDraw")
|
|
28
29
|
}) : this.props.children;
|
|
29
30
|
}
|
|
30
31
|
};
|
|
@@ -34,7 +35,7 @@ const WidgetView = ({ part }) => {
|
|
|
34
35
|
const Widget = Object.hasOwn(components, part.name) ? components[part.name] : void 0;
|
|
35
36
|
if (!Widget) return /* @__PURE__ */ jsx(Fallback, {
|
|
36
37
|
part,
|
|
37
|
-
note: "
|
|
38
|
+
note: text("cannotShowLive")
|
|
38
39
|
});
|
|
39
40
|
return /* @__PURE__ */ jsx(WidgetBoundary, {
|
|
40
41
|
part,
|
package/dist/auth/auth-gate.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Spinner } from "../primitives/spinner.js";
|
|
2
2
|
import { providerMessage } from "./auth-messages.js";
|
|
3
3
|
import { readProviderError, readSignInLink, withoutSignInLink } from "./provider-link.js";
|
|
4
|
+
import { text } from "./messages.js";
|
|
4
5
|
import { useAuth } from "./auth-provider.js";
|
|
5
6
|
import { Button } from "../primitives/button.js";
|
|
6
7
|
import { useRouter } from "../app/router.js";
|
|
@@ -121,7 +122,7 @@ const useAuthPage = (workspace, children) => {
|
|
|
121
122
|
if (state.kind === "signed-in") await signOut();
|
|
122
123
|
leaveResetPage({
|
|
123
124
|
kind: "sign-in",
|
|
124
|
-
notice: "
|
|
125
|
+
notice: text("passwordChanged")
|
|
125
126
|
});
|
|
126
127
|
};
|
|
127
128
|
const backToSignIn = () => {
|
|
@@ -131,16 +132,20 @@ const useAuthPage = (workspace, children) => {
|
|
|
131
132
|
switch (state.kind) {
|
|
132
133
|
case "loading": return /* @__PURE__ */ jsxs("div", {
|
|
133
134
|
className: "flex h-full min-h-48 items-center justify-center gap-2 text-muted-foreground",
|
|
134
|
-
children: [
|
|
135
|
+
children: [
|
|
136
|
+
/* @__PURE__ */ jsx(Spinner, {}),
|
|
137
|
+
" ",
|
|
138
|
+
text("loading")
|
|
139
|
+
]
|
|
135
140
|
});
|
|
136
141
|
case "error": return /* @__PURE__ */ jsxs("div", {
|
|
137
142
|
className: "flex h-full min-h-48 flex-col items-center justify-center gap-3 p-8 text-center",
|
|
138
|
-
children: [/* @__PURE__ */
|
|
143
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
139
144
|
className: "text-muted-foreground",
|
|
140
|
-
children:
|
|
145
|
+
children: text("cannotReach", state.message)
|
|
141
146
|
}), /* @__PURE__ */ jsx(Button, {
|
|
142
147
|
onClick: recheck,
|
|
143
|
-
children: "
|
|
148
|
+
children: text("tryAgain")
|
|
144
149
|
})]
|
|
145
150
|
});
|
|
146
151
|
case "needs-admin": return /* @__PURE__ */ jsx(FirstRunPage, { onCheckAgain: recheck });
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useAuth } from "./auth-provider.js";
|
|
2
|
+
import { AppLocale } from "../locale/app-locale.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/auth/auth-locale.tsx
|
|
5
|
+
/**
|
|
6
|
+
* Puts the screens below in the language the setup status names: the sign-in screens and public forms come before
|
|
7
|
+
* `/meta`, and are in the app's language all the same.
|
|
8
|
+
*/
|
|
9
|
+
const AuthLocale = ({ children }) => /* @__PURE__ */ jsx(AppLocale, {
|
|
10
|
+
locale: useAuth().locale,
|
|
11
|
+
children
|
|
12
|
+
});
|
|
13
|
+
//#endregion
|
|
14
|
+
export { AuthLocale };
|
|
@@ -1,58 +1,137 @@
|
|
|
1
|
+
import { defineMessages } from "../locale/messages.js";
|
|
1
2
|
//#region src/auth/auth-messages.ts
|
|
2
|
-
const
|
|
3
|
-
|
|
3
|
+
const text = defineMessages({
|
|
4
|
+
en: {
|
|
5
|
+
tooManyRequests: "Too many attempts. Wait a minute and try again.",
|
|
6
|
+
passkeyClosed: "The passkey prompt closed before it finished. Try again.",
|
|
7
|
+
wrongEmailOrPassword: "The email or password is not right.",
|
|
8
|
+
wrongPassword: "The password is not right.",
|
|
9
|
+
wrongCode: "The code is not right.",
|
|
10
|
+
codeExpired: "The code has expired. Ask for a new one.",
|
|
11
|
+
tooManyCodes: "Too many wrong codes. Ask for a new one.",
|
|
12
|
+
wrongBackupCode: "The backup code is not right, or was used before.",
|
|
13
|
+
tooManyCodesSignIn: "Too many wrong codes. Sign in again.",
|
|
14
|
+
locked: "Too many wrong codes. Wait 15 minutes and try again.",
|
|
15
|
+
tooSlow: "This sign-in took too long. Sign in again.",
|
|
16
|
+
passkeyNotFound: "This passkey is not registered for an account here.",
|
|
17
|
+
passkeyFailed: "The passkey could not be checked. Try again.",
|
|
18
|
+
passkeyAdded: "This passkey is added already.",
|
|
19
|
+
notFresh: "For this change, sign out and sign in again first.",
|
|
20
|
+
staffPermissionMissing: "Your staff account has no permission to sign in as people here.",
|
|
21
|
+
staffNotStrong: "Sign in to your staff account with a passkey or a second step, then try again.",
|
|
22
|
+
staffStale: "Your staff sign-in is too old. Sign in to your staff account again.",
|
|
23
|
+
staffExpired: "This staff sign-in took too long or was used already. Start again.",
|
|
24
|
+
staffProviderFailed: "The staff sign-in did not go through at the provider. Try again.",
|
|
25
|
+
staffUserUnavailable: "There is no account with this address, or it is disabled.",
|
|
26
|
+
staffReasonRequired: "Say why you sign in as this person, in at least 10 characters.",
|
|
27
|
+
staffForbidden: "Staff sign-in is turned off for this app.",
|
|
28
|
+
untrustedCallback: "This page is not on an address the server trusts.",
|
|
29
|
+
staffFailed: "The staff sign-in did not go through. Try again."
|
|
30
|
+
},
|
|
31
|
+
nl: {
|
|
32
|
+
tooManyRequests: "Te veel pogingen. Wacht een minuut en probeer het opnieuw.",
|
|
33
|
+
passkeyClosed: "De passkey-vraag sloot voordat die klaar was. Probeer het opnieuw.",
|
|
34
|
+
wrongEmailOrPassword: "Het e-mailadres of wachtwoord klopt niet.",
|
|
35
|
+
wrongPassword: "Het wachtwoord klopt niet.",
|
|
36
|
+
wrongCode: "De code klopt niet.",
|
|
37
|
+
codeExpired: "De code is verlopen. Vraag een nieuwe aan.",
|
|
38
|
+
tooManyCodes: "Te veel verkeerde codes. Vraag een nieuwe aan.",
|
|
39
|
+
wrongBackupCode: "De back-upcode klopt niet, of is al eerder gebruikt.",
|
|
40
|
+
tooManyCodesSignIn: "Te veel verkeerde codes. Log opnieuw in.",
|
|
41
|
+
locked: "Te veel verkeerde codes. Wacht 15 minuten en probeer het opnieuw.",
|
|
42
|
+
tooSlow: "Deze inlogpoging duurde te lang. Log opnieuw in.",
|
|
43
|
+
passkeyNotFound: "Deze passkey hoort hier bij geen enkel account.",
|
|
44
|
+
passkeyFailed: "De passkey kon niet worden gecontroleerd. Probeer het opnieuw.",
|
|
45
|
+
passkeyAdded: "Deze passkey is al toegevoegd.",
|
|
46
|
+
notFresh: "Log voor deze wijziging eerst uit en opnieuw in.",
|
|
47
|
+
staffPermissionMissing: "Je medewerkersaccount mag hier niet als iemand anders inloggen.",
|
|
48
|
+
staffNotStrong: "Log in op je medewerkersaccount met een passkey of een tweede stap, en probeer het dan opnieuw.",
|
|
49
|
+
staffStale: "Je inlog als medewerker is te oud. Log opnieuw in op je medewerkersaccount.",
|
|
50
|
+
staffExpired: "Deze inlog als medewerker duurde te lang of is al gebruikt. Begin opnieuw.",
|
|
51
|
+
staffProviderFailed: "De inlog als medewerker lukte niet bij de provider. Probeer het opnieuw.",
|
|
52
|
+
staffUserUnavailable: "Er is geen account met dit adres, of het is uitgeschakeld.",
|
|
53
|
+
staffReasonRequired: "Zeg in minstens 10 tekens waarom je als deze persoon inlogt.",
|
|
54
|
+
staffForbidden: "Inloggen als medewerker staat uit voor deze app.",
|
|
55
|
+
untrustedCallback: "Deze pagina staat niet op een adres dat de server vertrouwt.",
|
|
56
|
+
staffFailed: "De inlog als medewerker lukte niet. Probeer het opnieuw."
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
const providerText = defineMessages({
|
|
60
|
+
en: {
|
|
61
|
+
signupDisabled: (name) => `No account here belongs to this ${name} account. Ask an admin to add you, or sign in another way.`,
|
|
62
|
+
notLinked: (name) => `Your ${name} account is not linked to your account here. Sign in another way, then connect ${name} on the Sign-in & security page.`,
|
|
63
|
+
linkedToOther: (name) => `This ${name} account is linked to someone else here already.`,
|
|
64
|
+
couldNotLink: (name) => `Your ${name} account could not be linked. Try again.`,
|
|
65
|
+
accessDenied: (name) => `${name} did not let you in, or you cancelled.`,
|
|
66
|
+
domainNotAllowed: (name) => `${name} signed you in with an address this app does not accept from it. Sign in another way.`,
|
|
67
|
+
providerFailed: (name) => `Signing in with ${name} did not go through. Try again.`
|
|
68
|
+
},
|
|
69
|
+
nl: {
|
|
70
|
+
signupDisabled: (name) => `Geen account hier hoort bij dit ${name}-account. Vraag een beheerder om je toe te voegen, of log op een andere manier in.`,
|
|
71
|
+
notLinked: (name) => `Je ${name}-account is niet gekoppeld aan je account hier. Log op een andere manier in en koppel ${name} dan op de pagina Inloggen en beveiliging.`,
|
|
72
|
+
linkedToOther: (name) => `Dit ${name}-account is hier al aan iemand anders gekoppeld.`,
|
|
73
|
+
couldNotLink: (name) => `Je ${name}-account kon niet worden gekoppeld. Probeer het opnieuw.`,
|
|
74
|
+
accessDenied: (name) => `${name} liet je niet binnen, of je hebt geannuleerd.`,
|
|
75
|
+
domainNotAllowed: (name) => `${name} logde je in met een adres dat deze app daarvan niet accepteert. Log op een andere manier in.`,
|
|
76
|
+
providerFailed: (name) => `Inloggen met ${name} lukte niet. Probeer het opnieuw.`
|
|
77
|
+
}
|
|
78
|
+
});
|
|
4
79
|
const messages = {
|
|
5
|
-
INVALID_EMAIL_OR_PASSWORD: "
|
|
6
|
-
INVALID_PASSWORD: "
|
|
7
|
-
INVALID_OTP: "
|
|
8
|
-
OTP_EXPIRED: "
|
|
9
|
-
TOO_MANY_ATTEMPTS: "
|
|
10
|
-
INVALID_CODE: "
|
|
11
|
-
INVALID_BACKUP_CODE: "
|
|
12
|
-
TOO_MANY_ATTEMPTS_REQUEST_NEW_CODE: "
|
|
13
|
-
ACCOUNT_TEMPORARILY_LOCKED: "
|
|
14
|
-
INVALID_TWO_FACTOR_COOKIE: "
|
|
15
|
-
AUTH_CANCELLED: passkeyClosed,
|
|
16
|
-
ERROR_CEREMONY_ABORTED: passkeyClosed,
|
|
17
|
-
REGISTRATION_CANCELLED: passkeyClosed,
|
|
18
|
-
PASSKEY_NOT_FOUND: "
|
|
19
|
-
AUTHENTICATION_FAILED: "
|
|
20
|
-
PREVIOUSLY_REGISTERED: "
|
|
21
|
-
ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED: "
|
|
22
|
-
SESSION_NOT_FRESH: "
|
|
80
|
+
INVALID_EMAIL_OR_PASSWORD: "wrongEmailOrPassword",
|
|
81
|
+
INVALID_PASSWORD: "wrongPassword",
|
|
82
|
+
INVALID_OTP: "wrongCode",
|
|
83
|
+
OTP_EXPIRED: "codeExpired",
|
|
84
|
+
TOO_MANY_ATTEMPTS: "tooManyCodes",
|
|
85
|
+
INVALID_CODE: "wrongCode",
|
|
86
|
+
INVALID_BACKUP_CODE: "wrongBackupCode",
|
|
87
|
+
TOO_MANY_ATTEMPTS_REQUEST_NEW_CODE: "tooManyCodesSignIn",
|
|
88
|
+
ACCOUNT_TEMPORARILY_LOCKED: "locked",
|
|
89
|
+
INVALID_TWO_FACTOR_COOKIE: "tooSlow",
|
|
90
|
+
AUTH_CANCELLED: "passkeyClosed",
|
|
91
|
+
ERROR_CEREMONY_ABORTED: "passkeyClosed",
|
|
92
|
+
REGISTRATION_CANCELLED: "passkeyClosed",
|
|
93
|
+
PASSKEY_NOT_FOUND: "passkeyNotFound",
|
|
94
|
+
AUTHENTICATION_FAILED: "passkeyFailed",
|
|
95
|
+
PREVIOUSLY_REGISTERED: "passkeyAdded",
|
|
96
|
+
ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED: "passkeyAdded",
|
|
97
|
+
SESSION_NOT_FRESH: "notFresh"
|
|
23
98
|
};
|
|
24
|
-
const
|
|
99
|
+
const lookup = (ids, code) => {
|
|
100
|
+
const id = code ? ids[code] : void 0;
|
|
101
|
+
return id && text(id);
|
|
102
|
+
};
|
|
103
|
+
const known = (error) => lookup(messages, error.code);
|
|
25
104
|
/** Better Auth's error from a sign-in step or an account change, in words for the person at the keyboard. */
|
|
26
|
-
const authMessage = (error) => known(error) ?? (error.status === 429 ? tooManyRequests : error.message);
|
|
105
|
+
const authMessage = (error) => known(error) ?? (error.status === 429 ? text("tooManyRequests") : error.message);
|
|
27
106
|
/** As `authMessage`, for the password form: any other 401 is a wrong email or password. */
|
|
28
|
-
const signInMessage = (error) => known(error) ?? (error.status === 429 ? tooManyRequests : error.status === 401 ?
|
|
107
|
+
const signInMessage = (error) => known(error) ?? (error.status === 429 ? text("tooManyRequests") : error.status === 401 ? text("wrongEmailOrPassword") : error.message);
|
|
29
108
|
const staffMessages = {
|
|
30
|
-
STAFF_PERMISSION_MISSING: "
|
|
31
|
-
STAFF_SIGN_IN_NOT_STRONG: "
|
|
32
|
-
STAFF_SIGN_IN_STALE: "
|
|
33
|
-
STAFF_SIGN_IN_EXPIRED: "
|
|
34
|
-
STAFF_SIGN_IN_FAILED: "
|
|
35
|
-
STAFF_USER_UNAVAILABLE: "
|
|
36
|
-
STAFF_REASON_REQUIRED: "
|
|
37
|
-
SIGN_IN_METHOD_FORBIDDEN: "
|
|
38
|
-
INVALID_CALLBACK_URL: "
|
|
109
|
+
STAFF_PERMISSION_MISSING: "staffPermissionMissing",
|
|
110
|
+
STAFF_SIGN_IN_NOT_STRONG: "staffNotStrong",
|
|
111
|
+
STAFF_SIGN_IN_STALE: "staffStale",
|
|
112
|
+
STAFF_SIGN_IN_EXPIRED: "staffExpired",
|
|
113
|
+
STAFF_SIGN_IN_FAILED: "staffProviderFailed",
|
|
114
|
+
STAFF_USER_UNAVAILABLE: "staffUserUnavailable",
|
|
115
|
+
STAFF_REASON_REQUIRED: "staffReasonRequired",
|
|
116
|
+
SIGN_IN_METHOD_FORBIDDEN: "staffForbidden",
|
|
117
|
+
INVALID_CALLBACK_URL: "untrustedCallback"
|
|
39
118
|
};
|
|
40
119
|
/** Why a staff sign-in did not go through, from the code it came back with or an `AuthError` of its start. */
|
|
41
120
|
const staffSignInMessage = (failure) => {
|
|
42
|
-
const
|
|
43
|
-
if (
|
|
44
|
-
if (typeof failure === "string") return "
|
|
45
|
-
return failure.status === 429 ? tooManyRequests : failure.message;
|
|
121
|
+
const message = lookup(staffMessages, typeof failure === "string" ? failure : failure.code);
|
|
122
|
+
if (message) return message;
|
|
123
|
+
if (typeof failure === "string") return text("staffFailed");
|
|
124
|
+
return failure.status === 429 ? text("tooManyRequests") : failure.message;
|
|
46
125
|
};
|
|
47
126
|
const providerMessages = {
|
|
48
|
-
signup_disabled: (name) =>
|
|
49
|
-
account_not_linked: (name) =>
|
|
50
|
-
account_already_linked_to_different_user: (name) =>
|
|
51
|
-
unable_to_link_account: (name) =>
|
|
52
|
-
access_denied: (name) =>
|
|
53
|
-
EMAIL_DOMAIN_NOT_ALLOWED: (name) =>
|
|
127
|
+
signup_disabled: (name) => providerText("signupDisabled", name),
|
|
128
|
+
account_not_linked: (name) => providerText("notLinked", name),
|
|
129
|
+
account_already_linked_to_different_user: (name) => providerText("linkedToOther", name),
|
|
130
|
+
unable_to_link_account: (name) => providerText("couldNotLink", name),
|
|
131
|
+
access_denied: (name) => providerText("accessDenied", name),
|
|
132
|
+
EMAIL_DOMAIN_NOT_ALLOWED: (name) => providerText("domainNotAllowed", name)
|
|
54
133
|
};
|
|
55
134
|
/** Why signing in or linking with the provider `name` did not go through, from the code it came back with. */
|
|
56
|
-
const providerMessage = (code, name) => providerMessages[code]?.(name) ??
|
|
135
|
+
const providerMessage = (code, name) => providerMessages[code]?.(name) ?? providerText("providerFailed", name);
|
|
57
136
|
//#endregion
|
|
58
137
|
export { authMessage, providerMessage, signInMessage, staffSignInMessage };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { providerName, withoutSignInLink } from "./provider-link.js";
|
|
2
|
+
import { text } from "./messages.js";
|
|
2
3
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
3
4
|
import { createAuthSession } from "@protobase/client";
|
|
4
5
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -23,6 +24,7 @@ const AuthProvider = ({ session: given, children }) => {
|
|
|
23
24
|
const [organizations, setOrganizations] = useState();
|
|
24
25
|
const [anonymous, setAnonymous] = useState(false);
|
|
25
26
|
const [beforeSignIn, setBeforeSignIn] = useState([]);
|
|
27
|
+
const [locale, setLocale] = useState();
|
|
26
28
|
const signedOutState = useCallback(() => anonymous ? { kind: "visitor" } : { kind: "signed-out" }, [anonymous]);
|
|
27
29
|
const markSignedOut = useCallback(() => setState((current) => current.kind === "signed-in" ? { kind: "signed-out" } : current), []);
|
|
28
30
|
const signedOut = useRef(markSignedOut);
|
|
@@ -58,12 +60,13 @@ const AuthProvider = ({ session: given, children }) => {
|
|
|
58
60
|
setOrganizations(status.organizations);
|
|
59
61
|
setAnonymous(Boolean(status.anonymous));
|
|
60
62
|
setBeforeSignIn(status.plugins ?? []);
|
|
63
|
+
setLocale(status.locale);
|
|
61
64
|
if (status.needsAdmin) return setState({ kind: "needs-admin" });
|
|
62
65
|
const user = await session.session();
|
|
63
66
|
return user ? enter(user) : setState({ kind: status.anonymous ? "visitor" : "signed-out" });
|
|
64
67
|
}).catch((error) => setState({
|
|
65
68
|
kind: "error",
|
|
66
|
-
message: error instanceof Error ? error.message : "
|
|
69
|
+
message: error instanceof Error ? error.message : text("noAnswer")
|
|
67
70
|
}));
|
|
68
71
|
}, [session, enter]);
|
|
69
72
|
useEffect(recheck, [recheck]);
|
|
@@ -84,6 +87,7 @@ const AuthProvider = ({ session: given, children }) => {
|
|
|
84
87
|
markSignedOut,
|
|
85
88
|
recheck,
|
|
86
89
|
beforeSignIn,
|
|
90
|
+
locale,
|
|
87
91
|
adoptSession: async () => {
|
|
88
92
|
const user = await session.session();
|
|
89
93
|
if (!user) return false;
|
|
@@ -131,6 +135,7 @@ const AuthProvider = ({ session: given, children }) => {
|
|
|
131
135
|
organizations,
|
|
132
136
|
anonymous,
|
|
133
137
|
beforeSignIn,
|
|
138
|
+
locale,
|
|
134
139
|
signedOutState,
|
|
135
140
|
markSignedOut,
|
|
136
141
|
recheck,
|
package/dist/auth/code-form.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { text } from "./messages.js";
|
|
1
2
|
import { Button } from "../primitives/button.js";
|
|
2
3
|
import { OtpInput } from "../primitives/otp-input.js";
|
|
3
4
|
import { AuthLayout } from "./auth-layout.js";
|
|
@@ -33,7 +34,7 @@ const CodeForm = ({ title, description, explanation, submitLabel, onSubmit, onRe
|
|
|
33
34
|
children: [
|
|
34
35
|
/* @__PURE__ */ jsxs("label", {
|
|
35
36
|
className: "flex flex-col gap-1.5 font-medium",
|
|
36
|
-
children: ["
|
|
37
|
+
children: [text("code"), /* @__PURE__ */ jsx(OtpInput, {
|
|
37
38
|
name: "code",
|
|
38
39
|
required: true,
|
|
39
40
|
autoFocus: true,
|