@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.
- package/dist/account/account-pages.js +3 -2
- package/dist/account/account-section.js +1 -1
- 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 +4 -3
- package/dist/account/sign-in-policy-form.js +14 -13
- 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 +19 -18
- package/dist/action-card/action-card.js +2 -1
- package/dist/action-card/field-list.js +1 -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 +7 -6
- 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/timeline-row.js +1 -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/error-banner.js +1 -1
- package/dist/app/export/builder-port.js +2 -1
- package/dist/app/export/export-dialog.js +39 -43
- 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 +21 -37
- 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/field.js +1 -1
- package/dist/app/pages/blocks/modal-form.js +5 -4
- package/dist/app/pages/blocks/progress.js +1 -1
- 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 +13 -20
- package/dist/app-shell/global-search.js +2 -2
- package/dist/app-shell/messages.js +4 -2
- package/dist/app-shell/sidebar-group.js +1 -1
- package/dist/app-shell/sidebar-item.js +1 -1
- package/dist/app-shell/sidebar.js +1 -1
- package/dist/assistant-dock/assistant-dock.js +6 -6
- 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 +4 -3
- 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 +15 -17
- 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 +12 -11
- package/dist/auth/reset-password-page.js +4 -3
- package/dist/auth/setup-required-form.js +8 -10
- package/dist/auth/setup-required-page.js +7 -2
- package/dist/auth/sign-in-form.js +18 -21
- 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 +15 -22
- package/dist/auth/sign-up-email-form.js +9 -8
- package/dist/auth/sign-up-page.js +2 -1
- package/dist/auth/staff-sign-in-form.js +16 -19
- package/dist/auth/two-factor-form.js +19 -18
- 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/data-grid/grid-header.js +1 -1
- package/dist/filter-panel/date-presets.js +1 -1
- package/dist/forms/public-form-page.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 +41 -51
- package/dist/organizations/invitations-page.js +11 -10
- package/dist/organizations/members-page.js +16 -11
- 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/button.js +1 -1
- package/dist/primitives/messages.js +16 -0
- package/dist/primitives/segmented.js +1 -1
- 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/field.js +2 -2
- 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-yCMYvqMX.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-BRkDA5KD.css → index-Bkc7w8I4.css} +1 -1
- package/dist/shell/assets/{index-xY0Mvv6V.js → index-HkjqX_O-.js} +2 -2
- package/dist/shell/assets/maplibre-DUTS_eJM.js +814 -0
- package/dist/shell/assets/{markdown-content-ukDTCu6u.js → markdown-content-CtGUP4W6.js} +1 -1
- package/dist/shell/assets/parse-worker-UhbwEjS0.js +5 -0
- package/dist/shell/assets/preload-helper-BZ3hrQDD.js +1 -0
- package/dist/shell/assets/{record-map-BJmYZ7kQ.js → record-map-DFy7sJEU.js} +1 -1
- package/dist/shell/assets/records-map-MfQEuiFB.js +1 -0
- package/dist/shell/assets/shared-protobase-ui-Bfa59vx6.js +1 -0
- package/dist/shell/index.html +6 -4
- 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-C-OLrsRR.js +0 -69
- package/dist/shell/assets/export-worker-Bz57Pf5g.js +0 -2
- package/dist/shell/assets/maplibre-Dov6nhPX.js +0 -814
- package/dist/shell/assets/parse-worker-BtcY0dQw.js +0 -5
- package/dist/shell/assets/records-map-C1_gDKHR.js +0 -1
- package/dist/shell/assets/shared-protobase-ui-CFYJAbMR.js +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { text } from "./messages.js";
|
|
1
2
|
import { createCsvParser } from "./csv-parser.js";
|
|
2
3
|
import { openWorkbook } from "./xlsx-reader.js";
|
|
3
4
|
//#region src/app/import/sheet-file.ts
|
|
@@ -14,7 +15,7 @@ const sheetFormat = async (file) => {
|
|
|
14
15
|
};
|
|
15
16
|
/** The workbook's sheet names, in order; a CSV has none. */
|
|
16
17
|
const sheetNames = async (file) => await sheetFormat(file) === "xlsx" ? (await openWorkbook(file)).sheets : [];
|
|
17
|
-
const notText = () =>
|
|
18
|
+
const notText = () => new Error(text("fileNotUtf8"));
|
|
18
19
|
async function* csvRows(file) {
|
|
19
20
|
const parser = createCsvParser();
|
|
20
21
|
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
@@ -51,7 +52,7 @@ async function* sheetRows(file, sheet) {
|
|
|
51
52
|
if (await sheetFormat(file) === "csv") return yield* csvRows(file);
|
|
52
53
|
const workbook = await openWorkbook(file);
|
|
53
54
|
const name = sheet ?? workbook.sheets[0];
|
|
54
|
-
if (name === void 0) throw new Error("
|
|
55
|
+
if (name === void 0) throw new Error(text("noSheets"));
|
|
55
56
|
yield* workbook.rows(name);
|
|
56
57
|
}
|
|
57
58
|
//#endregion
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { activeLocale } from "../../locale/active-locale.js";
|
|
2
|
+
import { text } from "./messages.js";
|
|
1
3
|
//#region src/app/import/sheet-source.ts
|
|
2
4
|
/** How many rows the worker sends at a time. */
|
|
3
5
|
const chunkRows = 500;
|
|
@@ -16,7 +18,7 @@ const startWorker = () => {
|
|
|
16
18
|
event.preventDefault();
|
|
17
19
|
const failed = {
|
|
18
20
|
type: "error",
|
|
19
|
-
message: "
|
|
21
|
+
message: text("unreadable")
|
|
20
22
|
};
|
|
21
23
|
if (waiting) waiting(failed);
|
|
22
24
|
else replies.push(failed);
|
|
@@ -36,7 +38,8 @@ const workerSheetSource = (file) => ({
|
|
|
36
38
|
try {
|
|
37
39
|
worker.send({
|
|
38
40
|
type: "sheets",
|
|
39
|
-
file
|
|
41
|
+
file,
|
|
42
|
+
locale: activeLocale()
|
|
40
43
|
});
|
|
41
44
|
const reply = await worker.receive();
|
|
42
45
|
if (reply.type === "error") throw new Error(reply.message);
|
|
@@ -53,7 +56,8 @@ const workerSheetSource = (file) => ({
|
|
|
53
56
|
type: "read",
|
|
54
57
|
file,
|
|
55
58
|
sheet,
|
|
56
|
-
chunk: chunkRows
|
|
59
|
+
chunk: chunkRows,
|
|
60
|
+
locale: activeLocale()
|
|
57
61
|
});
|
|
58
62
|
for (;;) {
|
|
59
63
|
const reply = await worker.receive();
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { text } from "./messages.js";
|
|
1
2
|
import { createRowScanner, dateStyles, parseRow, sharedStrings, workbookSheets } from "./xlsx-xml.js";
|
|
2
3
|
import { zipEntries, zipText, zipTextChunks } from "./zip-reader.js";
|
|
3
4
|
//#region src/app/import/xlsx-reader.ts
|
|
4
5
|
const part = (entries, name) => {
|
|
5
6
|
const entry = entries.get(name);
|
|
6
|
-
if (!entry) throw new Error(
|
|
7
|
+
if (!entry) throw new Error(text("notWorkbook", name));
|
|
7
8
|
return entry;
|
|
8
9
|
};
|
|
9
10
|
/**
|
|
@@ -24,11 +25,11 @@ const openWorkbook = async (blob) => {
|
|
|
24
25
|
};
|
|
25
26
|
async function* rows(name) {
|
|
26
27
|
const sheet = sheets.find((candidate) => candidate.name === name);
|
|
27
|
-
if (!sheet) throw new Error(
|
|
28
|
+
if (!sheet) throw new Error(text("noSheetCalled", name));
|
|
28
29
|
const shared = context ?? await sheetContext();
|
|
29
30
|
const scan = createRowScanner();
|
|
30
31
|
let line = 0;
|
|
31
|
-
for await (const
|
|
32
|
+
for await (const chunk of zipTextChunks(blob, part(entries, sheet.path))) for (const xml of scan(chunk)) {
|
|
32
33
|
const row = parseRow(xml, shared, line);
|
|
33
34
|
line = row.line;
|
|
34
35
|
yield row;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { text } from "./messages.js";
|
|
1
2
|
//#region src/app/import/xlsx-xml.ts
|
|
2
3
|
const entities = {
|
|
3
4
|
amp: "&",
|
|
@@ -35,7 +36,7 @@ const workbookSheets = (workbookXml, relsXml) => {
|
|
|
35
36
|
const sheets = [...workbookXml.matchAll(/<sheet\b([^>]*)>/g)].map((match) => {
|
|
36
37
|
const { name, id } = attributes(match[1]);
|
|
37
38
|
const path = targets.get(id);
|
|
38
|
-
if (!name || !path) throw new Error("
|
|
39
|
+
if (!name || !path) throw new Error(text("missingSheetPart"));
|
|
39
40
|
return {
|
|
40
41
|
name,
|
|
41
42
|
path
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { text } from "./messages.js";
|
|
1
2
|
//#region src/app/import/zip-reader.ts
|
|
2
3
|
const endSignature = 101010256;
|
|
3
4
|
const entrySignature = 33639248;
|
|
4
5
|
const localSignature = 67324752;
|
|
5
6
|
const endSearch = 65557;
|
|
6
7
|
const bytesOf = async (blob, start, end) => new DataView(await blob.slice(start, end).arrayBuffer());
|
|
7
|
-
const notZip = () =>
|
|
8
|
+
const notZip = () => new Error(text("notZip"));
|
|
8
9
|
const endRecordAt = (view) => {
|
|
9
10
|
for (let at = view.byteLength - 22; at >= 0; at--) if (view.getUint32(at, true) === endSignature) return at;
|
|
10
11
|
return -1;
|
|
@@ -18,7 +19,7 @@ const zipEntries = async (blob) => {
|
|
|
18
19
|
const count = tail.getUint16(end + 10, true);
|
|
19
20
|
const size = tail.getUint32(end + 12, true);
|
|
20
21
|
const start = tail.getUint32(end + 16, true);
|
|
21
|
-
if (count === 65535 || size === 4294967295 || start === 4294967295) throw new Error("
|
|
22
|
+
if (count === 65535 || size === 4294967295 || start === 4294967295) throw new Error(text("zip64"));
|
|
22
23
|
const directory = await bytesOf(blob, start, start + size);
|
|
23
24
|
const decoder = new TextDecoder();
|
|
24
25
|
const entries = /* @__PURE__ */ new Map();
|
|
@@ -47,7 +48,7 @@ const zipEntryStream = async (blob, entry) => {
|
|
|
47
48
|
const raw = blob.slice(dataStart, dataStart + entry.size).stream();
|
|
48
49
|
if (entry.method === 0) return raw;
|
|
49
50
|
if (entry.method === 8) return raw.pipeThrough(new DecompressionStream("deflate-raw"));
|
|
50
|
-
throw new Error(
|
|
51
|
+
throw new Error(text("compression", entry.name, entry.method));
|
|
51
52
|
};
|
|
52
53
|
/** The entry's content as text, decoded as UTF-8 a chunk at a time. */
|
|
53
54
|
async function* zipTextChunks(blob, entry) {
|
|
@@ -4,8 +4,8 @@ import { useToast } from "../../toasts/toast-provider.js";
|
|
|
4
4
|
import { recordKey } from "../../live/model-helpers.js";
|
|
5
5
|
import { text } from "./messages.js";
|
|
6
6
|
import { useRef, useState } from "react";
|
|
7
|
-
import { isApiError } from "@protobase/client";
|
|
8
7
|
import { encodeKey } from "@protobase/schema/internal";
|
|
8
|
+
import { isApiError } from "@protobase/client";
|
|
9
9
|
import { useQueryClient } from "@tanstack/react-query";
|
|
10
10
|
//#region src/app/list-edit/use-list-edits.ts
|
|
11
11
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { text } from "./messages.js";
|
|
1
2
|
import { humanize } from "../live/naming.js";
|
|
2
3
|
import { ChartView } from "./charts/chart-view.js";
|
|
3
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -6,7 +7,7 @@ const measureTitle = (chart, view, plural) => {
|
|
|
6
7
|
const name = chart.sum ?? chart.average;
|
|
7
8
|
if (name === void 0) return plural;
|
|
8
9
|
const label = view?.fields[name]?.label ?? humanize(name);
|
|
9
|
-
return chart.sum !== void 0 ? `${label}` :
|
|
10
|
+
return chart.sum !== void 0 ? `${label}` : text("average", label);
|
|
10
11
|
};
|
|
11
12
|
/** The view's chart per value of a field, above the list and following its filter. */
|
|
12
13
|
const ListGroupChart = ({ model, view, chart, plural, filter }) => {
|
package/dist/app/list-page.js
CHANGED
|
@@ -3,6 +3,7 @@ import { usePageScroll } from "../app-shell/page-scroll.js";
|
|
|
3
3
|
import { PageHeader } from "../app-shell/page-header.js";
|
|
4
4
|
import { useAuth } from "../auth/auth-provider.js";
|
|
5
5
|
import { Button, buttonClass } from "../primitives/button.js";
|
|
6
|
+
import { text } from "./messages.js";
|
|
6
7
|
import { humanize } from "../live/naming.js";
|
|
7
8
|
import { recordKey, recordTitleField } from "../live/model-helpers.js";
|
|
8
9
|
import { columnsFromModel, listColumnNames } from "../live/columns-from-model.js";
|
|
@@ -12,7 +13,6 @@ import { parseSort, sortToOrderBy } from "./list-order.js";
|
|
|
12
13
|
import { listedResource } from "./current-address.js";
|
|
13
14
|
import { Notice, useAdminMeta, usePermissions } from "./meta-gate.js";
|
|
14
15
|
import { AppLink, useAppAddress } from "./use-app-address.js";
|
|
15
|
-
import { text } from "./messages.js";
|
|
16
16
|
import { ErrorBanner } from "./error-banner.js";
|
|
17
17
|
import { useProjectUi } from "./pages/project-ui.js";
|
|
18
18
|
import { Sheet } from "../primitives/sheet.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Segmented } from "../../primitives/segmented.js";
|
|
2
2
|
import { chosenMapLayer, readMapLayer, writeMapLayer } from "./map-layer-choice.js";
|
|
3
|
+
import { text } from "./messages.js";
|
|
3
4
|
import { useState } from "react";
|
|
4
5
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
import { Layer, Source, useMap } from "react-map-gl/maplibre";
|
|
@@ -38,12 +39,12 @@ const MapLayerSwitch = ({ layers, below }) => {
|
|
|
38
39
|
}, chosen.id), /* @__PURE__ */ jsx("div", {
|
|
39
40
|
className: "absolute left-2.5 top-2.5 z-10 rounded-md shadow",
|
|
40
41
|
children: /* @__PURE__ */ jsx(Segmented, {
|
|
41
|
-
label: "
|
|
42
|
+
label: text("mapLayer"),
|
|
42
43
|
value: chosen?.id ?? styleValue,
|
|
43
44
|
onChange: choose,
|
|
44
45
|
options: [{
|
|
45
46
|
value: styleValue,
|
|
46
|
-
label: "
|
|
47
|
+
label: text("map")
|
|
47
48
|
}, ...layers.map((layer) => ({
|
|
48
49
|
value: layer.id,
|
|
49
50
|
label: layer.label
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineMessages } from "../../locale/messages.js";
|
|
2
|
+
//#region src/app/map/messages.ts
|
|
3
|
+
const text = defineMessages({
|
|
4
|
+
en: {
|
|
5
|
+
mapLayer: "Map layer",
|
|
6
|
+
map: "Map"
|
|
7
|
+
},
|
|
8
|
+
nl: {
|
|
9
|
+
mapLayer: "Kaartlaag",
|
|
10
|
+
map: "Kaart"
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
//#endregion
|
|
14
|
+
export { text };
|
package/dist/app/messages.js
CHANGED
|
@@ -4,12 +4,126 @@ const text = defineMessages({
|
|
|
4
4
|
en: {
|
|
5
5
|
notFound: "Not found",
|
|
6
6
|
noResource: (name) => `There is no resource called ${name}.`,
|
|
7
|
-
somethingWentWrong: "Something went wrong"
|
|
7
|
+
somethingWentWrong: "Something went wrong",
|
|
8
|
+
signInSecurity: "Sign-in & security",
|
|
9
|
+
signInPolicy: "Sign-in policy",
|
|
10
|
+
adminsOnly: "Admins only",
|
|
11
|
+
onlyAdminPolicy: "Only an admin can change how people sign in.",
|
|
12
|
+
ownersOnly: "Owners and admins only",
|
|
13
|
+
onlyOwners: "Only the organization's owners and admins manage its members.",
|
|
14
|
+
chooseResource: "Choose a resource",
|
|
15
|
+
pickFromSidebar: "Pick one from the sidebar.",
|
|
16
|
+
nothingHere: "There is nothing at this address.",
|
|
17
|
+
noPage: "There is no page called {}.",
|
|
18
|
+
assistant: "Assistant",
|
|
19
|
+
operationFailed: (index, label, message) => `Operation ${index} (${label}) failed: ${message} Nothing was saved.`,
|
|
20
|
+
nothingSaved: (message) => `${message} Nothing was saved.`,
|
|
21
|
+
admin: "Admin",
|
|
22
|
+
new: "New",
|
|
23
|
+
loadingRecord: "Loading record",
|
|
24
|
+
noComponent: "No component is registered as {}. Export it from protobase.ui.tsx, or load the plugin that provides it.",
|
|
25
|
+
choose: "Choose...",
|
|
26
|
+
fileMissing: "The file is missing from storage",
|
|
27
|
+
chooseFileFor: (label) => `Choose a file for ${label}`,
|
|
28
|
+
notUploaded: "Not uploaded",
|
|
29
|
+
uploadingLabel: (label) => `Uploading ${label}`,
|
|
30
|
+
uploading: (percent) => `Uploading… ${percent}%`,
|
|
31
|
+
replace: "Replace",
|
|
32
|
+
remove: "Remove",
|
|
33
|
+
dropFile: "Drop a file here or",
|
|
34
|
+
chooseFile: "Choose a file",
|
|
35
|
+
average: (label) => `Average ${label.toLowerCase()}`,
|
|
36
|
+
pages: "Pages",
|
|
37
|
+
account: "Account",
|
|
38
|
+
sales: "Sales",
|
|
39
|
+
crm: "CRM",
|
|
40
|
+
catalog: "Catalog",
|
|
41
|
+
inventory: "Inventory",
|
|
42
|
+
hr: "HR",
|
|
43
|
+
cannotReach: (label) => `Cannot reach ${label}`,
|
|
44
|
+
searchPlural: (plural) => `Search ${plural}`,
|
|
45
|
+
couldNotLoadOptions: "Could not load the options",
|
|
46
|
+
noMatches: "No matches",
|
|
47
|
+
loading: "Loading",
|
|
48
|
+
leaveTitle: "Leave without saving?",
|
|
49
|
+
leaveDescription: "You have unsaved changes on this page. They stay in this browser, and come back when you open the record again.",
|
|
50
|
+
stay: "Stay",
|
|
51
|
+
leave: "Leave",
|
|
52
|
+
show: (label) => `Show ${label}`,
|
|
53
|
+
hide: (label) => `Hide ${label}`,
|
|
54
|
+
couldNotShow: (label) => `Could not show the ${label}`,
|
|
55
|
+
noAnswer: "It did not answer.",
|
|
56
|
+
signInRefused: (message) => `It did not accept your sign-in: ${message}`,
|
|
57
|
+
loadingFrom: (label) => `Loading from ${label}`,
|
|
58
|
+
restWorks: "The rest of the app works as before.",
|
|
59
|
+
tryAgain: "Try again",
|
|
60
|
+
staffSession: "Staff session",
|
|
61
|
+
staffSignedIn: "{} is signed in as {} until {}. Reason: {}",
|
|
62
|
+
stopStaffSession: "Stop staff session",
|
|
63
|
+
open: "Open",
|
|
64
|
+
openLabel: (label) => `Open ${label}`
|
|
8
65
|
},
|
|
9
66
|
nl: {
|
|
10
67
|
notFound: "Niet gevonden",
|
|
11
68
|
noResource: (name) => `Er is geen onderdeel met de naam ${name}.`,
|
|
12
|
-
somethingWentWrong: "Er ging iets mis"
|
|
69
|
+
somethingWentWrong: "Er ging iets mis",
|
|
70
|
+
signInSecurity: "Inloggen en beveiliging",
|
|
71
|
+
signInPolicy: "Inlogbeleid",
|
|
72
|
+
adminsOnly: "Alleen beheerders",
|
|
73
|
+
onlyAdminPolicy: "Alleen een beheerder kan wijzigen hoe mensen inloggen.",
|
|
74
|
+
ownersOnly: "Alleen eigenaren en beheerders",
|
|
75
|
+
onlyOwners: "Alleen de eigenaren en beheerders van de organisatie beheren de leden.",
|
|
76
|
+
chooseResource: "Kies een onderdeel",
|
|
77
|
+
pickFromSidebar: "Kies er een in de zijbalk.",
|
|
78
|
+
nothingHere: "Er is niets op dit adres.",
|
|
79
|
+
noPage: "Er is geen pagina met de naam {}.",
|
|
80
|
+
assistant: "Assistent",
|
|
81
|
+
operationFailed: (index, label, message) => `Bewerking ${index} (${label}) mislukte: ${message} Er is niets bewaard.`,
|
|
82
|
+
nothingSaved: (message) => `${message} Er is niets bewaard.`,
|
|
83
|
+
admin: "Beheer",
|
|
84
|
+
new: "Nieuw",
|
|
85
|
+
loadingRecord: "Record laden",
|
|
86
|
+
noComponent: "Er is geen component geregistreerd als {}. Exporteer die uit protobase.ui.tsx, of laad de plug-in die haar levert.",
|
|
87
|
+
choose: "Kiezen...",
|
|
88
|
+
fileMissing: "Het bestand ontbreekt in de opslag",
|
|
89
|
+
chooseFileFor: (label) => `Kies een bestand voor ${label}`,
|
|
90
|
+
notUploaded: "Niet geüpload",
|
|
91
|
+
uploadingLabel: (label) => `${label} uploaden`,
|
|
92
|
+
uploading: (percent) => `Uploaden… ${percent}%`,
|
|
93
|
+
replace: "Vervangen",
|
|
94
|
+
remove: "Verwijderen",
|
|
95
|
+
dropFile: "Zet hier een bestand neer of",
|
|
96
|
+
chooseFile: "Kies een bestand",
|
|
97
|
+
average: (label) => `${label}, gemiddeld`,
|
|
98
|
+
pages: "Pagina's",
|
|
99
|
+
account: "Account",
|
|
100
|
+
sales: "Verkoop",
|
|
101
|
+
crm: "CRM",
|
|
102
|
+
catalog: "Catalogus",
|
|
103
|
+
inventory: "Voorraad",
|
|
104
|
+
hr: "HR",
|
|
105
|
+
cannotReach: (label) => `Kan ${label} niet bereiken`,
|
|
106
|
+
searchPlural: (plural) => `${plural} zoeken`,
|
|
107
|
+
couldNotLoadOptions: "Kon de keuzes niet laden",
|
|
108
|
+
noMatches: "Niets gevonden",
|
|
109
|
+
loading: "Laden",
|
|
110
|
+
leaveTitle: "Weggaan zonder te bewaren?",
|
|
111
|
+
leaveDescription: "Je hebt niet-bewaarde wijzigingen op deze pagina. Ze blijven in deze browser, en komen terug als je het record weer opent.",
|
|
112
|
+
stay: "Blijven",
|
|
113
|
+
leave: "Weggaan",
|
|
114
|
+
show: (label) => `${label} tonen`,
|
|
115
|
+
hide: (label) => `${label} verbergen`,
|
|
116
|
+
couldNotShow: (label) => `Kon ${label} niet tonen`,
|
|
117
|
+
noAnswer: "Het antwoordde niet.",
|
|
118
|
+
signInRefused: (message) => `Het accepteerde je inlog niet: ${message}`,
|
|
119
|
+
loadingFrom: (label) => `Laden van ${label}`,
|
|
120
|
+
restWorks: "De rest van de app werkt zoals eerst.",
|
|
121
|
+
tryAgain: "Opnieuw proberen",
|
|
122
|
+
staffSession: "Sessie van een medewerker",
|
|
123
|
+
staffSignedIn: "{} is ingelogd als {} tot {}. Reden: {}",
|
|
124
|
+
stopStaffSession: "Sessie van medewerker stoppen",
|
|
125
|
+
open: "Openen",
|
|
126
|
+
openLabel: (label) => `${label} openen`
|
|
13
127
|
}
|
|
14
128
|
});
|
|
15
129
|
//#endregion
|
package/dist/app/meta-gate.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Spinner } from "../primitives/spinner.js";
|
|
2
2
|
import { ClientProvider, useClient, useSourceClients } from "../data/api-provider.js";
|
|
3
|
+
import { AppLocale } from "../locale/app-locale.js";
|
|
3
4
|
import { withSources } from "../data/with-sources.js";
|
|
4
5
|
import { MetaContext } from "../data/meta-context.js";
|
|
5
6
|
import { allowEverything } from "../data/meta-data.js";
|
|
6
7
|
import { useMeta } from "../data/use-meta.js";
|
|
7
8
|
import { useSourceMetas } from "../data/use-source-metas.js";
|
|
8
|
-
import { AppLocale } from "../locale/app-locale.js";
|
|
9
9
|
import { text } from "./meta-gate-messages.js";
|
|
10
10
|
import { useContext, useMemo } from "react";
|
|
11
11
|
import { isApiError, routedClient } from "@protobase/client";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { text } from "./messages.js";
|
|
1
2
|
import { humanize } from "../live/naming.js";
|
|
2
3
|
import { iconFor } from "./icons.js";
|
|
3
4
|
import { menuIcon } from "./menu-icons.js";
|
|
@@ -8,12 +9,12 @@ import { appPath } from "@protobase/schema";
|
|
|
8
9
|
/** The sidebar item of a resource's list, or of one of its named lists. */
|
|
9
10
|
const navItemId = (resource, list) => list === void 0 ? resource : `${resource}/${list}`;
|
|
10
11
|
const groupLabels = {
|
|
11
|
-
sales: "
|
|
12
|
-
crm: "
|
|
13
|
-
catalog: "
|
|
14
|
-
inventory: "
|
|
15
|
-
core: "
|
|
16
|
-
hr: "
|
|
12
|
+
sales: "sales",
|
|
13
|
+
crm: "crm",
|
|
14
|
+
catalog: "catalog",
|
|
15
|
+
inventory: "inventory",
|
|
16
|
+
core: "admin",
|
|
17
|
+
hr: "hr"
|
|
17
18
|
};
|
|
18
19
|
/**
|
|
19
20
|
* One sidebar group per `nav.group` (default: the database schema, and "Pages" for pages); `nav.hidden` and a place in
|
|
@@ -29,7 +30,7 @@ const navFromMeta = (meta, basePath = "", recent = {}) => {
|
|
|
29
30
|
const inMenu = userMenuResources(meta);
|
|
30
31
|
for (const page of Object.values(meta.pages)) {
|
|
31
32
|
if (page.nav?.hidden || inMenu.has(page.name)) continue;
|
|
32
|
-
const groupName = page.nav?.group ?? "
|
|
33
|
+
const groupName = page.nav?.group ?? text("pages");
|
|
33
34
|
const group = groups.get(groupName) ?? {
|
|
34
35
|
label: groupName,
|
|
35
36
|
items: []
|
|
@@ -50,7 +51,7 @@ const navFromMeta = (meta, basePath = "", recent = {}) => {
|
|
|
50
51
|
const view = meta.views[model.name];
|
|
51
52
|
if (!view || inMenu.has(model.name)) continue;
|
|
52
53
|
const schema = model.table.schema ?? "public";
|
|
53
|
-
const defaultGroup = view.nav?.group ?? groupLabels[schema]
|
|
54
|
+
const defaultGroup = view.nav?.group ?? (groupLabels[schema] ? text(groupLabels[schema]) : humanize(schema));
|
|
54
55
|
const add = (groupName, item, order) => {
|
|
55
56
|
const group = groups.get(groupName) ?? {
|
|
56
57
|
label: groupName,
|
|
@@ -86,7 +87,7 @@ const navFromMeta = (meta, basePath = "", recent = {}) => {
|
|
|
86
87
|
}
|
|
87
88
|
for (const entry of Object.values(meta.signIn ?? {})) {
|
|
88
89
|
if (entry.nav?.hidden || inMenu.has(entry.resource)) continue;
|
|
89
|
-
const groupName = entry.nav?.group ?? "
|
|
90
|
+
const groupName = entry.nav?.group ?? text("account");
|
|
90
91
|
const group = groups.get(groupName) ?? {
|
|
91
92
|
label: groupName,
|
|
92
93
|
items: []
|
|
@@ -117,7 +118,7 @@ const navFromMeta = (meta, basePath = "", recent = {}) => {
|
|
|
117
118
|
kind: "list",
|
|
118
119
|
resource
|
|
119
120
|
}, basePath),
|
|
120
|
-
problem:
|
|
121
|
+
problem: text("cannotReach", status.source.label)
|
|
121
122
|
});
|
|
122
123
|
groups.set(status.source.label, group);
|
|
123
124
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Button } from "../../../primitives/button.js";
|
|
2
|
+
import { text } from "../messages.js";
|
|
2
3
|
import { Field } from "../../../record-view/field.js";
|
|
3
4
|
import { useAdminMeta } from "../../meta-gate.js";
|
|
4
5
|
import { isChosen } from "../../create/create-values.js";
|
|
@@ -74,7 +75,7 @@ const ActionInputsDialog = ({ action, label, danger, onCancel, onSubmit }) => {
|
|
|
74
75
|
onClose: onCancel,
|
|
75
76
|
actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button, {
|
|
76
77
|
onClick: onCancel,
|
|
77
|
-
children: "
|
|
78
|
+
children: text("cancel")
|
|
78
79
|
}), /* @__PURE__ */ jsx(Button, {
|
|
79
80
|
variant: danger ? "danger" : "primary",
|
|
80
81
|
type: "submit",
|
|
@@ -90,7 +91,7 @@ const ActionInputsDialog = ({ action, label, danger, onCancel, onSubmit }) => {
|
|
|
90
91
|
submit();
|
|
91
92
|
},
|
|
92
93
|
children: [failure !== void 0 && Object.keys(errors).length === 0 && /* @__PURE__ */ jsx(ErrorBanner, {
|
|
93
|
-
title:
|
|
94
|
+
title: text("failed", label),
|
|
94
95
|
error: failure
|
|
95
96
|
}), action.inputs.filter((input) => shown.has(input.name)).map((input) => /* @__PURE__ */ jsx(Field, {
|
|
96
97
|
label: input.label,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { text } from "../messages.js";
|
|
1
2
|
import { toDraft, toPatchValue } from "../../../live/field-values.js";
|
|
2
3
|
import { isChosen } from "../../create/create-values.js";
|
|
3
4
|
import { shownInputs } from "@protobase/schema/internal";
|
|
@@ -72,11 +73,11 @@ const answeredValues = (inputs, draft) => {
|
|
|
72
73
|
const decimal = /^-?\d+(\.\d+)?$/;
|
|
73
74
|
const date = /^\d{4}-\d{2}-\d{2}$/;
|
|
74
75
|
const refusal = (input, value) => {
|
|
75
|
-
if (value === null || value === "") return input.required ? "
|
|
76
|
-
if (input.kind === "integer" && !Number.isInteger(value)) return "
|
|
77
|
-
if (input.kind === "decimal" && !decimal.test(String(value))) return "
|
|
78
|
-
if (input.kind === "date" && !date.test(String(value))) return "
|
|
79
|
-
if (input.max !== void 0 && String(value).length > input.max) return
|
|
76
|
+
if (value === null || value === "") return input.required ? text("required") : void 0;
|
|
77
|
+
if (input.kind === "integer" && !Number.isInteger(value)) return text("wholeNumber");
|
|
78
|
+
if (input.kind === "decimal" && !decimal.test(String(value))) return text("number");
|
|
79
|
+
if (input.kind === "date" && !date.test(String(value))) return text("dateFormat");
|
|
80
|
+
if (input.max !== void 0 && String(value).length > input.max) return text("atMost", input.max);
|
|
80
81
|
};
|
|
81
82
|
/** What is wrong with the answers that show, by input name: one left empty that is required, a number that is none, a text too long. */
|
|
82
83
|
const refusedAnswers = (inputs, values) => Object.fromEntries(inputs.flatMap((input) => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Skeleton } from "../../../primitives/skeleton.js";
|
|
2
|
+
import { text } from "../messages.js";
|
|
2
3
|
import { useAdminMeta } from "../../meta-gate.js";
|
|
3
4
|
import { ErrorBanner } from "../../error-banner.js";
|
|
4
5
|
import { RecordScope } from "../record-scope.js";
|
|
@@ -22,9 +23,9 @@ const LoadedCardRow = ({ model, filter, sort, limit = 12, title, description, em
|
|
|
22
23
|
className: "flex gap-3",
|
|
23
24
|
children: Array.from({ length: 3 }, (_, index) => /* @__PURE__ */ jsx(Skeleton, { className: "h-24 w-56" }, index))
|
|
24
25
|
}) : page.error ? /* @__PURE__ */ jsx(ErrorBanner, {
|
|
25
|
-
title: "
|
|
26
|
+
title: text("couldNotLoad"),
|
|
26
27
|
error: page.error
|
|
27
|
-
}) : rows.length === 0 ? /* @__PURE__ */ jsx(Quiet, { children: empty ?? "
|
|
28
|
+
}) : rows.length === 0 ? /* @__PURE__ */ jsx(Quiet, { children: empty ?? text("nothingYet") }) : /* @__PURE__ */ jsx("ul", {
|
|
28
29
|
className: "relative -mx-4 flex snap-x gap-3 overflow-x-auto px-4 pb-1",
|
|
29
30
|
children: rows.map((row) => {
|
|
30
31
|
const scope = scopeOf(model, row);
|
|
@@ -30,7 +30,7 @@ const FieldBlock = ({ node }) => {
|
|
|
30
30
|
return /* @__PURE__ */ jsxs("div", {
|
|
31
31
|
className: "min-w-0",
|
|
32
32
|
children: [/* @__PURE__ */ jsx("div", {
|
|
33
|
-
className: "text-
|
|
33
|
+
className: "text-body text-muted-foreground",
|
|
34
34
|
children: text
|
|
35
35
|
}), /* @__PURE__ */ jsx("div", {
|
|
36
36
|
className: "mt-0.5 truncate",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Button } from "../../../primitives/button.js";
|
|
2
2
|
import { Dialog } from "../../../primitives/dialog.js";
|
|
3
3
|
import { useClient } from "../../../data/api-provider.js";
|
|
4
|
+
import { text } from "../messages.js";
|
|
4
5
|
import { humanize } from "../../../live/naming.js";
|
|
5
6
|
import { useToast } from "../../../toasts/toast-provider.js";
|
|
6
7
|
import { Field } from "../../../record-view/field.js";
|
|
@@ -54,7 +55,7 @@ const ModalFormDialog = ({ model, record, mode, label, title, fields, values, on
|
|
|
54
55
|
await refresh(model.name);
|
|
55
56
|
toast.show({
|
|
56
57
|
state: "success",
|
|
57
|
-
title:
|
|
58
|
+
title: text("saved", title ?? label)
|
|
58
59
|
});
|
|
59
60
|
onClose();
|
|
60
61
|
}, (error) => {
|
|
@@ -70,12 +71,12 @@ const ModalFormDialog = ({ model, record, mode, label, title, fields, values, on
|
|
|
70
71
|
onClose,
|
|
71
72
|
actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button, {
|
|
72
73
|
onClick: onClose,
|
|
73
|
-
children: "
|
|
74
|
+
children: text("cancel")
|
|
74
75
|
}), /* @__PURE__ */ jsx(Button, {
|
|
75
76
|
variant: "primary",
|
|
76
77
|
loading: saving,
|
|
77
78
|
onClick: () => void submit(),
|
|
78
|
-
children: mode === "create" ? "
|
|
79
|
+
children: mode === "create" ? text("create") : text("save")
|
|
79
80
|
})] }),
|
|
80
81
|
children: /* @__PURE__ */ jsxs("form", {
|
|
81
82
|
ref: formRef,
|
|
@@ -85,7 +86,7 @@ const ModalFormDialog = ({ model, record, mode, label, title, fields, values, on
|
|
|
85
86
|
submit();
|
|
86
87
|
},
|
|
87
88
|
children: [failure !== void 0 && Object.keys(errors).length === 0 && /* @__PURE__ */ jsx(ErrorBanner, {
|
|
88
|
-
title: "
|
|
89
|
+
title: text("notSaved"),
|
|
89
90
|
error: failure
|
|
90
91
|
}), fields.map((name) => {
|
|
91
92
|
const field = model.fields[name];
|
|
@@ -25,7 +25,7 @@ const ProgressBlock = ({ node }) => {
|
|
|
25
25
|
return /* @__PURE__ */ jsxs("div", {
|
|
26
26
|
className: "min-w-0",
|
|
27
27
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
28
|
-
className: "flex items-baseline justify-between gap-2 text-
|
|
28
|
+
className: "flex items-baseline justify-between gap-2 text-body",
|
|
29
29
|
children: [/* @__PURE__ */ jsx("span", {
|
|
30
30
|
className: "text-muted-foreground",
|
|
31
31
|
children: label
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Skeleton } from "../../../primitives/skeleton.js";
|
|
2
|
+
import { text } from "../messages.js";
|
|
2
3
|
import { useAdminMeta } from "../../meta-gate.js";
|
|
3
4
|
import { ErrorBanner } from "../../error-banner.js";
|
|
4
5
|
import { RecordScope } from "../record-scope.js";
|
|
@@ -21,12 +22,12 @@ const LoadedRecordCard = ({ model, filter, sort, recordKey, title, description,
|
|
|
21
22
|
className: "flex flex-col gap-2",
|
|
22
23
|
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/3" })]
|
|
23
24
|
}) : record.error ? /* @__PURE__ */ jsx(ErrorBanner, {
|
|
24
|
-
title: "
|
|
25
|
+
title: text("couldNotLoad"),
|
|
25
26
|
error: record.error
|
|
26
27
|
}) : record.data ? scoped(/* @__PURE__ */ jsx("div", {
|
|
27
28
|
className: "flex flex-col gap-3",
|
|
28
29
|
children
|
|
29
|
-
})) : /* @__PURE__ */ jsx(Quiet, { children: empty ?? "
|
|
30
|
+
})) : /* @__PURE__ */ jsx(Quiet, { children: empty ?? text("nothingYet") });
|
|
30
31
|
return /* @__PURE__ */ jsx(CardFrame, {
|
|
31
32
|
title,
|
|
32
33
|
description,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { formatTag } from "../../../locale/active-locale.js";
|
|
2
2
|
import { Skeleton } from "../../../primitives/skeleton.js";
|
|
3
|
+
import { text } from "../messages.js";
|
|
3
4
|
import { useAdminMeta } from "../../meta-gate.js";
|
|
4
5
|
import { AppLink } from "../../use-app-address.js";
|
|
5
6
|
import { useLayoutRecord } from "../record-scope.js";
|
|
@@ -18,7 +19,7 @@ const Count = ({ model, filter }) => {
|
|
|
18
19
|
if (count.isPending) return /* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-16" });
|
|
19
20
|
if (count.error) return /* @__PURE__ */ jsx("span", {
|
|
20
21
|
className: "text-danger-text",
|
|
21
|
-
children: "
|
|
22
|
+
children: text("couldNotCount")
|
|
22
23
|
});
|
|
23
24
|
return /* @__PURE__ */ jsx(AppLink, {
|
|
24
25
|
to: filteredListAddress(views[model.name], model.name, filter),
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
+
import { slotted } from "../../locale/slotted.js";
|
|
2
|
+
import { text } from "./messages.js";
|
|
1
3
|
import { Notice, useAdminMeta } from "../meta-gate.js";
|
|
2
4
|
import { RenderNode } from "./render-node.js";
|
|
3
|
-
import { jsx
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
6
|
//#region src/app/pages/composed-page.tsx
|
|
5
7
|
/** `/<page>`: the page's tree as `/meta` gave it to this user. */
|
|
6
8
|
const ComposedPage = ({ name }) => {
|
|
7
9
|
const page = useAdminMeta().pages[name];
|
|
8
|
-
if (!page) return /* @__PURE__ */
|
|
9
|
-
title: "
|
|
10
|
-
children:
|
|
11
|
-
"There is no page called ",
|
|
12
|
-
name,
|
|
13
|
-
"."
|
|
14
|
-
]
|
|
10
|
+
if (!page) return /* @__PURE__ */ jsx(Notice, {
|
|
11
|
+
title: text("notFound"),
|
|
12
|
+
children: slotted(text("noPage"), name)
|
|
15
13
|
});
|
|
16
14
|
return /* @__PURE__ */ jsx(RenderNode, { node: page.tree });
|
|
17
15
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Button } from "../../primitives/button.js";
|
|
2
2
|
import { Dialog } from "../../primitives/dialog.js";
|
|
3
|
+
import { text } from "./messages.js";
|
|
3
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
5
|
//#region src/app/pages/confirm-action.tsx
|
|
5
6
|
/** The question an action with `confirm` asks before it runs. */
|
|
@@ -9,7 +10,7 @@ const ConfirmAction = ({ action, label, danger, onCancel, onConfirm }) => /* @__
|
|
|
9
10
|
onClose: onCancel,
|
|
10
11
|
actions: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
|
|
11
12
|
onClick: onCancel,
|
|
12
|
-
children: "
|
|
13
|
+
children: text("cancel")
|
|
13
14
|
}), /* @__PURE__ */ jsx(Button, {
|
|
14
15
|
variant: danger ? "danger" : "primary",
|
|
15
16
|
onClick: onConfirm,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { slotted } from "../../locale/slotted.js";
|
|
1
2
|
import { reportRenderError } from "../error-reporting.js";
|
|
2
3
|
import { Problem } from "./problem.js";
|
|
4
|
+
import { text } from "./messages.js";
|
|
3
5
|
import { Component } from "react";
|
|
4
|
-
import {
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
7
|
//#region src/app/pages/custom-boundary.tsx
|
|
6
8
|
/** Draws a warning in place of a project's or plugin's component that throws, so one component cannot blank the app. */
|
|
7
9
|
var CustomBoundary = class extends Component {
|
|
@@ -14,7 +16,7 @@ var CustomBoundary = class extends Component {
|
|
|
14
16
|
}
|
|
15
17
|
render() {
|
|
16
18
|
if (!this.state.failed) return this.props.children;
|
|
17
|
-
return this.props.fallback === void 0 ? /* @__PURE__ */
|
|
19
|
+
return this.props.fallback === void 0 ? /* @__PURE__ */ jsx(Problem, { children: slotted(text("couldNotDraw"), this.props.name) }) : this.props.fallback;
|
|
18
20
|
}
|
|
19
21
|
};
|
|
20
22
|
//#endregion
|