@antelopejs/dms-database 0.1.1 → 0.2.0

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 (36) hide show
  1. package/README.md +1 -1
  2. package/dist/pages/schemas.js +2 -1
  3. package/dist/pages/schemas.js.map +1 -1
  4. package/dist/routes/tables.d.ts +1 -0
  5. package/dist/routes/tables.js +35 -10
  6. package/dist/routes/tables.js.map +1 -1
  7. package/frontend-vue/app/build/composables/useDataBrowserGrid.ts +4 -38
  8. package/frontend-vue/app/build/composables/useDatabaseHealth.ts +7 -4
  9. package/frontend-vue/app/build/composables/useDatabaseSchemas.ts +1 -2
  10. package/frontend-vue/app/build/composables/useDiagramPersistence.ts +49 -16
  11. package/frontend-vue/app/build/composables/useQueryStore.ts +59 -27
  12. package/frontend-vue/app/build/composables/useTableCounts.ts +50 -0
  13. package/frontend-vue/app/build/query/runs.ts +7 -27
  14. package/frontend-vue/app/build/schemas/useSchemasListing.ts +10 -33
  15. package/frontend-vue/app/components/ConnectionStatus.vue +14 -11
  16. package/frontend-vue/app/components/DataBrowserSidebar.vue +20 -42
  17. package/frontend-vue/app/components/DataBrowserTabBar.vue +1 -1
  18. package/frontend-vue/app/components/DataGrid.vue +43 -89
  19. package/frontend-vue/app/components/InstancePicker.vue +63 -55
  20. package/frontend-vue/app/components/QueryConsole.vue +47 -37
  21. package/frontend-vue/app/components/QueryLibrary.vue +20 -17
  22. package/frontend-vue/app/components/RowDrawer.vue +15 -18
  23. package/frontend-vue/app/components/SchemaDiagram.vue +7 -7
  24. package/frontend-vue/app/components/TableInspector.vue +134 -88
  25. package/frontend-vue/package.json +2 -1
  26. package/frontend-vue/pnpm-lock.yaml +883 -2587
  27. package/frontend-vue/tests/fixtures/inertia.ts +8 -0
  28. package/frontend-vue/tests/fixtures/serverRender.ts +219 -0
  29. package/frontend-vue/tests/fixtures/vueI18n.ts +4 -0
  30. package/frontend-vue/tests/helpers.test.ts +1 -0
  31. package/frontend-vue/tests/locales.test.ts +24 -0
  32. package/frontend-vue/tests/onDemandReads.test.ts +106 -0
  33. package/frontend-vue/tests/registration.test.ts +0 -12
  34. package/frontend-vue/tests/serverRender.test.ts +235 -0
  35. package/frontend-vue/vitest.config.ts +24 -0
  36. package/package.json +6 -5
package/README.md CHANGED
@@ -25,7 +25,7 @@ instance, `all` for every instance, otherwise the instance's name.
25
25
  - **Query console**: AQL with completion of the workspace's schemas, a library of past, saved and
26
26
  shared queries, and a dry run before any query that changes data.
27
27
 
28
- The module requires `@antelopejs/dms` 0.7.2 or later and `@antelopejs/dms-frontend` 0.5.2.
28
+ The module requires `@antelopejs/dms` 0.9 (`@antelopejs/interface-dms` 0.7) and `@antelopejs/dms-frontend` 0.6.
29
29
 
30
30
  ## Installation
31
31
 
@@ -15,10 +15,11 @@ const table_view_1 = require("@antelopejs/interface-dms/base/table-view");
15
15
  const page_1 = require("@antelopejs/interface-dms/page");
16
16
  const module_1 = require("../module");
17
17
  const schemaFilters_1 = require("../service/schemaFilters");
