@protobase/ui 0.21.5 → 0.21.7

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.
Files changed (70) hide show
  1. package/dist/app/app.d.ts +3 -3
  2. package/dist/app/app.js +32 -13
  3. package/dist/app/create/create-page.js +4 -4
  4. package/dist/app/custom-section.js +1 -1
  5. package/dist/app/displays/board-columns.js +1 -1
  6. package/dist/app/displays/board-display.js +1 -1
  7. package/dist/app/displays/list-displays.js +1 -1
  8. package/dist/app/displays/map-display.js +1 -1
  9. package/dist/app/displays/record-card.js +2 -2
  10. package/dist/app/displays/use-board-column.js +1 -1
  11. package/dist/app/displays/use-board-move.js +1 -1
  12. package/dist/app/displays/use-map-records.js +1 -1
  13. package/dist/app/embedded-list/cut-off-note.js +11 -0
  14. package/dist/app/embedded-list/embedded-list.js +17 -8
  15. package/dist/app/embedded-list/use-embedded-rows.js +16 -4
  16. package/dist/app/gallery/gallery-section.js +1 -1
  17. package/dist/app/gallery/lightbox.js +1 -1
  18. package/dist/app/hand-order/hand-sorted-list.js +3 -3
  19. package/dist/app/hand-order/use-hand-order.js +2 -2
  20. package/dist/app/import/import-dialog.js +1 -1
  21. package/dist/app/list-edit/use-list-edits.js +1 -1
  22. package/dist/app/list-page.js +4 -4
  23. package/dist/app/map/map-section.js +1 -1
  24. package/dist/app/pages/action-inputs/action-inputs-dialog.js +3 -3
  25. package/dist/app/pages/blocks/card-row.js +1 -1
  26. package/dist/app/pages/blocks/modal-form.js +3 -3
  27. package/dist/app/pages/blocks/record-card.js +1 -1
  28. package/dist/app/pages/field-value.js +1 -1
  29. package/dist/app/pages/use-run-action.js +1 -1
  30. package/dist/app/record-lines.js +1 -1
  31. package/dist/app/record-page.js +5 -5
  32. package/dist/app/record-row/record-row-body.js +1 -1
  33. package/dist/app/record-row/saved-record-row.js +1 -1
  34. package/dist/app/related-dots/related-dots.js +1 -1
  35. package/dist/app/related-section.js +8 -9
  36. package/dist/app/relation-picker.js +1 -1
  37. package/dist/app/search/search-model.js +1 -1
  38. package/dist/app/searches/saved-search-rows.js +2 -2
  39. package/dist/app/searches/saved-searches.js +2 -2
  40. package/dist/app/searches/update-search-dialog.js +1 -1
  41. package/dist/app/searches/use-save-search.js +1 -1
  42. package/dist/app/searches/use-saved-searches.js +1 -1
  43. package/dist/app/use-app-address.js +1 -1
  44. package/dist/assistant-dock/widget-view.js +1 -1
  45. package/dist/auth/auth-layout.d.ts +4 -2
  46. package/dist/auth/auth-layout.js +4 -3
  47. package/dist/data/api-provider.d.ts +6 -0
  48. package/dist/data/query-keys.js +3 -1
  49. package/dist/forms/prove-human.js +24 -0
  50. package/dist/forms/public-form-page.js +142 -0
  51. package/dist/forms/use-form-address.js +11 -0
  52. package/dist/index.js +7 -7
  53. package/dist/live/columns-from-model.js +1 -1
  54. package/dist/live/related-column-rows.js +7 -8
  55. package/dist/live/search-all.js +27 -0
  56. package/dist/live/use-filter-config.js +1 -1
  57. package/dist/package.js +1 -1
  58. package/dist/plugins/plugin-gate.js +1 -1
  59. package/dist/shell/assets/app-BbVdHzEY.js +69 -0
  60. package/dist/shell/assets/{index-BMiDZRGI.js → index-CQc-60lQ.js} +1 -1
  61. package/dist/shell/assets/{maplibre-BFMEpd4m.js → maplibre-BvtgTvfx.js} +1 -1
  62. package/dist/shell/assets/{markdown-content-yqq0wmAS.js → markdown-content-CJ8g5iKO.js} +1 -1
  63. package/dist/shell/assets/{record-map-DhpikXZs.js → record-map-DSXYVoqB.js} +1 -1
  64. package/dist/shell/assets/{records-map-LDeVJQab.js → records-map-cU_FAK7w.js} +1 -1
  65. package/dist/shell/assets/shared-protobase-ui-Bc0CoTXD.js +1 -0
  66. package/dist/shell/index.html +3 -3
  67. package/dist/shell/protobase.shell.json +1 -1
  68. package/package.json +5 -4
  69. package/dist/shell/assets/app-BmBlR0fJ.js +0 -69
  70. package/dist/shell/assets/shared-protobase-ui-DfPkkHCn.js +0 -1
package/dist/app/app.d.ts CHANGED
@@ -29,9 +29,9 @@ export type AppProps = {
29
29
  pluginLoader?: PluginLoader;
30
30
  };
