@standardbeagle/edit-db 0.4.494 → 0.4.583
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/common/saved-objects.d.ts +40 -0
- package/dist/common/schema-queries.d.ts +1 -0
- package/dist/components/bulk-edit-dialog.d.ts +18 -0
- package/dist/components/content-viewer.d.ts +8 -1
- package/dist/components/data-table.d.ts +49 -2
- package/dist/components/detail-panel.d.ts +2 -2
- package/dist/components/export-button.d.ts +19 -0
- package/dist/components/export-button.test.d.ts +1 -0
- package/dist/components/filters/number-filter.d.ts +8 -1
- package/dist/components/fk-cell-popover.d.ts +5 -5
- package/dist/components/form-runner-host.d.ts +14 -0
- package/dist/components/form-runner.d.ts +43 -0
- package/dist/components/form-subform.d.ts +11 -0
- package/dist/components/form-subform.test.d.ts +0 -0
- package/dist/components/grouped-grid-summary.d.ts +17 -0
- package/dist/components/grouped-grid-summary.test.d.ts +0 -0
- package/dist/components/m2m-panel.d.ts +4 -5
- package/dist/components/ui/table.test.d.ts +1 -0
- package/dist/data-edit.d.ts +17 -4
- package/dist/data-panel.d.ts +0 -11
- package/dist/edit-db.css +1 -1
- package/dist/editor.d.ts +22 -1
- package/dist/editor.es.js +6822 -4695
- package/dist/editor.stories.d.ts +0 -1
- package/dist/editor.umd.cjs +41 -27
- package/dist/hooks/useColumnNav.d.ts +3 -3
- package/dist/hooks/useColumnSizingPersistence.d.ts +19 -0
- package/dist/hooks/useColumnVisibilityPersistence.d.ts +34 -0
- package/dist/hooks/useColumnVisibilityPersistence.test.d.ts +1 -0
- package/dist/hooks/useCompositeTableRef.d.ts +2 -2
- package/dist/hooks/useDataTable.d.ts +46 -5
- package/dist/hooks/useDebouncedCommit.test.d.ts +1 -0
- package/dist/hooks/useDeltaMutation.d.ts +20 -0
- package/dist/hooks/useDeltaMutation.test.d.ts +0 -0
- package/dist/hooks/useEditorConfig.d.ts +27 -0
- package/dist/hooks/useFitMode.d.ts +23 -0
- package/dist/hooks/useFitMode.test.d.ts +1 -0
- package/dist/hooks/usePanelSize.d.ts +28 -0
- package/dist/hooks/usePanelSize.test.d.ts +1 -0
- package/dist/hooks/usePath.d.ts +1 -0
- package/dist/hooks/useRowHoverActions.d.ts +26 -0
- package/dist/hooks/useSchema.d.ts +8 -2
- package/dist/hooks/useSchemaFilter.test.d.ts +1 -0
- package/dist/hooks/useTableExport.d.ts +13 -0
- package/dist/hooks/useTableMutation.d.ts +1 -4
- package/dist/hooks/useTableRef.d.ts +3 -3
- package/dist/hooks/useTableStats.d.ts +0 -24
- package/dist/index.d.ts +13 -1
- package/dist/lib/column-order.d.ts +17 -0
- package/dist/lib/column-order.test.d.ts +1 -0
- package/dist/lib/content-detect.d.ts +34 -0
- package/dist/lib/content-detect.sniff.test.d.ts +1 -0
- package/dist/lib/drill-stack.d.ts +19 -2
- package/dist/lib/export.d.ts +122 -0
- package/dist/lib/export.test.d.ts +1 -0
- package/dist/lib/field-validation.d.ts +16 -0
- package/dist/lib/fk.d.ts +13 -0
- package/dist/lib/form-definition.d.ts +57 -0
- package/dist/lib/form-definition.test.d.ts +1 -0
- package/dist/lib/form-runner-nav.d.ts +19 -0
- package/dist/lib/form-runner-nav.test.d.ts +1 -0
- package/dist/lib/form-subform.d.ts +12 -0
- package/dist/lib/form-subform.test.d.ts +1 -0
- package/dist/lib/form-widget.d.ts +36 -0
- package/dist/lib/form-widget.test.d.ts +1 -0
- package/dist/lib/format-value.d.ts +26 -0
- package/dist/lib/grid-grouping.d.ts +63 -0
- package/dist/lib/grid-grouping.test.d.ts +1 -0
- package/dist/lib/m2m.d.ts +26 -1
- package/dist/lib/mutation-payload.d.ts +37 -0
- package/dist/lib/mutation-payload.test.d.ts +1 -0
- package/dist/lib/query-builder.d.ts +116 -9
- package/dist/lib/row-id.d.ts +11 -0
- package/dist/lib/rows-by-pk-query.test.d.ts +1 -0
- package/dist/lib/scalar-types.d.ts +30 -0
- package/dist/lib/scalar-types.test.d.ts +1 -0
- package/dist/lib/table-action.d.ts +24 -0
- package/dist/{tableList.d.ts → table-list.d.ts} +1 -1
- package/dist/table-list.test.d.ts +0 -0
- package/dist/table-view.chart.test.d.ts +1 -0
- package/dist/table-view.d.ts +22 -0
- package/dist/table-view.test.d.ts +0 -0
- package/dist/types/schema.d.ts +45 -10
- package/package.json +2 -2
- package/dist/common/schema.d.ts +0 -2
- package/dist/data-data-table.d.ts +0 -17
- /package/dist/common/{schema.test.d.ts → saved-objects.test.d.ts} +0 -0
- /package/dist/{components/filters/use-debounced-commit.test.d.ts → common/schema-queries.test.d.ts} +0 -0
- /package/dist/{data-data-table.test.d.ts → components/bulk-edit-dialog.test.d.ts} +0 -0
- /package/dist/components/{table-dimensions.test.d.ts → content-viewer.test.d.ts} +0 -0
- /package/dist/{tableList.test.d.ts → components/form-runner.test.d.ts} +0 -0
- /package/dist/{components/filters/use-debounced-commit.d.ts → hooks/useDebouncedCommit.d.ts} +0 -0
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
import { Table, Join,
|
|
1
|
+
import { Table, Column, Join, SchemaContextValue } from '../types/schema';
|
|
2
2
|
import { ColumnFiltersState } from '@tanstack/react-table';
|
|
3
|
-
import { PkEqFilterResult } from './row-id';
|
|
3
|
+
import { PkEqFilterResult, PkFilter } from './row-id';
|
|
4
4
|
export interface FilterResult {
|
|
5
5
|
variables: Record<string, unknown>;
|
|
6
6
|
param: string;
|
|
7
7
|
filterText: string;
|
|
8
|
+
/**
|
|
9
|
+
* Non-null when the filter could not be built. The predicate is NOT part of
|
|
10
|
+
* the query, so the caller MUST refuse to run it rather than showing rows the
|
|
11
|
+
* filter was supposed to exclude. `null` with an empty `filterText` means
|
|
12
|
+
* "no filter requested", which is a different thing entirely.
|
|
13
|
+
*/
|
|
14
|
+
error: string | null;
|
|
8
15
|
}
|
|
9
16
|
export interface ColumnFilterValue {
|
|
10
17
|
operator: string;
|
|
@@ -14,6 +21,12 @@ export interface ColumnFilterResult {
|
|
|
14
21
|
variables: Record<string, unknown>;
|
|
15
22
|
params: string[];
|
|
16
23
|
filterTexts: string[];
|
|
24
|
+
/**
|
|
25
|
+
* One message per column filter that could not be turned into a predicate.
|
|
26
|
+
* Non-empty means the built predicate is NARROWER than what the UI is showing
|
|
27
|
+
* as active, so the caller must refuse the query instead of returning rows.
|
|
28
|
+
*/
|
|
29
|
+
errors: string[];
|
|
17
30
|
}
|
|
18
31
|
export interface PkTypeInfo {
|
|
19
32
|
name: string;
|
|
@@ -26,11 +39,62 @@ interface RowData {
|
|
|
26
39
|
export declare function isGraphQlName(value: unknown): value is string;
|
|
27
40
|
export declare function assertGraphQlName(value: unknown, kind: string): asserts value is string;
|
|
28
41
|
export declare function getFilterOperators(paramType: string): string[];
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Parses the header filter (a JSON `[column, operator, value, type]` tuple carried
|
|
44
|
+
* in the `filter` URL param) into a GraphQL predicate.
|
|
45
|
+
*
|
|
46
|
+
* A rejected filter reports an error rather than degrading to "no filter". Silently
|
|
47
|
+
* dropping it left the grid showing the UNFILTERED table while the filter UI still
|
|
48
|
+
* advertised the predicate as active — and select-all + Delete then operated over a
|
|
49
|
+
* result set that was not the one the user believed they had narrowed to.
|
|
50
|
+
*/
|
|
51
|
+
export declare function parseTableFilterString(filterString: string): FilterResult;
|
|
52
|
+
export declare function getRowPkValue(row: RowData, table: Table, rowIndex?: number): string;
|
|
53
|
+
/**
|
|
54
|
+
* The GraphQL type a filter/lookup VARIABLE must be declared as for a column of
|
|
55
|
+
* this paramType. It has to be the column's own scalar: the variable is used in a
|
|
56
|
+
* `FilterType<T>Input` field position, and GraphQL rejects any variable whose
|
|
57
|
+
* declared type is not that exact scalar — "Variable '$cf_x_0' of type 'String'
|
|
58
|
+
* used in position expecting type 'DateTime'" fails the WHOLE document, so one
|
|
59
|
+
* mistyped column empties the grid rather than degrading that one predicate.
|
|
60
|
+
*
|
|
61
|
+
* BigInt/Decimal values travel as decimal STRINGS (coerceForGql's default branch
|
|
62
|
+
* stringifies): a JSON number is a double, which rounds a bigint key past 2^53 and
|
|
63
|
+
* drops exact-decimal precision. The server's BigInt/Decimal scalars accept the
|
|
64
|
+
* string form for exactly this reason — see ExactNumericScalars.cs.
|
|
65
|
+
*/
|
|
32
66
|
export declare function getGraphQlType(paramType: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Widens a date-only bound ("2024-02-01") to the instant at the requested edge of
|
|
69
|
+
* that LOCAL day, in the ISO-8601 form the server's DateTime/DateTimeOffset scalars
|
|
70
|
+
* require.
|
|
71
|
+
*
|
|
72
|
+
* The date filter's control is `<input type="date">`, so its value carries no time
|
|
73
|
+
* — but the column it filters is a timestamp. Sent verbatim the value is not
|
|
74
|
+
* ISO-8601-complete and the scalar rejects it outright; sent as midnight it silently
|
|
75
|
+
* means "the first instant of the day", so "on or before 1 Feb" excludes everything
|
|
76
|
+
* recorded ON 1 Feb. Each operator therefore takes the edge that makes it true for
|
|
77
|
+
* the whole day.
|
|
78
|
+
*/
|
|
79
|
+
export declare function dayBoundary(date: string, edge: "start" | "end", gqlType: string, offsetMinutes?: number): string;
|
|
80
|
+
/**
|
|
81
|
+
* The wire form of one column filter: the operator actually emitted and its
|
|
82
|
+
* value(s). Everything passes through unchanged except a date-only bound on a
|
|
83
|
+
* timestamp column, where the operator may widen to a day RANGE (`_eq` on a
|
|
84
|
+
* timestamp column matches nothing otherwise — no row is recorded at exactly
|
|
85
|
+
* midnight).
|
|
86
|
+
*/
|
|
87
|
+
export declare function toWireFilter(operator: string, value: unknown, gqlType: string, offsetMinutes?: number): {
|
|
88
|
+
operator: string;
|
|
89
|
+
value: unknown;
|
|
90
|
+
};
|
|
33
91
|
export declare function buildColumnFilters(columnFilters: ColumnFiltersState, table: Table): ColumnFilterResult;
|
|
92
|
+
/**
|
|
93
|
+
* Every reason the requested filters could not be fully applied, header filter
|
|
94
|
+
* first. Empty means the built predicate matches exactly what the filter UI is
|
|
95
|
+
* advertising, which is the only condition under which the grid query may run.
|
|
96
|
+
*/
|
|
97
|
+
export declare function collectFilterErrors(table: Table, filterString: string, columnFilters: ColumnFiltersState): string[];
|
|
34
98
|
export declare function serializeColumnFilters(columnFilters: ColumnFiltersState): string;
|
|
35
99
|
export declare function deserializeColumnFilters(raw: string): ColumnFiltersState;
|
|
36
100
|
/**
|
|
@@ -42,6 +106,17 @@ export declare function getPkType(table: Table): string;
|
|
|
42
106
|
* Empty array if the table has no primary keys.
|
|
43
107
|
*/
|
|
44
108
|
export declare function getPkTypes(table: Table): PkTypeInfo[];
|
|
109
|
+
/**
|
|
110
|
+
* Picks the best index-served sort column for a table with no usable primary
|
|
111
|
+
* key: the leading key column of the clustered index if any (it IS the row
|
|
112
|
+
* order — sorting by it is free), else of a unique index, else of any index.
|
|
113
|
+
* Only sortable columns qualify — an index leading on a LOB/JSON column can't
|
|
114
|
+
* drive the grid's ORDER BY. Returns null when no index leads on a sortable,
|
|
115
|
+
* visible column; the caller falls back to its positional heuristic. Sorting a
|
|
116
|
+
* large table by an unindexed column re-sorts every row on every page turn, so
|
|
117
|
+
* this choice is a correctness-of-experience matter, not a micro-optimization.
|
|
118
|
+
*/
|
|
119
|
+
export declare function pickIndexedSortColumn(table: Table, isSortable?: (col: Column) => boolean): string | null;
|
|
45
120
|
/**
|
|
46
121
|
* Builds the variables dict that accompanies a buildQuery result for a single-record lookup.
|
|
47
122
|
* - Single PK: returns `{ id: <coerced value> }` matching the `$id` variable in the query.
|
|
@@ -58,7 +133,39 @@ export declare function buildPkEqVariables(idRoute: string, table: Table): Recor
|
|
|
58
133
|
* row fresh before echoing it back in an update.
|
|
59
134
|
*/
|
|
60
135
|
export declare function buildSingleRowQuery(table: Pick<Table, 'name'>, pkEq: Pick<PkEqFilterResult, 'filterText' | 'params'>, fields: readonly string[]): string;
|
|
61
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Builds ONE query fetching fresh snapshots of several rows by primary key —
|
|
138
|
+
* `{or: [pkEq, pkEq, ...]}` — so a bulk edit can echo current server state for
|
|
139
|
+
* every selected row in a single round trip (the multi-row analogue of
|
|
140
|
+
* {@link buildSingleRowQuery}'s fresh re-read). Rows come back under the `value`
|
|
141
|
+
* alias. Every key column of every row participates (composite-safe), values
|
|
142
|
+
* coerce through the same GraphQL-type rules as single-row PK filters (BigInt
|
|
143
|
+
* keys stay strings), and identifiers are asserted before any text is built.
|
|
144
|
+
*/
|
|
145
|
+
export declare function buildRowsByPkQuery(table: Pick<Table, 'name' | 'primaryKeys' | 'columns'>, pks: readonly PkFilter[], fields: readonly string[]): {
|
|
146
|
+
query: string;
|
|
147
|
+
variables: Record<string, unknown>;
|
|
148
|
+
} | null;
|
|
149
|
+
/**
|
|
150
|
+
* Columns included in a full-data export: every column EXCEPT binary payloads
|
|
151
|
+
* (non-PK), which have no useful CSV/JSON representation. Long-text columns ARE
|
|
152
|
+
* included — export means the full data, not the grid's preview projection.
|
|
153
|
+
* Single source of truth for export headers, fields, and the export query's
|
|
154
|
+
* SELECT list so the three cannot drift.
|
|
155
|
+
*/
|
|
156
|
+
export declare function exportableColumns(table: Table): Column[];
|
|
157
|
+
export interface BuildQueryOptions {
|
|
158
|
+
/**
|
|
159
|
+
* `grid` (default): the on-screen projection — large values excluded, FK label
|
|
160
|
+
* blocks and multi-join count/preview blocks included.
|
|
161
|
+
* `export`: the full-data projection — every exportable scalar column (long
|
|
162
|
+
* text included, binary excluded), and NO join/multi-join blocks: exports
|
|
163
|
+
* project scalar fields only, so fetching label/preview blocks for every row
|
|
164
|
+
* would be pure transfer waste.
|
|
165
|
+
*/
|
|
166
|
+
fields?: 'grid' | 'export';
|
|
167
|
+
}
|
|
168
|
+
export declare function buildQuery(table: Table, schema: SchemaContextValue, filterString: string, columnFilters: ColumnFiltersState, id?: string, filterTable?: string, filterColumn?: string, options?: BuildQueryOptions): string | null;
|
|
62
169
|
export interface DrillDownTarget {
|
|
63
170
|
/** The parent table whose row owns the child collection. */
|
|
64
171
|
parentTable: Table;
|
|
@@ -79,8 +186,8 @@ export interface DrillDownTarget {
|
|
|
79
186
|
export declare function canFlatFilterDrill(childJoin: Join): boolean;
|
|
80
187
|
/**
|
|
81
188
|
* Resolve the parent table + child collection field for a parent→child
|
|
82
|
-
* related-records drill-down. The child is `table`; the parent is `
|
|
83
|
-
* (or the destination of `table`'s single-join named `
|
|
189
|
+
* related-records drill-down. The child is `table`; the parent is `filterTable`
|
|
190
|
+
* (or the destination of `table`'s single-join named `filterTable` when the
|
|
84
191
|
* relationship is described from the child side). `filterColumn` (the child
|
|
85
192
|
* destination column) disambiguates when the parent has several multi-joins to
|
|
86
193
|
* the same child. Returns `null` when no parent multi-join targets the child —
|
|
@@ -100,5 +207,5 @@ export interface PagedResult {
|
|
|
100
207
|
* parent row was not found (no children / unknown id).
|
|
101
208
|
*/
|
|
102
209
|
export declare function unwrapDrillDownPage(response: Record<string, unknown> | null | undefined, parentField: string, childField: string): PagedResult;
|
|
103
|
-
export declare function resolveDrillDown(table: Table, schema:
|
|
210
|
+
export declare function resolveDrillDown(table: Table, schema: SchemaContextValue, filterTable?: string, filterColumn?: string): DrillDownTarget | null;
|
|
104
211
|
export {};
|
package/dist/lib/row-id.d.ts
CHANGED
|
@@ -26,5 +26,16 @@ export declare function rowIdOf(row: Record<string, unknown> | null | undefined,
|
|
|
26
26
|
export declare function pkFilterFor(row: Record<string, unknown> | null | undefined, table: TableLike): PkFilter | null;
|
|
27
27
|
export declare function buildPkEqFilter(row: Record<string, unknown> | null | undefined, table: Pick<Table, 'primaryKeys' | 'columns'>): PkEqFilterResult | null;
|
|
28
28
|
export declare function encodePkRoute(filter: PkFilter, table: TableLike): string;
|
|
29
|
+
/**
|
|
30
|
+
* Parses a route-encoded id back into a PK filter, or null when the route cannot
|
|
31
|
+
* key a row.
|
|
32
|
+
*
|
|
33
|
+
* An EMPTY segment is a parse failure, not a null key value. Primary-key columns
|
|
34
|
+
* are non-nullable, so `{line_id: null}` can never match a stored row — but it is
|
|
35
|
+
* a structurally valid filter, so callers guarding on "did the key resolve?"
|
|
36
|
+
* (see `pkResolveFailed` in data-edit.tsx) saw success, queried, matched zero
|
|
37
|
+
* rows, and then wrote an all-columns-blank UPDATE back. Returning null here is
|
|
38
|
+
* the established failure shape every caller already handles.
|
|
39
|
+
*/
|
|
29
40
|
export declare function parsePkRoute(raw: string, table: TableLike): PkFilter | null;
|
|
30
41
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One place that classifies a column's GraphQL scalar (`paramType`).
|
|
3
|
+
*
|
|
4
|
+
* The type mappers can emit Int, Short, Byte, BigInt, Decimal, Float, Boolean,
|
|
5
|
+
* DateTime, DateTimeOffset, JSON and String. Every surface that reasoned about
|
|
6
|
+
* types used to carry its own `['Int', 'Float']` list, so the four less common
|
|
7
|
+
* numeric scalars and the second timestamp scalar were each handled by whichever
|
|
8
|
+
* surfaces happened to remember them: a smallint column could not be filtered from
|
|
9
|
+
* the grid header, was not validated as a number in a form, and was sent as a
|
|
10
|
+
* string on write (which its `Short!` input rejects). Classifying in one module is
|
|
11
|
+
* what keeps those surfaces from drifting apart again.
|
|
12
|
+
*/
|
|
13
|
+
/** Strips the non-null marker: `Int!` -> `Int`. */
|
|
14
|
+
export declare function baseParamType(paramType: string | undefined): string;
|
|
15
|
+
/** Whole-number columns — they reject a fractional value. */
|
|
16
|
+
export declare function isIntegerScalar(paramType: string | undefined): boolean;
|
|
17
|
+
/** Any numeric column, whole or fractional. */
|
|
18
|
+
export declare function isNumericScalar(paramType: string | undefined): boolean;
|
|
19
|
+
/** Columns whose value must never be routed through a JS number. */
|
|
20
|
+
export declare function isExactScalar(paramType: string | undefined): boolean;
|
|
21
|
+
/** DateTime and DateTimeOffset — the columns whose bounds are instants. */
|
|
22
|
+
export declare function isTimestampScalar(paramType: string | undefined): boolean;
|
|
23
|
+
export declare function isBooleanScalar(paramType: string | undefined): boolean;
|
|
24
|
+
export declare function isStringScalar(paramType: string | undefined): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Validates numeric text and returns the value to send: the digits unchanged for
|
|
27
|
+
* an exact column, otherwise a number. Null means "not (yet) a complete numeric
|
|
28
|
+
* literal", which callers read as "no value", never as zero.
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseScalarNumber(raw: string, paramType: string | undefined): number | string | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { Table } from '../types/schema';
|
|
3
|
+
/**
|
|
4
|
+
* A host-contributed action on a TABLE in the navigation list. The editor renders
|
|
5
|
+
* every action in each table's kebab menu; what the action does is entirely the
|
|
6
|
+
* host's business (open a query designer, copy a connection string, …) — edit-db
|
|
7
|
+
* stays transport- and host-agnostic and just invokes the callback with the
|
|
8
|
+
* schema table. Built-in actions (Download CSV/JSON) use this same shape, so a
|
|
9
|
+
* host's contributions and the built-ins render as one uniform menu.
|
|
10
|
+
*/
|
|
11
|
+
export interface TableAction {
|
|
12
|
+
/** Stable identity, e.g. `edit-as-query`. */
|
|
13
|
+
id: string;
|
|
14
|
+
/** Menu item label. */
|
|
15
|
+
label: string;
|
|
16
|
+
/** Optional 16px icon component (lucide-style: takes className). */
|
|
17
|
+
icon?: ComponentType<{
|
|
18
|
+
className?: string;
|
|
19
|
+
}>;
|
|
20
|
+
/** Hides the action for tables it does not apply to. Absent means always shown. */
|
|
21
|
+
enabled?: (table: Table) => boolean;
|
|
22
|
+
/** Invoked with the schema table when the user picks the action. */
|
|
23
|
+
onSelect: (table: Table) => void | Promise<void>;
|
|
24
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Scales to several hundred tables:
|
|
5
5
|
* - Search filters by label, raw db name, and schema.
|
|
6
6
|
* - Tables group under collapsible schema headers (only when >1 schema exists).
|
|
7
|
-
* - The visible rows (headers + tables) are paged at {@link
|
|
7
|
+
* - The visible rows (headers + tables) are paged at {@link TABLE_LIST_PAGE_SIZE} so the DOM
|
|
8
8
|
* stays small regardless of total table count.
|
|
9
9
|
*
|
|
10
10
|
* @component
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Table } from './types/schema';
|
|
2
|
+
import { DrillFrame } from './lib/drill-stack';
|
|
3
|
+
import { ColumnFiltersState } from '@tanstack/react-table';
|
|
4
|
+
interface TableViewParams {
|
|
5
|
+
table: Table;
|
|
6
|
+
id?: string;
|
|
7
|
+
filterTable?: string;
|
|
8
|
+
filterColumn?: string;
|
|
9
|
+
selectedRowId?: string | null;
|
|
10
|
+
onRowSelect?: (rowId: string | null) => void;
|
|
11
|
+
onOpenColumn?: (panel: DrillFrame) => void;
|
|
12
|
+
/** Current stacking (parent/child drill-down) mode state. */
|
|
13
|
+
stackingEnabled?: boolean;
|
|
14
|
+
/** Toggle stacking mode. When supplied, the grid renders the mode toggle. */
|
|
15
|
+
onToggleStacking?: (next: boolean) => void;
|
|
16
|
+
}
|
|
17
|
+
/** Converts the already schema-validated grid filter state into GraphQL input
|
|
18
|
+
* variables. No identifier text is accepted from the UI: columns are looked up
|
|
19
|
+
* in the current schema and operators are validated by the shared builder. */
|
|
20
|
+
export declare function chartFilter(filters: ColumnFiltersState, table: Table): Record<string, unknown> | undefined;
|
|
21
|
+
export declare function TableView({ table, id, filterTable, filterColumn, selectedRowId, onRowSelect, onOpenColumn, stackingEnabled, onToggleStacking }: TableViewParams): JSX.Element;
|
|
22
|
+
export {};
|
|
File without changes
|
package/dist/types/schema.d.ts
CHANGED
|
@@ -57,16 +57,31 @@ export interface Column {
|
|
|
57
57
|
isReadOnly: boolean;
|
|
58
58
|
/** Custom metadata for the column */
|
|
59
59
|
metadata: ColumnMetadata;
|
|
60
|
+
/**
|
|
61
|
+
* Dialect-decided LOB semantics from the server: true when the value may be
|
|
62
|
+
* arbitrarily large and should be fetched on demand. Authoritative over any
|
|
63
|
+
* dbType-name guess (Postgres text / SQLite TEXT are ordinary strings).
|
|
64
|
+
* Optional only for servers that predate the field.
|
|
65
|
+
*/
|
|
66
|
+
isLargeValue?: boolean;
|
|
60
67
|
/** Maximum string length (for validation) */
|
|
61
68
|
maxLength?: number;
|
|
62
69
|
/** Minimum string length (for validation) */
|
|
63
70
|
minLength?: number;
|
|
64
|
-
/**
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
71
|
+
/**
|
|
72
|
+
* Minimum bound (for validation). Numeric for number columns; an ISO date
|
|
73
|
+
* string for temporal columns — the server fills engine storable windows
|
|
74
|
+
* (SQL Server datetime >= 1753) when no metadata min is declared.
|
|
75
|
+
*/
|
|
76
|
+
min?: number | string;
|
|
77
|
+
/** Maximum bound, same forms as min */
|
|
78
|
+
max?: number | string;
|
|
68
79
|
/** Step increment for numeric inputs */
|
|
69
80
|
step?: number;
|
|
81
|
+
/** Declared decimal precision from the database schema (null for non-decimal columns) */
|
|
82
|
+
precision?: number | null;
|
|
83
|
+
/** Declared decimal scale paired with precision */
|
|
84
|
+
scale?: number | null;
|
|
70
85
|
/** Regex pattern for validation */
|
|
71
86
|
pattern?: string;
|
|
72
87
|
/** Error message for pattern validation failures */
|
|
@@ -75,10 +90,10 @@ export interface Column {
|
|
|
75
90
|
inputType?: 'text' | 'email' | 'url' | 'tel' | 'date' | 'datetime-local' | 'number' | 'password' | 'search';
|
|
76
91
|
/** Default value for new records */
|
|
77
92
|
defaultValue?: string;
|
|
78
|
-
/** Allowed enum values */
|
|
79
|
-
enumValues?: string[];
|
|
80
|
-
/** Display labels for enum values */
|
|
81
|
-
enumLabels?: string[];
|
|
93
|
+
/** Allowed enum values. The server sends null, not undefined, for non-enum columns. */
|
|
94
|
+
enumValues?: string[] | null;
|
|
95
|
+
/** Display labels for enum values. Null for non-enum columns, as `enumValues` is. */
|
|
96
|
+
enumLabels?: string[] | null;
|
|
82
97
|
}
|
|
83
98
|
/**
|
|
84
99
|
* Relationship join definition between tables.
|
|
@@ -161,12 +176,32 @@ export interface Table {
|
|
|
161
176
|
singleJoins: Join[];
|
|
162
177
|
/** Many-to-many bridges through junction tables (optional; absent on older servers). */
|
|
163
178
|
manyToManyJoins?: ManyToManyJoin[];
|
|
179
|
+
/** Database indexes (optional; absent on older servers). */
|
|
180
|
+
indexes?: TableIndex[];
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* A database index on a table, key columns in key order (GraphQL names).
|
|
184
|
+
* Lets the grid pick a default sort an index can serve — sorting a large
|
|
185
|
+
* table by an unindexed column re-sorts every row on every page.
|
|
186
|
+
* @interface TableIndex
|
|
187
|
+
*/
|
|
188
|
+
export interface TableIndex {
|
|
189
|
+
/** Index name in the database catalog. */
|
|
190
|
+
name: string;
|
|
191
|
+
/** True when the index enforces uniqueness (includes PK indexes). */
|
|
192
|
+
isUnique: boolean;
|
|
193
|
+
/** True when the index defines the physical row order — the cheapest sort. */
|
|
194
|
+
isClustered: boolean;
|
|
195
|
+
/** True when the index backs the primary key constraint. */
|
|
196
|
+
isPrimaryKey: boolean;
|
|
197
|
+
/** Key column GraphQL names in key order; the leading column can be sorted for free. */
|
|
198
|
+
columns: string[];
|
|
164
199
|
}
|
|
165
200
|
/**
|
|
166
201
|
* Schema context value containing database metadata and loading state.
|
|
167
|
-
* @interface
|
|
202
|
+
* @interface SchemaContextValue
|
|
168
203
|
*/
|
|
169
|
-
export interface
|
|
204
|
+
export interface SchemaContextValue {
|
|
170
205
|
/** Whether schema data is currently loading */
|
|
171
206
|
loading: boolean;
|
|
172
207
|
/** Error object if schema loading failed, null otherwise */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@standardbeagle/edit-db",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.583",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@radix-ui/react-slot": "^1.2.4",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"storybook": "^10.4.1",
|
|
40
40
|
"tailwindcss": "^4.3.0",
|
|
41
41
|
"typescript": "^5.9.3",
|
|
42
|
-
"vite": "^7.3.
|
|
42
|
+
"vite": "^7.3.6",
|
|
43
43
|
"vite-plugin-dts": "^4.5.4",
|
|
44
44
|
"vitest": "^4.1.8"
|
|
45
45
|
},
|
package/dist/common/schema.d.ts
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
export declare const GET_SCHEMA = "{\n schema: __schema {\n queryType {\n fields {\n name\n type {\n fields {\n name\n type {\n ofType {\n fields {\n name\n type {\n kind\n ofType {\n name\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n ";
|
|
2
|
-
export declare const GET_DB_SCHEMA = "\nquery dbSchema {\n _dbSchema {\n dbName\n graphQlName\n labelColumn\n primaryKeys\n isEditable\n metadata {\n key\n value\n }\n columns {\n dbName\n graphQlName\n paramType\n dbType\n isPrimaryKey\n isIdentity\n isNullable\n isReadOnly\n maxLength\n minLength\n min\n max\n step\n pattern\n patternMessage\n inputType\n defaultValue\n enumValues\n enumLabels\n metadata {\n key\n value\n }\n }\n multiJoins {\n name\n fieldName\n sourceColumnNames\n destinationTable\n destinationColumnNames\n }\n singleJoins {\n name\n fieldName\n sourceColumnNames\n destinationTable\n destinationColumnNames\n }\n manyToManyJoins {\n name\n targetTable\n junctionTable\n junctionTargetField\n sourceColumnNames\n junctionSourceColumnNames\n junctionTargetColumnNames\n targetColumnNames\n hasPayload\n }\n }\n}";
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Table } from './types/schema';
|
|
2
|
-
import { ColumnPanel } from './data-panel';
|
|
3
|
-
interface DataDataTableParams {
|
|
4
|
-
table: Table;
|
|
5
|
-
id?: string;
|
|
6
|
-
tableFilter?: string;
|
|
7
|
-
filterColumn?: string;
|
|
8
|
-
selectedRowId?: string | null;
|
|
9
|
-
onRowSelect?: (rowId: string | null) => void;
|
|
10
|
-
onOpenColumn?: (panel: ColumnPanel) => void;
|
|
11
|
-
/** Current stacking (parent/child drill-down) mode state. */
|
|
12
|
-
stackingEnabled?: boolean;
|
|
13
|
-
/** Toggle stacking mode. When supplied, the grid renders the mode toggle. */
|
|
14
|
-
onToggleStacking?: (next: boolean) => void;
|
|
15
|
-
}
|
|
16
|
-
export declare function DataDataTable({ table, id, tableFilter, filterColumn, selectedRowId, onRowSelect, onOpenColumn, stackingEnabled, onToggleStacking }: DataDataTableParams): JSX.Element;
|
|
17
|
-
export {};
|
|
File without changes
|
/package/dist/{components/filters/use-debounced-commit.test.d.ts → common/schema-queries.test.d.ts}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/{components/filters/use-debounced-commit.d.ts → hooks/useDebouncedCommit.d.ts}
RENAMED
|
File without changes
|