18
- const TABLE_QUERY = "schema={schema}&table={name}";
18
+ const TABLE_QUERY = "schema={{row.schema}}&table={{row.name}}";
19
19
  const tables = table_view_1.TableView.fromSource({
20
20
  caption: "$dms_database.schemas.caption",
21
21
  fetchUrl: "/api/database/tables/source",
22
+ fetchRowUrl: "/api/database/tables/source/row?id={{row.id}}",
22
23
  rowIdKey: "id",
23
24
  labelKey: "name",
24
25
  capabilities: { search: false, filter: true },
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/pages/schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/pages/schemas.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,7 @@ interface InstancesResult {
21
21
  declare const DatabaseTablesController_base: import("@antelopejs/interface-api").ControllerClass<object>;
22
22
  export declare class DatabaseTablesController extends DatabaseTablesController_base {
23
23
  source(user: User, scope: unknown, instance: unknown, q: unknown, has: unknown): Promise<TableSourceResult>;
24
+ sourceRow(user: User, idRaw: unknown): Promise<TableSourceRow>;
24
25
  instances(schemaRaw: unknown, search: unknown, limitRaw: unknown): Promise<InstancesResult>;
25
26
  }
26
27
  export {};
@@ -62,22 +62,28 @@ function countRows(schemaId, tableName, instance) {
62
62
  return (0, introspect_1.getTableElementCount)(schemaId, tableName);
63
63
  return (0, introspect_1.getTableElementCount)(schemaId, tableName, instance.id);
64
64
  }
65
- async function listTableSourceRows(locale, filters) {
66
- const needle = needleOf(filters.q);
67
- const summaries = await (0, introspect_1.listSchemaSummaries)();
68
- const registered = summaries.flatMap((summary) => summary.tables.map((table) => ({ schemaId: summary.id, table })));
69
- const tables = registered.filter((listed) => matchesStructure(listed, filters, needle));
70
- const counts = await Promise.all(tables.map(({ schemaId, table }) => countRows(schemaId, table.name, filters.instance)));
71
- const rows = tables.map(({ schemaId, table }, index) => ({
72
- id: `${schemaId}::${table.name}`,
65
+ function sourceRowId(schemaId, tableName) {
66
+ return `${schemaId}::${tableName}`;
67
+ }
68
+ function toSourceRow({ schemaId, table }, elementCount, locale) {
69
+ return {
70
+ id: sourceRowId(schemaId, table.name),
73
71
  schema: schemaId,
74
72
  name: table.name,
75
- elementCount: counts[index] ?? 0,
73
+ elementCount,
76
74
  columnCount: Object.keys(table.fields).length,
77
75
  indexCount: Object.keys(table.indexes ?? {}).length,
78
76
  relations: relationTargets(schemaId, table),
79
77
  modifiers: modifierNames(table, locale),
80
- }));
78
+ };
79
+ }
80
+ async function listTableSourceRows(locale, filters) {
81
+ const needle = needleOf(filters.q);
82
+ const summaries = await (0, introspect_1.listSchemaSummaries)();
83
+ const registered = summaries.flatMap((summary) => summary.tables.map((table) => ({ schemaId: summary.id, table })));
84
+ const tables = registered.filter((listed) => matchesStructure(listed, filters, needle));
85
+ const counts = await Promise.all(tables.map(({ schemaId, table }) => countRows(schemaId, table.name, filters.instance)));
86
+ const rows = tables.map((listed, index) => toSourceRow(listed, counts[index] ?? 0, locale));
81
87
  return {
82
88
  rows: filters.has.includes("empty")
83
89
  ? rows.filter((row) => row.elementCount === 0)
@@ -97,6 +103,17 @@ let DatabaseTablesController = class DatabaseTablesController extends (0, interf
97
103
  const { rows, all } = await listTableSourceRows((0, messages_1.localeOf)(user), (0, schemaFilters_1.readSchemaFilters)({ scope, instance, q, has }));
98
104
  return { results: rows, total: rows.length, all };
99
105
  }
106
+ async sourceRow(user, idRaw) {
107
+ const id = (0, query_1.asNonEmptyString)(idRaw);
108
+ (0, interface_api_util_1.assert)(id, 400, "Missing 'id'");
109
+ const summaries = await (0, introspect_1.listSchemaSummaries)();
110
+ const listed = summaries
111
+ .flatMap((summary) => summary.tables.map((table) => ({ schemaId: summary.id, table })))
112
+ .find(({ schemaId, table }) => sourceRowId(schemaId, table.name) === id);
113
+ (0, interface_api_util_1.assert)(listed, 404, `Unknown table ${id}`);
114
+ const count = await (0, introspect_1.getTableElementCount)(listed.schemaId, listed.table.name);
115
+ return toSourceRow(listed, count, (0, messages_1.localeOf)(user));
116
+ }
100
117
  async instances(schemaRaw, search, limitRaw) {
101
118
  const schema = (0, query_1.asNonEmptyString)(schemaRaw);
102
119
  (0, interface_api_util_1.assert)(schema, 400, "Missing 'schema'");
@@ -119,6 +136,14 @@ __decorate([
119
136
  __metadata("design:paramtypes", [Function, Object, Object, Object, Object]),
120
137
  __metadata("design:returntype", Promise)
121
138
  ], DatabaseTablesController.prototype, "source", null);
139
+ __decorate([
140
+ (0, interface_api_1.Get)("/source/row"),
141
+ __param(0, (0, auth_1.AuthRawUser)()),
142
+ __param(1, (0, interface_api_1.Parameter)("id", "query")),
143
+ __metadata("design:type", Function),
144
+ __metadata("design:paramtypes", [Function, Object]),
145
+ __metadata("design:returntype", Promise)
146
+ ], DatabaseTablesController.prototype, "sourceRow", null);
122
147
  __decorate([
123
148
  (0, interface_api_1.Get)("/instances"),
124
149
  __param(0, (0, interface_api_1.Parameter)("schema", "query")),
@@ -1 +1 @@
1
- {"version":3,"file":"tables.js","sourceRoot":"","sources":["../../src/routes/tables.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tables.js","sourceRoot":"","sources":["../../src/routes/tables.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { type BrowserTab, DEFAULT_INSTANCE_VALUE } from './useDataBrowserTabs'
2
- // Per-tab grid state (paging, sort, filters, column widths) and a data cache
3
- // so switching tabs restores instantly without a refetch. Keyed by
4
- // BrowserTab.id.
2
+ // Per-tab grid state (paging, sort, filters, column widths), keyed by
3
+ // BrowserTab.id. The rows themselves are `useApiData`'s: a tab switched back
4
+ // to shows its last page at once and reads it again.
5
5
 
6
6
  export interface ColumnFilterState {
7
7
  mode: 'is' | 'contains'
@@ -31,9 +31,6 @@ export interface GridData {
31
31
  rows: Record<string, unknown>[]
32
32
  total: number
33
33
  primaryKey: string | null
34
- // Serialised query parameters that produced this payload; lets the grid
35
- // skip refetching when nothing changed.
36
- paramsKey: string
37
34
  }
38
35
 
39
36
  export const GRID_PAGE_SIZES = [25, 50, 100, 200]
@@ -55,32 +52,15 @@ export function useDataBrowserGrid() {
55
52
  'dms-database-grid-states',
56
53
  () => ({}),
57
54
  )
58
- const cache = useDmsState<Record<string, GridData>>(
59
- 'dms-database-grid-cache',
60
- () => ({}),
61
- )
62
55
 
63
56
  function getState(tabId: string): GridState {
64
57
  if (!states.value[tabId]) states.value[tabId] = defaultGridState()
65
58
  return states.value[tabId]
66
59
  }
67
60
 
68
- function getCache(tabId: string): GridData | null {
69
- return cache.value[tabId] ?? null
70
- }
71
-
72
- function setCache(tabId: string, data: GridData) {
73
- cache.value[tabId] = data
74
- }
75
-
76
- function invalidate(tabId: string) {
77
- Reflect.deleteProperty(cache.value, tabId)
78
- }
79
-
80
61
  // Forget everything about a closed tab.
81
62
  function drop(tabId: string) {
82
63
  Reflect.deleteProperty(states.value, tabId)
83
- Reflect.deleteProperty(cache.value, tabId)
84
64
  }
85
65
 
86
66
  // A tab switched to another instance keeps what the user narrowed the
@@ -94,10 +74,9 @@ export function useDataBrowserGrid() {
94
74
  columnWidths: { ...from.columnWidths },
95
75
  page: 0,
96
76
  }
97
- Reflect.deleteProperty(cache.value, toId)
98
77
  }
99
78
 
100
- return { getState, getCache, setCache, invalidate, drop, carry }
79
+ return { getState, drop, carry }
101
80
  }
102
81
 
103
82
  // --- query helpers shared by the grid ---
@@ -162,16 +141,3 @@ export function browseListQuery(
162
141
  }
163
142
  return query
164
143
  }
165
-
166
- // Everything that changes the server payload (column widths deliberately not).
167
- export function browseParamsKey(tab: BrowserTab, state: GridState): string {
168
- return JSON.stringify([
169
- tab.id,
170
- state.page,
171
- state.pageSize,
172
- state.sortKey,
173
- state.sortDirection,
174
- state.search,
175
- activeFilterEntries(state),
176
- ])
177
- }
@@ -34,11 +34,14 @@ const EMPTY_HEALTH: OverviewHealth = {
34
34
  storage: [],
35
35
  }
36
36
 
37
- export function useDatabaseHealth() {
38
- const { useFetchAuth } = useAuthFetch()
39
- const { data, pending, error, refresh } = useFetchAuth<OverviewHealth>(
37
+ /** `refreshInterval` probes again on that interval while the page shows it. */
38
+ export function useDatabaseHealth(options: { refreshInterval?: number } = {}) {
39
+ const { data, pending, error, refresh } = useApiData<OverviewHealth>(
40
40
  HEALTH_ENDPOINT,
41
- { default: () => ({ ...EMPTY_HEALTH }) },
41
+ {
42
+ default: () => ({ ...EMPTY_HEALTH }),
43
+ refreshInterval: options.refreshInterval,
44
+ },
42
45
  )
43
46
 
44
47
  return {
@@ -110,8 +110,7 @@ export function inboundRelationsIn(
110
110
  }
111
111
 
112
112
  export function useDatabaseSchemas() {
113
- const { useFetchAuth } = useAuthFetch()
114
- const { data, pending, error, status, refresh } = useFetchAuth<{
113
+ const { data, pending, error, status, refresh } = useApiData<{
115
114
  schemas: SchemaSummary[]
116
115
  }>(SCHEMAS_ENDPOINT, { default: () => EMPTY_SCHEMAS })
117
116
 
@@ -32,6 +32,13 @@ export type DiagramNoteUpdate = Partial<
32
32
  Pick<DiagramNote, 'text' | 'x' | 'y' | 'width' | 'height' | 'color'>
33
33
  >
34
34
 
35
+ /** A schema's diagram as stored: its layout and its notes. */
36
+ export interface StoredDiagram {
37
+ schema: string
38
+ positions: DiagramPositions
39
+ notes: DiagramNote[]
40
+ }
41
+
35
42
  const BASE = '/api/database/diagram'
36
43
  // A request that hangs fails after this (ofetch's own `timeout`), so the
37
44
  // canvas shows the error and its "Try again" instead of "Saving…" forever.
@@ -40,12 +47,47 @@ const REQUEST_TIMEOUT_MS = 15_000
40
47
  export function useDiagramPersistence() {
41
48
  const { $authFetch } = useAuthFetch()
42
49
 
43
- async function fetchLayout(schema: string): Promise<DiagramPositions> {
44
- const res = await $authFetch<{ positions: DiagramPositions }>(
45
- `${BASE}/layout/${encodeURIComponent(schema)}`,
46
- { timeout: REQUEST_TIMEOUT_MS },
47
- )
48
- return res.positions ?? {}
50
+ // The schema whose diagram is read: in the browser only, when the canvas
51
+ // asks, since it draws and edits a working copy of it.
52
+ const readSchema = shallowRef<string | null>(null)
53
+ const stored = useApiData<StoredDiagram>(
54
+ () =>
55
+ readSchema.value ? `dms-database:diagram:${readSchema.value}` : null,
56
+ async ({ $authFetch: read, signal }) => {
57
+ const schema = readSchema.value as string
58
+ const [layout, notes] = await Promise.all([
59
+ read<{ positions: DiagramPositions }>(
60
+ `${BASE}/layout/${encodeURIComponent(schema)}`,
61
+ { timeout: REQUEST_TIMEOUT_MS, signal },
62
+ ),
63
+ read<{ items: DiagramNote[] }>(`${BASE}/notes`, {
64
+ query: { schema },
65
+ timeout: REQUEST_TIMEOUT_MS,
66
+ signal,
67
+ }),
68
+ ])
69
+ return {
70
+ schema,
71
+ positions: layout.positions ?? {},
72
+ notes: notes.items ?? [],
73
+ }
74
+ },
75
+ {
76
+ immediate: false,
77
+ server: false,
78
+ watch: false,
79
+ refreshOnPageRefresh: false,
80
+ },
81
+ )
82
+
83
+ /** Reads a schema's layout and notes; throws when they cannot be read. */
84
+ async function readDiagram(schema: string): Promise<StoredDiagram> {
85
+ readSchema.value = schema
86
+ await stored.execute()
87
+ const diagram = stored.data.value
88
+ if (stored.error.value || diagram?.schema !== schema)
89
+ throw stored.error.value ?? new Error('Diagram not read')
90
+ return diagram
49
91
  }
50
92
 
51
93
  async function saveLayout(
@@ -62,14 +104,6 @@ export function useDiagramPersistence() {
62
104
  )
63
105
  }
64
106
 
65
- async function fetchNotes(schema: string): Promise<DiagramNote[]> {
66
- const res = await $authFetch<{ items: DiagramNote[] }>(`${BASE}/notes`, {
67
- query: { schema },
68
- timeout: REQUEST_TIMEOUT_MS,
69
- })
70
- return res.items ?? []
71
- }
72
-
73
107
  async function createNote(payload: DiagramNoteCreate): Promise<DiagramNote> {
74
108
  return $authFetch<DiagramNote>(`${BASE}/notes`, {
75
109
  method: 'POST',
@@ -97,9 +131,8 @@ export function useDiagramPersistence() {
97
131
  }
98
132
 
99
133
  return {
100
- fetchLayout,
134
+ readDiagram,
101
135
  saveLayout,
102
- fetchNotes,
103
136
  createNote,
104
137
  updateNote,
105
138
  deleteNote,
@@ -1,5 +1,4 @@
1
1
  export type QueryLanguage = 'aql'
2
- export type QueryScope = 'me' | 'shared'
3
2
 
4
3
  export interface SavedQuery {
5
4
  id: string
@@ -68,31 +67,61 @@ import { HISTORY_KEPT } from '../query/runs'
68
67
 
69
68
  const QUERY_BASE = '/api/database/query'
70
69
 
70
+ /**
71
+ * The query console's library and requests. The library (the caller's saved
72
+ * queries, the team's shared ones, the runs the server keeps) is read as the
73
+ * console sets up: a server render reads it and hands it over with the page.
74
+ * Every write is a request of its own, after which the console refreshes
75
+ * the part of the library it changed.
76
+ */
71
77
  export function useQueryStore() {
72
78
  const { $authFetch } = useAuthFetch()
73
79
 
74
- const savedQueries = ref<SavedQuery[]>([])
75
- const historyItems = ref<HistoryEntry[]>([])
76
-
77
- async function fetchSaved(scope: QueryScope): Promise<void> {
78
- const response = await $authFetch<{ items: SavedQuery[] }>(
79
- `${QUERY_BASE}/saved`,
80
- { query: { scope } },
81
- )
82
- savedQueries.value = response.items ?? []
80
+ const saved = useApiData<{ items: SavedQuery[] }>(`${QUERY_BASE}/saved`, {
81
+ query: { scope: 'me' },
82
+ })
83
+ const shared = useApiData<{ items: SavedQuery[] }>(`${QUERY_BASE}/saved`, {
84
+ query: { scope: 'shared' },
85
+ })
86
+ const history = useApiData<{ items: HistoryEntry[] }>(
87
+ `${QUERY_BASE}/history`,
88
+ { query: { limit: HISTORY_KEPT } },
89
+ )
90
+ const reads = [saved, shared, history]
91
+
92
+ /** The saved queries and the shared ones, read again. */
93
+ async function refreshSaved(): Promise<void> {
94
+ await Promise.all([saved.refresh(), shared.refresh()])
83
95
  }
84
96
 
97
+ // A run a link names (`?history=`), read when the console opens it.
98
+ const entryId = shallowRef<string | null>(null)
99
+ const entry = useApiData<HistoryEntry>(
100
+ () =>
101
+ entryId.value
102
+ ? `${QUERY_BASE}/history/${encodeURIComponent(entryId.value)}`
103
+ : null,
104
+ {
105
+ immediate: false,
106
+ server: false,
107
+ watch: false,
108
+ refreshOnPageRefresh: false,
109
+ },
110
+ )
111
+
85
112
  async function fetchHistoryEntry(id: string): Promise<HistoryEntry> {
86
- return $authFetch<HistoryEntry>(
87
- `${QUERY_BASE}/history/${encodeURIComponent(id)}`,
88
- )
113
+ entryId.value = id
114
+ await entry.execute()
115
+ if (entry.error.value || !entry.data.value)
116
+ throw entry.error.value ?? new Error('History entry not read')
117
+ return entry.data.value
89
118
  }
90
119
 
91
120
  async function clearHistory(): Promise<void> {
92
121
  await $authFetch<{ success: boolean }>(`${QUERY_BASE}/history`, {
93
122
  method: 'DELETE',
94
123
  })
95
- historyItems.value = []
124
+ history.data.value = { items: [] }
96
125
  }
97
126
 
98
127
  async function dryRun(query: Record<string, unknown>): Promise<DryRunResult> {
@@ -102,15 +131,6 @@ export function useQueryStore() {
102
131
  })
103
132
  }
104
133
 
105
- /** Every run the server keeps, at once. */
106
- async function fetchHistory(): Promise<void> {
107
- const response = await $authFetch<{ items: HistoryEntry[] }>(
108
- `${QUERY_BASE}/history`,
109
- { query: { limit: HISTORY_KEPT } },
110
- )
111
- historyItems.value = response.items ?? []
112
- }
113
-
114
134
  async function executeQuery(
115
135
  query: Record<string, unknown>,
116
136
  source: string,
@@ -147,10 +167,22 @@ export function useQueryStore() {
147
167
  }
148
168
 
149
169
  return {
150
- savedQueries,
151
- historyItems,
152
- fetchSaved,
153
- fetchHistory,
170
+ /** The caller's saved queries. A failed refresh keeps the last list. */
171
+ savedQueries: computed(() => saved.data.value?.items ?? []),
172
+ /** The queries shared with the team, the caller's own included. */
173
+ sharedQueries: computed(() => shared.data.value?.items ?? []),
174
+ /** Every run the server keeps, newest first. */
175
+ historyItems: computed(() => history.data.value?.items ?? []),
176
+ /** The library's first read is still running. */
177
+ libraryLoading: computed(() =>
178
+ reads.some(
179
+ (read) => read.data.value === null && read.status.value !== 'error',
180
+ ),
181
+ ),
182
+ /** Settles once the library's first read did, failed or not. */
183
+ libraryRead: Promise.all(reads).then(() => undefined),
184
+ refreshSaved,
185
+ refreshHistory: () => history.refresh(),
154
186
  fetchHistoryEntry,
155
187
  clearHistory,
156
188
  dryRun,
@@ -0,0 +1,50 @@
1
+ import type { Ref } from 'vue'
2
+ import { isFilterToken } from './useDataBrowserGrid'
3
+ import { DEFAULT_INSTANCE_VALUE } from './useDataBrowserTabs'
4
+
5
+ const TABLES_ENDPOINT = '/api/database/browse/tables'
6
+
7
+ interface TableEntry {
8
+ name: string
9
+ elementCount: number
10
+ }
11
+
12
+ /**
13
+ * The rows of each table of a schema in one instance, for the data browser's
14
+ * table list. A server render reads them and hands them over with the page;
15
+ * another schema or instance is read once picked. No count shows while they
16
+ * load, nor once they failed: `failed` says so.
17
+ */
18
+ export function useTableCounts(
19
+ schema: Ref<string | null>,
20
+ instance: Ref<string>,
21
+ ) {
22
+ const { data, status } = useApiData<{ items: TableEntry[] }>(
23
+ () => (schema.value ? TABLES_ENDPOINT : null),
24
+ {
25
+ query: () => {
26
+ const query: Record<string, string> = {
27
+ filter_schema: isFilterToken(schema.value ?? ''),
28
+ }
29
+ if (instance.value !== DEFAULT_INSTANCE_VALUE)
30
+ query.filter_instance = isFilterToken(instance.value)
31
+ return query
32
+ },
33
+ },
34
+ )
35
+
36
+ return {
37
+ /** Rows by table name. */
38
+ counts: computed<Record<string, number>>(() =>
39
+ status.value === 'success'
40
+ ? Object.fromEntries(
41
+ (data.value?.items ?? []).map((item) => [
42
+ item.name,
43
+ item.elementCount,
44
+ ]),
45
+ )
46
+ : {},
47
+ ),
48
+ failed: computed(() => status.value === 'error'),
49
+ }
50
+ }
@@ -33,19 +33,20 @@ export interface DayGroup<T> {
33
33
  items: T[]
34
34
  }
35
35
 
36
- function dayKey(date: Date): string {
37
- return `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`
38
- }
39
-
40
- /** Entries by local calendar day, newest day first, in their given order. */
36
+ /**
37
+ * Entries by calendar day, newest day first, in their given order. `dayOf`
38
+ * names a date's day: the reader's (`regionalDayKey`), so that a server
39
+ * render groups as the browser does.
40
+ */
41
41
  export function groupByDay<T>(
42
42
  entries: T[],
43
43
  dateOf: (entry: T) => string,
44
+ dayOf: (date: Date) => string,
44
45
  ): DayGroup<T>[] {
45
46
  const groups = new Map<string, DayGroup<T>>()
46
47
  for (const entry of entries) {
47
48
  const date = new Date(dateOf(entry))
48
- const key = dayKey(date)
49
+ const key = dayOf(date)
49
50
  const group = groups.get(key) ?? { key, date, items: [] }
50
51
  group.items.push(entry)
51
52
  groups.set(key, group)
@@ -53,27 +54,6 @@ export function groupByDay<T>(
53
54
  return [...groups.values()]
54
55
  }
55
56
 
56
- const DAY_MS = 86_400_000
57
-
58
- /** "Today", "Yesterday" or the date, in the interface language. */
59
- export function dayLabel(
60
- date: Date,
61
- locale: string,
62
- words: { today: string; yesterday: string },
63
- ): string {
64
- const today = new Date()
65
- today.setHours(0, 0, 0, 0)
66
- const day = new Date(date)
67
- day.setHours(0, 0, 0, 0)
68
- const days = Math.round((today.getTime() - day.getTime()) / DAY_MS)
69
- if (days === 0) return words.today
70
- if (days === 1) return words.yesterday
71
- return new Intl.DateTimeFormat(locale, {
72
- day: 'numeric',
73
- month: 'short',
74
- }).format(date)
75
- }
76
-
77
57
  export type UnknownKind = 'schema' | 'instance' | 'table'
78
58
 
79
59
  /** A name a query used that its schema does not know. */
@@ -1,4 +1,4 @@
1
- import { computed, ref, watch } from 'vue'
1
+ import { computed } from 'vue'
2
2
  import {
3
3
  readFilterState,
4
4
  sourceQuery,
@@ -16,47 +16,24 @@ interface SourceResponse {
16
16
  all?: number
17
17
  }
18
18
 
19
- type ListingStatus = 'idle' | 'pending' | 'success' | 'error'
20
-
21
19
  export function useSchemasListing() {
22
20
  const route = useDmsRoute()
23
- const { $authFetch } = useAuthFetch()
24
21
  const state = computed<SchemasFilterState>(() => readFilterState(route.query))
25
- const query = computed(() => sourceQuery(state.value))
26
-
27
- // The counts of the last answer stay while the next one loads.
28
- const total = ref(0)
29
- const all = ref<number | null>(null)
30
- const status = ref<ListingStatus>('idle')
31
- let latest = 0
32
22
 
33
- async function load() {
34
- const request = ++latest
35
- status.value = 'pending'
36
- try {
37
- const response = await $authFetch<SourceResponse>(TABLES_SOURCE, {
38
- query: query.value,
39
- })
40
- if (request !== latest) return
41
- total.value = response.total
42
- all.value = response.all ?? null
43
- status.value = 'success'
44
- } catch {
45
- if (request === latest) status.value = 'error'
46
- }
47
- }
48
-
49
- // In the browser only: the server renders no count.
50
- if (typeof window !== 'undefined') {
51
- watch(() => JSON.stringify(query.value), load, { immediate: true })
52
- }
23
+ // Rendered on the server and handed over, the counts only (not the rows
24
+ // the route lists); the counts of the last answer stay while the next one
25
+ // loads.
26
+ const { data, status } = useApiData<SourceResponse>(TABLES_SOURCE, {
27
+ query: () => sourceQuery(state.value),
28
+ pick: ['total', 'all'],
29
+ })
53
30
 
54
31
  return {
55
32
  state,
56
33
  /** Tables the bar's filters list. */
57
- total,
34
+ total: computed(() => data.value?.total ?? 0),
58
35
  /** Registered tables before any filter; null until known. */
59
- all,
36
+ all: computed(() => data.value?.all ?? null),
60
37
  status,
61
38
  }
62
39
  }