@aglyn/shared-ui-jsx 1.0.0-beta.197 → 1.0.0-beta.199
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/package.json +5 -5
- package/src/lib/components/list-query-notices.component.d.ts +43 -0
- package/src/lib/components/list-query-notices.component.js +50 -0
- package/src/lib/components/list-query-notices.component.js.map +1 -0
- package/src/lib/const/list-filter.d.ts +6 -0
- package/src/lib/const/list-filter.js.map +1 -1
- package/src/lib/const/list-grid-filter.d.ts +8 -2
- package/src/lib/const/list-grid-filter.js +35 -3
- package/src/lib/const/list-grid-filter.js.map +1 -1
- package/src/lib/const/list-query-plan.d.ts +165 -0
- package/src/lib/const/list-query-plan.js +624 -0
- package/src/lib/const/list-query-plan.js.map +1 -0
- package/src/lib/hooks/use-list-rows-filter.d.ts +4 -1
- package/src/lib/hooks/use-list-rows-filter.js +4 -1
- package/src/lib/hooks/use-list-rows-filter.js.map +1 -1
- package/src/lib/hooks/use-paged-rows-filter.d.ts +4 -1
- package/src/lib/hooks/use-paged-rows-filter.js +4 -1
- package/src/lib/hooks/use-paged-rows-filter.js.map +1 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { type ListFilterField, type ListFilterRequest } from './list-filter';
|
|
18
|
+
/**
|
|
19
|
+
* How the written search fields were normalized, so a typed value becomes the
|
|
20
|
+
* key the query can match: the lower-cased key (`equals`, `startsWith`), the
|
|
21
|
+
* one word-prefix token (`contains`, search), and the reversed key
|
|
22
|
+
* (`endsWith`). `maxPrefix` is the longest token a writer stores.
|
|
23
|
+
*/
|
|
24
|
+
export interface ListQueryNormalizers {
|
|
25
|
+
key(value: string): string;
|
|
26
|
+
token(value: string): string;
|
|
27
|
+
reversed(value: string): string;
|
|
28
|
+
maxPrefix: number;
|
|
29
|
+
}
|
|
30
|
+
/** A predicate on the query, SDK-free. `path` `__name__` is the document id. */
|
|
31
|
+
export type ListQueryOp = '==' | '!=' | '<' | '<=' | '>' | '>=' | 'in' | 'array-contains' | 'array-contains-any';
|
|
32
|
+
export type ListQueryValue = string | number | boolean | null | Date | readonly (string | number)[];
|
|
33
|
+
export interface ListQueryFilter {
|
|
34
|
+
path: string;
|
|
35
|
+
op: ListQueryOp;
|
|
36
|
+
value: ListQueryValue;
|
|
37
|
+
}
|
|
38
|
+
export interface ListQuerySort {
|
|
39
|
+
path: string;
|
|
40
|
+
direction: 'asc' | 'desc';
|
|
41
|
+
/** The grid column this order sorts, when the list lets the grid sort by it. */
|
|
42
|
+
column?: string;
|
|
43
|
+
}
|
|
44
|
+
/** The document id, as a path. */
|
|
45
|
+
export declare const LIST_QUERY_ID_PATH = "__name__";
|
|
46
|
+
/** Firestore's cap on disjunctions — `in` values times `array-contains-any` values. */
|
|
47
|
+
export declare const LIST_QUERY_DISJUNCTIONS = 30;
|
|
48
|
+
export interface ListQueryDeclaration {
|
|
49
|
+
/** Every field the Filters panel may name. */
|
|
50
|
+
fields: readonly ListFilterField[];
|
|
51
|
+
/**
|
|
52
|
+
* The orders the list offers, its default FIRST. The query takes no other:
|
|
53
|
+
* each is a composite the index file carries for every filterable field.
|
|
54
|
+
*/
|
|
55
|
+
sorts: readonly ListQuerySort[];
|
|
56
|
+
/**
|
|
57
|
+
* The quick search: the token array every write stamps (see
|
|
58
|
+
* `nameSearchTokens`), queried with `array-contains` on one typed word.
|
|
59
|
+
* Absent, the list offers no search box.
|
|
60
|
+
*/
|
|
61
|
+
search?: {
|
|
62
|
+
tokensPath: string;
|
|
63
|
+
/**
|
|
64
|
+
* Under a scope clause the search cannot be a SECOND array clause, so a
|
|
65
|
+
* scoped list writes `<scopeToken><join><prefix>` tokens and the query
|
|
66
|
+
* asks `array-contains-any` over the scope's tokens joined to the word —
|
|
67
|
+
* one array clause that answers both.
|
|
68
|
+
*/
|
|
69
|
+
scoped?: {
|
|
70
|
+
tokensPath: string;
|
|
71
|
+
join: string;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Keys a presence-map field (`keysOf`) is filtered by, for the index
|
|
76
|
+
* enumeration: `sources.form`, `sources.order`, …
|
|
77
|
+
*/
|
|
78
|
+
keys?: Readonly<Record<string, readonly string[]>>;
|
|
79
|
+
}
|
|
80
|
+
/** What the list asks this time. */
|
|
81
|
+
export interface ListQueryRequest {
|
|
82
|
+
clauses: readonly ListFilterRequest[];
|
|
83
|
+
/** The quick search's words. */
|
|
84
|
+
search?: readonly string[];
|
|
85
|
+
/** The order asked for; a sort the declaration does not offer is ignored. */
|
|
86
|
+
sort?: ListQuerySort | null;
|
|
87
|
+
/**
|
|
88
|
+
* Predicates the list always applies — its scope — which count against
|
|
89
|
+
* the same limits. An `array-contains-any` scope is what a scoped search
|
|
90
|
+
* folds into (`declaration.search.scoped`).
|
|
91
|
+
*/
|
|
92
|
+
base?: readonly ListQueryFilter[];
|
|
93
|
+
}
|
|
94
|
+
export interface ListQueryRefusal {
|
|
95
|
+
/** The clause refused, or `search`. */
|
|
96
|
+
clause: ListFilterRequest | 'search';
|
|
97
|
+
reason: string;
|
|
98
|
+
}
|
|
99
|
+
export interface ListQueryPlan {
|
|
100
|
+
/** Every predicate, base included, in the order the SDK should add them. */
|
|
101
|
+
filters: ListQueryFilter[];
|
|
102
|
+
/** The one order: the range field's when there is one, else the sort. */
|
|
103
|
+
orderBy: ListQuerySort;
|
|
104
|
+
/** The clauses on the query. */
|
|
105
|
+
served: ListFilterRequest[];
|
|
106
|
+
/** The search word on the query, or null. */
|
|
107
|
+
searched: string | null;
|
|
108
|
+
/** What was asked and could not be put on the query, with why. */
|
|
109
|
+
refused: ListQueryRefusal[];
|
|
110
|
+
/** Said to the reader about what WAS served — e.g. one search word of two. */
|
|
111
|
+
notices: string[];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Every clause and the search, as ONE query — or as much of it as one query
|
|
115
|
+
* can hold, with the rest refused by name.
|
|
116
|
+
*
|
|
117
|
+
* Order of claim: the base (the list's scope) first, then the search, then
|
|
118
|
+
* the clauses in the order they were added. A clause that would be a second
|
|
119
|
+
* array clause, a second inequality field or push the disjunctions past
|
|
120
|
+
* thirty is refused, and the list shows the refusal beside its chip; the
|
|
121
|
+
* clauses before it stand. The search is claimed before the clauses because
|
|
122
|
+
* it is the thing a reader typed last and looks at.
|
|
123
|
+
*/
|
|
124
|
+
export declare function planListQuery(declaration: ListQueryDeclaration, request: ListQueryRequest, names: ListQueryNormalizers): ListQueryPlan;
|
|
125
|
+
/** A composite the plan's shapes need, in the index file's own terms. */
|
|
126
|
+
export interface ListQueryIndex {
|
|
127
|
+
fields: Array<{
|
|
128
|
+
fieldPath: string;
|
|
129
|
+
order?: 'ASCENDING' | 'DESCENDING';
|
|
130
|
+
arrayConfig?: 'CONTAINS';
|
|
131
|
+
}>;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Every composite a declaration's queries can need, under index merging:
|
|
135
|
+
* one `(predicate field, order)` index per equality or array field and per
|
|
136
|
+
* order the list can take — its sorts, and the order each range imposes.
|
|
137
|
+
*
|
|
138
|
+
* `base` names the scope predicates the list always applies (their paths
|
|
139
|
+
* and whether they are array clauses), which need their own index per order
|
|
140
|
+
* like any other equality. Pinned by each list's spec against
|
|
141
|
+
* `cloud/firebase-firestore.indexes.json`.
|
|
142
|
+
*/
|
|
143
|
+
export declare function listQueryIndexes(declaration: ListQueryDeclaration, base?: readonly {
|
|
144
|
+
path: string;
|
|
145
|
+
array?: boolean;
|
|
146
|
+
}[]): ListQueryIndex[];
|
|
147
|
+
/** An index entry as `cloud/firebase-firestore.indexes.json` stores it. */
|
|
148
|
+
interface IndexFileEntry {
|
|
149
|
+
collectionGroup: string;
|
|
150
|
+
queryScope: string;
|
|
151
|
+
fields: Array<{
|
|
152
|
+
fieldPath: string;
|
|
153
|
+
order?: string;
|
|
154
|
+
arrayConfig?: string;
|
|
155
|
+
}>;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The composites a declaration needs that an index file does not hold — what
|
|
159
|
+
* a list's spec asserts is empty, so a declared filter cannot ship without
|
|
160
|
+
* the index that serves it.
|
|
161
|
+
*/
|
|
162
|
+
export declare function missingListQueryIndexes(file: {
|
|
163
|
+
indexes: readonly IndexFileEntry[];
|
|
164
|
+
}, collectionGroup: string, needed: readonly ListQueryIndex[], queryScope?: 'COLLECTION' | 'COLLECTION_GROUP'): ListQueryIndex[];
|
|
165
|
+
export {};
|