@protobase/ui 0.19.9 → 0.19.11
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/app/app.js +4 -4
- package/dist/app/create/create-offered.js +9 -0
- package/dist/app/create/create-page.js +3 -3
- package/dist/app/create/create-record-form.js +26 -62
- package/dist/app/create/create-route.js +29 -0
- package/dist/app/create/form.d.ts +30 -0
- package/dist/app/create/form.js +72 -0
- package/dist/app/custom-section.js +1 -1
- package/dist/app/displays/map-display.js +1 -1
- package/dist/app/displays/record-card.js +3 -3
- package/dist/app/displays/record-link.js +1 -1
- package/dist/app/displays/use-map-records.js +2 -2
- package/dist/app/embedded-list/embedded-columns.js +2 -2
- package/dist/app/embedded-list/embedded-list.js +5 -5
- package/dist/app/embedded-list/use-embedded-rows.js +2 -2
- package/dist/app/field-editor.js +7 -7
- package/dist/app/gallery/gallery-section.js +1 -1
- package/dist/app/gallery/photo-details.js +2 -2
- package/dist/app/list-page.js +18 -17
- package/dist/app/pages/blocks/card-row.js +2 -2
- package/dist/app/pages/blocks/field.js +2 -2
- package/dist/app/pages/blocks/link.js +1 -1
- package/dist/app/pages/blocks/modal-form.js +6 -6
- package/dist/app/pages/blocks/progress.js +1 -1
- package/dist/app/pages/blocks/record-card.js +2 -2
- package/dist/app/pages/blocks/record-row.js +1 -1
- package/dist/app/pages/blocks/show.js +2 -2
- package/dist/app/pages/blocks/stat.js +3 -3
- package/dist/app/pages/blocks/table.js +1 -1
- package/dist/app/pages/field-value.js +3 -3
- package/dist/app/pages/record-actions.js +2 -2
- package/dist/app/pages/use-run-action.js +2 -2
- package/dist/app/record-page.js +8 -8
- package/dist/app/record-row/record-row-body.js +2 -2
- package/dist/app/record-row/saved-record-row.js +1 -1
- package/dist/app/related-section.js +1 -1
- package/dist/app/runtime/runtime-status.js +30 -6
- package/dist/app/runtime/runtime-update-dialog.js +66 -0
- package/dist/app/runtime/runtime-update.js +10 -46
- package/dist/app/runtime/use-runtime-status.js +3 -5
- package/dist/app/searches/saved-search-rows.js +1 -1
- package/dist/app/searches/saved-search-section.js +2 -2
- package/dist/app/searches/saved-searches.js +2 -2
- package/dist/app/searches/search-controls.js +1 -1
- package/dist/app/searches/search-name-dialog.js +1 -1
- package/dist/app/searches/update-search-dialog.js +2 -2
- package/dist/app/searches/use-filter-chips.js +1 -1
- package/dist/app/searches/use-save-search.js +2 -2
- package/dist/app/searches/use-saved-searches.js +1 -1
- package/dist/app/searches/use-search-row.js +1 -1
- package/dist/app/sensitive-field.js +1 -1
- package/dist/app/use-app-address.js +1 -1
- package/dist/app/value-badge.js +1 -1
- package/dist/auth/sign-in-prompt.js +1 -1
- package/dist/data-grid/cells.js +1 -1
- package/dist/format/date.js +7 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +10 -2
- package/dist/live/columns-from-model.js +1 -1
- package/dist/live/grid-loader.js +1 -1
- package/dist/live/use-filter-config.js +1 -1
- package/dist/markdown/markdown-editor.js +1 -1
- package/dist/package.js +1 -1
- package/dist/primitives/choices.d.ts +22 -0
- package/dist/primitives/choices.js +33 -0
- package/dist/primitives/dialog.d.ts +15 -0
- package/dist/primitives/menu-select.d.ts +14 -0
- package/dist/primitives/segmented.d.ts +23 -0
- package/dist/primitives/textarea.d.ts +9 -0
- package/dist/record-view/field.d.ts +27 -0
- package/dist/record-view/section.d.ts +10 -0
- package/dist/shell/assets/app-DQRL4UH0.js +69 -0
- package/dist/shell/assets/{index-d-04ZYJt.js → index-C15EeI8X.js} +1 -1
- package/dist/shell/assets/{index-DLVcUwwG.css → index-DxV5Rp_F.css} +1 -1
- package/dist/shell/assets/{maplibre-BACAMuVa.js → maplibre-CqK5gKEr.js} +2 -2
- package/dist/shell/assets/{markdown-content-CHU2BTHn.js → markdown-content-DS62HyvW.js} +1 -1
- package/dist/shell/assets/{record-map-B6USTMW8.js → record-map-Cp9MkzTk.js} +1 -1
- package/dist/shell/assets/{records-map-DVwLP4Ey.js → records-map-BQm4s9Cw.js} +1 -1
- package/dist/shell/assets/shared-protobase-ui-Cqe5I8UQ.js +1 -0
- package/dist/shell/index.html +4 -4
- package/dist/shell/protobase.shell.json +1 -1
- package/package.json +4 -4
- package/dist/shell/assets/app-CB1ojooV.js +0 -69
- package/dist/shell/assets/shared-protobase-ui-BEvX9eTO.js +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useAdminMeta } from "../../meta-gate.js";
|
|
2
|
-
import { RecordRowBody } from "../../record-row/record-row-body.js";
|
|
3
2
|
import { propsOf } from "./block-props.js";
|
|
4
3
|
import { CardFrame } from "./card-frame.js";
|
|
4
|
+
import { RecordRowBody } from "../../record-row/record-row-body.js";
|
|
5
5
|
import { SavedRecordRow } from "../../record-row/saved-record-row.js";
|
|
6
6
|
import { SavedSearchRows } from "../../searches/saved-search-rows.js";
|
|
7
7
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useClient } from "../../../data/api-provider.js";
|
|
2
2
|
import { useAdminMeta } from "../../meta-gate.js";
|
|
3
|
-
import { countQuery } from "../use-layout-data.js";
|
|
4
|
-
import { usePathValues } from "../use-path-value.js";
|
|
5
3
|
import { useLayoutRecord } from "../record-scope.js";
|
|
4
|
+
import { countQuery } from "../use-layout-data.js";
|
|
6
5
|
import { propsOf } from "./block-props.js";
|
|
6
|
+
import { usePathValues } from "../use-path-value.js";
|
|
7
7
|
import { useMemo } from "react";
|
|
8
8
|
import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
|
|
9
9
|
import { useQueries } from "@tanstack/react-query";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Skeleton } from "../../../primitives/skeleton.js";
|
|
2
2
|
import { useAdminMeta } from "../../meta-gate.js";
|
|
3
|
+
import { useLayoutRecord } from "../record-scope.js";
|
|
3
4
|
import { AppLink } from "../../use-app-address.js";
|
|
4
5
|
import { useCount } from "../use-layout-data.js";
|
|
5
|
-
import { FieldValue } from "../field-value.js";
|
|
6
|
-
import { usePathValue } from "../use-path-value.js";
|
|
7
|
-
import { useLayoutRecord } from "../record-scope.js";
|
|
8
6
|
import { propsOf } from "./block-props.js";
|
|
9
7
|
import { CardFrame } from "./card-frame.js";
|
|
8
|
+
import { FieldValue } from "../field-value.js";
|
|
9
|
+
import { usePathValue } from "../use-path-value.js";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
//#region src/app/pages/blocks/stat.tsx
|
|
12
12
|
const big = "text-2xl font-semibold tracking-tight tabular-nums";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useAdminMeta } from "../../meta-gate.js";
|
|
2
|
-
import { EmbeddedDisplaySwitch, EmbeddedList } from "../../embedded-list/embedded-list.js";
|
|
3
2
|
import { propsOf } from "./block-props.js";
|
|
4
3
|
import { CardFrame } from "./card-frame.js";
|
|
4
|
+
import { EmbeddedDisplaySwitch, EmbeddedList } from "../../embedded-list/embedded-list.js";
|
|
5
5
|
import { useEmbeddedDisplay } from "../../embedded-list/use-embedded-display.js";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
//#region src/app/pages/blocks/table.tsx
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { cn } from "../../lib/cn.js";
|
|
2
2
|
import { keys } from "../../data/query-keys.js";
|
|
3
3
|
import { useClient } from "../../data/api-provider.js";
|
|
4
|
-
import {
|
|
4
|
+
import { useAdminMeta } from "../meta-gate.js";
|
|
5
5
|
import { fileShown, shownImage } from "../../live/file-values.js";
|
|
6
6
|
import { displayValue } from "../../live/display-value.js";
|
|
7
|
-
import { useAdminMeta } from "../meta-gate.js";
|
|
8
7
|
import { AppLink } from "../use-app-address.js";
|
|
9
8
|
import { FileImage } from "../../live/file-image.js";
|
|
9
|
+
import { fetchLabels } from "../../live/relation-labels.js";
|
|
10
10
|
import { useShownWidget } from "../field-types/shown-widget.js";
|
|
11
11
|
import { WidgetPart } from "../field-types/widget-part.js";
|
|
12
|
-
import { Markdown } from "../../markdown/markdown.js";
|
|
13
12
|
import { isMarkdown } from "../../markdown/markdown-hint.js";
|
|
14
13
|
import { ValueBadge } from "../value-badge.js";
|
|
14
|
+
import { Markdown } from "../../markdown/markdown.js";
|
|
15
15
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
16
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
17
17
|
//#region src/app/pages/field-value.tsx
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { AppLink, useAppAddress } from "../use-app-address.js";
|
|
2
|
-
import { ActionRail } from "../../record-view/action-rail.js";
|
|
3
1
|
import { ConfirmAction } from "./confirm-action.js";
|
|
2
|
+
import { AppLink, useAppAddress } from "../use-app-address.js";
|
|
4
3
|
import { useActionRunner } from "./use-run-action.js";
|
|
4
|
+
import { ActionRail } from "../../record-view/action-rail.js";
|
|
5
5
|
import { actionIcon } from "../action-icon.js";
|
|
6
6
|
import { useState } from "react";
|
|
7
7
|
import { Pencil, Trash2 } from "lucide-react";
|
|
@@ -2,10 +2,10 @@ import { useClient, useResourceClient } from "../../data/api-provider.js";
|
|
|
2
2
|
import { useToast } from "../../toasts/toast-provider.js";
|
|
3
3
|
import { useProjectUi } from "./project-ui.js";
|
|
4
4
|
import { useAdminMeta, usePermissions } from "../meta-gate.js";
|
|
5
|
-
import { useAppAddress } from "../use-app-address.js";
|
|
6
5
|
import { can } from "../permissions.js";
|
|
7
|
-
import {
|
|
6
|
+
import { useAppAddress } from "../use-app-address.js";
|
|
8
7
|
import { actionFor, linkTarget, openLink } from "./action-href.js";
|
|
8
|
+
import { useRefreshResource } from "./use-layout-data.js";
|
|
9
9
|
import { useState } from "react";
|
|
10
10
|
import { fillAddress } from "@protobase/schema/internal";
|
|
11
11
|
//#region src/app/pages/use-run-action.ts
|
package/dist/app/record-page.js
CHANGED
|
@@ -9,29 +9,29 @@ import { useRecord } from "../data/use-record.js";
|
|
|
9
9
|
import { recordTitle } from "../live/model-helpers.js";
|
|
10
10
|
import { humanize } from "../live/naming.js";
|
|
11
11
|
import { useProjectUi } from "./pages/project-ui.js";
|
|
12
|
+
import { Notice, useAdminMeta, usePermissions } from "./meta-gate.js";
|
|
13
|
+
import { can, fieldAccess } from "./permissions.js";
|
|
12
14
|
import { displayValue } from "../live/display-value.js";
|
|
13
15
|
import { filledFields } from "./filled-fields.js";
|
|
14
|
-
import { Notice, useAdminMeta, usePermissions } from "./meta-gate.js";
|
|
15
16
|
import { AppLink, useAppAddress } from "./use-app-address.js";
|
|
16
17
|
import { ErrorBanner } from "./error-banner.js";
|
|
17
18
|
import { shownWidget } from "./field-types/shown-widget.js";
|
|
18
19
|
import { WidgetPart } from "./field-types/widget-part.js";
|
|
19
|
-
import { Markdown } from "../markdown/markdown.js";
|
|
20
20
|
import { isMarkdown } from "../markdown/markdown-hint.js";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
21
|
+
import { toneFor } from "../live/columns-from-model.js";
|
|
22
|
+
import { ValueBadge } from "./value-badge.js";
|
|
23
|
+
import { Markdown } from "../markdown/markdown.js";
|
|
24
|
+
import { FieldValue } from "./pages/field-value.js";
|
|
23
25
|
import { Field } from "../record-view/field.js";
|
|
24
26
|
import { Section } from "../record-view/section.js";
|
|
25
27
|
import { MetadataCard, RelatedRecords, SidebarCard } from "../record-view/record-sidebar.js";
|
|
26
28
|
import { RecordHeader } from "../record-view/record-header.js";
|
|
27
29
|
import { SpecTable } from "../record-view/spec-table.js";
|
|
28
30
|
import { KeyFacts } from "../record-view/key-facts.js";
|
|
29
|
-
import {
|
|
31
|
+
import { FieldEditor } from "./field-editor.js";
|
|
32
|
+
import { namedIcon } from "./named-icon.js";
|
|
30
33
|
import { useDeleteFlow } from "./delete/use-delete-flow.js";
|
|
31
34
|
import { useRestore } from "./delete/use-restore.js";
|
|
32
|
-
import { namedIcon } from "./named-icon.js";
|
|
33
|
-
import { ValueBadge } from "./value-badge.js";
|
|
34
|
-
import { FieldValue } from "./pages/field-value.js";
|
|
35
35
|
import { auditField } from "../live/audit-fields.js";
|
|
36
36
|
import { CustomSection } from "./custom-section.js";
|
|
37
37
|
import { MapSection } from "./map/map-section.js";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { useIsXs } from "../../lib/use-media-query.js";
|
|
2
2
|
import { Skeleton } from "../../primitives/skeleton.js";
|
|
3
3
|
import { humanize } from "../../live/naming.js";
|
|
4
|
+
import { useAdminMeta } from "../meta-gate.js";
|
|
4
5
|
import { displaysOf, loadedFields } from "../displays/list-displays.js";
|
|
5
6
|
import { defaultOrderBy } from "../list-order.js";
|
|
6
|
-
import { useAdminMeta } from "../meta-gate.js";
|
|
7
7
|
import { AppLink } from "../use-app-address.js";
|
|
8
8
|
import { ErrorBanner } from "../error-banner.js";
|
|
9
9
|
import { useLiveRows } from "../../live/use-live-rows.js";
|
|
10
|
-
import { FilterChipList } from "../searches/filter-chip-list.js";
|
|
11
10
|
import { viewAllAddress } from "../embedded-list/embedded-display.js";
|
|
11
|
+
import { FilterChipList } from "../searches/filter-chip-list.js";
|
|
12
12
|
import { useFilterChips } from "../searches/use-filter-chips.js";
|
|
13
13
|
import { RecordRow } from "./record-row.js";
|
|
14
14
|
import { useMemo } from "react";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Skeleton } from "../../primitives/skeleton.js";
|
|
2
2
|
import { humanize } from "../../live/naming.js";
|
|
3
|
-
import { listedResource } from "../current-address.js";
|
|
4
3
|
import { useAdminMeta } from "../meta-gate.js";
|
|
4
|
+
import { listedResource } from "../current-address.js";
|
|
5
5
|
import { ErrorBanner } from "../error-banner.js";
|
|
6
6
|
import { savedScope } from "../saved/saved-records.js";
|
|
7
7
|
import { useSavedRecords } from "../saved/use-saved-records.js";
|
|
@@ -3,8 +3,8 @@ import { keys } from "../data/query-keys.js";
|
|
|
3
3
|
import { useClient } from "../data/api-provider.js";
|
|
4
4
|
import { useAdminMeta } from "./meta-gate.js";
|
|
5
5
|
import { ErrorBanner } from "./error-banner.js";
|
|
6
|
-
import { Section } from "../record-view/section.js";
|
|
7
6
|
import { listColumnNames } from "../live/columns-from-model.js";
|
|
7
|
+
import { Section } from "../record-view/section.js";
|
|
8
8
|
import { EmbeddedDisplaySwitch, EmbeddedList } from "./embedded-list/embedded-list.js";
|
|
9
9
|
import { useEmbeddedDisplay } from "./embedded-list/use-embedded-display.js";
|
|
10
10
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -1,25 +1,49 @@
|
|
|
1
|
-
import { formatDateTime } from "../../format/date.js";
|
|
1
|
+
import { formatAgo, formatDateTime } from "../../format/date.js";
|
|
2
2
|
import { isApiError } from "@protobase/client";
|
|
3
3
|
//#region src/app/runtime/runtime-status.ts
|
|
4
4
|
/** The top bar shows the update button only when there is an update and the endpoint wants it shown. */
|
|
5
5
|
const showsUpdateButton = (status) => Boolean(status?.updateAvailable && status.indicator);
|
|
6
|
+
/** How often the status is read again: rarely, and every few seconds while an update runs so its progress shows. */
|
|
7
|
+
const refreshMs = (updating) => updating ? 5e3 : 18e5;
|
|
6
8
|
const policyLabels = {
|
|
7
9
|
immediate: "Updates as soon as a release is out",
|
|
8
10
|
weekly: "Updates at a set time every week",
|
|
9
11
|
scheduled: "Updates at the time set for this release",
|
|
10
12
|
manual: "Updates only when asked to"
|
|
11
13
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
const stageLabels = {
|
|
15
|
+
job: "Preparing the update",
|
|
16
|
+
build: "Building"
|
|
17
|
+
};
|
|
18
|
+
const runningText = (status, now) => {
|
|
19
|
+
if (!status.updateStage) return "Updating now";
|
|
20
|
+
const label = stageLabels[status.updateStage];
|
|
21
|
+
if (!status.updateStartedAt) return label;
|
|
22
|
+
const seconds = Math.max(0, Math.floor((now - Date.parse(status.updateStartedAt)) / 1e3));
|
|
23
|
+
return `${label}, started ${formatAgo(seconds)}`;
|
|
24
|
+
};
|
|
25
|
+
/** How far the running update is, or when the latest version will be applied on its own, in words; `now` in ms. */
|
|
26
|
+
const nextUpdateText = (status, now = Date.now()) => {
|
|
27
|
+
if (status.updating) return runningText(status, now);
|
|
15
28
|
if (status.nextUpdateAt) return `${policyLabels[status.policy]}: next on ${formatDateTime(Date.parse(status.nextUpdateAt))} UTC`;
|
|
16
29
|
return policyLabels[status.policy];
|
|
17
30
|
};
|
|
18
|
-
/**
|
|
31
|
+
/** How the last update ended, in words, with the endpoint's message for the owner when it has one. */
|
|
32
|
+
const lastUpdateText = (last) => {
|
|
33
|
+
const when = `${formatDateTime(Date.parse(last.finishedAt))} UTC`;
|
|
34
|
+
const headline = {
|
|
35
|
+
succeeded: `Updated to ${last.toVersion} on ${when}`,
|
|
36
|
+
unchanged: `The update to ${last.toVersion} on ${when} changed nothing`,
|
|
37
|
+
failed: `The update to ${last.toVersion} failed on ${when}`
|
|
38
|
+
}[last.outcome];
|
|
39
|
+
return last.message ? `${headline}: ${last.message}` : `${headline}.`;
|
|
40
|
+
};
|
|
41
|
+
/** Why "Update now" failed, in words: the endpoint's own message for a refusal, when it sends one. */
|
|
19
42
|
const updateErrorText = (error) => {
|
|
43
|
+
if (isApiError(error) && error.status < 500 && error.problem.detail) return error.problem.detail;
|
|
20
44
|
if (isApiError(error) && error.status === 409) return "Already on the latest version, or an update is running.";
|
|
21
45
|
if (isApiError(error) && error.status === 403) return "Only an admin can update the runtime.";
|
|
22
46
|
return "The update could not be started. Try again later.";
|
|
23
47
|
};
|
|
24
48
|
//#endregion
|
|
25
|
-
export { nextUpdateText, showsUpdateButton, updateErrorText };
|
|
49
|
+
export { lastUpdateText, nextUpdateText, refreshMs, showsUpdateButton, updateErrorText };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Spinner } from "../../primitives/spinner.js";
|
|
2
|
+
import { Button } from "../../primitives/button.js";
|
|
3
|
+
import { Dialog } from "../../primitives/dialog.js";
|
|
4
|
+
import { lastUpdateText, nextUpdateText, updateErrorText } from "./runtime-status.js";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/app/runtime/runtime-update-dialog.tsx
|
|
7
|
+
const Row = ({ label, value }) => /* @__PURE__ */ jsxs("div", {
|
|
8
|
+
className: "flex justify-between gap-4 py-1",
|
|
9
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
10
|
+
className: "text-muted-foreground",
|
|
11
|
+
children: label
|
|
12
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
13
|
+
className: "font-medium tabular-nums",
|
|
14
|
+
children: value
|
|
15
|
+
})]
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* The runtime update dialog: the versions, how far a running update is or when the policy applies the latest one, how
|
|
19
|
+
* the last update ended (while none runs), and "Update now".
|
|
20
|
+
*/
|
|
21
|
+
const RuntimeUpdateDialog = ({ status, requesting, error, checkError, onUpdate, onClose }) => {
|
|
22
|
+
const last = status.updating ? void 0 : status.lastUpdate;
|
|
23
|
+
return /* @__PURE__ */ jsxs(Dialog, {
|
|
24
|
+
title: "Runtime update",
|
|
25
|
+
description: status.updating ? /* @__PURE__ */ jsxs("span", {
|
|
26
|
+
className: "inline-flex items-center gap-1.5",
|
|
27
|
+
children: [/* @__PURE__ */ jsx(Spinner, { className: "size-3.5" }), nextUpdateText(status)]
|
|
28
|
+
}) : nextUpdateText(status),
|
|
29
|
+
onClose,
|
|
30
|
+
actions: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
|
|
31
|
+
onClick: onClose,
|
|
32
|
+
children: "Close"
|
|
33
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
34
|
+
variant: "primary",
|
|
35
|
+
loading: requesting,
|
|
36
|
+
disabled: status.updating || !status.updateAvailable,
|
|
37
|
+
onClick: onUpdate,
|
|
38
|
+
children: status.updating ? "Updating…" : "Update now"
|
|
39
|
+
})] }),
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ jsx(Row, {
|
|
42
|
+
label: "Current version",
|
|
43
|
+
value: status.version
|
|
44
|
+
}),
|
|
45
|
+
/* @__PURE__ */ jsx(Row, {
|
|
46
|
+
label: "Latest version",
|
|
47
|
+
value: status.latest
|
|
48
|
+
}),
|
|
49
|
+
last && /* @__PURE__ */ jsx("p", {
|
|
50
|
+
className: last.outcome === "failed" ? "mt-3 text-danger-text" : "mt-3 text-muted-foreground",
|
|
51
|
+
children: lastUpdateText(last)
|
|
52
|
+
}),
|
|
53
|
+
error !== void 0 && /* @__PURE__ */ jsx("p", {
|
|
54
|
+
role: "alert",
|
|
55
|
+
className: "mt-3 text-danger-text",
|
|
56
|
+
children: updateErrorText(error)
|
|
57
|
+
}),
|
|
58
|
+
checkError !== void 0 && /* @__PURE__ */ jsx("p", {
|
|
59
|
+
className: "mt-3 text-muted-foreground",
|
|
60
|
+
children: "The status could not be checked again; this is the last one read."
|
|
61
|
+
})
|
|
62
|
+
]
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
export { RuntimeUpdateDialog };
|
|
@@ -1,24 +1,14 @@
|
|
|
1
1
|
import { Button } from "../../primitives/button.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { showsUpdateButton } from "./runtime-status.js";
|
|
3
|
+
import { RuntimeUpdateDialog } from "./runtime-update-dialog.js";
|
|
4
4
|
import { useRuntimeClient, useRuntimeStatus } from "./use-runtime-status.js";
|
|
5
5
|
import { useState } from "react";
|
|
6
6
|
import { ArrowUpCircle } from "lucide-react";
|
|
7
7
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
//#region src/app/runtime/runtime-update.tsx
|
|
9
|
-
const Row = ({ label, value }) => /* @__PURE__ */ jsxs("div", {
|
|
10
|
-
className: "flex justify-between gap-4 py-1",
|
|
11
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
12
|
-
className: "text-muted-foreground",
|
|
13
|
-
children: label
|
|
14
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
15
|
-
className: "font-medium tabular-nums",
|
|
16
|
-
children: value
|
|
17
|
-
})]
|
|
18
|
-
});
|
|
19
9
|
/**
|
|
20
10
|
* The top bar's runtime update button, shown while the endpoint reports an update and wants it shown, and the dialog
|
|
21
|
-
* it opens
|
|
11
|
+
* it opens. On mobile only the icon shows.
|
|
22
12
|
*/
|
|
23
13
|
const RuntimeUpdate = ({ client }) => {
|
|
24
14
|
const { status, update, requesting, error, checkError } = useRuntimeStatus(client);
|
|
@@ -35,39 +25,13 @@ const RuntimeUpdate = ({ client }) => {
|
|
|
35
25
|
className: "max-md:sr-only",
|
|
36
26
|
children: "Update"
|
|
37
27
|
})]
|
|
38
|
-
}), open && /* @__PURE__ */
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}), /* @__PURE__ */ jsx(Button, {
|
|
46
|
-
variant: "primary",
|
|
47
|
-
loading: requesting,
|
|
48
|
-
disabled: status.updating || !status.updateAvailable,
|
|
49
|
-
onClick: () => void update(),
|
|
50
|
-
children: status.updating ? "Updating…" : "Update now"
|
|
51
|
-
})] }),
|
|
52
|
-
children: [
|
|
53
|
-
/* @__PURE__ */ jsx(Row, {
|
|
54
|
-
label: "Current version",
|
|
55
|
-
value: status.version
|
|
56
|
-
}),
|
|
57
|
-
/* @__PURE__ */ jsx(Row, {
|
|
58
|
-
label: "Latest version",
|
|
59
|
-
value: status.latest
|
|
60
|
-
}),
|
|
61
|
-
error !== void 0 && /* @__PURE__ */ jsx("p", {
|
|
62
|
-
role: "alert",
|
|
63
|
-
className: "mt-3 text-danger-text",
|
|
64
|
-
children: updateErrorText(error)
|
|
65
|
-
}),
|
|
66
|
-
checkError !== void 0 && /* @__PURE__ */ jsx("p", {
|
|
67
|
-
className: "mt-3 text-muted-foreground",
|
|
68
|
-
children: "The status could not be checked again; this is the last one read."
|
|
69
|
-
})
|
|
70
|
-
]
|
|
28
|
+
}), open && /* @__PURE__ */ jsx(RuntimeUpdateDialog, {
|
|
29
|
+
status,
|
|
30
|
+
requesting,
|
|
31
|
+
error,
|
|
32
|
+
checkError,
|
|
33
|
+
onUpdate: () => void update(),
|
|
34
|
+
onClose: () => setOpen(false)
|
|
71
35
|
})] });
|
|
72
36
|
};
|
|
73
37
|
const OwnRuntimeUpdate = ({ url }) => /* @__PURE__ */ jsx(RuntimeUpdate, { client: useRuntimeClient(url) });
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { useApiToken } from "../../auth/use-api-token.js";
|
|
2
|
+
import { refreshMs } from "./runtime-status.js";
|
|
2
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
4
|
import { createRuntimeClient } from "@protobase/client";
|
|
4
5
|
//#region src/app/runtime/use-runtime-status.ts
|
|
5
|
-
/** How often the status is read again: rarely, and more often while an update runs so the button goes away when it is done. */
|
|
6
|
-
const refreshMs = 18e5;
|
|
7
|
-
const updatingRefreshMs = 3e4;
|
|
8
6
|
/** A client of the runtime endpoint at `url`, authenticated as the signed-in user; `undefined` until their token is there. */
|
|
9
7
|
const useRuntimeClient = (url) => {
|
|
10
8
|
const token = useApiToken();
|
|
@@ -17,7 +15,7 @@ const useRuntimeClient = (url) => {
|
|
|
17
15
|
}) : void 0, [url, ready]);
|
|
18
16
|
};
|
|
19
17
|
/**
|
|
20
|
-
* The runtime's status, read on load and every half hour after, and `update` to apply the latest version now.
|
|
18
|
+
* The runtime's status, read on load and every half hour after (every few seconds while an update runs), and `update` to apply the latest version now.
|
|
21
19
|
* `status` keeps the last answer when a later read fails, which `checkError` then holds; `error` is why "Update now" failed.
|
|
22
20
|
*/
|
|
23
21
|
const useRuntimeStatus = (client) => {
|
|
@@ -35,7 +33,7 @@ const useRuntimeStatus = (client) => {
|
|
|
35
33
|
setCheckError(void 0);
|
|
36
34
|
}, (reason) => active && setCheckError(reason));
|
|
37
35
|
read();
|
|
38
|
-
const timer = setInterval(() => void read(), updating
|
|
36
|
+
const timer = setInterval(() => void read(), refreshMs(updating));
|
|
39
37
|
return () => {
|
|
40
38
|
active = false;
|
|
41
39
|
clearInterval(timer);
|
|
@@ -5,8 +5,8 @@ import { useAdminMeta } from "../meta-gate.js";
|
|
|
5
5
|
import { AppLink } from "../use-app-address.js";
|
|
6
6
|
import { ErrorBanner } from "../error-banner.js";
|
|
7
7
|
import { InlineFilterChips } from "./filter-chip-list.js";
|
|
8
|
-
import { useSavedSearches } from "./use-saved-searches.js";
|
|
9
8
|
import { RecordRowBody } from "../record-row/record-row-body.js";
|
|
9
|
+
import { useSavedSearches } from "./use-saved-searches.js";
|
|
10
10
|
import { useSearchRow } from "./use-search-row.js";
|
|
11
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
12
|
import { encodeKey } from "@protobase/schema/internal";
|
|
@@ -5,10 +5,10 @@ import { useToast } from "../../toasts/toast-provider.js";
|
|
|
5
5
|
import { AppLink } from "../use-app-address.js";
|
|
6
6
|
import { useRefreshResource } from "../pages/use-layout-data.js";
|
|
7
7
|
import { InlineFilterChips } from "./filter-chip-list.js";
|
|
8
|
-
import { SearchNameDialog } from "./search-name-dialog.js";
|
|
9
8
|
import { RecordRowBody } from "../record-row/record-row-body.js";
|
|
10
|
-
import { SearchControls } from "./search-controls.js";
|
|
11
9
|
import { useSearchRow } from "./use-search-row.js";
|
|
10
|
+
import { SearchNameDialog } from "./search-name-dialog.js";
|
|
11
|
+
import { SearchControls } from "./search-controls.js";
|
|
12
12
|
import { useState } from "react";
|
|
13
13
|
import { Pencil, Trash2 } from "lucide-react";
|
|
14
14
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -3,11 +3,11 @@ import { PageHeader } from "../../app-shell/page-header.js";
|
|
|
3
3
|
import { recordKey } from "../../live/model-helpers.js";
|
|
4
4
|
import { humanize } from "../../live/naming.js";
|
|
5
5
|
import { Notice, useAdminMeta, usePermissions } from "../meta-gate.js";
|
|
6
|
+
import { can } from "../permissions.js";
|
|
6
7
|
import { AppLink } from "../use-app-address.js";
|
|
7
8
|
import { ErrorBanner } from "../error-banner.js";
|
|
8
|
-
import { can } from "../permissions.js";
|
|
9
|
-
import { useDeleteFlow } from "../delete/use-delete-flow.js";
|
|
10
9
|
import { useSavedSearches } from "./use-saved-searches.js";
|
|
10
|
+
import { useDeleteFlow } from "../delete/use-delete-flow.js";
|
|
11
11
|
import { SavedSearchSection } from "./saved-search-section.js";
|
|
12
12
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
13
|
import { encodeKey } from "@protobase/schema/internal";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useClient } from "../../data/api-provider.js";
|
|
2
2
|
import { humanize } from "../../live/naming.js";
|
|
3
3
|
import { useToast } from "../../toasts/toast-provider.js";
|
|
4
|
-
import { Switch } from "../../primitives/switch.js";
|
|
5
4
|
import { useRefreshResource } from "../pages/use-layout-data.js";
|
|
5
|
+
import { Switch } from "../../primitives/switch.js";
|
|
6
6
|
import { useId } from "react";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { useMutation } from "@tanstack/react-query";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Input } from "../../primitives/input.js";
|
|
2
2
|
import { Button } from "../../primitives/button.js";
|
|
3
|
-
import { ResponsiveDialog } from "../../primitives/responsive-dialog.js";
|
|
4
3
|
import { FilterChipList } from "./filter-chip-list.js";
|
|
4
|
+
import { ResponsiveDialog } from "../../primitives/responsive-dialog.js";
|
|
5
5
|
import { useId, useState } from "react";
|
|
6
6
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
//#region src/app/searches/search-name-dialog.tsx
|
|
@@ -3,11 +3,11 @@ import { Button } from "../../primitives/button.js";
|
|
|
3
3
|
import { useClient } from "../../data/api-provider.js";
|
|
4
4
|
import { humanize } from "../../live/naming.js";
|
|
5
5
|
import { defaultOrderBy } from "../list-order.js";
|
|
6
|
-
import { ResponsiveDialog } from "../../primitives/responsive-dialog.js";
|
|
7
6
|
import { countQuery } from "../pages/use-layout-data.js";
|
|
7
|
+
import { useFilterChips } from "./use-filter-chips.js";
|
|
8
|
+
import { ResponsiveDialog } from "../../primitives/responsive-dialog.js";
|
|
8
9
|
import { EmbeddedList } from "../embedded-list/embedded-list.js";
|
|
9
10
|
import { addedFilter, filterChanges, netChange, removedFilter } from "./search-diff.js";
|
|
10
|
-
import { useFilterChips } from "./use-filter-chips.js";
|
|
11
11
|
import { useMemo } from "react";
|
|
12
12
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
13
13
|
import { useQuery } from "@tanstack/react-query";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { keys } from "../../data/query-keys.js";
|
|
2
2
|
import { useClient } from "../../data/api-provider.js";
|
|
3
|
-
import { fetchLabels } from "../../live/relation-labels.js";
|
|
4
3
|
import { useAdminMeta } from "../meta-gate.js";
|
|
4
|
+
import { fetchLabels } from "../../live/relation-labels.js";
|
|
5
5
|
import { chosenRelations, filterChips } from "./saved-search.js";
|
|
6
6
|
import { useQueries, useQueryClient } from "@tanstack/react-query";
|
|
7
7
|
//#region src/app/searches/use-filter-chips.ts
|
|
@@ -3,11 +3,11 @@ import { recordKey } from "../../live/model-helpers.js";
|
|
|
3
3
|
import { humanize } from "../../live/naming.js";
|
|
4
4
|
import { useToast } from "../../toasts/toast-provider.js";
|
|
5
5
|
import { useAdminMeta } from "../meta-gate.js";
|
|
6
|
-
import { useAppAddress } from "../use-app-address.js";
|
|
7
6
|
import { can } from "../permissions.js";
|
|
7
|
+
import { useAppAddress } from "../use-app-address.js";
|
|
8
8
|
import { useRefreshResource } from "../pages/use-layout-data.js";
|
|
9
|
-
import { useOpenedSearch } from "./use-opened-search.js";
|
|
10
9
|
import { useSavedSearches } from "./use-saved-searches.js";
|
|
10
|
+
import { useOpenedSearch } from "./use-opened-search.js";
|
|
11
11
|
import { useMutation } from "@tanstack/react-query";
|
|
12
12
|
import { encodeKey } from "@protobase/schema/internal";
|
|
13
13
|
//#region src/app/searches/use-save-search.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { keys } from "../../data/query-keys.js";
|
|
2
2
|
import { useClient } from "../../data/api-provider.js";
|
|
3
|
-
import { defaultOrderBy } from "../list-order.js";
|
|
4
3
|
import { useAdminMeta } from "../meta-gate.js";
|
|
4
|
+
import { defaultOrderBy } from "../list-order.js";
|
|
5
5
|
import { useQuery } from "@tanstack/react-query";
|
|
6
6
|
//#region src/app/searches/use-saved-searches.ts
|
|
7
7
|
/** Where the user's saved searches of `resource` are cached; a list key, so a write to the resource refreshes it. */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useClient } from "../../data/api-provider.js";
|
|
2
2
|
import { humanize } from "../../live/naming.js";
|
|
3
3
|
import { countQuery, useRefreshResource } from "../pages/use-layout-data.js";
|
|
4
|
-
import { isUnseen, unseenFilter } from "./saved-search.js";
|
|
5
4
|
import { chipsText } from "./filter-chip-list.js";
|
|
5
|
+
import { isUnseen, unseenFilter } from "./saved-search.js";
|
|
6
6
|
import { useFilterChips } from "./use-filter-chips.js";
|
|
7
7
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
8
8
|
//#region src/app/searches/use-search-row.ts
|
|
@@ -3,8 +3,8 @@ import { Input } from "../primitives/input.js";
|
|
|
3
3
|
import { Button } from "../primitives/button.js";
|
|
4
4
|
import { humanize } from "../live/naming.js";
|
|
5
5
|
import { displayValue } from "../live/display-value.js";
|
|
6
|
-
import { toDraft } from "../live/field-values.js";
|
|
7
6
|
import { ErrorBanner } from "./error-banner.js";
|
|
7
|
+
import { toDraft } from "../live/field-values.js";
|
|
8
8
|
import { useState } from "react";
|
|
9
9
|
import { Eye, EyeOff } from "lucide-react";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useIsXs } from "../lib/use-media-query.js";
|
|
2
2
|
import { Link, useRouter } from "./router.js";
|
|
3
|
-
import { changedList, currentAddress, listDefaults, listedResource } from "./current-address.js";
|
|
4
3
|
import { useAdminMeta } from "./meta-gate.js";
|
|
4
|
+
import { changedList, currentAddress, listDefaults, listedResource } from "./current-address.js";
|
|
5
5
|
import { useCallback, useMemo } from "react";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
import { appPath, readAppPath } from "@protobase/schema";
|
package/dist/app/value-badge.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Badge } from "../primitives/badge.js";
|
|
2
|
-
import { valueColor } from "../live/value-color.js";
|
|
3
2
|
import { toneFor } from "../live/columns-from-model.js";
|
|
3
|
+
import { valueColor } from "../live/value-color.js";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
//#region src/app/value-badge.tsx
|
|
6
6
|
/** A stored value as a badge: filled with the colour the view gives it and in its badge shape, else in its tone. */
|
|
@@ -2,8 +2,8 @@ import { RouteLink } from "../primitives/route-link.js";
|
|
|
2
2
|
import { useAuth } from "./auth-provider.js";
|
|
3
3
|
import { Button, buttonClass } from "../primitives/button.js";
|
|
4
4
|
import { useSignInAddress } from "./use-sign-in-address.js";
|
|
5
|
-
import { ResponsiveDialog } from "../primitives/responsive-dialog.js";
|
|
6
5
|
import { namedIcon } from "../app/named-icon.js";
|
|
6
|
+
import { ResponsiveDialog } from "../primitives/responsive-dialog.js";
|
|
7
7
|
import { useId } from "react";
|
|
8
8
|
import { Check, LogIn } from "lucide-react";
|
|
9
9
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
package/dist/data-grid/cells.js
CHANGED
|
@@ -6,8 +6,8 @@ import { formatInt, formatPercent, formatSigned } from "../format/number.js";
|
|
|
6
6
|
import { formatDate, formatDateTime } from "../format/date.js";
|
|
7
7
|
import { fileShown, shownImage } from "../live/file-values.js";
|
|
8
8
|
import { FileImage } from "../live/file-image.js";
|
|
9
|
-
import { userById } from "../mocks/users.js";
|
|
10
9
|
import { valueColor } from "../live/value-color.js";
|
|
10
|
+
import { userById } from "../mocks/users.js";
|
|
11
11
|
import { Check, Paperclip } from "lucide-react";
|
|
12
12
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
13
|
import { enumLabel } from "@protobase/schema";
|
package/dist/format/date.js
CHANGED
|
@@ -19,6 +19,12 @@ const time = new Intl.DateTimeFormat("en-GB", {
|
|
|
19
19
|
const formatDate = (ms) => day.format(ms);
|
|
20
20
|
const formatDayShort = (ms) => dayShort.format(ms);
|
|
21
21
|
const formatDateTime = (ms) => `${day.format(ms)}, ${time.format(ms)}`;
|
|
22
|
+
const formatAgo = (seconds) => {
|
|
23
|
+
if (seconds < 60) return `${seconds} s ago`;
|
|
24
|
+
if (seconds < 3600) return `${Math.floor(seconds / 60)} min ago`;
|
|
25
|
+
if (seconds < 86400) return `${Math.floor(seconds / 3600)} h ago`;
|
|
26
|
+
return `${Math.floor(seconds / 86400)} d ago`;
|
|
27
|
+
};
|
|
22
28
|
new Intl.RelativeTimeFormat("en", { numeric: "auto" });
|
|
23
29
|
//#endregion
|
|
24
|
-
export { formatDate, formatDateTime, formatDayShort };
|
|
30
|
+
export { formatAgo, formatDate, formatDateTime, formatDayShort };
|
package/dist/index.d.ts
CHANGED
|
@@ -48,5 +48,13 @@ import { CodeForm, CodeFormProps } from "./auth/code-form.js";
|
|
|
48
48
|
import { ResendCodeButton, ResendCodeButtonProps } from "./auth/resend-code-button.js";
|
|
49
49
|
import { Button, ButtonProps, buttonClass } from "./primitives/button.js";
|
|
50
50
|
import { Input, InputProps } from "./primitives/input.js";
|
|
51
|
+
import { Textarea, TextareaProps } from "./primitives/textarea.js";
|
|
52
|
+
import { Segmented, SegmentedOption, SegmentedProps } from "./primitives/segmented.js";
|
|
53
|
+
import { MenuSelect, MenuSelectProps } from "./primitives/menu-select.js";
|
|
54
|
+
import { ChoiceOption, Choices, ChoicesProps } from "./primitives/choices.js";
|
|
55
|
+
import { Dialog, DialogProps } from "./primitives/dialog.js";
|
|
56
|
+
import { Field, FieldProps } from "./record-view/field.js";
|
|
57
|
+
import { Section } from "./record-view/section.js";
|
|
58
|
+
import { Form, FormProps } from "./app/create/form.js";
|
|
51
59
|
import { Spinner } from "./primitives/spinner.js";
|
|
52
|
-
export { ActionCard, type ActionCardProps, type ActionContext, type ActionHandler, ApiProvider, type ApiProviderProps, App, AppLink, type AppProps, AssistantDock, type AssistantDockProps, AuthLayout, type AuthLayoutProps, type BackendData, type BackendRefresh, type BeforeSignInProps, Button, type ButtonProps, type CardAction, type CardTone, ChatMessage, ChatThread, type ChatThreadProps, CodeForm, type CodeFormProps, CompactTable, type CompactTableProps, Composer, type ComposerProps, type CurrentAddress, type DiffLine, DiffView, type DiffViewProps, FieldList, type FieldWidget, type FieldWidgetEditorProps, type FieldWidgetProps, Input, type InputProps, type LayoutRecord, type ListAddress, type ListChange, type ListDisplay, type ListDisplayRow, LogoMark, type MetaData, OtpInput, type OtpInputProps, PartView, type PluginInfo, type ProjectUi, type RecordCardProps, RecordLink, ResendCodeButton, type ResendCodeButtonProps, ResponsiveDialog, type ResponsiveDialogProps, type ShellLogoProps, SidePanel, type SidePanelProps, SignInPrompt, type SignInPromptProps, Spinner, type Step, StepList, type StepState, buttonClass, definePlugin, defineUi, diffStats, isConflict, mergeUi, parseDiff, pluginApi, protobaseVersion, uiFromModule, useApiToken, useAppAddress, useAssistant, useAssistantClient, useBackendData, useClient, useFacets, useHistogram, useLayoutRecord, useList, useListDisplay, useMeta, usePlugin, useRecord, useResourceClient, useSeries, useUpdateRecord };
|
|
60
|
+
export { ActionCard, type ActionCardProps, type ActionContext, type ActionHandler, ApiProvider, type ApiProviderProps, App, AppLink, type AppProps, AssistantDock, type AssistantDockProps, AuthLayout, type AuthLayoutProps, type BackendData, type BackendRefresh, type BeforeSignInProps, Button, type ButtonProps, type CardAction, type CardTone, ChatMessage, ChatThread, type ChatThreadProps, type ChoiceOption, Choices, type ChoicesProps, CodeForm, type CodeFormProps, CompactTable, type CompactTableProps, Composer, type ComposerProps, type CurrentAddress, Dialog, type DialogProps, type DiffLine, DiffView, type DiffViewProps, Field, FieldList, type FieldProps, type FieldWidget, type FieldWidgetEditorProps, type FieldWidgetProps, Form, type FormProps, Input, type InputProps, type LayoutRecord, type ListAddress, type ListChange, type ListDisplay, type ListDisplayRow, LogoMark, MenuSelect, type MenuSelectProps, type MetaData, OtpInput, type OtpInputProps, PartView, type PluginInfo, type ProjectUi, type RecordCardProps, RecordLink, ResendCodeButton, type ResendCodeButtonProps, ResponsiveDialog, type ResponsiveDialogProps, Section, Segmented, type SegmentedOption, type SegmentedProps, type ShellLogoProps, SidePanel, type SidePanelProps, SignInPrompt, type SignInPromptProps, Spinner, type Step, StepList, type StepState, Textarea, type TextareaProps, buttonClass, definePlugin, defineUi, diffStats, isConflict, mergeUi, parseDiff, pluginApi, protobaseVersion, uiFromModule, useApiToken, useAppAddress, useAssistant, useAssistantClient, useBackendData, useClient, useFacets, useHistogram, useLayoutRecord, useList, useListDisplay, useMeta, usePlugin, useRecord, useResourceClient, useSeries, useUpdateRecord };
|