@navette-js/tables 1.0.0-beta.1 → 1.0.0-beta.2
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/README.md +2 -2
- package/lib/index.d.ts +149 -148
- package/lib/index.js +167 -166
- package/lib/query-builder.d.ts +53 -53
- package/lib/query-builder.js +89 -95
- package/package.json +7 -8
- package/views/column-manager.ejs +2 -2
- package/views/index.ejs +14 -15
package/lib/query-builder.d.ts
CHANGED
|
@@ -2,10 +2,10 @@ import type { ListQuery } from '@navette-js/database';
|
|
|
2
2
|
import { Block, Builder } from '@navette-js/forms/builder';
|
|
3
3
|
import { Component } from '@navette-js/schemas';
|
|
4
4
|
import type { FilterIndicator, FilterState, TableFilter, TableHost } from './index.ts';
|
|
5
|
-
/**
|
|
5
|
+
/** Limits applied to the rule tree received from the browser. */
|
|
6
6
|
export declare const MAX_RULES = 100;
|
|
7
7
|
export declare const MAX_NESTING_DEPTH = 3;
|
|
8
|
-
/**
|
|
8
|
+
/** Maximum number of values in a multiple select. */
|
|
9
9
|
export declare const MAX_LIST_VALUES = 100;
|
|
10
10
|
type Comparison = '=' | '!=' | '<' | '<=' | '>' | '>=';
|
|
11
11
|
type Key = string | number;
|
|
@@ -29,7 +29,7 @@ export type Condition = {
|
|
|
29
29
|
operator: Comparison;
|
|
30
30
|
value: string | number;
|
|
31
31
|
}
|
|
32
|
-
/**
|
|
32
|
+
/** Value is filled (neither null nor an empty string), or the opposite. */
|
|
33
33
|
| {
|
|
34
34
|
kind: 'filled';
|
|
35
35
|
column: string;
|
|
@@ -40,7 +40,7 @@ export type Condition = {
|
|
|
40
40
|
values: Key[];
|
|
41
41
|
negate: boolean;
|
|
42
42
|
}
|
|
43
|
-
/**
|
|
43
|
+
/** Number of related records compared to a value. */
|
|
44
44
|
| {
|
|
45
45
|
kind: 'relationCount';
|
|
46
46
|
relationship: string;
|
|
@@ -48,7 +48,7 @@ export type Condition = {
|
|
|
48
48
|
value: number;
|
|
49
49
|
modify?: RelationshipQueryModifier;
|
|
50
50
|
}
|
|
51
|
-
/**
|
|
51
|
+
/** At least one related record (among `keys` when given), or none (`negate`). */
|
|
52
52
|
| {
|
|
53
53
|
kind: 'related';
|
|
54
54
|
relationship: string;
|
|
@@ -56,7 +56,7 @@ export type Condition = {
|
|
|
56
56
|
negate: boolean;
|
|
57
57
|
modify?: RelationshipQueryModifier;
|
|
58
58
|
};
|
|
59
|
-
/** `
|
|
59
|
+
/** `{ relationship, nodes }`: the nodes apply to the related records (`whereExists` subquery). */
|
|
60
60
|
export type ConditionNode = Condition | {
|
|
61
61
|
or: ConditionNode[][];
|
|
62
62
|
} | {
|
|
@@ -69,27 +69,27 @@ type Resolved = {
|
|
|
69
69
|
condition: Condition;
|
|
70
70
|
summary: string;
|
|
71
71
|
};
|
|
72
|
-
/**
|
|
72
|
+
/** Constraint operator: its settings form and how it turns into a condition. */
|
|
73
73
|
type Operator = {
|
|
74
74
|
name: string;
|
|
75
75
|
label: (inverse: boolean) => string;
|
|
76
|
-
/**
|
|
76
|
+
/** Default settings (null: the operator has no form). */
|
|
77
77
|
defaults: () => Settings | null;
|
|
78
78
|
fields: () => Component[];
|
|
79
|
-
/** Null
|
|
79
|
+
/** Null when the settings fail the form's validation: the rule then has no effect. */
|
|
80
80
|
resolve: (settings: Settings, inverse: boolean, constraint: Constraint) => Resolved | null;
|
|
81
|
-
/** Condition
|
|
81
|
+
/** Condition applied to the base query even when the constraint targets a relationship (RelationshipConstraint operators). */
|
|
82
82
|
onBaseQuery?: boolean;
|
|
83
83
|
};
|
|
84
|
-
/** Date (
|
|
84
|
+
/** Date (or date-time, with `hasTime`) targeted by an "after / before" operator's settings. */
|
|
85
85
|
export declare function resolveRuleDate(settings: Settings, now?: Date, hasTime?: boolean): string | null;
|
|
86
86
|
declare const OPERATORS: Record<'text' | 'number' | 'boolean' | 'date', Operator[]>;
|
|
87
87
|
type ConstraintType = keyof typeof OPERATORS | 'select' | 'relationship';
|
|
88
|
-
/**
|
|
88
|
+
/** Application-defined modifier of the related records query (knex / objection). */
|
|
89
89
|
export type RelationshipQueryModifier = (query: any) => void;
|
|
90
90
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
91
|
+
* Attribute the query builder can filter on. The queried column and relationship are the ones declared here, never browser values:
|
|
92
|
+
* the browser only picks a constraint (by name) and one of its operators.
|
|
93
93
|
*/
|
|
94
94
|
export declare class Constraint {
|
|
95
95
|
readonly name: string;
|
|
@@ -101,22 +101,22 @@ export declare class Constraint {
|
|
|
101
101
|
protected _relationship: string | null;
|
|
102
102
|
protected _modifyRelationshipQuery: RelationshipQueryModifier | null;
|
|
103
103
|
protected _nullable: boolean;
|
|
104
|
-
/**
|
|
104
|
+
/** Objection model of the table's records, used to list related records. */
|
|
105
105
|
protected _model: any;
|
|
106
106
|
constructor(name: string, type: ConstraintType, icon: string);
|
|
107
107
|
label(label: string): this;
|
|
108
|
-
/**
|
|
108
|
+
/** Attribute name used in rule summaries (defaults to the label). */
|
|
109
109
|
attributeLabel(label: string | null): this;
|
|
110
110
|
icon(name: string): this;
|
|
111
|
-
/**
|
|
111
|
+
/** Queried column (or query alias) when it differs from the name. */
|
|
112
112
|
attribute(column: string): this;
|
|
113
113
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
114
|
+
* Filters on an attribute of related records: `relationship('author', 'name')` filters on the author's name.
|
|
115
|
+
* The relationship must be declared by the Objection model (`relationMappings`).
|
|
116
116
|
*/
|
|
117
117
|
relationship(name: string, titleAttribute: string, modifyQueryUsing?: RelationshipQueryModifier | null): this;
|
|
118
118
|
modifyRelationshipQueryUsing(callback: RelationshipQueryModifier | null): this;
|
|
119
|
-
/**
|
|
119
|
+
/** Adds the "Is filled" / "Is blank" operator. */
|
|
120
120
|
nullable(condition?: boolean): this;
|
|
121
121
|
isNullable(): boolean;
|
|
122
122
|
model(model: any): this;
|
|
@@ -125,19 +125,19 @@ export declare class Constraint {
|
|
|
125
125
|
getAttributeLabel(): string;
|
|
126
126
|
getIcon(): string;
|
|
127
127
|
getColumn(): string;
|
|
128
|
-
/**
|
|
128
|
+
/** Relationship whose records hold the attribute, or `null` for a column of the table. */
|
|
129
129
|
getRelationshipName(): string | null;
|
|
130
130
|
getModifyRelationshipQueryUsing(): RelationshipQueryModifier | null;
|
|
131
131
|
getOperators(): Operator[];
|
|
132
|
-
/** `contains`
|
|
132
|
+
/** `contains` or `contains.inverse` → operator and direction; null if the constraint does not declare it. */
|
|
133
133
|
parseOperator(value: unknown): {
|
|
134
134
|
operator: Operator;
|
|
135
135
|
inverse: boolean;
|
|
136
136
|
} | null;
|
|
137
137
|
getOperatorOptions(): [string, string][];
|
|
138
|
-
/**
|
|
138
|
+
/** Setting names known to the constraint across all operators (switching operator keeps the previous settings). */
|
|
139
139
|
getSettingNames(): string[];
|
|
140
|
-
/**
|
|
140
|
+
/** Settings whose value is a list (multiple select). */
|
|
141
141
|
getListSettingNames(): string[];
|
|
142
142
|
getDefaultData(): Record<string, unknown>;
|
|
143
143
|
}
|
|
@@ -150,7 +150,7 @@ export declare class NumberConstraint extends Constraint {
|
|
|
150
150
|
export declare class BooleanConstraint extends Constraint {
|
|
151
151
|
static make(name: string): BooleanConstraint;
|
|
152
152
|
}
|
|
153
|
-
/** Date ;
|
|
153
|
+
/** Date constraint; with `time()`, date and time (date-time picker, minute and hour presets and units). */
|
|
154
154
|
export declare class DateConstraint extends Constraint {
|
|
155
155
|
private _time;
|
|
156
156
|
static make(name: string): DateConstraint;
|
|
@@ -158,13 +158,13 @@ export declare class DateConstraint extends Constraint {
|
|
|
158
158
|
hasTime(): boolean;
|
|
159
159
|
getOperators(): Operator[];
|
|
160
160
|
}
|
|
161
|
-
/**
|
|
161
|
+
/** Value picked from a fixed list; with `multiple()`, any of the picked values. */
|
|
162
162
|
export declare class SelectConstraint extends Constraint {
|
|
163
163
|
private _options;
|
|
164
164
|
private _multiple;
|
|
165
165
|
private _searchable;
|
|
166
166
|
static make(name: string): SelectConstraint;
|
|
167
|
-
/** Options `[
|
|
167
|
+
/** Options as `[value, label]` pairs or `{ value: label }`; only these values can filter. */
|
|
168
168
|
options(options: [string | number, string][] | Record<string, string>): this;
|
|
169
169
|
getOptions(): [string, string][];
|
|
170
170
|
multiple(condition?: boolean): this;
|
|
@@ -173,8 +173,8 @@ export declare class SelectConstraint extends Constraint {
|
|
|
173
173
|
getOperators(): Operator[];
|
|
174
174
|
}
|
|
175
175
|
/**
|
|
176
|
-
*
|
|
177
|
-
*
|
|
176
|
+
* "Is" / "Contains" operator of a RelationshipConstraint: related records are picked by key from a list loaded from the related model;
|
|
177
|
+
* `titleAttribute` is the displayed column.
|
|
178
178
|
*/
|
|
179
179
|
export declare class IsRelatedToOperator {
|
|
180
180
|
private _titleAttribute;
|
|
@@ -193,19 +193,19 @@ export declare class IsRelatedToOperator {
|
|
|
193
193
|
optionsLimit(limit: number): this;
|
|
194
194
|
modifyRelationshipQueryUsing(callback: RelationshipQueryModifier | null): this;
|
|
195
195
|
getModifyRelationshipQueryUsing(): RelationshipQueryModifier | null;
|
|
196
|
-
/**
|
|
196
|
+
/** Builds the query builder operator for the given constraint. */
|
|
197
197
|
toOperator(constraint: RelationshipConstraint): Operator;
|
|
198
198
|
getOptionsLimit(): number;
|
|
199
199
|
}
|
|
200
200
|
/**
|
|
201
|
-
*
|
|
202
|
-
*
|
|
201
|
+
* Related records: minimum, maximum or exact count (`multiple()`), empty relationship (`emptyable()`, on by default with `multiple()`),
|
|
202
|
+
* or related to picked records (`selectable(IsRelatedToOperator.make()…)`).
|
|
203
203
|
*/
|
|
204
204
|
export declare class RelationshipConstraint extends Constraint {
|
|
205
205
|
private _multiple;
|
|
206
206
|
private _emptyable;
|
|
207
207
|
private _selectable;
|
|
208
|
-
/**
|
|
208
|
+
/** Labels of the related records cited by rules, loaded before indicators are computed. */
|
|
209
209
|
private _relatedLabels;
|
|
210
210
|
static make(name: string): RelationshipConstraint;
|
|
211
211
|
multiple(condition?: boolean): this;
|
|
@@ -214,16 +214,16 @@ export declare class RelationshipConstraint extends Constraint {
|
|
|
214
214
|
canBeEmpty(): boolean;
|
|
215
215
|
selectable(operator: IsRelatedToOperator): this;
|
|
216
216
|
getSelectableOperator(): IsRelatedToOperator | null;
|
|
217
|
-
/**
|
|
217
|
+
/** Queried relationship: from `relationship()`, else `attribute()`, else the constraint name. */
|
|
218
218
|
getRelationshipName(): string;
|
|
219
219
|
getOperators(): Operator[];
|
|
220
220
|
getRelatedLabel(key: Key): string | null;
|
|
221
|
-
/**
|
|
221
|
+
/** Related model, found through the table model's relationship (declared, or the host's Objection adapter model). */
|
|
222
222
|
private relatedModel;
|
|
223
223
|
private relatedQuery;
|
|
224
|
-
/**
|
|
224
|
+
/** Select options: records of the related model, sorted by title. */
|
|
225
225
|
loadRelatedOptions(operator: IsRelatedToOperator, host: unknown): Promise<[string, string][]>;
|
|
226
|
-
/**
|
|
226
|
+
/** Loads labels of the keys cited by rules (for indicators such as "Author is Ada or Linus"). */
|
|
227
227
|
loadRelatedLabels(keys: Key[], host: unknown): Promise<void>;
|
|
228
228
|
}
|
|
229
229
|
type Rule = {
|
|
@@ -232,41 +232,41 @@ type Rule = {
|
|
|
232
232
|
};
|
|
233
233
|
type Rules = Record<string, Rule>;
|
|
234
234
|
/**
|
|
235
|
-
*
|
|
236
|
-
*
|
|
235
|
+
* Reduces the browser's rule tree to what the filter declares: known block types, the constraint's operators, scalar settings with
|
|
236
|
+
* known names, bounded depth and rule count. An unknown operator is reset to null (the rule has no effect).
|
|
237
237
|
*/
|
|
238
238
|
export declare function sanitizeRules(constraints: Constraint[], raw: unknown, depth?: number, budget?: {
|
|
239
239
|
rules: number;
|
|
240
240
|
}): Rules;
|
|
241
|
-
/**
|
|
241
|
+
/** Sanitized rules → conditions and indicator labels (one entry per effective top-level rule). */
|
|
242
242
|
export declare function compileRules(constraints: Constraint[], rules: Rules, iteration?: number): {
|
|
243
243
|
nodes: ConditionNode[];
|
|
244
244
|
summaries: Record<string, string>;
|
|
245
245
|
};
|
|
246
|
-
/**
|
|
246
|
+
/** SQL dialect of the query's knex connection. */
|
|
247
247
|
export type SqlDialect = 'sqlite' | 'mysql' | 'pg' | 'mssql';
|
|
248
|
-
/**
|
|
248
|
+
/** Dialect read from the knex client (`query.client.config.client`, or the Objection model's connection); SQLite by default. */
|
|
249
249
|
export declare function sqlDialectOf(query: any): SqlDialect;
|
|
250
250
|
/**
|
|
251
|
-
*
|
|
252
|
-
*
|
|
251
|
+
* Applies conditions to a knex / objection query. Columns are bound as identifiers and values as parameters; comparison operators
|
|
252
|
+
* come from a closed list. Date and search SQL follows the connection's dialect.
|
|
253
253
|
*/
|
|
254
254
|
export declare function applyConditions(query: any, nodes: ConditionNode[], dialect?: SqlDialect): void;
|
|
255
|
-
/**
|
|
255
|
+
/** Rule builder: a Builder whose blocks are the filter's constraints, plus the "OR" block. */
|
|
256
256
|
export declare class RuleBuilder extends Builder {
|
|
257
257
|
readonly filter: QueryBuilder;
|
|
258
258
|
readonly depth: number;
|
|
259
259
|
constructor(name: string, filter: QueryBuilder, depth?: number);
|
|
260
|
-
/**
|
|
260
|
+
/** The "OR" block is neither offered nor accepted beyond the maximum depth; nothing is offered once the rule limit is reached. */
|
|
261
261
|
getBlockPickerBlocks(): Block[];
|
|
262
262
|
getBlock(name: unknown): Block | undefined;
|
|
263
263
|
protected canAdd(): boolean;
|
|
264
|
-
/**
|
|
264
|
+
/** Counts rules across the whole tree ("OR" blocks excluded), read from the host's deferred filter state. */
|
|
265
265
|
isAtRuleLimit(): boolean;
|
|
266
|
-
/**
|
|
266
|
+
/** Component action without modal (also used by "OR" groups). */
|
|
267
267
|
makeAction(name: string, handler: (args: Record<string, unknown>) => void): any;
|
|
268
268
|
}
|
|
269
|
-
/**
|
|
269
|
+
/** Query builder table filter. */
|
|
270
270
|
export declare class QueryBuilder implements TableFilter {
|
|
271
271
|
readonly name = "queryBuilder";
|
|
272
272
|
private _constraints;
|
|
@@ -274,9 +274,9 @@ export declare class QueryBuilder implements TableFilter {
|
|
|
274
274
|
private _model;
|
|
275
275
|
static make(): QueryBuilder;
|
|
276
276
|
constraints(constraints: Constraint[]): this;
|
|
277
|
-
/**
|
|
277
|
+
/** Objection model of the table, passed to relationship constraints (related record lists). */
|
|
278
278
|
model(model: any): this;
|
|
279
|
-
/**
|
|
279
|
+
/** Before indicators: loads labels of the related records cited by rules (`RelationshipConstraint.selectable`). */
|
|
280
280
|
loadIndicatorData(state: FilterState, host: TableHost): Promise<void>;
|
|
281
281
|
constraintPickerColumns(columns?: number | null): this;
|
|
282
282
|
getConstraints(): Constraint[];
|
|
@@ -287,7 +287,7 @@ export declare class QueryBuilder implements TableFilter {
|
|
|
287
287
|
placeholder: string;
|
|
288
288
|
options: [string, string][];
|
|
289
289
|
};
|
|
290
|
-
/**
|
|
290
|
+
/** The filter spans the full width of the filters form. */
|
|
291
291
|
getColumnSpan(): Record<string, number | string>;
|
|
292
292
|
getFormComponents(): Component[];
|
|
293
293
|
sanitizeState(state: unknown): FilterState;
|
|
@@ -295,7 +295,7 @@ export declare class QueryBuilder implements TableFilter {
|
|
|
295
295
|
private compile;
|
|
296
296
|
isActive(state: FilterState): boolean;
|
|
297
297
|
getIndicators(state: FilterState): FilterIndicator[];
|
|
298
|
-
/**
|
|
298
|
+
/** Removing an indicator removes the matching top-level rule. */
|
|
299
299
|
removeIndicator(state: FilterState, field: string): FilterState;
|
|
300
300
|
apply(query: Omit<ListQuery, 'page' | 'perPage'>, state: FilterState): void;
|
|
301
301
|
}
|