31
31
  /**
32
- * The admin: the sign-in route first, `/-/sign-in`, or browsing as a visitor when the project has an anonymous role,
33
- * then a sidebar from `/meta`, `/:page` composed pages, `/:resource` lists and `/:resource/:key` records. Fills its
34
- * parent, in the theme this browser chose, light, dark or the system's.
32
+ * The admin: a public form at `/-/forms/<name>` for anyone, the sign-in route first, `/-/sign-in`, or browsing as a
33
+ * visitor when the project's anonymous role reads, then a sidebar from `/meta`, `/:page` composed pages, `/:resource`
34
+ * lists and `/:resource/:key` records. Fills its parent, in the theme this browser chose, light, dark or the system's.
35
35
  */
36
36
  export declare const App: ({ auth, workspace, basePath, initialUrl, pluginLoader, ...rest }: AppProps) => import("react").JSX.Element;
37
37
  //#endregion
package/dist/app/app.js CHANGED
@@ -13,18 +13,20 @@ import { PluginSourceProvider } from "../plugins/plugin-source.js";
13
13
  import { AuthGate } from "../auth/auth-gate.js";
14
14
  import { isAdmin, userToShell } from "../auth/user-to-shell.js";
15
15
  import { useOpenedRecord } from "../data/use-record.js";
16
- import { recordTitle } from "../live/model-helpers.js";
17
16
  import { humanize } from "../live/naming.js";
18
- import { ThemeProvider, useTheme } from "../theme/theme-provider.js";
19
17
  import { ToastProvider } from "../toasts/toast-provider.js";
20
- import { useProjectUi } from "./pages/project-ui.js";
21
- import { AssistantButton, AssistantPanel } from "./assistant-shell.js";
22
- import { bottomBarFromMeta } from "./bottom-bar-from-meta.js";
23
- import { breadcrumbFor } from "./breadcrumb-for.js";
24
18
  import { documentTitle, titleParts, useDocumentTitle } from "./document-title.js";
19
+ import { recordTitle } from "../live/model-helpers.js";
25
20
  import { sourceStatusOf } from "../data/with-sources.js";
26
21
  import { MetaGate, Notice, useAdminMeta } from "./meta-gate.js";
27
22
  import { useAppAddress } from "./use-app-address.js";
23
+ import { ProjectUiContext, useProjectUi } from "./pages/project-ui.js";
24
+ import { PublicFormPage } from "../forms/public-form-page.js";
25
+ import { useFormAddress } from "../forms/use-form-address.js";
26
+ import { ThemeProvider, useTheme } from "../theme/theme-provider.js";
27
+ import { AssistantButton, AssistantPanel } from "./assistant-shell.js";
28
+ import { bottomBarFromMeta } from "./bottom-bar-from-meta.js";
29
+ import { breadcrumbFor } from "./breadcrumb-for.js";
28
30
  import { ComposedPage } from "./pages/composed-page.js";
29
31
  import { CreateRoute } from "./create/create-route.js";
30
32
  import { ListPage } from "./list-page.js";
@@ -278,10 +280,22 @@ const Authenticated = ({ baseUrl, client, sources, workspace, sidebarMode, ui, a
278
280
  }) }) })
279
281
  });
280
282
  };
283
+ const PublicFormGate = ({ baseUrl, client, ui, children }) => {
284
+ const address = useFormAddress();
285
+ if (!address) return children;
286
+ return /* @__PURE__ */ jsx(ApiProvider, {
287
+ baseUrl,
288
+ client,
289
+ children: /* @__PURE__ */ jsx(ProjectUiContext.Provider, {
290
+ value: ui ?? {},
291
+ children: /* @__PURE__ */ jsx(PublicFormPage, { name: address.name }, address.name)
292
+ })
293
+ });
294
+ };
281
295
  /**
282
- * The admin: the sign-in route first, `/-/sign-in`, or browsing as a visitor when the project has an anonymous role,
283
- * then a sidebar from `/meta`, `/:page` composed pages, `/:resource` lists and `/:resource/:key` records. Fills its
284
- * parent, in the theme this browser chose, light, dark or the system's.
296
+ * The admin: a public form at `/-/forms/<name>` for anyone, the sign-in route first, `/-/sign-in`, or browsing as a
297
+ * visitor when the project's anonymous role reads, then a sidebar from `/meta`, `/:page` composed pages, `/:resource`
298
+ * lists and `/:resource/:key` records. Fills its parent, in the theme this browser chose, light, dark or the system's.
285
299
  */
