@atscript/ui-table 0.1.138 → 0.1.139
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/index.cjs +418 -99
- package/dist/index.d.cts +134 -10
- package/dist/index.d.mts +134 -10
- package/dist/index.mjs +413 -100
- package/package.json +8 -8
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FilterExpr, Uniquery } from "@uniqu/core";
|
|
2
1
|
import { ColumnDef, PaginationControl, SortControl, TableDef } from "@atscript/ui";
|
|
2
|
+
import { FilterExpr, Uniquery } from "@uniqu/core";
|
|
3
3
|
import { Client } from "@atscript/db-client";
|
|
4
4
|
|
|
5
5
|
//#region src/filters/filter-types.d.ts
|
|
@@ -44,6 +44,34 @@ type ColumnFilterType = "text" | "number" | "date" | "boolean" | "enum" | "ref";
|
|
|
44
44
|
declare function conditionsForType(type: ColumnFilterType, nullable?: boolean): readonly FilterConditionType[];
|
|
45
45
|
/** Map a ColumnDef display type string to a ColumnFilterType. */
|
|
46
46
|
declare function columnFilterType(columnType: string): ColumnFilterType;
|
|
47
|
+
/** The `ColumnDef` fields that decide which filter conditions a column offers. */
|
|
48
|
+
type FilterableColumn = Pick<ColumnDef, "type" | "nullable" | "filterable" | "filterOps">;
|
|
49
|
+
/**
|
|
50
|
+
* Filter conditions a column offers — the one answer every filter UI (column
|
|
51
|
+
* menu, filter dialog, filter bar, config dialog) reads.
|
|
52
|
+
*
|
|
53
|
+
* - Value-filterable (`filterable: true`) → {@link conditionsForType} for its
|
|
54
|
+
* display type.
|
|
55
|
+
* - Existence-only (`filterable: false`, `filterOps` includes `$exists` — a
|
|
56
|
+
* JSON-stored column) → `null` / `notNull`: whether a value is present,
|
|
57
|
+
* never what it is.
|
|
58
|
+
* - Otherwise → `[]`: the column takes no filter.
|
|
59
|
+
*
|
|
60
|
+
* `null` / `notNull` are dropped for non-nullable columns, so an existence-only
|
|
61
|
+
* column that is never empty offers nothing.
|
|
62
|
+
*
|
|
63
|
+
* @since 0.1.139
|
|
64
|
+
*/
|
|
65
|
+
declare function columnFilterConditions(column: FilterableColumn): readonly FilterConditionType[];
|
|
66
|
+
/**
|
|
67
|
+
* Whether a column takes any filter at all — value comparisons or the
|
|
68
|
+
* existence-only `null` / `notNull` pair. Use it (not
|
|
69
|
+
* `column.filterable`, which is value comparison only) to decide whether to
|
|
70
|
+
* show a column in a filter UI.
|
|
71
|
+
*
|
|
72
|
+
* @since 0.1.139
|
|
73
|
+
*/
|
|
74
|
+
declare function isColumnFilterable(column: FilterableColumn): boolean;
|
|
47
75
|
//#endregion
|
|
48
76
|
//#region src/filters/escape-regex.d.ts
|
|
49
77
|
/** Escape special regex characters in user input for safe embedding in $regex. */
|
|
@@ -54,6 +82,14 @@ declare function unescapeRegex(input: string): string;
|
|
|
54
82
|
//#region src/filters/filter-input-format.d.ts
|
|
55
83
|
/** Default condition type when no symbol matches the input. */
|
|
56
84
|
declare function defaultCondition(columnType: ColumnFilterType): FilterConditionType;
|
|
85
|
+
/**
|
|
86
|
+
* The condition a column's filter input starts with: its type's
|
|
87
|
+
* {@link defaultCondition} when the column offers it, otherwise the first
|
|
88
|
+
* condition it does offer (`null` on an existence-only column).
|
|
89
|
+
*
|
|
90
|
+
* @since 0.1.139
|
|
91
|
+
*/
|
|
92
|
+
declare function columnDefaultCondition(column: FilterableColumn): FilterConditionType;
|
|
57
93
|
/**
|
|
58
94
|
* Parse a user-typed filter input string into a FilterCondition.
|
|
59
95
|
*
|
|
@@ -77,9 +113,19 @@ declare function defaultCondition(columnType: ColumnFilterType): FilterCondition
|
|
|
77
113
|
* number/date/boolean → eq
|
|
78
114
|
*
|
|
79
115
|
* Returns undefined for empty/invalid input or if the parsed operator
|
|
80
|
-
* is not available for the column type.
|
|
116
|
+
* is not available for the column type. To honour what a specific column
|
|
117
|
+
* offers (an existence-only column takes only `<empty>` / `!<empty>`), use
|
|
118
|
+
* {@link parseColumnFilterInput}.
|
|
81
119
|
*/
|
|
82
120
|
declare function parseFilterInput(text: string, columnType: ColumnFilterType, nullable?: boolean): FilterCondition | undefined;
|
|
121
|
+
/**
|
|
122
|
+
* {@link parseFilterInput} for a column: the type comes from the column and
|
|
123
|
+
* the accepted operators are {@link columnFilterConditions} — the ones the
|
|
124
|
+
* column's filter UI offers.
|
|
125
|
+
*
|
|
126
|
+
* @since 0.1.139
|
|
127
|
+
*/
|
|
128
|
+
declare function parseColumnFilterInput(text: string, column: FilterableColumn): FilterCondition | undefined;
|
|
83
129
|
/**
|
|
84
130
|
* Format a FilterCondition for chip/token display using operator symbols.
|
|
85
131
|
*
|
|
@@ -101,17 +147,57 @@ declare function formatFilterCondition(condition: FilterCondition): string;
|
|
|
101
147
|
declare function filtersToUniqueryFilter(fieldFilters: FieldFilters): FilterExpr | undefined;
|
|
102
148
|
//#endregion
|
|
103
149
|
//#region src/filters/uniquery-to-filters.d.ts
|
|
150
|
+
/**
|
|
151
|
+
* Why part of a Uniquery filter has no `FieldFilters` equivalent.
|
|
152
|
+
*
|
|
153
|
+
* - `"cross-field"` — an `$or` / `$not` that spans several fields
|
|
154
|
+
* (`a=1 OR b=2`). The model ANDs fields, so it cannot hold a correlation.
|
|
155
|
+
* - `"operator"` — an operator or operand no condition type expresses
|
|
156
|
+
* (`$nor`, an unknown `$op`, an object value, an empty `$in`, …).
|
|
157
|
+
* - `"negation"` — a negative inside an `$or`, or a `$not` that is not a
|
|
158
|
+
* plain inversion of equality / emptiness.
|
|
159
|
+
* - `"conjunction"` — a second positive group AND'd onto a field that already
|
|
160
|
+
* has one (`a>1 AND a<5`). A field's positive conditions are OR'd.
|
|
161
|
+
*
|
|
162
|
+
* @since 0.1.139
|
|
163
|
+
*/
|
|
164
|
+
type UnsupportedFilterReason = "cross-field" | "operator" | "negation" | "conjunction";
|
|
165
|
+
/**
|
|
166
|
+
* One AND-ed piece of a Uniquery filter that {@link uniqueryFilterToFieldFilters}
|
|
167
|
+
* left out of its result.
|
|
168
|
+
*
|
|
169
|
+
* @since 0.1.139
|
|
170
|
+
*/
|
|
171
|
+
interface UnsupportedFilter {
|
|
172
|
+
reason: UnsupportedFilterReason;
|
|
173
|
+
/** The left-out sub-expression, as it appeared in the input. */
|
|
174
|
+
expr: FilterExpr;
|
|
175
|
+
/** Field paths the sub-expression references, in order of appearance. */
|
|
176
|
+
fields: string[];
|
|
177
|
+
}
|
|
104
178
|
/**
|
|
105
179
|
* Convert a Uniquery `FilterExpr` back into the UI's `FieldFilters` shape.
|
|
106
180
|
*
|
|
107
|
-
* Inverse of `filtersToUniqueryFilter
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
181
|
+
* Inverse of `filtersToUniqueryFilter`, and exact for everything that encoder
|
|
182
|
+
* produces. For any other input, each AND-ed piece is either converted exactly
|
|
183
|
+
* or left out whole and reported — never approximated:
|
|
184
|
+
*
|
|
185
|
+
* - `$in` becomes equality conditions on the field, `$nin` inequality ones.
|
|
186
|
+
* - A same-field `$or` becomes that field's OR'd conditions.
|
|
187
|
+
* - A `$not` that inverts equality / emptiness becomes the inverse conditions.
|
|
188
|
+
* - Fields next to `$and` / `$or` / `$not` in one object are all kept.
|
|
189
|
+
* - Anything else (see {@link UnsupportedFilterReason}) is left out. Leaving
|
|
190
|
+
* an AND-ed piece out only ever widens the match, so the result selects a
|
|
191
|
+
* superset of `expr`. Each left-out piece goes to `onUnsupportedFilter`, or
|
|
192
|
+
* to a dev-mode `console.warn` when no handler is given.
|
|
193
|
+
*
|
|
194
|
+
* Conditions on fields outside `knownFields` (when provided) are ignored
|
|
195
|
+
* silently: they are not this table's (a host page flag, a stale column). A
|
|
196
|
+
* piece that mixes known and unknown fields is reported.
|
|
111
197
|
*
|
|
112
198
|
* Returns `{}` for an empty/missing expression. Never throws.
|
|
113
199
|
*/
|
|
114
|
-
declare function uniqueryFilterToFieldFilters(expr: FilterExpr | undefined, knownFields?: Iterable<string> | Set<string
|
|
200
|
+
declare function uniqueryFilterToFieldFilters(expr: FilterExpr | undefined, knownFields?: Iterable<string> | Set<string>, onUnsupportedFilter?: (issue: UnsupportedFilter) => void): FieldFilters;
|
|
115
201
|
//#endregion
|
|
116
202
|
//#region src/filters/date-shortcuts.d.ts
|
|
117
203
|
/** A date shortcut produces a label and a [start, end] ISO date range. */
|
|
@@ -678,10 +764,35 @@ interface UrlQueryStateLike {
|
|
|
678
764
|
*/
|
|
679
765
|
ignoreSorters?: boolean;
|
|
680
766
|
}
|
|
767
|
+
/**
|
|
768
|
+
* The URL control that marks a query string as a complete snapshot of the
|
|
769
|
+
* table's filters and sorters. Restoring a URL that carries it clears every
|
|
770
|
+
* filter and sorter the URL owns before applying its own, so nothing the URL
|
|
771
|
+
* omits survives (empty `$sort` included). A URL without it is an overlay:
|
|
772
|
+
* its filters and sorters are laid over the table's starting ones.
|
|
773
|
+
*
|
|
774
|
+
* The encoder writes it bare (`…&$snapshot`) on every URL; the decoder goes
|
|
775
|
+
* by presence alone, whatever the value. `UrlQuerySync.snapshot: false` turns
|
|
776
|
+
* both off.
|
|
777
|
+
*
|
|
778
|
+
* @since 0.1.139
|
|
779
|
+
*/
|
|
780
|
+
declare const URL_SNAPSHOT_KEY = "$snapshot";
|
|
681
781
|
/** Snapshot recovered from a URL string — partial on purpose so callers can layer it onto state. */
|
|
682
782
|
interface UrlQueryStateSnapshot {
|
|
683
783
|
filters: FieldFilters;
|
|
684
784
|
sorters: SortControl[];
|
|
785
|
+
/**
|
|
786
|
+
* `true` when the URL carried {@link URL_SNAPSHOT_KEY} (and `sync.snapshot`
|
|
787
|
+
* is not `false`). Omitted otherwise. Since 0.1.139.
|
|
788
|
+
*/
|
|
789
|
+
snapshot?: true;
|
|
790
|
+
/**
|
|
791
|
+
* Pieces of the URL's filter that `filters` leaves out because field filters
|
|
792
|
+
* cannot express them — see `uniqueryFilterToFieldFilters`. Omitted when
|
|
793
|
+
* the filter converted exactly. Since 0.1.139.
|
|
794
|
+
*/
|
|
795
|
+
unsupported?: UnsupportedFilter[];
|
|
685
796
|
/**
|
|
686
797
|
* Raw record offset from `$skip` (omitted when no `$skip` in URL). The
|
|
687
798
|
* decoder does NOT compute a page index — that requires `itemsPerPage`,
|
|
@@ -719,6 +830,12 @@ interface UrlQuerySync {
|
|
|
719
830
|
search?: boolean;
|
|
720
831
|
/** Whether pagination (`$skip` + `$limit`) syncs. Page and limit are coupled — one knob. */
|
|
721
832
|
pagination?: boolean;
|
|
833
|
+
/**
|
|
834
|
+
* Whether the encoder writes {@link URL_SNAPSHOT_KEY} and the decoder
|
|
835
|
+
* honours it. Default `true`; `false` makes every URL an overlay.
|
|
836
|
+
* Since 0.1.139.
|
|
837
|
+
*/
|
|
838
|
+
snapshot?: boolean;
|
|
722
839
|
}
|
|
723
840
|
interface UrlQueryDefaults {
|
|
724
841
|
/** Consumer's `:limit` prop. Used to omit `$limit` from the URL when state matches it. */
|
|
@@ -762,7 +879,9 @@ declare function gateOwns(gate: AspectGate, path: string): boolean;
|
|
|
762
879
|
* `$actions`, `forceFilters`, `forceSorters` — those are not user state) and
|
|
763
880
|
* appends `$skip` / `$limit` for pagination.
|
|
764
881
|
*
|
|
765
|
-
*
|
|
882
|
+
* Stamps {@link URL_SNAPSHOT_KEY} unless `defaults.sync.snapshot` is `false`
|
|
883
|
+
* (or neither filters nor sorters sync), so the default view serializes to
|
|
884
|
+
* `"$snapshot"`; with the marker off it serializes to `""` (no leading `?`).
|
|
766
885
|
*/
|
|
767
886
|
declare function stateToUrlQueryString(state: UrlQueryStateLike, defaults: UrlQueryDefaults): string;
|
|
768
887
|
/**
|
|
@@ -796,7 +915,9 @@ interface UrlQueryParseOptions {
|
|
|
796
915
|
* Robust by design — schema drift and copy-paste errors must not break the
|
|
797
916
|
* recipient's view:
|
|
798
917
|
* - unknown fields (not in `knownFields`) → silently dropped
|
|
799
|
-
* -
|
|
918
|
+
* - filter pieces field filters cannot express (cross-field OR, unknown
|
|
919
|
+
* operator, …) → left out of `filters` and listed in `unsupported`, never
|
|
920
|
+
* approximated (the parser does not warn — the caller decides)
|
|
800
921
|
* - unknown controls (e.g. `$weird=42`) → silently ignored
|
|
801
922
|
* - malformed query → `{ filters: {}, sorters: [], searchTerm: "" }`
|
|
802
923
|
*
|
|
@@ -1306,4 +1427,7 @@ declare function cellAsString(v: unknown): string;
|
|
|
1306
1427
|
*/
|
|
1307
1428
|
declare function sortRowsLocally<T extends Record<string, unknown>>(rows: T[], sorters: readonly SortControl[], getValue?: (row: T, field: string) => unknown): T[];
|
|
1308
1429
|
//#endregion
|
|
1309
|
-
|
|
1430
|
+
//#region src/utils/dev.d.ts
|
|
1431
|
+
declare const DEV: boolean;
|
|
1432
|
+
//#endregion
|
|
1433
|
+
export { APP_CONF_PREFIX, type AppConfData, AppPrefsClient, type AppPrefsClientConfig, type AppPrefsLoadResult, type AsPresetEntryData, type AsPresetEntryRow, type AsPresetsErrorCode, type AspectGate, type AspectMask, type BuildTableQueryOptions, type ColumnFilterType, type ColumnReorderPosition, type ColumnWidthEntry, type ColumnWidthsMap, type ConfigTab, type CsvOptions, DEFAULT_EXPORT_PAGE_SIZE, DEFAULT_ROW_HEIGHT_PX, DEV, DRAFT_PERSISTED_ASPECTS, type DateShortcut, type DisplayColumnDef, type DraftPersistedAspect, ExportAbortError, type ExportPage, type ExportPageFetcher, type ExportScalar, type FetchPlan, type FetchPlanMode, type FieldFilters, type FilterCondition, type FilterConditionType, type FilterableColumn, MAX_DEFAULT_COLUMN_WIDTH_PX, type MergeResult, NULL_OPS, PRESET_ASPECTS, type PageAlignedBlock, type PlanFetchArgs, type PresetAspect, type PresetCapabilities, type PresetColumnWidthEntry, type PresetData, type PresetDraft, type PresetFilterOpEntry, type PresetLimitReachedBody, type PresetSnapshot, type PresetSnapshotWire, type PresetSorterEntry, PresetsClient, type PresetsClientConfig, PresetsHttpError, type PresetsListResult, type PresetsSaveAsOptions, type PresetsSaveResult, type QueryOptions, RESERVED_ID_PREFIXES, STANDARD_PRESET_ID, SYSTEM_PRESET_PREFIX, type SelectionMode, type SystemPreset, type SystemPresetInput, type TableStateData, type TableStateMethods, URL_SNAPSHOT_KEY, USER_CONF_PREFIX, type UnsupportedFilter, type UnsupportedFilterReason, type UrlQueryDefaults, type UrlQueryParseOptions, type UrlQueryStateLike, type UrlQueryStateSnapshot, type UrlQuerySync, type UserConfData, appConfId, arraysEqual, blockStartFor, buildTableQuery, cellAsString, clampTopIndex, collectExportRows, columnDefaultCondition, columnFilterConditions, columnFilterType, computeDefaultColumnWidth, conditionLabel, conditionsForType, csvCell, dateShortcuts, debounce, defaultCondition, derivePresetAspects, deserializeDraft, draftMatchesPreset, escapeRegex, filledFilterCount, filterTokenLabel, filtersToUniqueryFilter, formatFilterCondition, fromWireSnapshot, gateOwns, hasSecondValue, isAuthError, isColumnFilterable, isDirtyAgainst, isEmptyDraft, isFilled, isSimpleEq, isSystemPresetId, isUnavailableError, mergeDisplayColumns, mergeFilters, mergeSorters, normaliseSystemPresetId, pageAlignedBlocksFor, parseColumnFilterInput, parseFilterInput, planFetch, reconcileColumnWidthDefaults, reorderColumnNames, resolveAspectGate, resolveExportValue, resolveSystemPresets, rowsToPks, sameColumnSet, serializeDraft, setsEqual, sortRowsLocally, sortersEqual, stableStringify, stateToUrlQueryString, toCsv, toWireSnapshot, togglePk, trimSelection, unescapeRegex, uniqueryFilterToFieldFilters, urlQueryConsumesKey, urlQueryStringToState, userConfId, walkBackwardAbsorb, walkForwardAbsorb, withStableOrder };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { FilterExpr, Uniquery } from "@uniqu/core";
|
|
1
2
|
import { Client } from "@atscript/db-client";
|
|
2
3
|
import { ColumnDef, PaginationControl, SortControl, TableDef } from "@atscript/ui";
|
|
3
|
-
import { FilterExpr, Uniquery } from "@uniqu/core";
|
|
4
4
|
|
|
5
5
|
//#region src/filters/filter-types.d.ts
|
|
6
6
|
/** Filter condition type identifiers. */
|
|
@@ -44,6 +44,34 @@ type ColumnFilterType = "text" | "number" | "date" | "boolean" | "enum" | "ref";
|
|
|
44
44
|
declare function conditionsForType(type: ColumnFilterType, nullable?: boolean): readonly FilterConditionType[];
|
|
45
45
|
/** Map a ColumnDef display type string to a ColumnFilterType. */
|
|
46
46
|
declare function columnFilterType(columnType: string): ColumnFilterType;
|
|
47
|
+
/** The `ColumnDef` fields that decide which filter conditions a column offers. */
|
|
48
|
+
type FilterableColumn = Pick<ColumnDef, "type" | "nullable" | "filterable" | "filterOps">;
|
|
49
|
+
/**
|
|
50
|
+
* Filter conditions a column offers — the one answer every filter UI (column
|
|
51
|
+
* menu, filter dialog, filter bar, config dialog) reads.
|
|
52
|
+
*
|
|
53
|
+
* - Value-filterable (`filterable: true`) → {@link conditionsForType} for its
|
|
54
|
+
* display type.
|
|
55
|
+
* - Existence-only (`filterable: false`, `filterOps` includes `$exists` — a
|
|
56
|
+
* JSON-stored column) → `null` / `notNull`: whether a value is present,
|
|
57
|
+
* never what it is.
|
|
58
|
+
* - Otherwise → `[]`: the column takes no filter.
|
|
59
|
+
*
|
|
60
|
+
* `null` / `notNull` are dropped for non-nullable columns, so an existence-only
|
|
61
|
+
* column that is never empty offers nothing.
|
|
62
|
+
*
|
|
63
|
+
* @since 0.1.139
|
|
64
|
+
*/
|
|
65
|
+
declare function columnFilterConditions(column: FilterableColumn): readonly FilterConditionType[];
|
|
66
|
+
/**
|
|
67
|
+
* Whether a column takes any filter at all — value comparisons or the
|
|
68
|
+
* existence-only `null` / `notNull` pair. Use it (not
|
|
69
|
+
* `column.filterable`, which is value comparison only) to decide whether to
|
|
70
|
+
* show a column in a filter UI.
|
|
71
|
+
*
|
|
72
|
+
* @since 0.1.139
|
|
73
|
+
*/
|
|
74
|
+
declare function isColumnFilterable(column: FilterableColumn): boolean;
|
|
47
75
|
//#endregion
|
|
48
76
|
//#region src/filters/escape-regex.d.ts
|
|
49
77
|
/** Escape special regex characters in user input for safe embedding in $regex. */
|
|
@@ -54,6 +82,14 @@ declare function unescapeRegex(input: string): string;
|
|
|
54
82
|
//#region src/filters/filter-input-format.d.ts
|
|
55
83
|
/** Default condition type when no symbol matches the input. */
|
|
56
84
|
declare function defaultCondition(columnType: ColumnFilterType): FilterConditionType;
|
|
85
|
+
/**
|
|
86
|
+
* The condition a column's filter input starts with: its type's
|
|
87
|
+
* {@link defaultCondition} when the column offers it, otherwise the first
|
|
88
|
+
* condition it does offer (`null` on an existence-only column).
|
|
89
|
+
*
|
|
90
|
+
* @since 0.1.139
|
|
91
|
+
*/
|
|
92
|
+
declare function columnDefaultCondition(column: FilterableColumn): FilterConditionType;
|
|
57
93
|
/**
|
|
58
94
|
* Parse a user-typed filter input string into a FilterCondition.
|
|
59
95
|
*
|
|
@@ -77,9 +113,19 @@ declare function defaultCondition(columnType: ColumnFilterType): FilterCondition
|
|
|
77
113
|
* number/date/boolean → eq
|
|
78
114
|
*
|
|
79
115
|
* Returns undefined for empty/invalid input or if the parsed operator
|
|
80
|
-
* is not available for the column type.
|
|
116
|
+
* is not available for the column type. To honour what a specific column
|
|
117
|
+
* offers (an existence-only column takes only `<empty>` / `!<empty>`), use
|
|
118
|
+
* {@link parseColumnFilterInput}.
|
|
81
119
|
*/
|
|
82
120
|
declare function parseFilterInput(text: string, columnType: ColumnFilterType, nullable?: boolean): FilterCondition | undefined;
|
|
121
|
+
/**
|
|
122
|
+
* {@link parseFilterInput} for a column: the type comes from the column and
|
|
123
|
+
* the accepted operators are {@link columnFilterConditions} — the ones the
|
|
124
|
+
* column's filter UI offers.
|
|
125
|
+
*
|
|
126
|
+
* @since 0.1.139
|
|
127
|
+
*/
|
|
128
|
+
declare function parseColumnFilterInput(text: string, column: FilterableColumn): FilterCondition | undefined;
|
|
83
129
|
/**
|
|
84
130
|
* Format a FilterCondition for chip/token display using operator symbols.
|
|
85
131
|
*
|
|
@@ -101,17 +147,57 @@ declare function formatFilterCondition(condition: FilterCondition): string;
|
|
|
101
147
|
declare function filtersToUniqueryFilter(fieldFilters: FieldFilters): FilterExpr | undefined;
|
|
102
148
|
//#endregion
|
|
103
149
|
//#region src/filters/uniquery-to-filters.d.ts
|
|
150
|
+
/**
|
|
151
|
+
* Why part of a Uniquery filter has no `FieldFilters` equivalent.
|
|
152
|
+
*
|
|
153
|
+
* - `"cross-field"` — an `$or` / `$not` that spans several fields
|
|
154
|
+
* (`a=1 OR b=2`). The model ANDs fields, so it cannot hold a correlation.
|
|
155
|
+
* - `"operator"` — an operator or operand no condition type expresses
|
|
156
|
+
* (`$nor`, an unknown `$op`, an object value, an empty `$in`, …).
|
|
157
|
+
* - `"negation"` — a negative inside an `$or`, or a `$not` that is not a
|
|
158
|
+
* plain inversion of equality / emptiness.
|
|
159
|
+
* - `"conjunction"` — a second positive group AND'd onto a field that already
|
|
160
|
+
* has one (`a>1 AND a<5`). A field's positive conditions are OR'd.
|
|
161
|
+
*
|
|
162
|
+
* @since 0.1.139
|
|
163
|
+
*/
|
|
164
|
+
type UnsupportedFilterReason = "cross-field" | "operator" | "negation" | "conjunction";
|
|
165
|
+
/**
|
|
166
|
+
* One AND-ed piece of a Uniquery filter that {@link uniqueryFilterToFieldFilters}
|
|
167
|
+
* left out of its result.
|
|
168
|
+
*
|
|
169
|
+
* @since 0.1.139
|
|
170
|
+
*/
|
|
171
|
+
interface UnsupportedFilter {
|
|
172
|
+
reason: UnsupportedFilterReason;
|
|
173
|
+
/** The left-out sub-expression, as it appeared in the input. */
|
|
174
|
+
expr: FilterExpr;
|
|
175
|
+
/** Field paths the sub-expression references, in order of appearance. */
|
|
176
|
+
fields: string[];
|
|
177
|
+
}
|
|
104
178
|
/**
|
|
105
179
|
* Convert a Uniquery `FilterExpr` back into the UI's `FieldFilters` shape.
|
|
106
180
|
*
|
|
107
|
-
* Inverse of `filtersToUniqueryFilter
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
181
|
+
* Inverse of `filtersToUniqueryFilter`, and exact for everything that encoder
|
|
182
|
+
* produces. For any other input, each AND-ed piece is either converted exactly
|
|
183
|
+
* or left out whole and reported — never approximated:
|
|
184
|
+
*
|
|
185
|
+
* - `$in` becomes equality conditions on the field, `$nin` inequality ones.
|
|
186
|
+
* - A same-field `$or` becomes that field's OR'd conditions.
|
|
187
|
+
* - A `$not` that inverts equality / emptiness becomes the inverse conditions.
|
|
188
|
+
* - Fields next to `$and` / `$or` / `$not` in one object are all kept.
|
|
189
|
+
* - Anything else (see {@link UnsupportedFilterReason}) is left out. Leaving
|
|
190
|
+
* an AND-ed piece out only ever widens the match, so the result selects a
|
|
191
|
+
* superset of `expr`. Each left-out piece goes to `onUnsupportedFilter`, or
|
|
192
|
+
* to a dev-mode `console.warn` when no handler is given.
|
|
193
|
+
*
|
|
194
|
+
* Conditions on fields outside `knownFields` (when provided) are ignored
|
|
195
|
+
* silently: they are not this table's (a host page flag, a stale column). A
|
|
196
|
+
* piece that mixes known and unknown fields is reported.
|
|
111
197
|
*
|
|
112
198
|
* Returns `{}` for an empty/missing expression. Never throws.
|
|
113
199
|
*/
|
|
114
|
-
declare function uniqueryFilterToFieldFilters(expr: FilterExpr | undefined, knownFields?: Iterable<string> | Set<string
|
|
200
|
+
declare function uniqueryFilterToFieldFilters(expr: FilterExpr | undefined, knownFields?: Iterable<string> | Set<string>, onUnsupportedFilter?: (issue: UnsupportedFilter) => void): FieldFilters;
|
|
115
201
|
//#endregion
|
|
116
202
|
//#region src/filters/date-shortcuts.d.ts
|
|
117
203
|
/** A date shortcut produces a label and a [start, end] ISO date range. */
|
|
@@ -678,10 +764,35 @@ interface UrlQueryStateLike {
|
|
|
678
764
|
*/
|
|
679
765
|
ignoreSorters?: boolean;
|
|
680
766
|
}
|
|
767
|
+
/**
|
|
768
|
+
* The URL control that marks a query string as a complete snapshot of the
|
|
769
|
+
* table's filters and sorters. Restoring a URL that carries it clears every
|
|
770
|
+
* filter and sorter the URL owns before applying its own, so nothing the URL
|
|
771
|
+
* omits survives (empty `$sort` included). A URL without it is an overlay:
|
|
772
|
+
* its filters and sorters are laid over the table's starting ones.
|
|
773
|
+
*
|
|
774
|
+
* The encoder writes it bare (`…&$snapshot`) on every URL; the decoder goes
|
|
775
|
+
* by presence alone, whatever the value. `UrlQuerySync.snapshot: false` turns
|
|
776
|
+
* both off.
|
|
777
|
+
*
|
|
778
|
+
* @since 0.1.139
|
|
779
|
+
*/
|
|
780
|
+
declare const URL_SNAPSHOT_KEY = "$snapshot";
|
|
681
781
|
/** Snapshot recovered from a URL string — partial on purpose so callers can layer it onto state. */
|
|
682
782
|
interface UrlQueryStateSnapshot {
|
|
683
783
|
filters: FieldFilters;
|
|
684
784
|
sorters: SortControl[];
|
|
785
|
+
/**
|
|
786
|
+
* `true` when the URL carried {@link URL_SNAPSHOT_KEY} (and `sync.snapshot`
|
|
787
|
+
* is not `false`). Omitted otherwise. Since 0.1.139.
|
|
788
|
+
*/
|
|
789
|
+
snapshot?: true;
|
|
790
|
+
/**
|
|
791
|
+
* Pieces of the URL's filter that `filters` leaves out because field filters
|
|
792
|
+
* cannot express them — see `uniqueryFilterToFieldFilters`. Omitted when
|
|
793
|
+
* the filter converted exactly. Since 0.1.139.
|
|
794
|
+
*/
|
|
795
|
+
unsupported?: UnsupportedFilter[];
|
|
685
796
|
/**
|
|
686
797
|
* Raw record offset from `$skip` (omitted when no `$skip` in URL). The
|
|
687
798
|
* decoder does NOT compute a page index — that requires `itemsPerPage`,
|
|
@@ -719,6 +830,12 @@ interface UrlQuerySync {
|
|
|
719
830
|
search?: boolean;
|
|
720
831
|
/** Whether pagination (`$skip` + `$limit`) syncs. Page and limit are coupled — one knob. */
|
|
721
832
|
pagination?: boolean;
|
|
833
|
+
/**
|
|
834
|
+
* Whether the encoder writes {@link URL_SNAPSHOT_KEY} and the decoder
|
|
835
|
+
* honours it. Default `true`; `false` makes every URL an overlay.
|
|
836
|
+
* Since 0.1.139.
|
|
837
|
+
*/
|
|
838
|
+
snapshot?: boolean;
|
|
722
839
|
}
|
|
723
840
|
interface UrlQueryDefaults {
|
|
724
841
|
/** Consumer's `:limit` prop. Used to omit `$limit` from the URL when state matches it. */
|
|
@@ -762,7 +879,9 @@ declare function gateOwns(gate: AspectGate, path: string): boolean;
|
|
|
762
879
|
* `$actions`, `forceFilters`, `forceSorters` — those are not user state) and
|
|
763
880
|
* appends `$skip` / `$limit` for pagination.
|
|
764
881
|
*
|
|
765
|
-
*
|
|
882
|
+
* Stamps {@link URL_SNAPSHOT_KEY} unless `defaults.sync.snapshot` is `false`
|
|
883
|
+
* (or neither filters nor sorters sync), so the default view serializes to
|
|
884
|
+
* `"$snapshot"`; with the marker off it serializes to `""` (no leading `?`).
|
|
766
885
|
*/
|
|
767
886
|
declare function stateToUrlQueryString(state: UrlQueryStateLike, defaults: UrlQueryDefaults): string;
|
|
768
887
|
/**
|
|
@@ -796,7 +915,9 @@ interface UrlQueryParseOptions {
|
|
|
796
915
|
* Robust by design — schema drift and copy-paste errors must not break the
|
|
797
916
|
* recipient's view:
|
|
798
917
|
* - unknown fields (not in `knownFields`) → silently dropped
|
|
799
|
-
* -
|
|
918
|
+
* - filter pieces field filters cannot express (cross-field OR, unknown
|
|
919
|
+
* operator, …) → left out of `filters` and listed in `unsupported`, never
|
|
920
|
+
* approximated (the parser does not warn — the caller decides)
|
|
800
921
|
* - unknown controls (e.g. `$weird=42`) → silently ignored
|
|
801
922
|
* - malformed query → `{ filters: {}, sorters: [], searchTerm: "" }`
|
|
802
923
|
*
|
|
@@ -1306,4 +1427,7 @@ declare function cellAsString(v: unknown): string;
|
|
|
1306
1427
|
*/
|
|
1307
1428
|
declare function sortRowsLocally<T extends Record<string, unknown>>(rows: T[], sorters: readonly SortControl[], getValue?: (row: T, field: string) => unknown): T[];
|
|
1308
1429
|
//#endregion
|
|
1309
|
-
|
|
1430
|
+
//#region src/utils/dev.d.ts
|
|
1431
|
+
declare const DEV: boolean;
|
|
1432
|
+
//#endregion
|
|
1433
|
+
export { APP_CONF_PREFIX, type AppConfData, AppPrefsClient, type AppPrefsClientConfig, type AppPrefsLoadResult, type AsPresetEntryData, type AsPresetEntryRow, type AsPresetsErrorCode, type AspectGate, type AspectMask, type BuildTableQueryOptions, type ColumnFilterType, type ColumnReorderPosition, type ColumnWidthEntry, type ColumnWidthsMap, type ConfigTab, type CsvOptions, DEFAULT_EXPORT_PAGE_SIZE, DEFAULT_ROW_HEIGHT_PX, DEV, DRAFT_PERSISTED_ASPECTS, type DateShortcut, type DisplayColumnDef, type DraftPersistedAspect, ExportAbortError, type ExportPage, type ExportPageFetcher, type ExportScalar, type FetchPlan, type FetchPlanMode, type FieldFilters, type FilterCondition, type FilterConditionType, type FilterableColumn, MAX_DEFAULT_COLUMN_WIDTH_PX, type MergeResult, NULL_OPS, PRESET_ASPECTS, type PageAlignedBlock, type PlanFetchArgs, type PresetAspect, type PresetCapabilities, type PresetColumnWidthEntry, type PresetData, type PresetDraft, type PresetFilterOpEntry, type PresetLimitReachedBody, type PresetSnapshot, type PresetSnapshotWire, type PresetSorterEntry, PresetsClient, type PresetsClientConfig, PresetsHttpError, type PresetsListResult, type PresetsSaveAsOptions, type PresetsSaveResult, type QueryOptions, RESERVED_ID_PREFIXES, STANDARD_PRESET_ID, SYSTEM_PRESET_PREFIX, type SelectionMode, type SystemPreset, type SystemPresetInput, type TableStateData, type TableStateMethods, URL_SNAPSHOT_KEY, USER_CONF_PREFIX, type UnsupportedFilter, type UnsupportedFilterReason, type UrlQueryDefaults, type UrlQueryParseOptions, type UrlQueryStateLike, type UrlQueryStateSnapshot, type UrlQuerySync, type UserConfData, appConfId, arraysEqual, blockStartFor, buildTableQuery, cellAsString, clampTopIndex, collectExportRows, columnDefaultCondition, columnFilterConditions, columnFilterType, computeDefaultColumnWidth, conditionLabel, conditionsForType, csvCell, dateShortcuts, debounce, defaultCondition, derivePresetAspects, deserializeDraft, draftMatchesPreset, escapeRegex, filledFilterCount, filterTokenLabel, filtersToUniqueryFilter, formatFilterCondition, fromWireSnapshot, gateOwns, hasSecondValue, isAuthError, isColumnFilterable, isDirtyAgainst, isEmptyDraft, isFilled, isSimpleEq, isSystemPresetId, isUnavailableError, mergeDisplayColumns, mergeFilters, mergeSorters, normaliseSystemPresetId, pageAlignedBlocksFor, parseColumnFilterInput, parseFilterInput, planFetch, reconcileColumnWidthDefaults, reorderColumnNames, resolveAspectGate, resolveExportValue, resolveSystemPresets, rowsToPks, sameColumnSet, serializeDraft, setsEqual, sortRowsLocally, sortersEqual, stableStringify, stateToUrlQueryString, toCsv, toWireSnapshot, togglePk, trimSelection, unescapeRegex, uniqueryFilterToFieldFilters, urlQueryConsumesKey, urlQueryStringToState, userConfId, walkBackwardAbsorb, walkForwardAbsorb, withStableOrder };
|