@protobase/ui 0.63.3 → 0.63.5
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/devices-section.js +1 -1
- package/dist/account/passkeys-section.js +1 -1
- package/dist/account/staff-sign-in-log.js +1 -1
- package/dist/activity-chart/activity-chart.js +2 -2
- package/dist/activity-chart/activity-tooltip.js +1 -1
- package/dist/app/app.js +1 -1
- package/dist/app/change-confirm/use-change-confirm.js +15 -18
- package/dist/app/charts/chart-view.js +1 -1
- package/dist/app/comments/comment-composer.js +1 -1
- package/dist/app/comments/comments-section.js +2 -2
- package/dist/app/create/create-record-form.js +1 -1
- package/dist/app/custom-section.js +1 -1
- package/dist/app/delete/use-delete-flow.js +1 -1
- package/dist/app/displays/board-column.js +1 -1
- package/dist/app/displays/calendar-display.js +1 -1
- package/dist/app/displays/cards-display.js +1 -1
- package/dist/app/displays/list-cards.js +1 -1
- package/dist/app/displays/timeline-display.js +1 -1
- package/dist/app/displays/use-board-move.js +1 -1
- package/dist/app/displays/use-calendar-move.js +1 -1
- package/dist/app/embedded-list/embedded-list.js +1 -1
- package/dist/app/field-editor.js +2 -2
- package/dist/app/gallery/gallery-section.js +1 -1
- package/dist/app/gallery/photo-details.js +1 -1
- package/dist/app/hand-order/hand-sorted-list.js +1 -1
- package/dist/app/hand-order/use-hand-order.js +1 -1
- package/dist/app/history/history-section.js +1 -1
- package/dist/app/incoming-card.js +1 -1
- package/dist/app/lines-plan.js +116 -0
- package/dist/app/list-edit/use-list-edits.js +1 -1
- package/dist/app/list-order.js +7 -1
- package/dist/app/new-version/new-version-toast.js +1 -1
- package/dist/app/pages/blocks/field.js +1 -1
- package/dist/app/pages/blocks/modal-form.js +2 -2
- package/dist/app/pages/blocks/settings.js +2 -2
- package/dist/app/pages/record-actions.js +1 -1
- package/dist/app/pages/use-run-action.js +1 -1
- package/dist/app/picker/picker-combobox.js +1 -1
- package/dist/app/record-chart/record-chart-section.js +2 -2
- package/dist/app/record-lines-cell.js +47 -0
- package/dist/app/record-lines.js +103 -26
- package/dist/app/record-messages.js +8 -2
- package/dist/app/record-page.js +18 -20
- package/dist/app/record-row/record-row-body.js +1 -1
- package/dist/app/record-row/record-row.js +1 -1
- package/dist/app/record-row/saved-record-row.js +1 -1
- package/dist/app/related-cards/related-card.js +1 -1
- package/dist/app/related-cards/related-cards.js +1 -1
- package/dist/app/related-section.js +1 -1
- package/dist/app/saved/saved-list.js +1 -1
- package/dist/app/searches/saved-search-rows.js +1 -1
- package/dist/app/searches/saved-search-section.js +1 -1
- package/dist/app/searches/saved-searches.js +1 -1
- package/dist/app/searches/search-controls.js +1 -1
- package/dist/app/searches/update-search-dialog.js +1 -1
- package/dist/app/searches/use-save-search.js +1 -1
- package/dist/app/sensitive-field.js +1 -1
- package/dist/app/use-lines-draft.js +94 -35
- package/dist/app/use-lines.js +21 -7
- package/dist/app/use-record-editor.js +15 -10
- package/dist/app/use-record-lines.js +47 -0
- package/dist/app-shell/profile-menu.js +2 -2
- package/dist/auth/forgot-password-form.js +1 -1
- package/dist/auth/sign-in-form.js +1 -1
- package/dist/calls/call-guests-panel.js +1 -1
- package/dist/calls/call-rings.js +1 -1
- package/dist/chat/chat-message.js +1 -1
- package/dist/data/use-list.d.ts +27 -1
- package/dist/data/use-list.js +10 -3
- package/dist/data-grid/cell-text.js +3 -3
- package/dist/data-grid/cells.js +3 -3
- package/dist/data-grid/grid-row.js +1 -1
- package/dist/forms/public-form-page.js +1 -1
- package/dist/index.js +3 -3
- package/dist/inline-child-table/columns.js +7 -2
- package/dist/inline-child-table/inline-child-table.js +29 -48
- package/dist/inline-child-table/line-row.js +16 -44
- package/dist/inline-child-table/messages.js +4 -18
- package/dist/notifications/bell/notification-item.js +1 -1
- package/dist/organizations/invitation-page.js +1 -1
- package/dist/package.js +1 -1
- package/dist/primitives/dialog.d.ts +7 -2
- package/dist/primitives/dialog.js +9 -4
- package/dist/record-view/field.js +1 -1
- package/dist/record-view/messages.js +0 -4
- package/dist/record-view/record-header.js +2 -2
- package/dist/shell/assets/app-BPv_SjnU.js +9 -0
- package/dist/shell/assets/{calls-CEW8hdPi.js → calls-CPiQcC70.js} +2 -2
- package/dist/shell/assets/index-Or2wt-ck.css +2 -0
- package/dist/shell/assets/{index-D7O0sMwH.js → index-_ZpZ2ro0.js} +2 -2
- package/dist/shell/assets/{records-map-BIDl1ull.js → records-map-DU29d6QK.js} +2 -2
- package/dist/shell/assets/shared-protobase-ui-Cab5nqST.js +2 -0
- package/dist/shell/assets/{vendor-xNCj9Gc_.js → vendor-iwLB0x-s.js} +39 -39
- package/dist/shell/index.html +5 -5
- package/dist/shell/protobase.shell.json +2 -2
- package/dist/shell/protobase.sw.js +2 -2
- package/dist/shell-source-maps/assets/app-BPv_SjnU.js.map +1 -0
- package/dist/shell-source-maps/assets/{calls-CEW8hdPi.js.map → calls-CPiQcC70.js.map} +1 -1
- package/dist/shell-source-maps/assets/{index-D7O0sMwH.js.map → index-_ZpZ2ro0.js.map} +1 -1
- package/dist/shell-source-maps/assets/{records-map-BIDl1ull.js.map → records-map-DU29d6QK.js.map} +1 -1
- package/dist/shell-source-maps/assets/{shared-protobase-ui-F5elmh4N.js.map → shared-protobase-ui-Cab5nqST.js.map} +1 -1
- package/dist/shell-source-maps/assets/vendor-iwLB0x-s.js.map +1 -0
- package/dist/status/status-dialog.js +1 -1
- package/package.json +4 -4
- package/dist/inline-child-table/number-cell.js +0 -25
- package/dist/inline-child-table/totals-footer.js +0 -39
- package/dist/mocks/invoices.js +0 -13
- package/dist/mocks/products.js +0 -167
- package/dist/shell/assets/app-Bm6h0l5D.js +0 -9
- package/dist/shell/assets/index-Be8nCyRW.css +0 -2
- package/dist/shell/assets/shared-protobase-ui-F5elmh4N.js +0 -2
- package/dist/shell-source-maps/assets/app-Bm6h0l5D.js.map +0 -1
- package/dist/shell-source-maps/assets/vendor-xNCj9Gc_.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { text } from "./messages.js";
|
|
2
2
|
import { Button } from "../primitives/button.js";
|
|
3
3
|
import { Dialog } from "../primitives/dialog.js";
|
|
4
|
-
import { formatDateTime } from "../format/date.js";
|
|
5
4
|
import { Badge } from "../primitives/badge.js";
|
|
5
|
+
import { formatDateTime } from "../format/date.js";
|
|
6
6
|
import { AccountSection, SectionError } from "./account-section.js";
|
|
7
7
|
import { authMessage } from "../auth/auth-messages.js";
|
|
8
8
|
import { deviceOf } from "./device-name.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { text } from "./messages.js";
|
|
2
2
|
import { Button } from "../primitives/button.js";
|
|
3
3
|
import { Dialog } from "../primitives/dialog.js";
|
|
4
|
+
import { Badge } from "../primitives/badge.js";
|
|
4
5
|
import { formatDate } from "../format/date.js";
|
|
5
6
|
import { Input } from "../primitives/input.js";
|
|
6
|
-
import { Badge } from "../primitives/badge.js";
|
|
7
7
|
import { AccountSection, SectionError } from "./account-section.js";
|
|
8
8
|
import { authMessage } from "../auth/auth-messages.js";
|
|
9
9
|
import { useState } from "react";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { text } from "./messages.js";
|
|
2
|
-
import { formatDateTime } from "../format/date.js";
|
|
3
2
|
import { Badge } from "../primitives/badge.js";
|
|
3
|
+
import { formatDateTime } from "../format/date.js";
|
|
4
4
|
import { AccountSection, SectionError } from "./account-section.js";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
//#region src/account/staff-sign-in-log.tsx
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { cn } from "../lib/cn.js";
|
|
2
2
|
import { useMediaQuery } from "../lib/use-media-query.js";
|
|
3
|
-
import { activitySeries } from "../mocks/activity.js";
|
|
4
|
-
import { formatInt } from "../format/number.js";
|
|
5
3
|
import { formatDayShort } from "../format/date.js";
|
|
4
|
+
import { formatInt } from "../format/number.js";
|
|
5
|
+
import { activitySeries } from "../mocks/activity.js";
|
|
6
6
|
import { Segmented } from "../primitives/segmented.js";
|
|
7
7
|
import { halfOverHalfDelta, totalCount } from "./activity-math.js";
|
|
8
8
|
import { ActivityTooltip } from "./activity-tooltip.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { formatInt } from "../format/number.js";
|
|
2
1
|
import { formatDate } from "../format/date.js";
|
|
2
|
+
import { formatInt } from "../format/number.js";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
//#region src/activity-chart/activity-tooltip.tsx
|
|
5
5
|
const ActivityTooltip = ({ active, payload, noun }) => {
|
package/dist/app/app.js
CHANGED
|
@@ -5,7 +5,6 @@ import { ApiProvider } from "../data/api-provider.js";
|
|
|
5
5
|
import { sourceStatusOf } from "../data/with-sources.js";
|
|
6
6
|
import { MetaGate, Notice, useAdminMeta } from "./meta-gate.js";
|
|
7
7
|
import { pageTabs, shownPageTab } from "./pages/page-tabs.js";
|
|
8
|
-
import { ToastProvider } from "../toasts/toast-provider.js";
|
|
9
8
|
import { humanize } from "../live/naming.js";
|
|
10
9
|
import { text } from "./messages.js";
|
|
11
10
|
import { Router, useRouter } from "./router.js";
|
|
@@ -17,6 +16,7 @@ import { isAdmin, userToShell } from "../auth/user-to-shell.js";
|
|
|
17
16
|
import { startErrorReporting } from "./error-reporting.js";
|
|
18
17
|
import { slotted } from "../locale/slotted.js";
|
|
19
18
|
import { CustomBoundary } from "./pages/custom-boundary.js";
|
|
19
|
+
import { ToastProvider } from "../toasts/toast-provider.js";
|
|
20
20
|
import { useSidebarNoticeShown } from "../app-shell/sidebar-notice.js";
|
|
21
21
|
import { AppShell } from "../app-shell/app-shell.js";
|
|
22
22
|
import { useSignInAddress } from "../auth/use-sign-in-address.js";
|
|
@@ -5,13 +5,12 @@ import { asksToConfirm } from "./asks-to-confirm.js";
|
|
|
5
5
|
import { text } from "./messages.js";
|
|
6
6
|
import { useState } from "react";
|
|
7
7
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import { createPortal } from "react-dom";
|
|
9
8
|
//#region src/app/change-confirm/use-change-confirm.tsx
|
|
10
9
|
/**
|
|
11
10
|
* Whether `node` sits in the question a change asks. The dialog is portalled to the body, so a list cell does not clip
|
|
12
11
|
* it, while its events still bubble through the editor that asked it.
|
|
13
12
|
*/
|
|
14
|
-
const inChangeConfirm = (node) => node instanceof Element && node.closest("[data-change-confirm]") !== null;
|
|
13
|
+
const inChangeConfirm = (node) => node instanceof Element && node.closest("[data-dialog=\"change-confirm\"]") !== null;
|
|
15
14
|
/**
|
|
16
15
|
* The field's `onChange`, asking the view's `.confirm()` question before it hands on a change that `asksToConfirm`
|
|
17
16
|
* picks out, and the dialog that asks it. Cancelling drops the change, so the field keeps its value.
|
|
@@ -29,22 +28,20 @@ const useChangeConfirm = ({ field, hints, value, stored, onChange }) => {
|
|
|
29
28
|
};
|
|
30
29
|
return {
|
|
31
30
|
onChange: change,
|
|
32
|
-
dialog: pending &&
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
})
|
|
47
|
-
}), document.body)
|
|
31
|
+
dialog: pending && /* @__PURE__ */ jsx(Dialog, {
|
|
32
|
+
name: "change-confirm",
|
|
33
|
+
title: text("title", hints?.label ?? humanize(field.name)),
|
|
34
|
+
description: hints?.confirm,
|
|
35
|
+
onClose: cancel,
|
|
36
|
+
actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button, {
|
|
37
|
+
onClick: cancel,
|
|
38
|
+
children: text("cancel")
|
|
39
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
40
|
+
variant: "primary",
|
|
41
|
+
onClick: confirm,
|
|
42
|
+
children: text("change")
|
|
43
|
+
})] })
|
|
44
|
+
})
|
|
48
45
|
};
|
|
49
46
|
};
|
|
50
47
|
//#endregion
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useAdminMeta } from "../meta-gate.js";
|
|
2
2
|
import { viewerZone } from "../../format/zone.js";
|
|
3
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
4
3
|
import { labelFieldOf } from "../../live/model-helpers.js";
|
|
4
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
5
5
|
import { useAggregate } from "../../data/use-aggregates.js";
|
|
6
6
|
import { text } from "./messages.js";
|
|
7
7
|
import { periodPoints, valueSlices } from "./chart-groups.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useClient } from "../../data/api-provider.js";
|
|
2
2
|
import { Button } from "../../primitives/button.js";
|
|
3
|
-
import { useToast } from "../../toasts/toast-provider.js";
|
|
4
3
|
import { refusalReason } from "../displays/board-columns.js";
|
|
5
4
|
import { useNavigationGuard } from "../router.js";
|
|
5
|
+
import { useToast } from "../../toasts/toast-provider.js";
|
|
6
6
|
import { mentionedIds } from "../../mentions/mention-text.js";
|
|
7
7
|
import { MentionBox, emptyDraft } from "../../mentions/mention-box.js";
|
|
8
8
|
import { usePostComment } from "./use-post-comment.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Button } from "../../primitives/button.js";
|
|
2
|
-
import { formatDateTime, formatRelativeTime } from "../../format/date.js";
|
|
3
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
4
2
|
import { Avatar } from "../../primitives/avatar.js";
|
|
5
3
|
import { Section } from "../../record-view/section.js";
|
|
4
|
+
import { formatDateTime, formatRelativeTime } from "../../format/date.js";
|
|
5
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
6
6
|
import { ErrorBanner } from "../error-banner.js";
|
|
7
7
|
import { hueOf, initialsOf } from "../../auth/user-to-shell.js";
|
|
8
8
|
import { CommentBody } from "./comment-body.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Field } from "../../record-view/field.js";
|
|
2
1
|
import { Section } from "../../record-view/section.js";
|
|
2
|
+
import { Field } from "../../record-view/field.js";
|
|
3
3
|
import { text } from "./messages.js";
|
|
4
4
|
import { Form } from "./form.js";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Section } from "../record-view/section.js";
|
|
2
|
-
import { SidebarCard } from "../record-view/record-sidebar.js";
|
|
3
2
|
import { text } from "./messages.js";
|
|
3
|
+
import { SidebarCard } from "../record-view/record-sidebar.js";
|
|
4
4
|
import { useProjectUi } from "./pages/project-ui.js";
|
|
5
5
|
import { Problem } from "./pages/problem.js";
|
|
6
6
|
import { slotted } from "../locale/slotted.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useClient } from "../../data/api-provider.js";
|
|
2
2
|
import { useAdminMeta } from "../meta-gate.js";
|
|
3
|
-
import { useToast } from "../../toasts/toast-provider.js";
|
|
4
3
|
import { humanize } from "../../live/naming.js";
|
|
5
4
|
import { useAppAddress } from "../use-app-address.js";
|
|
5
|
+
import { useToast } from "../../toasts/toast-provider.js";
|
|
6
6
|
import { text } from "./messages.js";
|
|
7
7
|
import { blockedDelete } from "./blocked-delete.js";
|
|
8
8
|
import { BulkDeleteDialog, ConfirmDeleteDialog, ConflictDialog } from "./dialogs.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { formatTag } from "../../locale/active-locale.js";
|
|
2
2
|
import { cn } from "../../lib/cn.js";
|
|
3
3
|
import { Button } from "../../primitives/button.js";
|
|
4
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
5
4
|
import { humanize } from "../../live/naming.js";
|
|
6
5
|
import { text } from "./messages.js";
|
|
7
6
|
import { boardCard } from "./board-columns.js";
|
|
7
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
8
8
|
import { ErrorBanner } from "../error-banner.js";
|
|
9
9
|
import { rowAllows } from "../permissions.js";
|
|
10
10
|
import { ValueBadge } from "../value-badge.js";
|
|
@@ -2,8 +2,8 @@ import { cn } from "../../lib/cn.js";
|
|
|
2
2
|
import { usePermissions } from "../meta-gate.js";
|
|
3
3
|
import { dayIn, viewerZone } from "../../format/zone.js";
|
|
4
4
|
import { formatDate, formatWeekday } from "../../format/date.js";
|
|
5
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
6
5
|
import { text } from "./messages.js";
|
|
6
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
7
7
|
import { AppLink } from "../use-app-address.js";
|
|
8
8
|
import { ErrorBanner } from "../error-banner.js";
|
|
9
9
|
import { can, rowAllows } from "../permissions.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cn } from "../../lib/cn.js";
|
|
2
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
3
2
|
import { humanize } from "../../live/naming.js";
|
|
4
3
|
import { text } from "./messages.js";
|
|
4
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
5
5
|
import { RecordCard } from "./record-card.js";
|
|
6
6
|
import { DisplayFooter, DisplayState } from "./display-frame.js";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
2
1
|
import { humanize } from "../../live/naming.js";
|
|
3
2
|
import { text } from "./messages.js";
|
|
4
3
|
import { displayRow } from "./list-displays.js";
|
|
4
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
5
5
|
import { ErrorBanner } from "../error-banner.js";
|
|
6
6
|
import { RecordCard } from "./record-card.js";
|
|
7
7
|
import { VirtualCards } from "./virtual-cards.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { usePermissions } from "../meta-gate.js";
|
|
2
2
|
import { dayIn, viewerZone } from "../../format/zone.js";
|
|
3
3
|
import { formatDate } from "../../format/date.js";
|
|
4
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
5
4
|
import { humanize } from "../../live/naming.js";
|
|
6
5
|
import { text } from "./messages.js";
|
|
6
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
7
7
|
import { ErrorBanner } from "../error-banner.js";
|
|
8
8
|
import { can, rowAllows } from "../permissions.js";
|
|
9
9
|
import { addDays, inStartOrder, recordDays } from "./calendar-range.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useClient } from "../../data/api-provider.js";
|
|
2
|
-
import { useToast } from "../../toasts/toast-provider.js";
|
|
3
2
|
import { recordKey } from "../../live/model-helpers.js";
|
|
4
3
|
import { text } from "./messages.js";
|
|
5
4
|
import { refusalReason } from "./board-columns.js";
|
|
5
|
+
import { useToast } from "../../toasts/toast-provider.js";
|
|
6
6
|
import { useRefreshResource } from "../pages/use-layout-data.js";
|
|
7
7
|
import { dropWrite } from "./board-drop.js";
|
|
8
8
|
import { text as text$1 } from "../hand-order/messages.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useClient } from "../../data/api-provider.js";
|
|
2
2
|
import { formatDate } from "../../format/date.js";
|
|
3
|
-
import { useToast } from "../../toasts/toast-provider.js";
|
|
4
3
|
import { recordKey } from "../../live/model-helpers.js";
|
|
5
4
|
import { text } from "./messages.js";
|
|
6
5
|
import { refusalReason } from "./board-columns.js";
|
|
6
|
+
import { useToast } from "../../toasts/toast-provider.js";
|
|
7
7
|
import { useRefreshResource } from "../pages/use-layout-data.js";
|
|
8
8
|
import { movedPatch } from "./calendar-range.js";
|
|
9
9
|
import { useState } from "react";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useAdminMeta, usePermissions } from "../meta-gate.js";
|
|
2
2
|
import { useIsDesktop, useIsXs } from "../../lib/use-media-query.js";
|
|
3
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
4
3
|
import { humanize } from "../../live/naming.js";
|
|
5
4
|
import { listColumnNames } from "../../live/columns-from-model.js";
|
|
6
5
|
import { displayRow, loadedFields, shownDisplay } from "../displays/list-displays.js";
|
|
7
6
|
import { defaultOrderBy, parseSort, sortToOrderBy } from "../list-order.js";
|
|
7
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
8
8
|
import { AppLink, useAppAddress } from "../use-app-address.js";
|
|
9
9
|
import { ErrorBanner } from "../error-banner.js";
|
|
10
10
|
import { useProjectUi } from "../pages/project-ui.js";
|
package/dist/app/field-editor.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { cn } from "../lib/cn.js";
|
|
2
2
|
import { buttonClass } from "../primitives/button.js";
|
|
3
|
-
import { useFieldControl } from "../primitives/field-control.js";
|
|
4
|
-
import { Input } from "../primitives/input.js";
|
|
5
3
|
import { humanize } from "../live/naming.js";
|
|
6
4
|
import { isMarkdown } from "../markdown/markdown-hint.js";
|
|
7
5
|
import { contactFormat, contactInputProps } from "../live/contact-links.js";
|
|
8
6
|
import { displayValue, valueTitle } from "../live/display-value.js";
|
|
9
7
|
import { text } from "./messages.js";
|
|
10
8
|
import { AppLink } from "./use-app-address.js";
|
|
9
|
+
import { useFieldControl } from "../primitives/field-control.js";
|
|
10
|
+
import { Input } from "../primitives/input.js";
|
|
11
11
|
import { fromDraft, isEditable, toFieldDraft } from "../live/field-values.js";
|
|
12
12
|
import { Switch } from "../primitives/switch.js";
|
|
13
13
|
import { Textarea } from "../primitives/textarea.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { cn } from "../../lib/cn.js";
|
|
2
2
|
import { useAdminMeta, usePermissions } from "../meta-gate.js";
|
|
3
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
4
3
|
import { Section } from "../../record-view/section.js";
|
|
5
4
|
import { shownImage } from "../../live/file-values.js";
|
|
6
5
|
import { humanize } from "../../live/naming.js";
|
|
6
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
7
7
|
import { ErrorBanner } from "../error-banner.js";
|
|
8
8
|
import { FileImage } from "../../live/file-image.js";
|
|
9
9
|
import { galleryTiles } from "./gallery-layout.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
2
1
|
import { humanize } from "../../live/naming.js";
|
|
2
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
3
3
|
import { AppLink } from "../use-app-address.js";
|
|
4
4
|
import { SpecTable } from "../../record-view/spec-table.js";
|
|
5
5
|
import { ErrorBanner } from "../error-banner.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useAdminMeta } from "../meta-gate.js";
|
|
2
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
3
2
|
import { recordKey, recordTitle } from "../../live/model-helpers.js";
|
|
4
3
|
import { loadedFields } from "../displays/list-displays.js";
|
|
4
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
5
5
|
import { useAppAddress } from "../use-app-address.js";
|
|
6
6
|
import { ErrorBanner } from "../error-banner.js";
|
|
7
7
|
import { useProjectUi } from "../pages/project-ui.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { keys } from "../../data/query-keys.js";
|
|
2
2
|
import { useClient } from "../../data/api-provider.js";
|
|
3
3
|
import { useAdminMeta } from "../meta-gate.js";
|
|
4
|
-
import { useToast } from "../../toasts/toast-provider.js";
|
|
5
4
|
import { recordId, recordKey, recordTitle } from "../../live/model-helpers.js";
|
|
6
5
|
import { refusalReason } from "../displays/board-columns.js";
|
|
7
6
|
import { displayRow } from "../displays/list-displays.js";
|
|
7
|
+
import { useToast } from "../../toasts/toast-provider.js";
|
|
8
8
|
import { useRefreshResource } from "../pages/use-layout-data.js";
|
|
9
9
|
import { listLabels, withLabels } from "../../live/relation-labels.js";
|
|
10
10
|
import { text } from "./messages.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Button } from "../../primitives/button.js";
|
|
2
|
+
import { Section } from "../../record-view/section.js";
|
|
2
3
|
import { formatDateTime, formatRelativeTime } from "../../format/date.js";
|
|
3
4
|
import { Skeleton } from "../../primitives/skeleton.js";
|
|
4
|
-
import { Section } from "../../record-view/section.js";
|
|
5
5
|
import { ErrorBanner } from "../error-banner.js";
|
|
6
6
|
import { describeChange } from "./describe-change.js";
|
|
7
7
|
import { useRecordHistory } from "./use-record-history.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useAdminMeta } from "./meta-gate.js";
|
|
2
2
|
import { formatInt } from "../format/number.js";
|
|
3
3
|
import { Skeleton } from "../primitives/skeleton.js";
|
|
4
|
-
import { SidebarCard } from "../record-view/record-sidebar.js";
|
|
5
4
|
import { AppLink } from "./use-app-address.js";
|
|
5
|
+
import { SidebarCard } from "../record-view/record-sidebar.js";
|
|
6
6
|
import { text } from "./record-messages.js";
|
|
7
7
|
import { incomingAddress, incomingRelations } from "./incoming-relations.js";
|
|
8
8
|
import { useIncomingCounts } from "./use-incoming-counts.js";
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { recordId, recordKey } from "../live/model-helpers.js";
|
|
2
|
+
import { differs, toPatchValue } from "../live/field-values.js";
|
|
3
|
+
import { encodeKey } from "@protobase/schema/internal";
|
|
4
|
+
//#region src/app/lines-plan.ts
|
|
5
|
+
const emptyLinesState = {
|
|
6
|
+
added: [],
|
|
7
|
+
edits: {},
|
|
8
|
+
removed: []
|
|
9
|
+
};
|
|
10
|
+
/** The ids on screen, in order: the stored lines that are kept, then the new ones, as far as `order` does not say otherwise. */
|
|
11
|
+
const shownIds = (storedIds, state) => {
|
|
12
|
+
const kept = [...storedIds.filter((id) => !state.removed.includes(id)), ...state.added];
|
|
13
|
+
if (!state.order) return kept;
|
|
14
|
+
return [...state.order.filter((id) => kept.includes(id)), ...kept.filter((id) => !state.order.includes(id))];
|
|
15
|
+
};
|
|
16
|
+
/** The edited fields that differ from the stored line, as the API takes them. */
|
|
17
|
+
const changedData = (model, edits, line) => Object.fromEntries(Object.entries(edits).flatMap(([name, draft]) => {
|
|
18
|
+
const field = model.fields[name];
|
|
19
|
+
return field && differs(field, draft, line[name]) ? [[name, toPatchValue(field, draft)]] : [];
|
|
20
|
+
}));
|
|
21
|
+
/** The fields filled in on a new line; the database's defaults fill the rest. */
|
|
22
|
+
const filledData = (model, edits) => Object.fromEntries(Object.entries(edits).flatMap(([name, draft]) => {
|
|
23
|
+
const field = model.fields[name];
|
|
24
|
+
if (!field || field.type !== "boolean" && String(draft ?? "").trim() === "") return [];
|
|
25
|
+
return [[name, toPatchValue(field, draft)]];
|
|
26
|
+
}));
|
|
27
|
+
/**
|
|
28
|
+
* The batch that writes the lines as they are on screen: removed lines are deleted, edited ones updated with the ETag
|
|
29
|
+
* they were read with, and new ones created with the parent's key and their place. New lines after the kept ones are
|
|
30
|
+
* numbered on from them; new lines between kept ones need the kept ones out of the way first, so those are moved above
|
|
31
|
+
* every position in use, the new lines created at their places, and the kept ones moved to theirs. A kept line the batch
|
|
32
|
+
* wrote before is moved with `*`, as its ETag was checked by that earlier operation of the same transaction.
|
|
33
|
+
*/
|
|
34
|
+
const planLinesOps = ({ model, position, link, stored, state }) => {
|
|
35
|
+
const plan = {
|
|
36
|
+
ops: [],
|
|
37
|
+
rows: []
|
|
38
|
+
};
|
|
39
|
+
const push = (op, row) => {
|
|
40
|
+
plan.ops.push(op);
|
|
41
|
+
plan.rows.push(row);
|
|
42
|
+
};
|
|
43
|
+
const byId = new Map(stored.map((line) => [recordId(model, line), line]));
|
|
44
|
+
const storedIds = [...byId.keys()];
|
|
45
|
+
const final = shownIds(storedIds, state);
|
|
46
|
+
const keyOf = (id) => recordKey(model, byId.get(id));
|
|
47
|
+
const etagOf = (id) => {
|
|
48
|
+
const etag = byId.get(id).etag;
|
|
49
|
+
return typeof etag === "string" ? etag : void 0;
|
|
50
|
+
};
|
|
51
|
+
for (const id of state.removed) {
|
|
52
|
+
if (!byId.has(id)) continue;
|
|
53
|
+
const etag = etagOf(id);
|
|
54
|
+
push({
|
|
55
|
+
op: "delete",
|
|
56
|
+
resource: model.name,
|
|
57
|
+
key: keyOf(id),
|
|
58
|
+
...etag && { etag }
|
|
59
|
+
}, id);
|
|
60
|
+
}
|
|
61
|
+
const written = /* @__PURE__ */ new Set();
|
|
62
|
+
for (const [id, edits] of Object.entries(state.edits)) {
|
|
63
|
+
if (!byId.has(id) || state.removed.includes(id)) continue;
|
|
64
|
+
const data = changedData(model, edits, byId.get(id));
|
|
65
|
+
if (Object.keys(data).length === 0) continue;
|
|
66
|
+
const etag = etagOf(id);
|
|
67
|
+
push({
|
|
68
|
+
op: "update",
|
|
69
|
+
resource: model.name,
|
|
70
|
+
key: keyOf(id),
|
|
71
|
+
data,
|
|
72
|
+
...etag && { etag }
|
|
73
|
+
}, id);
|
|
74
|
+
written.add(id);
|
|
75
|
+
}
|
|
76
|
+
const kept = final.filter((id) => byId.has(id));
|
|
77
|
+
const added = final.filter((id) => !byId.has(id));
|
|
78
|
+
const etags = (ids, wildcard) => Object.fromEntries(ids.flatMap((id) => {
|
|
79
|
+
const etag = wildcard || written.has(id) ? "*" : etagOf(id);
|
|
80
|
+
return etag ? [[encodeKey(keyOf(id)), etag]] : [];
|
|
81
|
+
}));
|
|
82
|
+
const reorder = (keys, start, tags) => ({
|
|
83
|
+
op: "reorder",
|
|
84
|
+
resource: model.name,
|
|
85
|
+
field: position,
|
|
86
|
+
keys,
|
|
87
|
+
...start !== 1 && { start },
|
|
88
|
+
etags: tags
|
|
89
|
+
});
|
|
90
|
+
const create = (id, place, ref) => ({
|
|
91
|
+
op: "create",
|
|
92
|
+
resource: model.name,
|
|
93
|
+
data: {
|
|
94
|
+
...filledData(model, state.edits[id] ?? {}),
|
|
95
|
+
[link.field]: link.value,
|
|
96
|
+
[position]: place
|
|
97
|
+
},
|
|
98
|
+
...ref && { ref }
|
|
99
|
+
});
|
|
100
|
+
const placeOf = (line) => Number(line[position]) || 0;
|
|
101
|
+
const moved = kept.some((id, index) => id !== storedIds.filter((each) => kept.includes(each))[index]);
|
|
102
|
+
if (added.every((id) => final.indexOf(id) >= kept.length)) {
|
|
103
|
+
if (moved) push(reorder(kept.map(keyOf), 1, etags(kept, false)));
|
|
104
|
+
const last = moved ? kept.length : Math.max(0, ...kept.map((id) => placeOf(byId.get(id))));
|
|
105
|
+
added.forEach((id, index) => push(create(id, last + 1 + index), id));
|
|
106
|
+
return plan;
|
|
107
|
+
}
|
|
108
|
+
const above = Math.max(final.length, ...stored.map(placeOf)) + 1;
|
|
109
|
+
if (kept.length > 0) push(reorder(kept.map(keyOf), above, etags(kept, false)));
|
|
110
|
+
const refOf = (id) => `line${added.indexOf(id) + 1}`;
|
|
111
|
+
for (const id of added) push(create(id, final.indexOf(id) + 1, refOf(id)), id);
|
|
112
|
+
push(reorder(final.map((id) => byId.has(id) ? keyOf(id) : { $ref: refOf(id) }), 1, etags(kept, true)));
|
|
113
|
+
return plan;
|
|
114
|
+
};
|
|
115
|
+
//#endregion
|
|
116
|
+
export { emptyLinesState, planLinesOps, shownIds };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { keys } from "../../data/query-keys.js";
|
|
2
2
|
import { useClient } from "../../data/api-provider.js";
|
|
3
|
-
import { useToast } from "../../toasts/toast-provider.js";
|
|
4
3
|
import { recordKey } from "../../live/model-helpers.js";
|
|
4
|
+
import { useToast } from "../../toasts/toast-provider.js";
|
|
5
5
|
import { text } from "./messages.js";
|
|
6
6
|
import { useRef, useState } from "react";
|
|
7
7
|
import { encodeKey } from "@protobase/schema/internal";
|
package/dist/app/list-order.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
//#region src/app/list-order.ts
|
|
2
|
+
/**
|
|
3
|
+
* The order a list opens in: the view's sort, else the primary key's when it is sortable. Otherwise none, as the API
|
|
4
|
+
* refuses a sort by a field that is not sortable and orders a list without one by its key anyway.
|
|
5
|
+
*/
|
|
2
6
|
const defaultOrderBy = (model, view) => {
|
|
3
7
|
const sort = view?.list?.sort?.[0];
|
|
4
|
-
|
|
8
|
+
if (sort) return `${sort[0]} ${sort[1]}`;
|
|
9
|
+
const key = model.primaryKey[0];
|
|
10
|
+
return model.fields[key]?.sortable ? `${key} asc` : "";
|
|
5
11
|
};
|
|
6
12
|
const parseSort = (orderBy) => {
|
|
7
13
|
const [columnId = "", direction] = orderBy.trim().split(/\s+/);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useAdminMeta } from "../meta-gate.js";
|
|
2
|
-
import { useToast } from "../../toasts/toast-provider.js";
|
|
3
2
|
import { useRouter } from "../router.js";
|
|
3
|
+
import { useToast } from "../../toasts/toast-provider.js";
|
|
4
4
|
import { text } from "./messages.js";
|
|
5
5
|
import { useModalOpen } from "./use-modal-open.js";
|
|
6
6
|
import { useEffect, useState } from "react";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useAdminMeta } from "../../meta-gate.js";
|
|
2
|
-
import { Skeleton } from "../../../primitives/skeleton.js";
|
|
3
2
|
import { humanize } from "../../../live/naming.js";
|
|
3
|
+
import { Skeleton } from "../../../primitives/skeleton.js";
|
|
4
4
|
import { useLayoutRecord } from "../record-scope.js";
|
|
5
5
|
import { propsOf } from "./block-props.js";
|
|
6
6
|
import { FieldValue } from "../field-value.js";
|
|
@@ -2,15 +2,15 @@ import { useClient } from "../../../data/api-provider.js";
|
|
|
2
2
|
import { useAdminMeta, usePermissions } from "../../meta-gate.js";
|
|
3
3
|
import { Button } from "../../../primitives/button.js";
|
|
4
4
|
import { Dialog } from "../../../primitives/dialog.js";
|
|
5
|
-
import { useToast } from "../../../toasts/toast-provider.js";
|
|
6
|
-
import { Field } from "../../../record-view/field.js";
|
|
7
5
|
import { humanize } from "../../../live/naming.js";
|
|
8
6
|
import { useNavigationGuard } from "../../router.js";
|
|
7
|
+
import { Field } from "../../../record-view/field.js";
|
|
9
8
|
import { createBody, isChosen } from "../../create/create-values.js";
|
|
10
9
|
import { ErrorBanner } from "../../error-banner.js";
|
|
11
10
|
import { text } from "../messages.js";
|
|
12
11
|
import { FieldEditor } from "../../field-editor.js";
|
|
13
12
|
import { useLayoutRecord } from "../record-scope.js";
|
|
13
|
+
import { useToast } from "../../../toasts/toast-provider.js";
|
|
14
14
|
import { can } from "../../permissions.js";
|
|
15
15
|
import { useFirstRecord, useRefreshResource } from "../use-layout-data.js";
|
|
16
16
|
import { propsOf } from "./block-props.js";
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { useClient } from "../../../data/api-provider.js";
|
|
2
2
|
import { useAdminMeta, usePermissions } from "../../meta-gate.js";
|
|
3
3
|
import { Button } from "../../../primitives/button.js";
|
|
4
|
+
import { humanize } from "../../../live/naming.js";
|
|
4
5
|
import { Skeleton } from "../../../primitives/skeleton.js";
|
|
5
|
-
import { useToast } from "../../../toasts/toast-provider.js";
|
|
6
6
|
import { Field } from "../../../record-view/field.js";
|
|
7
|
-
import { humanize } from "../../../live/naming.js";
|
|
8
7
|
import { differs } from "../../../live/field-values.js";
|
|
9
8
|
import { createBody } from "../../create/create-values.js";
|
|
10
9
|
import { ErrorBanner } from "../../error-banner.js";
|
|
11
10
|
import { text } from "../messages.js";
|
|
12
11
|
import { FieldEditor } from "../../field-editor.js";
|
|
12
|
+
import { useToast } from "../../../toasts/toast-provider.js";
|
|
13
13
|
import { can } from "../../permissions.js";
|
|
14
14
|
import { scopeOf, useFirstRecord, useRefreshResource } from "../use-layout-data.js";
|
|
15
15
|
import { propsOf } from "./block-props.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ActionRail } from "../../record-view/action-rail.js";
|
|
2
1
|
import { RouteLink } from "../../primitives/route-link.js";
|
|
3
2
|
import { AppLink, useAppAddress } from "../use-app-address.js";
|
|
3
|
+
import { ActionRail } from "../../record-view/action-rail.js";
|
|
4
4
|
import { ActionMenu } from "../../record-view/action-menu.js";
|
|
5
5
|
import { ActionPrompt, asksFirst, isDanger } from "./action-prompt.js";
|
|
6
6
|
import { useActionRunner } from "./use-run-action.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useClient, useResourceClient } from "../../data/api-provider.js";
|
|
2
2
|
import { useAdminMeta, usePermissions } from "../meta-gate.js";
|
|
3
|
-
import { useToast } from "../../toasts/toast-provider.js";
|
|
4
3
|
import { useAppAddress } from "../use-app-address.js";
|
|
5
4
|
import { useProjectUi } from "./project-ui.js";
|
|
6
5
|
import { text } from "./messages.js";
|
|
6
|
+
import { useToast } from "../../toasts/toast-provider.js";
|
|
7
7
|
import { can } from "../permissions.js";
|
|
8
8
|
import { actionApplies } from "./action-when.js";
|
|
9
9
|
import { actionFor, linkTarget, openLink } from "./action-href.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cn } from "../../lib/cn.js";
|
|
2
|
-
import { Input } from "../../primitives/input.js";
|
|
3
2
|
import { text } from "../messages.js";
|
|
3
|
+
import { Input } from "../../primitives/input.js";
|
|
4
4
|
import { useEffect, useId, useRef, useState } from "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
//#region src/app/picker/picker-combobox.tsx
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useAdminMeta } from "../meta-gate.js";
|
|
2
|
-
import { viewerZone } from "../../format/zone.js";
|
|
3
|
-
import { Skeleton } from "../../primitives/skeleton.js";
|
|
4
2
|
import { Section } from "../../record-view/section.js";
|
|
3
|
+
import { viewerZone } from "../../format/zone.js";
|
|
5
4
|
import { humanize } from "../../live/naming.js";
|
|
5
|
+
import { Skeleton } from "../../primitives/skeleton.js";
|
|
6
6
|
import { Segmented } from "../../primitives/segmented.js";
|
|
7
7
|
import { useAggregates } from "../../data/use-aggregates.js";
|
|
8
8
|
import { PeriodChart } from "../charts/period-chart.js";
|