@protobase/ui 0.25.2 → 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-xY0Mvv6V.js → index-B7cIjCuz.js} +2 -2
- package/dist/shell/assets/maplibre-CVG5L9FD.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-BX9CcZkY.js +1 -0
- package/dist/shell/assets/{record-map-BJmYZ7kQ.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-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
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineMessages } from "../locale/messages.js";
|
|
2
|
+
//#region src/compact-table/messages.ts
|
|
3
|
+
const text = defineMessages({
|
|
4
|
+
en: {
|
|
5
|
+
table: "Table",
|
|
6
|
+
noRows: "No rows.",
|
|
7
|
+
rows: (count) => `${count} ${count === 1 ? "row" : "rows"}`,
|
|
8
|
+
cutOff: ", cut off at the limit"
|
|
9
|
+
},
|
|
10
|
+
nl: {
|
|
11
|
+
table: "Tabel",
|
|
12
|
+
noRows: "Geen rijen.",
|
|
13
|
+
rows: (count) => `${count} ${count === 1 ? "rij" : "rijen"}`,
|
|
14
|
+
cutOff: ", afgekapt bij de limiet"
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
//#endregion
|
|
18
|
+
export { text };
|
package/dist/data/meta-data.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { MapLayerModel, PluginRef, ResourcePermissions, SourceRef } from "@protobase/client";
|
|
2
1
|
import { Locale } from "@protobase/schema/internal";
|
|
2
|
+
import { MapLayerModel, PluginRef, ResourcePermissions, SourceRef } from "@protobase/client";
|
|
3
3
|
import { BottomBarModel, ResourceModel, SignInViewModel, UserMenuModel, ViewModel } from "@protobase/schema";
|
|
4
4
|
import { PageModel } from "@protobase/layout";
|
|
5
5
|
//#region src/data/meta-data.d.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { keys } from "./query-keys.js";
|
|
2
2
|
import { useClient } from "./api-provider.js";
|
|
3
|
-
import { PreconditionFailedError } from "@protobase/client";
|
|
4
3
|
import { encodeKey } from "@protobase/schema/internal";
|
|
4
|
+
import { PreconditionFailedError } from "@protobase/client";
|
|
5
5
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
6
6
|
//#region src/data/use-update-record.ts
|
|
7
7
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Button } from "../primitives/button.js";
|
|
2
2
|
import { productAt } from "../mocks/products.js";
|
|
3
3
|
import { lineGrid } from "./columns.js";
|
|
4
|
+
import { text } from "./messages.js";
|
|
4
5
|
import { LineRow } from "./line-row.js";
|
|
5
6
|
import { reorder } from "./reorder.js";
|
|
6
7
|
import { TotalsFooter } from "./totals-footer.js";
|
|
@@ -10,15 +11,14 @@ import { DndContext, KeyboardSensor, MouseSensor, TouchSensor, closestCenter, us
|
|
|
10
11
|
import { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
|
11
12
|
//#region src/inline-child-table/inline-child-table.tsx
|
|
12
13
|
const headerCell = "px-2 text-[11px] font-medium uppercase tracking-wide text-muted-foreground";
|
|
13
|
-
const instructions = "To pick up a line, press space or enter on its drag handle. Use the up and down arrow keys to move it, space or enter to drop it, and escape to cancel. The row menu also has Move up and Move down.";
|
|
14
14
|
const announcementsFor = (lines) => {
|
|
15
|
-
const name = (id) => lines.find((line) => line.id === id)?.description ?? "line";
|
|
15
|
+
const name = (id) => lines.find((line) => line.id === id)?.description ?? text("line");
|
|
16
16
|
const place = (id) => lines.findIndex((line) => line.id === id) + 1;
|
|
17
17
|
return {
|
|
18
|
-
onDragStart: ({ active }) =>
|
|
19
|
-
onDragOver: ({ active, over }) => over ?
|
|
20
|
-
onDragEnd: ({ active, over }) => over ?
|
|
21
|
-
onDragCancel: ({ active }) =>
|
|
18
|
+
onDragStart: ({ active }) => text("pickedUp", name(active.id), place(active.id), lines.length),
|
|
19
|
+
onDragOver: ({ active, over }) => over ? text("over", name(active.id), place(over.id), lines.length) : void 0,
|
|
20
|
+
onDragEnd: ({ active, over }) => over ? text("dropped", name(active.id), place(over.id), lines.length) : text("droppedAtStart", name(active.id)),
|
|
21
|
+
onDragCancel: ({ active }) => text("cancelled", name(active.id), place(active.id))
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
const InlineChildTable = ({ lines, onChange, onReorder, vatRate = .21, readOnly, reorderable = !readOnly }) => {
|
|
@@ -58,19 +58,19 @@ const InlineChildTable = ({ lines, onChange, onReorder, vatRate = .21, readOnly,
|
|
|
58
58
|
/* @__PURE__ */ jsx("span", {}),
|
|
59
59
|
/* @__PURE__ */ jsx("span", {
|
|
60
60
|
className: headerCell,
|
|
61
|
-
children: "
|
|
61
|
+
children: text("item")
|
|
62
62
|
}),
|
|
63
63
|
/* @__PURE__ */ jsx("span", {
|
|
64
64
|
className: `${headerCell} text-right`,
|
|
65
|
-
children: "
|
|
65
|
+
children: text("qty")
|
|
66
66
|
}),
|
|
67
67
|
/* @__PURE__ */ jsx("span", {
|
|
68
68
|
className: `${headerCell} text-right`,
|
|
69
|
-
children: "
|
|
69
|
+
children: text("unitPrice")
|
|
70
70
|
}),
|
|
71
71
|
/* @__PURE__ */ jsx("span", {
|
|
72
72
|
className: `${headerCell} text-right`,
|
|
73
|
-
children: "
|
|
73
|
+
children: text("lineTotal")
|
|
74
74
|
}),
|
|
75
75
|
/* @__PURE__ */ jsx("span", {})
|
|
76
76
|
]
|
|
@@ -81,7 +81,7 @@ const InlineChildTable = ({ lines, onChange, onReorder, vatRate = .21, readOnly,
|
|
|
81
81
|
onDragEnd,
|
|
82
82
|
accessibility: {
|
|
83
83
|
announcements: announcementsFor(lines),
|
|
84
|
-
screenReaderInstructions: { draggable: instructions }
|
|
84
|
+
screenReaderInstructions: { draggable: text("instructions") }
|
|
85
85
|
},
|
|
86
86
|
children: /* @__PURE__ */ jsx(SortableContext, {
|
|
87
87
|
items: lines.map((line) => line.id),
|
|
@@ -107,7 +107,7 @@ const InlineChildTable = ({ lines, onChange, onReorder, vatRate = .21, readOnly,
|
|
|
107
107
|
variant: "ghost",
|
|
108
108
|
size: "sm",
|
|
109
109
|
onClick: addLine,
|
|
110
|
-
children: [/* @__PURE__ */ jsx(Plus, { className: "size-3.5" }), "
|
|
110
|
+
children: [/* @__PURE__ */ jsx(Plus, { className: "size-3.5" }), text("addLine")]
|
|
111
111
|
})
|
|
112
112
|
})
|
|
113
113
|
]
|
|
@@ -4,26 +4,27 @@ import { lineTotalCents } from "../mocks/invoices.js";
|
|
|
4
4
|
import { lineGrid } from "./columns.js";
|
|
5
5
|
import { LineMenu } from "./line-menu.js";
|
|
6
6
|
import { NumberCell } from "./number-cell.js";
|
|
7
|
+
import { text } from "./messages.js";
|
|
7
8
|
import { GripVertical } from "lucide-react";
|
|
8
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
10
|
import { useSortable } from "@dnd-kit/sortable";
|
|
10
11
|
//#region src/inline-child-table/line-row.tsx
|
|
11
|
-
const parseEuros = (
|
|
12
|
+
const parseEuros = (typed) => Math.round(Number(typed.replace(",", ".").replace(/[^0-9.]/g, "")) * 100);
|
|
12
13
|
const LineRow = ({ line, position, count, reorderable, editable, onChange, onRemove, onMove }) => {
|
|
13
14
|
const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({
|
|
14
15
|
id: line.id,
|
|
15
16
|
disabled: !reorderable
|
|
16
17
|
});
|
|
17
18
|
const menu = [...reorderable ? [{
|
|
18
|
-
label: "
|
|
19
|
+
label: text("moveUp"),
|
|
19
20
|
disabled: position === 0,
|
|
20
21
|
onSelect: () => onMove(position - 1)
|
|
21
22
|
}, {
|
|
22
|
-
label: "
|
|
23
|
+
label: text("moveDown"),
|
|
23
24
|
disabled: position === count - 1,
|
|
24
25
|
onSelect: () => onMove(position + 1)
|
|
25
26
|
}] : [], ...editable ? [{
|
|
26
|
-
label: "
|
|
27
|
+
label: text("removeLine"),
|
|
27
28
|
destructive: true,
|
|
28
29
|
onSelect: onRemove
|
|
29
30
|
}] : []];
|
|
@@ -39,7 +40,7 @@ const LineRow = ({ line, position, count, reorderable, editable, onChange, onRem
|
|
|
39
40
|
reorderable ? /* @__PURE__ */ jsx("button", {
|
|
40
41
|
ref: setActivatorNodeRef,
|
|
41
42
|
type: "button",
|
|
42
|
-
"aria-label":
|
|
43
|
+
"aria-label": text("dragToReorder", line.description),
|
|
43
44
|
...attributes,
|
|
44
45
|
...listeners,
|
|
45
46
|
style: { touchAction: "none" },
|
|
@@ -57,17 +58,17 @@ const LineRow = ({ line, position, count, reorderable, editable, onChange, onRem
|
|
|
57
58
|
})]
|
|
58
59
|
}),
|
|
59
60
|
editable ? /* @__PURE__ */ jsx(NumberCell, {
|
|
60
|
-
label: "
|
|
61
|
+
label: text("quantity"),
|
|
61
62
|
value: line.quantity,
|
|
62
63
|
format: String,
|
|
63
|
-
parse: (
|
|
64
|
+
parse: (typed) => Math.round(Number(typed)),
|
|
64
65
|
onCommit: (quantity) => onChange({ quantity })
|
|
65
66
|
}) : /* @__PURE__ */ jsx("span", {
|
|
66
67
|
className: "px-2 text-right tabular-nums",
|
|
67
68
|
children: line.quantity
|
|
68
69
|
}),
|
|
69
70
|
editable ? /* @__PURE__ */ jsx(NumberCell, {
|
|
70
|
-
label: "
|
|
71
|
+
label: text("unitPrice"),
|
|
71
72
|
value: line.unitPriceCents,
|
|
72
73
|
format: (cents) => (cents / 100).toFixed(2),
|
|
73
74
|
parse: parseEuros,
|
|
@@ -81,7 +82,7 @@ const LineRow = ({ line, position, count, reorderable, editable, onChange, onRem
|
|
|
81
82
|
children: formatMoney(lineTotalCents(line))
|
|
82
83
|
}),
|
|
83
84
|
menu.length > 0 ? /* @__PURE__ */ jsx(LineMenu, {
|
|
84
|
-
label:
|
|
85
|
+
label: text("actionsFor", line.description),
|
|
85
86
|
items: menu
|
|
86
87
|
}) : /* @__PURE__ */ jsx("span", {})
|
|
87
88
|
]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { defineMessages } from "../locale/messages.js";
|
|
2
|
+
//#region src/inline-child-table/messages.ts
|
|
3
|
+
const text = defineMessages({
|
|
4
|
+
en: {
|
|
5
|
+
instructions: "To pick up a line, press space or enter on its drag handle. Use the up and down arrow keys to move it, space or enter to drop it, and escape to cancel. The row menu also has Move up and Move down.",
|
|
6
|
+
line: "line",
|
|
7
|
+
pickedUp: (name, place, count) => `Picked up ${name}, line ${place} of ${count}.`,
|
|
8
|
+
over: (name, place, count) => `${name} is over line ${place} of ${count}.`,
|
|
9
|
+
dropped: (name, place, count) => `${name} was dropped at line ${place} of ${count}.`,
|
|
10
|
+
droppedAtStart: (name) => `${name} was dropped where it started.`,
|
|
11
|
+
cancelled: (name, place) => `Moving ${name} was cancelled. It is back at line ${place}.`,
|
|
12
|
+
item: "Item",
|
|
13
|
+
qty: "Qty",
|
|
14
|
+
quantity: "Quantity",
|
|
15
|
+
unitPrice: "Unit price",
|
|
16
|
+
lineTotal: "Line total",
|
|
17
|
+
addLine: "Add line",
|
|
18
|
+
moveUp: "Move up",
|
|
19
|
+
moveDown: "Move down",
|
|
20
|
+
removeLine: "Remove line",
|
|
21
|
+
dragToReorder: (name) => `Drag to reorder ${name}`,
|
|
22
|
+
actionsFor: (name) => `Actions for ${name}`,
|
|
23
|
+
subtotal: "Subtotal",
|
|
24
|
+
vat: (percent) => `VAT ${percent}%`,
|
|
25
|
+
total: "Total"
|
|
26
|
+
},
|
|
27
|
+
nl: {
|
|
28
|
+
instructions: "Druk op spatie of enter op de sleepgreep om een regel op te pakken. Verplaats hem met de pijltjestoetsen omhoog en omlaag, zet hem neer met spatie of enter, en annuleer met escape. Het regelmenu heeft ook Omhoog en Omlaag.",
|
|
29
|
+
line: "regel",
|
|
30
|
+
pickedUp: (name, place, count) => `${name} opgepakt, regel ${place} van ${count}.`,
|
|
31
|
+
over: (name, place, count) => `${name} is boven regel ${place} van ${count}.`,
|
|
32
|
+
dropped: (name, place, count) => `${name} is neergezet op regel ${place} van ${count}.`,
|
|
33
|
+
droppedAtStart: (name) => `${name} is neergezet waar hij begon.`,
|
|
34
|
+
cancelled: (name, place) => `Verplaatsen van ${name} is geannuleerd. Hij staat weer op regel ${place}.`,
|
|
35
|
+
item: "Artikel",
|
|
36
|
+
qty: "Aantal",
|
|
37
|
+
quantity: "Aantal",
|
|
38
|
+
unitPrice: "Stukprijs",
|
|
39
|
+
lineTotal: "Regeltotaal",
|
|
40
|
+
addLine: "Regel toevoegen",
|
|
41
|
+
moveUp: "Omhoog",
|
|
42
|
+
moveDown: "Omlaag",
|
|
43
|
+
removeLine: "Regel verwijderen",
|
|
44
|
+
dragToReorder: (name) => `Sleep om ${name} te verplaatsen`,
|
|
45
|
+
actionsFor: (name) => `Acties voor ${name}`,
|
|
46
|
+
subtotal: "Subtotaal",
|
|
47
|
+
vat: (percent) => `Btw ${percent}%`,
|
|
48
|
+
total: "Totaal"
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
//#endregion
|
|
52
|
+
export { text };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { formatMoney } from "../format/money.js";
|
|
2
2
|
import { invoiceTotals } from "../mocks/invoices.js";
|
|
3
|
+
import { text } from "./messages.js";
|
|
3
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
5
|
//#region src/inline-child-table/totals-footer.tsx
|
|
5
6
|
const TotalsFooter = ({ lines, vatRate }) => {
|
|
@@ -9,19 +10,15 @@ const TotalsFooter = ({ lines, vatRate }) => {
|
|
|
9
10
|
children: [
|
|
10
11
|
/* @__PURE__ */ jsx("dt", {
|
|
11
12
|
className: "text-muted-foreground",
|
|
12
|
-
children: "
|
|
13
|
+
children: text("subtotal")
|
|
13
14
|
}),
|
|
14
15
|
/* @__PURE__ */ jsx("dd", {
|
|
15
16
|
className: "text-right text-foreground",
|
|
16
17
|
children: formatMoney(totals.subtotalCents)
|
|
17
18
|
}),
|
|
18
|
-
/* @__PURE__ */
|
|
19
|
+
/* @__PURE__ */ jsx("dt", {
|
|
19
20
|
className: "text-muted-foreground",
|
|
20
|
-
children:
|
|
21
|
-
"VAT ",
|
|
22
|
-
Math.round(vatRate * 100),
|
|
23
|
-
"%"
|
|
24
|
-
]
|
|
21
|
+
children: text("vat", Math.round(vatRate * 100))
|
|
25
22
|
}),
|
|
26
23
|
/* @__PURE__ */ jsx("dd", {
|
|
27
24
|
className: "text-right text-foreground",
|
|
@@ -29,7 +26,7 @@ const TotalsFooter = ({ lines, vatRate }) => {
|
|
|
29
26
|
}),
|
|
30
27
|
/* @__PURE__ */ jsx("dt", {
|
|
31
28
|
className: "mt-1 border-t border-border pt-2 font-semibold text-foreground",
|
|
32
|
-
children: "
|
|
29
|
+
children: text("total")
|
|
33
30
|
}),
|
|
34
31
|
/* @__PURE__ */ jsx("dd", {
|
|
35
32
|
className: "mt-1 border-t border-border pt-2 text-right text-[16px] font-semibold text-foreground",
|
|
@@ -2,6 +2,7 @@ import { Input } from "../primitives/input.js";
|
|
|
2
2
|
import { Button } from "../primitives/button.js";
|
|
3
3
|
import { AccountSection, SectionError } from "../account/account-section.js";
|
|
4
4
|
import { useAction } from "../organizations/use-action.js";
|
|
5
|
+
import { text } from "./messages.js";
|
|
5
6
|
import { LinkNotice } from "./link-notice.js";
|
|
6
7
|
import { useState } from "react";
|
|
7
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -30,7 +31,7 @@ const InviteForm = ({ title, description, onInvite, beside, children, incomplete
|
|
|
30
31
|
className: "flex flex-col gap-2 sm:flex-row",
|
|
31
32
|
children: [
|
|
32
33
|
/* @__PURE__ */ jsx(Input, {
|
|
33
|
-
"aria-label": "
|
|
34
|
+
"aria-label": text("email"),
|
|
34
35
|
type: "email",
|
|
35
36
|
placeholder: "name@example.com",
|
|
36
37
|
value: email,
|
|
@@ -43,7 +44,7 @@ const InviteForm = ({ title, description, onInvite, beside, children, incomplete
|
|
|
43
44
|
variant: "primary",
|
|
44
45
|
loading: busy,
|
|
45
46
|
disabled: !email.trim() || incomplete,
|
|
46
|
-
children: "
|
|
47
|
+
children: text("invite")
|
|
47
48
|
})
|
|
48
49
|
]
|
|
49
50
|
}), children]
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { slotted } from "../locale/slotted.js";
|
|
2
|
+
import { text } from "./messages.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
4
|
//#region src/invitations/link-notice.tsx
|
|
3
5
|
/** The invitation link to pass on, when the app cannot email it. */
|
|
4
|
-
const LinkNotice = ({ link }) => link ? /* @__PURE__ */
|
|
6
|
+
const LinkNotice = ({ link }) => link ? /* @__PURE__ */ jsx("p", {
|
|
5
7
|
className: "mt-3 break-all rounded-md border bg-muted px-3 py-2 text-xs",
|
|
6
|
-
children:
|
|
8
|
+
children: slotted(text("passLinkOn"), /* @__PURE__ */ jsx("span", {
|
|
7
9
|
className: "font-mono",
|
|
8
10
|
children: link
|
|
9
|
-
})
|
|
11
|
+
}))
|
|
10
12
|
}) : null;
|
|
11
13
|
//#endregion
|
|
12
14
|
export { LinkNotice };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { defineMessages } from "../locale/messages.js";
|
|
2
|
+
//#region src/invitations/messages.ts
|
|
3
|
+
const text = defineMessages({
|
|
4
|
+
en: {
|
|
5
|
+
email: "Email",
|
|
6
|
+
invite: "Invite",
|
|
7
|
+
expired: "Expired",
|
|
8
|
+
until: (date) => `Until ${date}`,
|
|
9
|
+
sendAgain: "Send again",
|
|
10
|
+
revoke: "Revoke",
|
|
11
|
+
passLinkOn: "This app cannot send email, so pass this link on yourself. It works once, until the invitation expires: {}"
|
|
12
|
+
},
|
|
13
|
+
nl: {
|
|
14
|
+
email: "E-mailadres",
|
|
15
|
+
invite: "Uitnodigen",
|
|
16
|
+
expired: "Verlopen",
|
|
17
|
+
until: (date) => `Tot ${date}`,
|
|
18
|
+
sendAgain: "Opnieuw sturen",
|
|
19
|
+
revoke: "Intrekken",
|
|
20
|
+
passLinkOn: "Deze app kan geen e-mail sturen, dus geef deze link zelf door. Die werkt één keer, tot de uitnodiging verloopt: {}"
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
//#endregion
|
|
24
|
+
export { text };
|
|
@@ -2,6 +2,7 @@ import { formatTag } from "../locale/active-locale.js";
|
|
|
2
2
|
import { Button } from "../primitives/button.js";
|
|
3
3
|
import { SectionError } from "../account/account-section.js";
|
|
4
4
|
import { useAction } from "../organizations/use-action.js";
|
|
5
|
+
import { text } from "./messages.js";
|
|
5
6
|
import { LinkNotice } from "./link-notice.js";
|
|
6
7
|
import { useState } from "react";
|
|
7
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -27,7 +28,7 @@ const PendingInvitationRow = ({ email, gives, expiresAt, onResend, onRevoke }) =
|
|
|
27
28
|
children: [
|
|
28
29
|
gives,
|
|
29
30
|
" · ",
|
|
30
|
-
expired ? "
|
|
31
|
+
expired ? text("expired") : text("until", new Date(expiresAt).toLocaleDateString(formatTag()))
|
|
31
32
|
]
|
|
32
33
|
})]
|
|
33
34
|
}),
|
|
@@ -35,14 +36,14 @@ const PendingInvitationRow = ({ email, gives, expiresAt, onResend, onRevoke }) =
|
|
|
35
36
|
size: "sm",
|
|
36
37
|
loading: busy,
|
|
37
38
|
onClick: () => void run(async () => setLink((await onResend()).link)),
|
|
38
|
-
children: "
|
|
39
|
+
children: text("sendAgain")
|
|
39
40
|
}),
|
|
40
41
|
/* @__PURE__ */ jsx(Button, {
|
|
41
42
|
size: "sm",
|
|
42
43
|
variant: "danger",
|
|
43
44
|
loading: busy,
|
|
44
45
|
onClick: () => void run(onRevoke),
|
|
45
|
-
children: "
|
|
46
|
+
children: text("revoke")
|
|
46
47
|
})
|
|
47
48
|
]
|
|
48
49
|
}),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Input } from "../primitives/input.js";
|
|
2
2
|
import { Button } from "../primitives/button.js";
|
|
3
3
|
import { AccountSection, SectionError } from "../account/account-section.js";
|
|
4
|
+
import { text } from "./messages.js";
|
|
4
5
|
import { Search } from "lucide-react";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
//#region src/lists/paged-search-list.tsx
|
|
@@ -34,7 +35,7 @@ const PagedSearchList = ({ title, description, searchLabel, placeholder, query,
|
|
|
34
35
|
className: "mt-3",
|
|
35
36
|
loading: list.loading,
|
|
36
37
|
onClick: () => void list.more(),
|
|
37
|
-
children: "
|
|
38
|
+
children: text("showMore")
|
|
38
39
|
})
|
|
39
40
|
]
|
|
40
41
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Fragment } from "react";
|
|
2
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
//#region src/locale/slotted.tsx
|
|
4
|
+
/**
|
|
5
|
+
* A built-in text with a `{}` for each element that goes in it, such as a highlighted address, rendered with the
|
|
6
|
+
* elements in their places in order: each language puts them where its sentence needs them.
|
|
7
|
+
*/
|
|
8
|
+
const slotted = (message, ...slots) => {
|
|
9
|
+
const parts = message.split("{}");
|
|
10
|
+
if (parts.length !== slots.length + 1) throw new Error(`The text "${message}" has ${parts.length - 1} places for ${slots.length} elements`);
|
|
11
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: parts.map((part, index) => /* @__PURE__ */ jsxs(Fragment, { children: [part, index < slots.length && slots[index]] }, index)) });
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { slotted };
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Segmented } from "../primitives/segmented.js";
|
|
2
2
|
import { Textarea } from "../primitives/textarea.js";
|
|
3
3
|
import { Markdown } from "./markdown.js";
|
|
4
|
+
import { text } from "./messages.js";
|
|
4
5
|
import { useState } from "react";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
//#region src/markdown/markdown-editor.tsx
|
|
7
|
-
const modes = [{
|
|
8
|
+
const modes = () => [{
|
|
8
9
|
value: "write",
|
|
9
|
-
label: "
|
|
10
|
+
label: text("write")
|
|
10
11
|
}, {
|
|
11
12
|
value: "preview",
|
|
12
|
-
label: "
|
|
13
|
+
label: text("preview")
|
|
13
14
|
}];
|
|
14
15
|
/**
|
|
15
16
|
* Markdown source in a box that grows with it, as GitHub edits a comment, and a switch to its rendered preview: the
|
|
@@ -23,7 +24,7 @@ const MarkdownEditor = ({ value, onChange, label, invalid, placeholder }) => {
|
|
|
23
24
|
className: "self-start",
|
|
24
25
|
children: /* @__PURE__ */ jsx(Segmented, {
|
|
25
26
|
value: mode,
|
|
26
|
-
options: modes,
|
|
27
|
+
options: modes(),
|
|
27
28
|
onChange: setMode,
|
|
28
29
|
label
|
|
29
30
|
})
|
|
@@ -37,7 +38,7 @@ const MarkdownEditor = ({ value, onChange, label, invalid, placeholder }) => {
|
|
|
37
38
|
className: "min-h-[7.5rem] rounded-md border border-border px-2.5 py-1.5",
|
|
38
39
|
children: value.trim() === "" ? /* @__PURE__ */ jsx("span", {
|
|
39
40
|
className: "text-faint-foreground",
|
|
40
|
-
children: "
|
|
41
|
+
children: text("nothingToPreview")
|
|
41
42
|
}) : /* @__PURE__ */ jsx(Markdown, { source: value })
|
|
42
43
|
})]
|
|
43
44
|
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineMessages } from "../locale/messages.js";
|
|
2
|
+
//#region src/markdown/messages.ts
|
|
3
|
+
const text = defineMessages({
|
|
4
|
+
en: {
|
|
5
|
+
write: "Write",
|
|
6
|
+
preview: "Preview",
|
|
7
|
+
nothingToPreview: "Nothing to preview"
|
|
8
|
+
},
|
|
9
|
+
nl: {
|
|
10
|
+
write: "Schrijven",
|
|
11
|
+
preview: "Voorbeeld",
|
|
12
|
+
nothingToPreview: "Niets om te tonen"
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
//#endregion
|
|
16
|
+
export { text };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useAuth } from "../auth/auth-provider.js";
|
|
2
|
+
import { text } from "./messages.js";
|
|
2
3
|
import { useAction } from "./use-action.js";
|
|
3
4
|
import { PagedSearchList } from "../lists/paged-search-list.js";
|
|
4
5
|
import { usePagedSearch } from "../lists/use-paged-search.js";
|
|
@@ -11,17 +12,17 @@ import { jsx } from "react/jsx-runtime";
|
|
|
11
12
|
const AllOrganizations = ({ basePath, currentId }) => {
|
|
12
13
|
const { session } = useAuth();
|
|
13
14
|
const [query, setQuery] = useState("");
|
|
14
|
-
const search = useCallback((
|
|
15
|
+
const search = useCallback((term, offset) => session.organizations.search(term, offset).then((page) => ({
|
|
15
16
|
items: page.organizations,
|
|
16
17
|
total: page.total
|
|
17
18
|
})), [session]);
|
|
18
19
|
const list = usePagedSearch(search, query);
|
|
19
20
|
const { busy, error, run } = useAction();
|
|
20
21
|
return /* @__PURE__ */ jsx(PagedSearchList, {
|
|
21
|
-
title: "
|
|
22
|
-
description: "
|
|
23
|
-
searchLabel: "
|
|
24
|
-
placeholder: "
|
|
22
|
+
title: text("allOrganizations"),
|
|
23
|
+
description: text("allOrganizationsDescription"),
|
|
24
|
+
searchLabel: text("findOrganization"),
|
|
25
|
+
placeholder: text("nameOrSlug"),
|
|
25
26
|
query,
|
|
26
27
|
onQuery: setQuery,
|
|
27
28
|
list,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cn } from "../lib/cn.js";
|
|
2
2
|
import { Checkbox } from "../primitives/checkbox.js";
|
|
3
|
+
import { text } from "./messages.js";
|
|
3
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
5
|
//#region src/organizations/app-roles-picker.tsx
|
|
5
6
|
/**
|
|
@@ -12,7 +13,7 @@ const AppRolesPicker = ({ roles, selected, grantable, disabled, onChange }) => /
|
|
|
12
13
|
const held = selected.includes(role.name);
|
|
13
14
|
const locked = disabled || !grantable.has(role.name);
|
|
14
15
|
return /* @__PURE__ */ jsxs("label", {
|
|
15
|
-
title: locked && !disabled ? "
|
|
16
|
+
title: locked && !disabled ? text("cannotChangeRole") : void 0,
|
|
16
17
|
className: cn("inline-flex items-center gap-1.5", locked && "text-muted-foreground"),
|
|
17
18
|
children: [/* @__PURE__ */ jsx(Checkbox, {
|
|
18
19
|
checked: held,
|