286
300
  const App = ({ auth, workspace, basePath, initialUrl, pluginLoader, ...rest }) => /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(AuthProvider, {
287
301
  session: auth,
@@ -290,11 +304,16 @@ const App = ({ auth, workspace, basePath, initialUrl, pluginLoader, ...rest }) =
290
304
  initialUrl,
291
305
  children: /* @__PURE__ */ jsx(PluginSourceProvider, {
292
306
  ...pluginLoader && { loader: pluginLoader },
293
- children: /* @__PURE__ */ jsx(AuthGate, {
294
- workspace,
295
- children: /* @__PURE__ */ jsx(Authenticated, {
307
+ children: /* @__PURE__ */ jsx(PublicFormGate, {
308
+ baseUrl: rest.baseUrl,
309
+ client: rest.client,
310
+ ui: rest.ui,
311
+ children: /* @__PURE__ */ jsx(AuthGate, {
296
312
  workspace,
297
- ...rest
313
+ children: /* @__PURE__ */ jsx(Authenticated, {
314
+ workspace,
315
+ ...rest
316
+ })
298
317
  })
299
318
  })
300
319
  })
@@ -1,14 +1,14 @@
1
1
  import { useClient } from "../../data/api-provider.js";
2
- import { recordKey } from "../../live/model-helpers.js";
3
2
  import { humanize } from "../../live/naming.js";
4
- import { Notice, useAdminMeta, usePermissions } from "../meta-gate.js";
5
3
  import { createBody, createSections, hasDatabaseDefault, initialDraft, isChosen, isRequired } from "./create-values.js";
4
+ import { recordKey } from "../../live/model-helpers.js";
5
+ import { Notice, useAdminMeta, usePermissions } from "../meta-gate.js";
6
6
  import { useAppAddress } from "../use-app-address.js";
7
7
  import { FieldEditor } from "../field-editor.js";
8
- import { can } from "../permissions.js";
9
- import { fetchLabels } from "../../live/relation-labels.js";
10
8
  import { fieldErrors, fieldMessage } from "../field-errors.js";
11
9
  import { useFocusFirstInvalid } from "../use-focus-first-invalid.js";
10
+ import { can } from "../permissions.js";
11
+ import { fetchLabels } from "../../live/relation-labels.js";
12
12
  import { useLiveSave } from "../use-live-save.js";
13
13
  import { CreateRecordForm } from "./create-record-form.js";
14
14
  import { useEffect, useState } from "react";
@@ -1,8 +1,8 @@
1
1
  import { Problem } from "./pages/problem.js";
2
2
  import { CustomBoundary } from "./pages/custom-boundary.js";
3
- import { useProjectUi } from "./pages/project-ui.js";
4
3
  import { Section } from "../record-view/section.js";
5
4
  import { SidebarCard } from "../record-view/record-sidebar.js";
5
+ import { useProjectUi } from "./pages/project-ui.js";
6
6
  import { RecordScope } from "./pages/record-scope.js";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import { unmarkFieldRefs } from "@protobase/schema/internal";
@@ -1,5 +1,5 @@
1
- import { recordTitleField } from "../../live/model-helpers.js";
2
1
  import { humanize } from "../../live/naming.js";
2
+ import { recordTitleField } from "../../live/model-helpers.js";
3
3
  import { isApiError } from "@protobase/client";
4
4
  import { enumLabel, printFilter, where } from "@protobase/schema";
5
5
  //#region src/app/displays/board-columns.ts
@@ -1,5 +1,5 @@
1
- import { usePermissions } from "../meta-gate.js";
2
1
  import { boardCard, boardColumns } from "./board-columns.js";
2
+ import { usePermissions } from "../meta-gate.js";
3
3
  import { can } from "../permissions.js";
4
4
  import { RecordCard } from "./record-card.js";
5
5
  import { collision, columnCoordinates, columnId } from "./board-dnd.js";
@@ -1,5 +1,5 @@
1
- import { recordKey, recordTitleField } from "../../live/model-helpers.js";
2
1
  import { humanize } from "../../live/naming.js";
2
+ import { recordKey, recordTitleField } from "../../live/model-helpers.js";
3
3
  import { listColumnNames } from "../../live/columns-from-model.js";
4
4
  import { displayValue } from "../../live/display-value.js";
5
5
  import { photosKey } from "../../live/row-photos.js";
@@ -2,9 +2,9 @@ import { cn } from "../../lib/cn.js";
2
2
  import { Button } from "../../primitives/button.js";
3
3
  import { Problem } from "../pages/problem.js";
4
4
  import { humanize } from "../../live/naming.js";
5
- import { useAdminMeta } from "../meta-gate.js";
6
5
  import { ErrorBanner } from "../error-banner.js";
7
6
  import { mapCards } from "./list-displays.js";
7
+ import { useAdminMeta } from "../meta-gate.js";
8
8
  import { useDebounced } from "../../lib/use-debounced.js";
9
9
  import { RecordCard } from "./record-card.js";
10
10
  import { boundsAround, worldArea } from "../map/map-area.js";
@@ -1,13 +1,13 @@
1
1
  import { Badge } from "../../primitives/badge.js";
2
2
  import { CustomBoundary } from "../pages/custom-boundary.js";
3
- import { recordKey } from "../../live/model-helpers.js";
4
3
  import { humanize } from "../../live/naming.js";
5
- import { useProjectUi } from "../pages/project-ui.js";
6
4
  import { markdownExcerpt } from "../../markdown/markdown-excerpt.js";
7
5
  import { isMarkdown } from "../../markdown/markdown-hint.js";
6
+ import { recordKey } from "../../live/model-helpers.js";
8
7
  import { displayValue } from "../../live/display-value.js";
9
8
  import { amountParts, cardFields, filledAmount, filledMeta } from "./list-displays.js";
10
9
  import { AppLink } from "../use-app-address.js";
10
+ import { useProjectUi } from "../pages/project-ui.js";
11
11
  import { shownWidget } from "../field-types/shown-widget.js";
12
12
  import { WidgetPart } from "../field-types/widget-part.js";
13
13
  import { Markdown } from "../../markdown/markdown.js";
@@ -1,5 +1,5 @@
1
- import { useAdminMeta } from "../meta-gate.js";
2
1
  import { columnFilter } from "./board-columns.js";
2
+ import { useAdminMeta } from "../meta-gate.js";
3
3
  import { useLiveRows } from "../../live/use-live-rows.js";
4
4
  import { useDisplayRows } from "./use-display-rows.js";
5
5
  //#region src/app/displays/use-board-column.ts
@@ -1,6 +1,6 @@
1
1
  import { useClient } from "../../data/api-provider.js";
2
- import { recordKey } from "../../live/model-helpers.js";
3
2
  import { useToast } from "../../toasts/toast-provider.js";
3
+ import { recordKey } from "../../live/model-helpers.js";
4
4
  import { refusalReason } from "./board-columns.js";
5
5
  import { useRefreshResource } from "../pages/use-layout-data.js";
6
6
  import { useState } from "react";
@@ -1,8 +1,8 @@
1
1
  import { keys } from "../../data/query-keys.js";
2
2
  import { useClient } from "../../data/api-provider.js";
3
- import { useAdminMeta } from "../meta-gate.js";
4
3
  import { listPhotos, withPhotos } from "../../live/row-photos.js";
5
4
  import { displayRow } from "./list-displays.js";
5
+ import { useAdminMeta } from "../meta-gate.js";
6
6
  import { listLabels, withLabels } from "../../live/relation-labels.js";
7
7
  import { areaFilter, requestZoom } from "../map/map-area.js";
8
8
  import { keepPreviousData, useQuery } from "@tanstack/react-query";
@@ -0,0 +1,11 @@
1
+ //#region src/app/embedded-list/cut-off-note.ts
2
+ /**
3
+ * What a list that shows only its first `shown` of `total` records says about the rest, as "The first 10 of 37.";
4
+ * nothing when it shows them all. An `estimated` total is the planner's, so it reads "about".
5
+ */
6
+ const cutOffNote = (shown, total, estimated) => {
7
+ if (shown >= total) return void 0;
8
+ return `The first ${shown} of ${estimated ? "about " : ""}${total.toLocaleString("en-GB")}.`;
9
+ };
10
+ //#endregion
11
+ export { cutOffNote };
@@ -1,14 +1,14 @@
1
1
  import { useIsDesktop, useIsXs } from "../../lib/use-media-query.js";
2
2
  import { Skeleton } from "../../primitives/skeleton.js";
3
- import { recordKey } from "../../live/model-helpers.js";
4
3
  import { humanize } from "../../live/naming.js";
5
- import { useProjectUi } from "../pages/project-ui.js";
6
- import { useAdminMeta } from "../meta-gate.js";
7
4
  import { ErrorBanner } from "../error-banner.js";
5
+ import { recordKey } from "../../live/model-helpers.js";
8
6
  import { listColumnNames } from "../../live/columns-from-model.js";
9
7
  import { displayRow, loadedFields, shownDisplay } from "../displays/list-displays.js";
10
8
  import { defaultOrderBy, parseSort, sortToOrderBy } from "../list-order.js";
9
+ import { useAdminMeta } from "../meta-gate.js";
11
10
  import { AppLink, useAppAddress } from "../use-app-address.js";
11
+ import { useProjectUi } from "../pages/project-ui.js";
12
12
  import { DataGrid } from "../../data-grid/data-grid.js";
13
13
  import { viewAllAddress } from "./embedded-display.js";
14
14
  import { BoardDisplay } from "../displays/board-display.js";
@@ -17,6 +17,7 @@ import { CustomDisplay } from "../displays/custom-display.js";
17
17
  import { MapDisplay } from "../displays/map-display.js";
18
18
  import { DisplaySwitch } from "../displays/display-controls.js";
19
19
  import { embeddedColumns } from "./embedded-columns.js";
20
+ import { cutOffNote } from "./cut-off-note.js";
20
21
  import { useEmbeddedRows } from "./use-embedded-rows.js";
21
22
  import { useMemo, useState } from "react";
22
23
  import { ArrowRight } from "lucide-react";
@@ -35,7 +36,8 @@ const Loading = () => /* @__PURE__ */ jsx("div", {
35
36
  });
36
37
  /**
37
38
  * The first `limit` records of a list, drawn by the list page's own table (sized to its rows) or display, and a link
38
- * to the whole list with the same filter, order and display. On a phone a cards display is one row that scrolls sideways.
39
+ * to the whole list with the same filter, order and display, beside a note such as "The first 10 of 37." when there are
40
+ * more. On a phone a cards display is one row that scrolls sideways.
39
41
  */
40
42
  const EmbeddedList = ({ model, view, filter, sort, columns, limit, display, empty, row = false, viewAll, link = true }) => {
41
43
  const { resources, views } = useAdminMeta();
@@ -68,7 +70,7 @@ const EmbeddedList = ({ model, view, filter, sort, columns, limit, display, empt
68
70
  limit,
69
71
  fields
70
72
  });
71
- const loaded = rows.data;
73
+ const loaded = rows.data?.rows;
72
74
  const source = useMemo(() => loaded && {
73
75
  total: loaded.length,
74
76
  rowAt: (index) => loaded[index]
@@ -113,8 +115,8 @@ const EmbeddedList = ({ model, view, filter, sort, columns, limit, display, empt
113
115
  }
114
116
  const list = {
115
117
  resource: model.name,
116
- rows: rows.data.map((row) => displayRow(model, row)),
117
- total: rows.data.length,
118
+ rows: rows.data.rows.map((row) => displayRow(model, row)),
119
+ total: rows.data.total,
118
120
  loading: false,
119
121
  error: null,
120
122
  more: false,
@@ -134,6 +136,7 @@ const EmbeddedList = ({ model, view, filter, sort, columns, limit, display, empt
134
136
  onFollow: () => openRecord(row)
135
137
  });
136
138
  const singular = view?.names?.singular ?? humanize(model.name);
139
+ const note = cutOffNote(source.total, rows.data.total, rows.data.estimated);
137
140
  return /* @__PURE__ */ jsxs("div", {
138
141
  className: "flex flex-col gap-3",
139
142
  children: [!shown ? /* @__PURE__ */ jsx(DataGrid, {
@@ -177,7 +180,13 @@ const EmbeddedList = ({ model, view, filter, sort, columns, limit, display, empt
177
180
  }) : /* @__PURE__ */ jsx(CustomDisplay, {
178
181
  display: shown,
179
182
  list
180
- }), allLink]
183
+ }), note && link ? /* @__PURE__ */ jsxs("div", {
184
+ className: "flex flex-wrap items-center justify-between gap-2",
185
+ children: [/* @__PURE__ */ jsx("p", {
186
+ className: "text-xs text-muted-foreground",
187
+ children: note
188
+ }), allLink]
189
+ }) : allLink]
181
190
  });
182
191
  };
183
192
  //#endregion
@@ -1,15 +1,16 @@
1
1
  import { keys } from "../../data/query-keys.js";
2
2
  import { useClient } from "../../data/api-provider.js";
3
3
  import { recordId } from "../../live/model-helpers.js";
4
- import { useAdminMeta } from "../meta-gate.js";
5
4
  import { listPhotos, withPhotos } from "../../live/row-photos.js";
5
+ import { useAdminMeta } from "../meta-gate.js";
6
6
  import { listLabels, withLabels } from "../../live/relation-labels.js";
7
7
  import { keepPreviousData, useQuery } from "@tanstack/react-query";
8
8
  //#region src/app/embedded-list/use-embedded-rows.ts
9
9
  /**
10
10
  * The first `limit` records in `orderBy` order, as the list page's table and displays get them: relations among
11
- * `fields` as `{ id, name }`, named in the same call, with the photos of its cards. A filter through a join resource may hold hundreds of keys, so it
12
- * goes in a JSON body.
11
+ * `fields` as `{ id, name }`, named in the same call, with the photos of its cards, and how many records match in all,
12
+ * counted in the same call: `estimated` when more than the server counts exactly match. A filter through a join
13
+ * resource may hold hundreds of keys, so it goes in a JSON body.
13
14
  */
14
15
  const useEmbeddedRows = ({ model, filter, orderBy, limit, fields }) => {
15
16
  const client = useClient();
@@ -24,13 +25,24 @@ const useEmbeddedRows = ({ model, filter, orderBy, limit, fields }) => {
24
25
  filter: filter || void 0,
25
26
  orderBy: orderBy || void 0,
26
27
  pageSize: limit,
28
+ count: "exact",
27
29
  labels,
28
30
  photos
29
31
  });
30
- return withLabels(resources, model, fields, withPhotos(model, page.items, page.photos), page.labels).map((row, index) => ({
32
+ const rows = withLabels(resources, model, fields, withPhotos(model, page.items, page.photos), page.labels).map((row, index) => ({
31
33
  ...row,
32
34
  id: recordId(model, page.items[index])
33
35
  }));
36
+ if (page.nextPageToken === "") return {
37
+ rows,
38
+ total: rows.length,
39
+ estimated: false
40
+ };
41
+ return {
42
+ rows,
43
+ total: page.totalSize ?? page.totalSizeEstimate,
44
+ estimated: page.totalSize === void 0
45
+ };
34
46
  }
35
47
  });
36
48
  };
@@ -1,10 +1,10 @@
1
1
  import { cn } from "../../lib/cn.js";
2
2
  import { Skeleton } from "../../primitives/skeleton.js";
3
3
  import { humanize } from "../../live/naming.js";
4
- import { useAdminMeta, usePermissions } from "../meta-gate.js";
5
4
  import { Section } from "../../record-view/section.js";
6
5
  import { shownImage } from "../../live/file-values.js";
7
6
  import { ErrorBanner } from "../error-banner.js";
7
+ import { useAdminMeta, usePermissions } from "../meta-gate.js";
8
8
  import { FileImage } from "../../live/file-image.js";
9
9
  import { galleryTiles } from "./gallery-layout.js";
10
10
  import { Lightbox } from "./lightbox.js";
@@ -1,9 +1,9 @@
1
1
  import { cn } from "../../lib/cn.js";
2
2
  import { useIsDesktop } from "../../lib/use-media-query.js";
3
3
  import { useFocusTrap } from "../../lib/use-focus-trap.js";
4
- import { Sheet } from "../../primitives/sheet.js";
5
4
  import { shownImage } from "../../live/file-values.js";
6
5
  import { FileImage } from "../../live/file-image.js";
6
+ import { Sheet } from "../../primitives/sheet.js";
7
7
  import { keyStep, steppedPhoto, swipeStep, togglesDetails } from "./gallery-layout.js";
8
8
  import { readDetailsOpen, writeDetailsOpen } from "./details-open-storage.js";
9
9
  import { useEffect, useId, useRef, useState } from "react";
@@ -1,11 +1,11 @@
1
1
  import { Skeleton } from "../../primitives/skeleton.js";
2
- import { recordKey, recordTitle } from "../../live/model-helpers.js";
3
2
  import { humanize } from "../../live/naming.js";
4
- import { useProjectUi } from "../pages/project-ui.js";
5
- import { useAdminMeta } from "../meta-gate.js";
6
3
  import { ErrorBanner } from "../error-banner.js";
4
+ import { recordKey, recordTitle } from "../../live/model-helpers.js";
7
5
  import { loadedFields } from "../displays/list-displays.js";
6
+ import { useAdminMeta } from "../meta-gate.js";
8
7
  import { useAppAddress } from "../use-app-address.js";
8
+ import { useProjectUi } from "../pages/project-ui.js";
9
9
  import { DataGrid } from "../../data-grid/data-grid.js";
10
10
  import { embeddedColumns } from "../embedded-list/embedded-columns.js";
11
11
  import { useHandOrder } from "./use-hand-order.js";
@@ -1,9 +1,9 @@
1
1
  import { keys } from "../../data/query-keys.js";
2
2
  import { useClient } from "../../data/api-provider.js";
3
- import { recordId, recordKey } from "../../live/model-helpers.js";
4
3
  import { useToast } from "../../toasts/toast-provider.js";
5
- import { useAdminMeta } from "../meta-gate.js";
4
+ import { recordId, recordKey } from "../../live/model-helpers.js";
6
5
  import { refusalReason } from "../displays/board-columns.js";
6
+ import { useAdminMeta } from "../meta-gate.js";
7
7
  import { useRefreshResource } from "../pages/use-layout-data.js";
8
8
  import { listLabels, withLabels } from "../../live/relation-labels.js";
9
9
  import { useRef, useState } from "react";
@@ -1,7 +1,7 @@
1
1
  import { Button } from "../../primitives/button.js";
2
2
  import { humanize } from "../../live/naming.js";
3
- import { ResponsiveDialog } from "../../primitives/responsive-dialog.js";
4
3
  import { ErrorBanner } from "../error-banner.js";
4
+ import { ResponsiveDialog } from "../../primitives/responsive-dialog.js";
5
5
  import { unmappedRequired } from "./mapping.js";
6
6
  import { ImportCheckStep, ImportChecking } from "./import-check-step.js";
7
7
  import { ImportFileStep } from "./import-file-step.js";
@@ -1,7 +1,7 @@
1
1
  import { keys } from "../../data/query-keys.js";
2
2
  import { useClient } from "../../data/api-provider.js";
3
- import { recordKey } from "../../live/model-helpers.js";
4
3
  import { useToast } from "../../toasts/toast-provider.js";
4
+ import { recordKey } from "../../live/model-helpers.js";
5
5
  import { useRef, useState } from "react";
6
6
  import { isApiError } from "@protobase/client";
7
7
  import { useQueryClient } from "@tanstack/react-query";
@@ -3,17 +3,17 @@ import { usePageScroll } from "../app-shell/page-scroll.js";
3
3
  import { PageHeader } from "../app-shell/page-header.js";
4
4
  import { useAuth } from "../auth/auth-provider.js";
5
5
  import { Button, buttonClass } from "../primitives/button.js";
6
- import { recordKey, recordTitleField } from "../live/model-helpers.js";
7
6
  import { humanize } from "../live/naming.js";
8
- import { useProjectUi } from "./pages/project-ui.js";
9
- import { Notice, useAdminMeta, usePermissions } from "./meta-gate.js";
10
- import { Sheet } from "../primitives/sheet.js";
11
7
  import { ErrorBanner } from "./error-banner.js";
8
+ import { recordKey, recordTitleField } from "../live/model-helpers.js";
12
9
  import { columnsFromModel, listColumnNames } from "../live/columns-from-model.js";
13
10
  import { displayRow, listDisplayChoices, loadedFields, shownListDisplay } from "./displays/list-displays.js";
14
11
  import { parseSort, sortToOrderBy } from "./list-order.js";
15
12
  import { listedResource } from "./current-address.js";
13
+ import { Notice, useAdminMeta, usePermissions } from "./meta-gate.js";
16
14
  import { AppLink, useAppAddress } from "./use-app-address.js";
15
+ import { useProjectUi } from "./pages/project-ui.js";
16
+ import { Sheet } from "../primitives/sheet.js";
17
17
  import { can, rowAllows } from "./permissions.js";
18
18
  import { pinnedStorageKey } from "../data-grid/pinned-storage.js";
19
19
  import { DataGrid } from "../data-grid/data-grid.js";
@@ -1,6 +1,6 @@
1
- import { useAdminMeta } from "../meta-gate.js";
2
1
  import { Section } from "../../record-view/section.js";
3
2
  import { SidebarCard } from "../../record-view/record-sidebar.js";
3
+ import { useAdminMeta } from "../meta-gate.js";
4
4
  import { recordPosition } from "./record-position.js";
5
5
  import { Suspense, lazy } from "react";
6
6
  import { jsx } from "react/jsx-runtime";
@@ -1,11 +1,11 @@
1
1
  import { Button } from "../../../primitives/button.js";
2
- import { useProjectUi } from "../project-ui.js";
3
- import { useAdminMeta } from "../../meta-gate.js";
4
- import { ResponsiveDialog } from "../../../primitives/responsive-dialog.js";
5
2
  import { Field } from "../../../record-view/field.js";
6
3
  import { isChosen } from "../../create/create-values.js";
7
4
  import { ErrorBanner } from "../../error-banner.js";
5
+ import { useAdminMeta } from "../../meta-gate.js";
6
+ import { useProjectUi } from "../project-ui.js";
8
7
  import { FieldEditor } from "../../field-editor.js";
8
+ import { ResponsiveDialog } from "../../../primitives/responsive-dialog.js";
9
9
  import { answeredValues, inputField, inputHints, refusedAnswers, startingAnswers } from "./input-answers.js";
10
10
  import { inputErrors } from "./input-errors.js";
11
11
  import { useId, useState } from "react";
@@ -1,6 +1,6 @@
1
1
  import { Skeleton } from "../../../primitives/skeleton.js";
2
- import { useAdminMeta } from "../../meta-gate.js";
3
2
  import { ErrorBanner } from "../../error-banner.js";
3
+ import { useAdminMeta } from "../../meta-gate.js";
4
4
  import { RecordScope } from "../record-scope.js";
5
5
  import { scopeOf, useListPage } from "../use-layout-data.js";
6
6
  import { propsOf } from "./block-props.js";
@@ -3,18 +3,18 @@ import { Dialog } from "../../../primitives/dialog.js";
3
3
  import { useClient } from "../../../data/api-provider.js";
4
4
  import { humanize } from "../../../live/naming.js";
5
5
  import { useToast } from "../../../toasts/toast-provider.js";
6
- import { useAdminMeta, usePermissions } from "../../meta-gate.js";
7
6
  import { Field } from "../../../record-view/field.js";
8
7
  import { differs, toDraft, toPatchValue } from "../../../live/field-values.js";
9
8
  import { createBody, isChosen } from "../../create/create-values.js";
10
9
  import { ErrorBanner } from "../../error-banner.js";
10
+ import { useAdminMeta, usePermissions } from "../../meta-gate.js";
11
11
  import { FieldEditor } from "../../field-editor.js";
12
+ import { fieldErrors, fieldMessage } from "../../field-errors.js";
13
+ import { useFocusFirstInvalid } from "../../use-focus-first-invalid.js";
12
14
  import { useLayoutRecord } from "../record-scope.js";
13
15
  import { can } from "../../permissions.js";
14
16
  import { useFirstRecord, useRefreshResource } from "../use-layout-data.js";
15
17
  import { propsOf } from "./block-props.js";
16
- import { fieldErrors, fieldMessage } from "../../field-errors.js";
17
- import { useFocusFirstInvalid } from "../../use-focus-first-invalid.js";
18
18
  import { useState } from "react";
19
19
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
20
20
  //#region src/app/pages/blocks/modal-form.tsx
@@ -1,6 +1,6 @@
1
1
  import { Skeleton } from "../../../primitives/skeleton.js";
2
- import { useAdminMeta } from "../../meta-gate.js";
3
2
  import { ErrorBanner } from "../../error-banner.js";
3
+ import { useAdminMeta } from "../../meta-gate.js";
4
4
  import { RecordScope } from "../record-scope.js";
5
5
  import { useFirstRecord } from "../use-layout-data.js";
6
6
  import { propsOf } from "./block-props.js";
@@ -1,10 +1,10 @@
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 { useAdminMeta } from "../meta-gate.js";
5
4
  import { fileShown, shownImage } from "../../live/file-values.js";
6
5
  import { isMarkdown } from "../../markdown/markdown-hint.js";
7
6
  import { displayValue } from "../../live/display-value.js";
7
+ import { useAdminMeta } from "../meta-gate.js";
8
8
  import { AppLink } from "../use-app-address.js";
9
9
  import { FileImage } from "../../live/file-image.js";
10
10
  import { useShownWidget } from "../field-types/shown-widget.js";
@@ -1,8 +1,8 @@
1
1
  import { useClient, useResourceClient } from "../../data/api-provider.js";
2
2
  import { useToast } from "../../toasts/toast-provider.js";
3
- import { useProjectUi } from "./project-ui.js";
4
3
  import { useAdminMeta, usePermissions } from "../meta-gate.js";
5
4
  import { useAppAddress } from "../use-app-address.js";
5
+ import { useProjectUi } from "./project-ui.js";
6
6
  import { can } from "../permissions.js";
7
7
  import { actionFor, linkTarget, openLink } from "./action-href.js";
8
8
  import { useRefreshResource } from "./use-layout-data.js";
@@ -1,6 +1,6 @@
1
- import { usePermissions } from "./meta-gate.js";
2
1
  import { InlineChildTable } from "../inline-child-table/inline-child-table.js";
3
2
  import { Section } from "../record-view/section.js";
3
+ import { usePermissions } from "./meta-gate.js";
4
4
  import { can } from "./permissions.js";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  //#region src/app/record-lines.tsx
@@ -8,10 +8,7 @@ import { keys } from "../data/query-keys.js";
8
8
  import { useClient } from "../data/api-provider.js";
9
9
  import { useNavigationGuard, useRouter } from "./router.js";
10
10
  import { useOpenedRecord } from "../data/use-record.js";
11
- import { recordTitle } from "../live/model-helpers.js";
12
11
  import { humanize } from "../live/naming.js";
13
- import { useProjectUi } from "./pages/project-ui.js";
14
- import { Notice, useAdminMeta, usePermissions } from "./meta-gate.js";
15
12
  import { Field } from "../record-view/field.js";
16
13
  import { Section } from "../record-view/section.js";
17
14
  import { MetadataCard, RelatedRecords, SidebarCard } from "../record-view/record-sidebar.js";
@@ -23,19 +20,22 @@ import { fieldHelp, helpShown, recordShown, whenShown } from "./record-mode/reco
23
20
  import { isChosen, keyValue } from "./create/create-values.js";
24
21
  import { ErrorBanner } from "./error-banner.js";
25
22
  import { isMarkdown } from "../markdown/markdown-hint.js";
23
+ import { recordTitle } from "../live/model-helpers.js";
26
24
  import { toneFor } from "../live/columns-from-model.js";
27
25
  import { displayValue } from "../live/display-value.js";
28
26
  import { filledFields } from "./filled-fields.js";
27
+ import { Notice, useAdminMeta, usePermissions } from "./meta-gate.js";
29
28
  import { AppLink, useAppAddress } from "./use-app-address.js";
29
+ import { useProjectUi } from "./pages/project-ui.js";
30
30
  import { shownWidget } from "./field-types/shown-widget.js";
31
31
  import { WidgetPart } from "./field-types/widget-part.js";
32
32
  import { Markdown } from "../markdown/markdown.js";
33
33
  import { FieldEditor } from "./field-editor.js";
34
+ import { fieldMessage } from "./field-errors.js";
35
+ import { useFocusFirstInvalid } from "./use-focus-first-invalid.js";
34
36
  import { can, fieldAccess } from "./permissions.js";
35
37
  import { ValueBadge } from "./value-badge.js";
36
38
  import { FieldValue } from "./pages/field-value.js";
37
- import { fieldMessage } from "./field-errors.js";
38
- import { useFocusFirstInvalid } from "./use-focus-first-invalid.js";
39
39
  import { namedIcon } from "./named-icon.js";
40
40
  import { useDeleteFlow } from "./delete/use-delete-flow.js";
41
41
  import { useRestore } from "./delete/use-restore.js";
@@ -1,10 +1,10 @@
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";
5
4
  import { ErrorBanner } from "../error-banner.js";
6
5
  import { displaysOf, loadedFields } from "../displays/list-displays.js";
7
6
  import { defaultOrderBy } from "../list-order.js";
7
+ import { useAdminMeta } from "../meta-gate.js";
8
8
  import { AppLink } from "../use-app-address.js";
9
9
  import { useLiveRows } from "../../live/use-live-rows.js";
10
10
  import { viewAllAddress } from "../embedded-list/embedded-display.js";
@@ -1,8 +1,8 @@
1
1
  import { Skeleton } from "../../primitives/skeleton.js";
2
2
  import { humanize } from "../../live/naming.js";
3
- import { useAdminMeta } from "../meta-gate.js";
4
3
  import { ErrorBanner } from "../error-banner.js";
5
4
  import { listedResource } from "../current-address.js";
5
+ import { useAdminMeta } from "../meta-gate.js";
6
6
  import { savedScope } from "../saved/saved-records.js";
7
7
  import { useSavedRecords } from "../saved/use-saved-records.js";
8
8
  import { RecordRowBody } from "./record-row-body.js";
@@ -1,7 +1,7 @@
1
1
  import { cn } from "../../lib/cn.js";
2
2
  import { toneDots } from "../../primitives/badge.js";
3
- import { recordTitleField } from "../../live/model-helpers.js";
4
3
  import { humanize } from "../../live/naming.js";
4
+ import { recordTitleField } from "../../live/model-helpers.js";
5
5
  import { toneFor } from "../../live/columns-from-model.js";
6
6
  import { displayValue } from "../../live/display-value.js";
7
7
  import { displayRow } from "../displays/list-displays.js";