@solidev/data 1.0.1 → 1.1.1
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/AGENTS.md +46 -0
- package/README.md +40 -44
- package/fesm2022/solidev-data-mdedit.mjs +583 -0
- package/fesm2022/solidev-data-mdedit.mjs.map +1 -0
- package/fesm2022/solidev-data-richedit.mjs +1132 -157
- package/fesm2022/solidev-data-richedit.mjs.map +1 -1
- package/fesm2022/solidev-data.mjs +1092 -719
- package/fesm2022/solidev-data.mjs.map +1 -1
- package/package.json +19 -2
- package/types/solidev-data-mdedit.d.ts +226 -0
- package/types/solidev-data-richedit.d.ts +286 -69
- package/types/solidev-data.d.ts +1261 -1038
package/types/solidev-data.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { InjectionToken,
|
|
3
|
-
import { ValidatorFn, FormControl, ValidationErrors, FormGroup,
|
|
4
|
-
import * as _angular_common_http from '@angular/common/http';
|
|
5
|
-
import { HttpClient, HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';
|
|
2
|
+
import { InjectionToken, OnInit, ElementRef, PipeTransform, NgZone, EventEmitter, OnDestroy } from '@angular/core';
|
|
3
|
+
import { ValidatorFn, FormControl, ValidationErrors, FormGroup, UntypedFormGroup, ControlValueAccessor, UntypedFormControl } from '@angular/forms';
|
|
6
4
|
import * as rxjs from 'rxjs';
|
|
7
5
|
import { Observable, ReplaySubject, Subject, Subscription } from 'rxjs';
|
|
8
6
|
import { ActivatedRoute, Router, Route, RouterState, UrlSegment } from '@angular/router';
|
|
9
7
|
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
|
10
8
|
import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap';
|
|
11
|
-
import
|
|
9
|
+
import * as _angular_common_http from '@angular/common/http';
|
|
10
|
+
import { HttpClient, HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';
|
|
11
|
+
import { SafeHtml } from '@angular/platform-browser';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Base URL of the REST API every {@link Collection} builds its endpoints on.
|
|
@@ -70,15 +70,13 @@ interface DataDisplayConfig {
|
|
|
70
70
|
* `"inline"` renders the value in flow, `"dd"` renders it as a definition
|
|
71
71
|
* list entry.
|
|
72
72
|
*/
|
|
73
|
-
defaultMode:
|
|
73
|
+
defaultMode: 'inline' | 'dd';
|
|
74
74
|
/**
|
|
75
75
|
* Class string per editor type, keyed by the editor names used in
|
|
76
76
|
* `DISPEDIT_EDITOR_TYPES` (e.g. `"input.text"`, `"select"`). A missing key
|
|
77
77
|
* simply yields no class.
|
|
78
78
|
*/
|
|
79
|
-
inputClasses:
|
|
80
|
-
[index: string]: string;
|
|
81
|
-
};
|
|
79
|
+
inputClasses: Record<string, string>;
|
|
82
80
|
};
|
|
83
81
|
}
|
|
84
82
|
/**
|
|
@@ -113,406 +111,148 @@ declare const BootstrapDataDisplayConfig: DataDisplayConfig;
|
|
|
113
111
|
declare const DATA_DISPLAY_CONFIG: InjectionToken<DataDisplayConfig>;
|
|
114
112
|
|
|
115
113
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* `
|
|
119
|
-
* label rendered in the dropdown or in display mode. Choices come either from
|
|
120
|
-
* the field manager (e.g. a `charField` declared with `choices`) or from the
|
|
121
|
-
* `[choices]` input of {@link DispeditComponent}, which overrides the manager.
|
|
122
|
-
*/
|
|
123
|
-
interface IDispEditChoice {
|
|
124
|
-
/** Human-readable label shown to the user. */
|
|
125
|
-
desc: string;
|
|
126
|
-
/** Raw value written to the model field when the option is picked. */
|
|
127
|
-
value: any;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Every editor widget {@link DispeditComponent} knows how to render.
|
|
114
|
+
* The HTTP layer every {@link Collection} sits on: it owns the API base URL,
|
|
115
|
+
* decides the headers, and optionally serves GET responses out of Angular's
|
|
116
|
+
* `TransferState` during SSR hydration.
|
|
131
117
|
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
118
|
+
* Collections never touch `HttpClient` directly, which makes this the one place
|
|
119
|
+
* to hook cross-cutting request concerns. The usual reason to care about this
|
|
120
|
+
* class is {@link headers}: subclass it, override that method to inject an auth
|
|
121
|
+
* token, and provide the subclass in place of the default.
|
|
135
122
|
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* - `input.decimal`: numeric `<input>` for a `decimalField`; the value is
|
|
140
|
-
* divided by the manager's `factor` on load and multiplied back on save.
|
|
141
|
-
* - `input.date` / `input.datetime`: native date / datetime-local `<input>`.
|
|
142
|
-
* - `input.checkbox`: a Oui/Non button group (not an actual checkbox).
|
|
143
|
-
* - `textarea`: multi-line `<textarea>`.
|
|
144
|
-
* - `select`: `<select>` built from the resolved choices. Automatically used
|
|
145
|
-
* whenever choices are available, whatever the manager advertises.
|
|
146
|
-
* - `quill`: rich text editor (rendered by the caller's own integration).
|
|
147
|
-
* - `fkselect`: `<data-fkselect>` typeahead, set by `ForeignKeyFieldManager`.
|
|
148
|
-
* - `m2mselect`: `<data-m2mselect>` multi-value typeahead, set by
|
|
149
|
-
* `ManyToManyFieldManager`.
|
|
150
|
-
*/
|
|
151
|
-
type DISPEDIT_EDITOR_TYPES = 'input.text' | 'input.email' | 'input.number' | 'input.decimal' | 'input.datetime' | 'input.date' | 'input.checkbox' | 'input.password' | 'textarea' | 'select' | 'quill' | 'fkselect' | 'm2mselect';
|
|
152
|
-
/**
|
|
153
|
-
* Every read-only renderer {@link DispeditComponent} knows how to produce.
|
|
123
|
+
* Requires {@link DATA_API_URL}. TransferState caching applies to GET only, and
|
|
124
|
+
* only when {@link DATA_MAX_TRANSFERSTATE_TIME} is provided and greater than
|
|
125
|
+
* zero — see {@link _cachedGet} for the exact conditions.
|
|
154
126
|
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
127
|
+
* Dependencies are resolved with `inject()`, so a subclass declares **no
|
|
128
|
+
* constructor**. To point one at a different API — a second backend alongside
|
|
129
|
+
* the main one — override {@link apiUrl} rather than passing a URL through
|
|
130
|
+
* `super()`; {@link maxTransferstateTime} is overridable the same way.
|
|
159
131
|
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* and `shortDate` respectively).
|
|
169
|
-
* - `quill`: rich text, rendered as HTML by the caller's integration.
|
|
170
|
-
*/
|
|
171
|
-
type DISPEDIT_DISPLAY_TYPES = 'text' | 'choice' | 'boolean' | 'decimal' | 'fkdetails' | 'm2mdetails' | 'datetime' | 'date' | 'quill';
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Options common to every field decorator. All are optional; each concrete
|
|
175
|
-
* field type extends this with its own (`ICharFieldMetadata`, etc.).
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* @Injectable({ providedIn: 'root' })
|
|
135
|
+
* export class AuthBackend extends DataBackend {
|
|
136
|
+
* protected override headers(headers: { [k: string]: string }) {
|
|
137
|
+
* return { ...super.headers(headers), Authorization: `Bearer ${token}` };
|
|
138
|
+
* }
|
|
139
|
+
* }
|
|
176
140
|
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
141
|
+
* @Injectable({ providedIn: 'root' })
|
|
142
|
+
* export class SupportBackend extends DataBackend {
|
|
143
|
+
* public override get apiUrl(): string {
|
|
144
|
+
* return 'https://support.example.com/api';
|
|
145
|
+
* }
|
|
146
|
+
* }
|
|
179
147
|
*
|
|
180
|
-
*
|
|
148
|
+
* providers: [
|
|
149
|
+
* { provide: DATA_API_URL, useValue: 'https://api.example.com' },
|
|
150
|
+
* { provide: DataBackend, useClass: AuthBackend },
|
|
151
|
+
* ];
|
|
152
|
+
* ```
|
|
181
153
|
*/
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Wire name of the field: the key used in the JSON payload. Defaults to the
|
|
185
|
-
* decorated property name, so it only needs setting when the API name and
|
|
186
|
-
* the TypeScript property name differ.
|
|
187
|
-
*/
|
|
188
|
-
name?: string;
|
|
189
|
-
/** Short hint shown next to the editor. Defaults to an empty string. */
|
|
190
|
-
help?: string;
|
|
191
|
-
/**
|
|
192
|
-
* Human-readable label used for column titles, form labels and hover
|
|
193
|
-
* details. Defaults to {@link IFieldMetadata.name} when omitted.
|
|
194
|
-
*/
|
|
195
|
-
description?: string;
|
|
154
|
+
declare class DataBackend {
|
|
196
155
|
/**
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
* Beware: combining `required: true` with no `defaultValue` throws at class
|
|
201
|
-
* definition time — see {@link BaseFieldManager.getDefaultValue}.
|
|
156
|
+
* Instantiation timestamp, used as the origin of the TransferState validity
|
|
157
|
+
* window (see {@link _cachedGet}) — the window runs from backend creation, not
|
|
158
|
+
* from each entry's insertion.
|
|
202
159
|
*/
|
|
203
|
-
|
|
160
|
+
private _created;
|
|
161
|
+
private _http;
|
|
162
|
+
private _transferState;
|
|
163
|
+
private _platform;
|
|
164
|
+
private _apiUrl;
|
|
165
|
+
private _maxTransferstateTime;
|
|
204
166
|
/**
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
167
|
+
* Base URL every collection URL is built on, as provided via
|
|
168
|
+
* {@link DATA_API_URL}. Read by `Collection.getUrl()`; exposed so custom
|
|
169
|
+
* collections can build URLs the same way.
|
|
208
170
|
*/
|
|
209
|
-
|
|
171
|
+
get apiUrl(): string;
|
|
210
172
|
/**
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* fresh array/date per instance instead of a shared one.
|
|
173
|
+
* TransferState window in ms, from {@link DATA_MAX_TRANSFERSTATE_TIME}; `0`
|
|
174
|
+
* disables the cache. Overridable for the same reason as {@link apiUrl}.
|
|
214
175
|
*/
|
|
215
|
-
|
|
176
|
+
protected get maxTransferstateTime(): number;
|
|
216
177
|
/**
|
|
217
|
-
*
|
|
178
|
+
* Issues an arbitrary request and returns the parsed JSON body.
|
|
218
179
|
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
* (`CharFieldManager`, `ForeignKeyFieldManager`, ...) cover the usual cases.
|
|
234
|
-
* Override `fromJson`/`toJson` to change the wire mapping and
|
|
235
|
-
* `getValidators()` to add constraints.
|
|
236
|
-
*/
|
|
237
|
-
declare class BaseFieldManager<FT> implements IFieldMetadata<FT> {
|
|
238
|
-
/** Name is mandatory in a field manager. It is given by
|
|
239
|
-
* field decorator if not directly given in field manager. */
|
|
240
|
-
name: string;
|
|
241
|
-
/** Human-readable label; falls back to {@link name} when not given. */
|
|
242
|
-
description: string;
|
|
243
|
-
/** Input hint; normalised to `''` when not given. */
|
|
244
|
-
help: string;
|
|
245
|
-
/** Whether a value must be present. Adds `Validators.required`. */
|
|
246
|
-
required: boolean;
|
|
247
|
-
/** Whether the field is excluded from forms and never written back. */
|
|
248
|
-
readonly: boolean;
|
|
249
|
-
/**
|
|
250
|
-
* Set to `true` only by `ComputedFieldManager`. `DataModel.setFV` skips
|
|
251
|
-
* assignment entirely for computed fields, making them permanently
|
|
252
|
-
* read-only in the eyes of the model.
|
|
180
|
+
* The general-purpose entry point, used by `Collection.action()` and
|
|
181
|
+
* `Collection.raw()`. GET requests are routed through {@link _cachedGet} and so
|
|
182
|
+
* may be answered from TransferState; every other method goes straight to the
|
|
183
|
+
* network and carries the body.
|
|
184
|
+
*
|
|
185
|
+
* @param collection collection the request belongs to; consulted for its
|
|
186
|
+
* `useTransferState` flag
|
|
187
|
+
* @param method HTTP method
|
|
188
|
+
* @param url absolute URL, normally from `Collection.getUrl()`
|
|
189
|
+
* @param body JSON body; ignored for GET
|
|
190
|
+
* @param params query parameters
|
|
191
|
+
* @param headers extra headers, passed through {@link headers}
|
|
192
|
+
*
|
|
193
|
+
* @return an observable of the response body
|
|
253
194
|
*/
|
|
254
|
-
|
|
255
|
-
/** Display ordering weight; higher is shown first. See {@link IFieldMetadata.priority}. */
|
|
256
|
-
priority: number;
|
|
257
|
-
/** Constant or factory used when the model has no value. */
|
|
258
|
-
defaultValue?: FT | ((args: any) => FT);
|
|
195
|
+
action<T extends DataModel, RT>(collection: Collection<T>, method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', url: string, { body, params, headers }?: IActionParams): Observable<RT>;
|
|
259
196
|
/**
|
|
260
|
-
*
|
|
197
|
+
* Issues a request whose response is taken as binary rather than JSON.
|
|
261
198
|
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
199
|
+
* Backs `Collection.blob()`; use that instead of calling this directly. Never
|
|
200
|
+
* cached through TransferState, whatever the method.
|
|
201
|
+
*
|
|
202
|
+
* @param collection collection the request belongs to; not used by this method
|
|
203
|
+
* @param method HTTP method
|
|
204
|
+
* @param url absolute URL
|
|
205
|
+
* @param body JSON body
|
|
206
|
+
* @param params query parameters
|
|
207
|
+
* @param headers extra headers, passed through {@link headers}
|
|
208
|
+
*
|
|
209
|
+
* @return an observable of the response as a `Blob`
|
|
267
210
|
*/
|
|
268
|
-
|
|
211
|
+
blob<T extends DataModel>(collection: Collection<T>, method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', url: string, { body, params, headers }?: IActionParams): Observable<Blob>;
|
|
269
212
|
/**
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
213
|
+
* Full-replacement write (HTTP PUT). Provided for completeness — the CRUD path
|
|
214
|
+
* in `Collection` uses {@link post}/{@link patch} instead, so this is only
|
|
215
|
+
* reached by callers that need PUT semantics explicitly.
|
|
216
|
+
*
|
|
217
|
+
* @param collection collection the request belongs to; not used by this method
|
|
218
|
+
* @param url absolute URL
|
|
219
|
+
* @param body JSON body
|
|
220
|
+
* @param params query parameters
|
|
221
|
+
* @param headers extra headers, passed through {@link headers}
|
|
273
222
|
*/
|
|
274
|
-
|
|
223
|
+
put<T extends DataModel>(collection: Collection<T>, url: string, { body, params, headers }?: IActionParams): Observable<T>;
|
|
275
224
|
/**
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
* `required` field with no `defaultValue` throws here, at decoration time.
|
|
225
|
+
* Creates a record (HTTP POST). Chosen by `Collection.save()`/`update()` when
|
|
226
|
+
* the model has no `id`.
|
|
279
227
|
*
|
|
280
|
-
* @param
|
|
228
|
+
* @param collection collection the request belongs to; not used by this method
|
|
229
|
+
* @param url absolute URL, normally the collection's list URL
|
|
230
|
+
* @param body JSON body
|
|
231
|
+
* @param params query parameters
|
|
232
|
+
* @param headers extra headers, passed through {@link headers}
|
|
233
|
+
* @returns the created record's JSON, expected to include the assigned `id`
|
|
281
234
|
*/
|
|
282
|
-
|
|
235
|
+
post<T extends DataModel>(collection: Collection<T>, url: string, { body, params, headers }?: IActionParams): Observable<Partial<T>>;
|
|
283
236
|
/**
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
237
|
+
* Partially updates a record (HTTP PATCH). Chosen by
|
|
238
|
+
* `Collection.save()`/`update()` when the model already has an `id`.
|
|
239
|
+
*
|
|
240
|
+
* @param collection collection the request belongs to; not used by this method
|
|
241
|
+
* @param url absolute URL, normally the record's detail URL
|
|
242
|
+
* @param body JSON body, holding only the fields to change
|
|
243
|
+
* @param params query parameters
|
|
244
|
+
* @param headers extra headers, passed through {@link headers}
|
|
287
245
|
*/
|
|
288
|
-
|
|
246
|
+
patch<T extends DataModel>(collection: Collection<T>, url: string, { body, params, headers }?: IActionParams): Observable<Partial<T>>;
|
|
289
247
|
/**
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
248
|
+
* Deletes a record (HTTP DELETE). Backs `Collection.delete()`.
|
|
249
|
+
*
|
|
250
|
+
* @param collection collection the request belongs to; not used by this method
|
|
251
|
+
* @param url absolute URL of the record
|
|
252
|
+
* @param params query parameters
|
|
253
|
+
* @param headers extra headers, passed through {@link headers}
|
|
293
254
|
*/
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Builds a typed `FormControl` for this field on a given model instance,
|
|
297
|
-
* seeded with the instance's current value and falling back to the default
|
|
298
|
-
* value, and wired with {@link validators}.
|
|
299
|
-
*
|
|
300
|
-
* Note the seed uses `||`, so falsy current values (`0`, `''`, `false`) fall
|
|
301
|
-
* back to the default rather than being kept.
|
|
302
|
-
*
|
|
303
|
-
* @param instance model whose value seeds the control
|
|
304
|
-
*/
|
|
305
|
-
formControl(instance: DataModel): FormControl<FT | null>;
|
|
306
|
-
/**
|
|
307
|
-
* Converts a raw JSON value coming from the API into the model value.
|
|
308
|
-
* The base implementation passes the data straight through; typed managers
|
|
309
|
-
* override it to coerce (`boolean`), parse (`date`) or instantiate
|
|
310
|
-
* (`details`).
|
|
311
|
-
*
|
|
312
|
-
* @param data raw value read from the JSON payload
|
|
313
|
-
*/
|
|
314
|
-
fromJson(data: any): FT;
|
|
315
|
-
/**
|
|
316
|
-
* Converts the model value back into its JSON representation for save.
|
|
317
|
-
* The base implementation passes the data straight through.
|
|
318
|
-
*
|
|
319
|
-
* @param data current model value
|
|
320
|
-
*/
|
|
321
|
-
toJson(data: FT): any;
|
|
322
|
-
/**
|
|
323
|
-
* Renders the value for display. The base implementation is plain string
|
|
324
|
-
* interpolation.
|
|
325
|
-
*
|
|
326
|
-
* @param data value to render
|
|
327
|
-
* @param format reserved; ignored by the base implementation
|
|
328
|
-
*/
|
|
329
|
-
toString(data: FT, format?: string): string;
|
|
330
|
-
/**
|
|
331
|
-
* Public accessor for this field's default value, invoking the
|
|
332
|
-
* `defaultValue` factory with `args` when one was declared.
|
|
333
|
-
*
|
|
334
|
-
* @param args passed through to a `defaultValue` function
|
|
335
|
-
*/
|
|
336
|
-
default(args?: any): FT | undefined;
|
|
337
|
-
/**
|
|
338
|
-
* Builds the base validator list: `Validators.required` when the field is
|
|
339
|
-
* required, nothing otherwise. Subclasses call it and push their own.
|
|
340
|
-
*
|
|
341
|
-
* @protected
|
|
342
|
-
*/
|
|
343
|
-
protected getValidators(): ValidatorFn[];
|
|
344
|
-
/**
|
|
345
|
-
* Resolves the default value: calls `defaultValue` when it is a function,
|
|
346
|
-
* otherwise returns it as-is.
|
|
347
|
-
*
|
|
348
|
-
* **Throws** when the field is `required` and no `defaultValue` was given.
|
|
349
|
-
* Because the constructor calls this, the error surfaces when the class is
|
|
350
|
-
* defined (module evaluation), not when a model is instantiated — a
|
|
351
|
-
* `required` field without a default breaks the app at import time.
|
|
352
|
-
*
|
|
353
|
-
* @param args passed through to a `defaultValue` function
|
|
354
|
-
* @throws Error if `required` is set and `defaultValue` is `undefined`
|
|
355
|
-
* @protected
|
|
356
|
-
*/
|
|
357
|
-
protected getDefaultValue(args?: any): FT | undefined;
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* What is actually kept in a model's metadata map: the options you passed to
|
|
361
|
-
* the decorator, plus the four entries the decorator computes. This is the
|
|
362
|
-
* shape returned by {@link getFieldsMetadata}.
|
|
363
|
-
*/
|
|
364
|
-
interface IFieldStoredMetadata<FT> extends IFieldMetadata<FT> {
|
|
365
|
-
/** Map key of this entry: `` `${__name}__${propertyKey}` ``. */
|
|
366
|
-
self: string;
|
|
367
|
-
/** Wire name; defaulted to the decorated property name. */
|
|
368
|
-
name: string;
|
|
369
|
-
/** Field type code, e.g. `'charField'`, `'foreignKeyField'`. */
|
|
370
|
-
type: string;
|
|
371
|
-
/** The live manager instance built for this field. */
|
|
372
|
-
manager: BaseFieldManager<FT>;
|
|
373
|
-
}
|
|
374
|
-
/**
|
|
375
|
-
* Shape of every field decorator returned by {@link genericDataField}: a plain
|
|
376
|
-
* property decorator, applied for its side effect on the prototype's metadata
|
|
377
|
-
* map.
|
|
378
|
-
*/
|
|
379
|
-
type FieldDecoratorFn = (target: any, propertyKey: string | symbol) => void;
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* The HTTP layer every {@link Collection} sits on: it owns the API base URL,
|
|
383
|
-
* decides the headers, and optionally serves GET responses out of Angular's
|
|
384
|
-
* `TransferState` during SSR hydration.
|
|
385
|
-
*
|
|
386
|
-
* Collections never touch `HttpClient` directly, which makes this the one place
|
|
387
|
-
* to hook cross-cutting request concerns. The usual reason to care about this
|
|
388
|
-
* class is {@link headers}: subclass it, override that method to inject an auth
|
|
389
|
-
* token, and provide the subclass in place of the default.
|
|
390
|
-
*
|
|
391
|
-
* Requires {@link DATA_API_URL}. TransferState caching applies to GET only, and
|
|
392
|
-
* only when {@link DATA_MAX_TRANSFERSTATE_TIME} is provided and greater than
|
|
393
|
-
* zero — see {@link _cachedGet} for the exact conditions.
|
|
394
|
-
*
|
|
395
|
-
* @example
|
|
396
|
-
* ```ts
|
|
397
|
-
* @Injectable({ providedIn: 'root' })
|
|
398
|
-
* export class AuthBackend extends DataBackend {
|
|
399
|
-
* protected override headers(headers: { [k: string]: string }) {
|
|
400
|
-
* return { ...super.headers(headers), Authorization: `Bearer ${token}` };
|
|
401
|
-
* }
|
|
402
|
-
* }
|
|
403
|
-
*
|
|
404
|
-
* providers: [
|
|
405
|
-
* { provide: DATA_API_URL, useValue: 'https://api.example.com' },
|
|
406
|
-
* { provide: DataBackend, useClass: AuthBackend },
|
|
407
|
-
* ];
|
|
408
|
-
* ```
|
|
409
|
-
*/
|
|
410
|
-
declare class DataBackend {
|
|
411
|
-
private _http;
|
|
412
|
-
private _transferState;
|
|
413
|
-
private _platform;
|
|
414
|
-
private _apiUrl;
|
|
415
|
-
private _maxTransferstateTime;
|
|
416
|
-
/**
|
|
417
|
-
* Instantiation timestamp, used as the origin of the TransferState validity
|
|
418
|
-
* window (see {@link _cachedGet}) — the window runs from backend creation, not
|
|
419
|
-
* from each entry's insertion.
|
|
420
|
-
*/
|
|
421
|
-
private _created;
|
|
422
|
-
/**
|
|
423
|
-
* @param _http Angular HTTP client
|
|
424
|
-
* @param _transferState SSR state bridge, used to replay server GETs in the browser
|
|
425
|
-
* @param _platform platform id, used to write TransferState on the server only
|
|
426
|
-
* @param _apiUrl base API URL; required, see {@link DATA_API_URL}
|
|
427
|
-
* @param _maxTransferstateTime TransferState window in ms; optional, `0`
|
|
428
|
-
* (the default) disables caching entirely
|
|
429
|
-
*/
|
|
430
|
-
constructor(_http: HttpClient, _transferState: TransferState, _platform: any, _apiUrl: string, _maxTransferstateTime?: number);
|
|
431
|
-
/**
|
|
432
|
-
* Base URL every collection URL is built on, as provided via
|
|
433
|
-
* {@link DATA_API_URL}. Read by `Collection.getUrl()`; exposed so custom
|
|
434
|
-
* collections can build URLs the same way.
|
|
435
|
-
*/
|
|
436
|
-
get apiUrl(): string;
|
|
437
|
-
/**
|
|
438
|
-
* Issues an arbitrary request and returns the parsed JSON body.
|
|
439
|
-
*
|
|
440
|
-
* The general-purpose entry point, used by `Collection.action()` and
|
|
441
|
-
* `Collection.raw()`. GET requests are routed through {@link _cachedGet} and so
|
|
442
|
-
* may be answered from TransferState; every other method goes straight to the
|
|
443
|
-
* network and carries the body.
|
|
444
|
-
*
|
|
445
|
-
* @param collection collection the request belongs to; consulted for its
|
|
446
|
-
* `useTransferState` flag
|
|
447
|
-
* @param method HTTP method
|
|
448
|
-
* @param url absolute URL, normally from `Collection.getUrl()`
|
|
449
|
-
* @param body JSON body; ignored for GET
|
|
450
|
-
* @param params query parameters
|
|
451
|
-
* @param headers extra headers, passed through {@link headers}
|
|
452
|
-
*
|
|
453
|
-
* @return an observable of the response body
|
|
454
|
-
*/
|
|
455
|
-
action<T extends DataModel, RT>(collection: Collection<T>, method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', url: string, { body, params, headers }?: IActionParams): Observable<RT>;
|
|
456
|
-
/**
|
|
457
|
-
* Issues a request whose response is taken as binary rather than JSON.
|
|
458
|
-
*
|
|
459
|
-
* Backs `Collection.blob()`; use that instead of calling this directly. Never
|
|
460
|
-
* cached through TransferState, whatever the method.
|
|
461
|
-
*
|
|
462
|
-
* @param collection collection the request belongs to; not used by this method
|
|
463
|
-
* @param method HTTP method
|
|
464
|
-
* @param url absolute URL
|
|
465
|
-
* @param body JSON body
|
|
466
|
-
* @param params query parameters
|
|
467
|
-
* @param headers extra headers, passed through {@link headers}
|
|
468
|
-
*
|
|
469
|
-
* @return an observable of the response as a `Blob`
|
|
470
|
-
*/
|
|
471
|
-
blob<T extends DataModel>(collection: Collection<T>, method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', url: string, { body, params, headers }?: IActionParams): Observable<Blob>;
|
|
472
|
-
/**
|
|
473
|
-
* Full-replacement write (HTTP PUT). Provided for completeness — the CRUD path
|
|
474
|
-
* in `Collection` uses {@link post}/{@link patch} instead, so this is only
|
|
475
|
-
* reached by callers that need PUT semantics explicitly.
|
|
476
|
-
*
|
|
477
|
-
* @param collection collection the request belongs to; not used by this method
|
|
478
|
-
* @param url absolute URL
|
|
479
|
-
* @param body JSON body
|
|
480
|
-
* @param params query parameters
|
|
481
|
-
* @param headers extra headers, passed through {@link headers}
|
|
482
|
-
*/
|
|
483
|
-
put<T extends DataModel>(collection: Collection<T>, url: string, { body, params, headers }?: IActionParams): Observable<T>;
|
|
484
|
-
/**
|
|
485
|
-
* Creates a record (HTTP POST). Chosen by `Collection.save()`/`update()` when
|
|
486
|
-
* the model has no `id`.
|
|
487
|
-
*
|
|
488
|
-
* @param collection collection the request belongs to; not used by this method
|
|
489
|
-
* @param url absolute URL, normally the collection's list URL
|
|
490
|
-
* @param body JSON body
|
|
491
|
-
* @param params query parameters
|
|
492
|
-
* @param headers extra headers, passed through {@link headers}
|
|
493
|
-
* @returns the created record's JSON, expected to include the assigned `id`
|
|
494
|
-
*/
|
|
495
|
-
post<T extends DataModel>(collection: Collection<T>, url: string, { body, params, headers }?: IActionParams): Observable<Partial<T>>;
|
|
496
|
-
/**
|
|
497
|
-
* Partially updates a record (HTTP PATCH). Chosen by
|
|
498
|
-
* `Collection.save()`/`update()` when the model already has an `id`.
|
|
499
|
-
*
|
|
500
|
-
* @param collection collection the request belongs to; not used by this method
|
|
501
|
-
* @param url absolute URL, normally the record's detail URL
|
|
502
|
-
* @param body JSON body, holding only the fields to change
|
|
503
|
-
* @param params query parameters
|
|
504
|
-
* @param headers extra headers, passed through {@link headers}
|
|
505
|
-
*/
|
|
506
|
-
patch<T extends DataModel>(collection: Collection<T>, url: string, { body, params, headers }?: IActionParams): Observable<Partial<T>>;
|
|
507
|
-
/**
|
|
508
|
-
* Deletes a record (HTTP DELETE). Backs `Collection.delete()`.
|
|
509
|
-
*
|
|
510
|
-
* @param collection collection the request belongs to; not used by this method
|
|
511
|
-
* @param url absolute URL of the record
|
|
512
|
-
* @param params query parameters
|
|
513
|
-
* @param headers extra headers, passed through {@link headers}
|
|
514
|
-
*/
|
|
515
|
-
delete<T extends DataModel, R>(collection: Collection<T>, url: string, { params, headers }?: IActionParams): Observable<R>;
|
|
255
|
+
delete<T extends DataModel, R>(collection: Collection<T>, url: string, { params, headers }?: IActionParams): Observable<R>;
|
|
516
256
|
/**
|
|
517
257
|
* Performs a GET, transparently replaying the server-rendered response from
|
|
518
258
|
* `TransferState` when that is still allowed.
|
|
@@ -559,7 +299,9 @@ declare class DataBackend {
|
|
|
559
299
|
* @param params query parameters, typically the queryset's filters and paging
|
|
560
300
|
* @param headers extra headers
|
|
561
301
|
*/
|
|
562
|
-
list<T extends DataModel>(collection: Collection<T>, url: string, { params, headers }?: IActionParams): Observable<
|
|
302
|
+
list<T extends DataModel>(collection: Collection<T>, url: string, { params, headers }?: IActionParams): Observable<{
|
|
303
|
+
results: Partial<T>[];
|
|
304
|
+
}>;
|
|
563
305
|
/**
|
|
564
306
|
* Resolves the headers actually sent with a request.
|
|
565
307
|
*
|
|
@@ -576,470 +318,168 @@ declare class DataBackend {
|
|
|
576
318
|
* @param headers per-request headers supplied by the caller
|
|
577
319
|
* @returns the complete header set to send
|
|
578
320
|
*/
|
|
579
|
-
protected headers(headers:
|
|
580
|
-
|
|
581
|
-
}): {
|
|
582
|
-
[key: string]: string;
|
|
583
|
-
};
|
|
584
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataBackend, [null, null, null, null, { optional: true; }]>;
|
|
321
|
+
protected headers(headers: Record<string, string>): Record<string, string>;
|
|
322
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataBackend, never>;
|
|
585
323
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<DataBackend>;
|
|
586
324
|
}
|
|
587
325
|
|
|
326
|
+
/** HTTP verbs this library issues. */
|
|
327
|
+
type IHttpMethod = 'POST' | 'GET' | 'DELETE' | 'PUT' | 'PATCH';
|
|
588
328
|
/**
|
|
589
|
-
*
|
|
590
|
-
*
|
|
329
|
+
* Per-request options shared by every {@link Collection} and {@link DataBackend}
|
|
330
|
+
* call: body, headers and query parameters.
|
|
591
331
|
*
|
|
592
|
-
*
|
|
593
|
-
* that filter, which is what lets a form bind a cleared control straight to a
|
|
594
|
-
* queryset filter.
|
|
332
|
+
* All members are optional, so `{}` is a valid "nothing special" argument.
|
|
595
333
|
*/
|
|
596
|
-
interface
|
|
597
|
-
|
|
334
|
+
interface IActionParams {
|
|
335
|
+
/** JSON body; ignored by GET/DELETE requests. */
|
|
336
|
+
body?: unknown;
|
|
337
|
+
/** Extra headers, merged on top of whatever the backend's `headers()` adds. */
|
|
338
|
+
headers?: Record<string, string>;
|
|
339
|
+
/** Query string parameters. */
|
|
340
|
+
params?: Record<string, string>;
|
|
341
|
+
/**
|
|
342
|
+
* Expected response type. Note that the backend does not currently read this:
|
|
343
|
+
* `DataBackend.action()` always parses JSON and `DataBackend.blob()` always
|
|
344
|
+
* requests a blob. Use `Collection.blob()` to get binary data.
|
|
345
|
+
*/
|
|
346
|
+
responseType?: 'json' | 'blob';
|
|
598
347
|
}
|
|
599
348
|
/**
|
|
600
|
-
*
|
|
601
|
-
*
|
|
349
|
+
* Shape for describing per-collection cache tuning.
|
|
350
|
+
*
|
|
351
|
+
* Currently unused by the runtime — TransferState behaviour is driven by
|
|
352
|
+
* `Collection.useTransferState` plus the `DATA_MAX_TRANSFERSTATE_TIME` token.
|
|
602
353
|
*/
|
|
603
|
-
interface
|
|
604
|
-
|
|
354
|
+
interface ICollectionCacheParams {
|
|
355
|
+
transferState?: {
|
|
356
|
+
enabled: boolean;
|
|
357
|
+
maxTime: number;
|
|
358
|
+
maxCount: number;
|
|
359
|
+
};
|
|
605
360
|
}
|
|
606
361
|
/**
|
|
607
|
-
*
|
|
608
|
-
*
|
|
362
|
+
* Constructor signature of a model class, letting a collection instantiate `T`
|
|
363
|
+
* without knowing it — this is the `model` argument passed to
|
|
364
|
+
* {@link Collection}'s constructor.
|
|
609
365
|
*/
|
|
610
|
-
type
|
|
366
|
+
type DataModelType<T extends DataModel> = new (_coll?: Collection<T>) => T;
|
|
611
367
|
/**
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
*/
|
|
615
|
-
interface IQuerysetOptions {
|
|
616
|
-
/**
|
|
617
|
-
* Whether the selected field list is sent to the API as a `fields` query
|
|
618
|
-
* parameter, letting the server return only those columns. Defaults to `true`;
|
|
619
|
-
* set it to `false` against an endpoint that does not understand `fields`.
|
|
620
|
-
*/
|
|
621
|
-
emitFields?: boolean;
|
|
622
|
-
/** Identifier for this queryset, used to tell several of them apart. */
|
|
623
|
-
name?: string;
|
|
624
|
-
/**
|
|
625
|
-
* Intended to let the queryset sync its state with the URL. Currently inert —
|
|
626
|
-
* nothing in the implementation reads it (the router code in `setPage` is
|
|
627
|
-
* commented out).
|
|
628
|
-
*/
|
|
629
|
-
route?: ActivatedRoute;
|
|
630
|
-
/**
|
|
631
|
-
* Intended to let the queryset push page changes into the URL. Currently inert
|
|
632
|
-
* — see the commented-out block in `setPage`.
|
|
633
|
-
*/
|
|
634
|
-
router?: Router;
|
|
635
|
-
/**
|
|
636
|
-
* Intended as the URL fragment identifying this queryset when several share a
|
|
637
|
-
* page. Currently inert.
|
|
638
|
-
*/
|
|
639
|
-
hash?: string;
|
|
640
|
-
}
|
|
641
|
-
/** Pagination request parameters: which page, and how many rows on it. */
|
|
642
|
-
interface IQueryNav {
|
|
643
|
-
page: number;
|
|
644
|
-
page_size: number;
|
|
645
|
-
}
|
|
646
|
-
/**
|
|
647
|
-
* Pagination state as reported by the API, and what a paginator component binds
|
|
648
|
-
* to: total row count, current page, total pages, and the neighbouring page
|
|
649
|
-
* numbers (`null` at either end).
|
|
650
|
-
*/
|
|
651
|
-
interface IQueryMetaNav {
|
|
652
|
-
/** Total number of rows matching the filters, across all pages. */
|
|
653
|
-
count: number;
|
|
654
|
-
/** Next page number, or `null` on the last page. */
|
|
655
|
-
next: number | null;
|
|
656
|
-
/** Current page number. */
|
|
657
|
-
page: number;
|
|
658
|
-
/** Total number of pages. */
|
|
659
|
-
pages: number;
|
|
660
|
-
/** Previous page number, or `null` on the first page. */
|
|
661
|
-
prev: number | null;
|
|
662
|
-
/** Rows per page. */
|
|
663
|
-
size: number;
|
|
664
|
-
}
|
|
665
|
-
/**
|
|
666
|
-
* Names the API uses for its pagination query parameters, echoed back so a client
|
|
667
|
-
* can build page links without hard-coding them.
|
|
668
|
-
*/
|
|
669
|
-
interface IQueryMetaNavParams {
|
|
670
|
-
page: string;
|
|
671
|
-
page_size: string;
|
|
672
|
-
}
|
|
673
|
-
/** Everything a list response says about itself apart from the rows. */
|
|
674
|
-
interface IQueryMeta {
|
|
675
|
-
nav: IQueryMetaNav;
|
|
676
|
-
parameters: IQueryMetaNavParams;
|
|
677
|
-
}
|
|
678
|
-
/**
|
|
679
|
-
* Full shape of a paginated list response: the rows under `results`, alongside
|
|
680
|
-
* the {@link IQueryMeta} envelope. This is the contract {@link Queryset} expects
|
|
681
|
-
* of every list endpoint it reads.
|
|
682
|
-
*/
|
|
683
|
-
interface IQueryFullResponse<T> extends IQueryMeta {
|
|
684
|
-
results: T[];
|
|
685
|
-
}
|
|
686
|
-
/**
|
|
687
|
-
* A filtered, sorted, paginated view over a {@link Collection}, exposing its
|
|
688
|
-
* results as observables ready to bind in a template.
|
|
368
|
+
* Binds a {@link DataModel} class to a REST endpoint and provides the CRUD
|
|
369
|
+
* operations over it.
|
|
689
370
|
*
|
|
690
|
-
*
|
|
691
|
-
*
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
* what re-runs the query.
|
|
371
|
+
* A collection is the seam between models and HTTP: it knows the path, builds
|
|
372
|
+
* URLs, hands raw JSON to the model for deserialization, and returns typed
|
|
373
|
+
* instances that carry a back-reference to it (so `thing.save()` works). One
|
|
374
|
+
* collection per endpoint, normally declared as a root-provided service.
|
|
695
375
|
*
|
|
696
|
-
*
|
|
697
|
-
*
|
|
698
|
-
*
|
|
699
|
-
*
|
|
376
|
+
* For anything involving filtering, sorting or pagination, go through
|
|
377
|
+
* {@link queryset} rather than {@link list}.
|
|
378
|
+
*
|
|
379
|
+
* The endpoint is assumed to follow Django REST Framework conventions:
|
|
380
|
+
* `/path` for the list, `/path/<id>` for a record, `/path/<id>/<action>` for
|
|
381
|
+
* custom actions, and a *paginated* list response (see {@link list}).
|
|
700
382
|
*
|
|
701
383
|
* @example
|
|
702
384
|
* ```ts
|
|
703
|
-
*
|
|
704
|
-
*
|
|
705
|
-
*
|
|
385
|
+
* @Injectable({ providedIn: 'root' })
|
|
386
|
+
* export class ThingService extends Collection<Thing> {
|
|
387
|
+
* constructor() {
|
|
388
|
+
* super(inject(DataBackend), '/path/to/things', Thing);
|
|
389
|
+
* }
|
|
390
|
+
* }
|
|
391
|
+
*
|
|
392
|
+
* // then
|
|
393
|
+
* things.fetch(1).subscribe((thing) => ...);
|
|
394
|
+
* things.queryset().filter({ status: 'active' }).get().subscribe((list) => ...);
|
|
706
395
|
* ```
|
|
707
396
|
*/
|
|
708
|
-
declare class
|
|
709
|
-
protected
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
/** Ordering terms currently staged, as last set by {@link sort}. */
|
|
713
|
-
sortData: SortData[];
|
|
714
|
-
/**
|
|
715
|
-
* Field names to request from the API, as last set by {@link setFields}. Only
|
|
716
|
-
* sent when `options.emitFields` is on and the list is non-empty.
|
|
717
|
-
*/
|
|
718
|
-
fields: string[];
|
|
719
|
-
/**
|
|
720
|
-
* Rows per page. Note the default is 500, not the API's own default: a queryset
|
|
721
|
-
* you never call {@link paginateBy} on asks for a large page rather than a
|
|
722
|
-
* small one.
|
|
723
|
-
*/
|
|
724
|
-
pageSize: number;
|
|
725
|
-
/** Page number to request, 1-based. */
|
|
726
|
-
page: number;
|
|
727
|
-
/** Options this queryset was built with, merged over the defaults. */
|
|
728
|
-
options: IQuerysetOptions;
|
|
729
|
-
private _loading;
|
|
730
|
-
/**
|
|
731
|
-
* Emits `true` when a fetch starts and `false` when its results have been
|
|
732
|
-
* processed — bind it to a spinner. Nothing is emitted before the first
|
|
733
|
-
* {@link get}, and note that a failed request leaves this at `true`.
|
|
734
|
-
*/
|
|
735
|
-
loading: Observable<boolean>;
|
|
736
|
-
private _meta;
|
|
737
|
-
/**
|
|
738
|
-
* Emits the pagination envelope of each response — row count, page, total
|
|
739
|
-
* pages. This is what a paginator component binds to, since {@link results}
|
|
740
|
-
* only carries the current page's rows.
|
|
741
|
-
*/
|
|
742
|
-
meta: Observable<IQueryMeta>;
|
|
743
|
-
private _results;
|
|
744
|
-
/**
|
|
745
|
-
* Emits the current page's rows as model instances on every successful fetch.
|
|
746
|
-
* The main output of a queryset. Being replayed, a late subscriber immediately
|
|
747
|
-
* receives the most recent page rather than waiting for the next `get()`.
|
|
748
|
-
*/
|
|
749
|
-
results: Observable<T[]>;
|
|
750
|
-
private _full;
|
|
397
|
+
declare class Collection<T extends DataModel> {
|
|
398
|
+
protected backend: DataBackend;
|
|
399
|
+
protected path: string;
|
|
400
|
+
model: DataModelType<T>;
|
|
751
401
|
/**
|
|
752
|
-
*
|
|
753
|
-
*
|
|
402
|
+
* Whether GET responses for this collection may be served from / stored in
|
|
403
|
+
* Angular's `TransferState` during SSR hydration.
|
|
754
404
|
*
|
|
755
|
-
*
|
|
756
|
-
*
|
|
757
|
-
*
|
|
758
|
-
* flips and results land.
|
|
405
|
+
* On by default, but only ever takes effect when `DATA_MAX_TRANSFERSTATE_TIME`
|
|
406
|
+
* is provided and greater than zero. Set it to `false` on collections whose
|
|
407
|
+
* data is user-specific or must not be embedded in the server-rendered HTML.
|
|
759
408
|
*/
|
|
760
|
-
|
|
409
|
+
useTransferState: boolean;
|
|
761
410
|
/**
|
|
762
|
-
* @param
|
|
763
|
-
* @param
|
|
411
|
+
* @param backend HTTP layer; supplies the API base URL and applies auth headers
|
|
412
|
+
* @param path endpoint path appended to the backend's `apiUrl`, leading slash
|
|
413
|
+
* included and trailing slash omitted (e.g. `'/path/to/things'`)
|
|
414
|
+
* @param model model class this collection instantiates
|
|
764
415
|
*/
|
|
765
|
-
constructor(
|
|
766
|
-
private _pristine;
|
|
416
|
+
constructor(backend: DataBackend, path: string, model: DataModelType<T>);
|
|
767
417
|
/**
|
|
768
|
-
*
|
|
418
|
+
* Builds a new, unsaved model instance attached to this collection.
|
|
769
419
|
*
|
|
770
|
-
*
|
|
771
|
-
*
|
|
772
|
-
*
|
|
773
|
-
* cached results.
|
|
774
|
-
*/
|
|
775
|
-
get pristine(): boolean;
|
|
776
|
-
/**
|
|
777
|
-
* Stages the filters for the next {@link get}. Chainable; issues no request.
|
|
420
|
+
* Use it to back a creation form: the returned instance has no `id`, so the
|
|
421
|
+
* first `save()` POSTs it. Values passed in `data` go through the field
|
|
422
|
+
* managers' deserializers, exactly as if they had come from the API.
|
|
778
423
|
*
|
|
779
|
-
* @param
|
|
780
|
-
* *removed* rather than sent, so a cleared form control can be passed
|
|
781
|
-
* straight through.
|
|
782
|
-
* @param update when `true`, merge into the existing filters; when `false` (the
|
|
783
|
-
* default), replace them wholesale
|
|
424
|
+
* @param data initial field values; omit for an empty instance
|
|
784
425
|
*
|
|
785
426
|
* @example
|
|
786
427
|
* ```ts
|
|
787
|
-
*
|
|
788
|
-
*
|
|
428
|
+
* const thing = things.create({ name: 'draft' });
|
|
429
|
+
* thing.save().subscribe(); // POST /path/to/things
|
|
789
430
|
* ```
|
|
790
431
|
*/
|
|
791
|
-
|
|
432
|
+
create(data?: Partial<T>): T;
|
|
792
433
|
/**
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
* Terms are sent joined into a single `ordering` query parameter, in the order
|
|
796
|
-
* given, so the first term is the primary sort key.
|
|
434
|
+
* Turns raw API JSON into model instances attached to this collection.
|
|
797
435
|
*
|
|
798
|
-
*
|
|
799
|
-
*
|
|
436
|
+
* Every read path funnels through here, and the attachment is the point: the
|
|
437
|
+
* resulting instances can `save()`/`update()`/`action()` themselves. Call it
|
|
438
|
+
* directly when you have JSON from somewhere other than this collection's own
|
|
439
|
+
* requests (a websocket push, an embedded payload, a fixture).
|
|
800
440
|
*
|
|
801
|
-
* @
|
|
802
|
-
* ```ts
|
|
803
|
-
* qs.sort('-created', 'name').get().subscribe();
|
|
804
|
-
* ```
|
|
441
|
+
* @param data one JSON object, or an array of them
|
|
805
442
|
*/
|
|
806
|
-
|
|
443
|
+
fromJson(data: Partial<T>): T;
|
|
444
|
+
fromJson(data: Partial<T>[]): T[];
|
|
807
445
|
/**
|
|
808
|
-
*
|
|
446
|
+
* Opens a filterable, sortable, paginated view over this collection.
|
|
809
447
|
*
|
|
810
|
-
*
|
|
811
|
-
*
|
|
448
|
+
* The normal way to read lists: a {@link Queryset} accumulates query state and
|
|
449
|
+
* exposes results/loading/meta as observables suitable for binding straight
|
|
450
|
+
* into a template. Each call returns an independent queryset, so a component
|
|
451
|
+
* showing two filtered lists of the same endpoint creates two.
|
|
812
452
|
*
|
|
813
|
-
* @param
|
|
814
|
-
* which is *not* the queryset's own default of 500
|
|
453
|
+
* @param options queryset behaviour; see {@link IQuerysetOptions}
|
|
815
454
|
*/
|
|
816
|
-
|
|
455
|
+
queryset(options?: IQuerysetOptions): Queryset<T>;
|
|
817
456
|
/**
|
|
818
|
-
*
|
|
819
|
-
* request, so a paginator must call {@link get} afterwards.
|
|
457
|
+
* Retrieves a single record by primary key and returns it as a model.
|
|
820
458
|
*
|
|
821
|
-
* @param
|
|
822
|
-
* @param
|
|
823
|
-
*
|
|
459
|
+
* @param id primary key
|
|
460
|
+
* @param prefix inserted between the collection path and the id, for endpoints
|
|
461
|
+
* nested under a segment
|
|
462
|
+
* @param suffix appended after the id, e.g. `'/detail'`
|
|
463
|
+
* @param params query parameters
|
|
464
|
+
* @param headers extra headers
|
|
465
|
+
*
|
|
466
|
+
* @example
|
|
467
|
+
* ```ts
|
|
468
|
+
* things.fetch(42).subscribe((thing) => ...); // GET /path/to/things/42
|
|
469
|
+
* ```
|
|
824
470
|
*/
|
|
825
|
-
|
|
471
|
+
fetch(id: number, { prefix, suffix, params, headers, }?: {
|
|
472
|
+
prefix?: string;
|
|
473
|
+
suffix?: string;
|
|
474
|
+
params?: Record<string, string>;
|
|
475
|
+
headers?: Record<string, string>;
|
|
476
|
+
}): Observable<T>;
|
|
826
477
|
/**
|
|
827
|
-
*
|
|
478
|
+
* Calls a custom (non-CRUD) endpoint on this collection, either on one record
|
|
479
|
+
* or on the collection as a whole, and returns the raw JSON response.
|
|
828
480
|
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
831
|
-
* `options.emitFields` is on — with it off, this is recorded but never
|
|
832
|
-
* transmitted.
|
|
833
|
-
*
|
|
834
|
-
* @param fields field names to request; an empty array means "no restriction"
|
|
835
|
-
*/
|
|
836
|
-
setFields(fields: string[]): Queryset<T>;
|
|
837
|
-
/**
|
|
838
|
-
* Flattens the staged filter/sort/page/fields state into the query parameters
|
|
839
|
-
* that will actually be sent.
|
|
840
|
-
*
|
|
841
|
-
* Exposed mainly for debugging and for building links that mirror the current
|
|
842
|
-
* view; {@link get} calls it itself. Ordering goes out as `ordering`, paging as
|
|
843
|
-
* `page`/`page_size`, and the field selection as `fields`.
|
|
844
|
-
*
|
|
845
|
-
* The `OutFilterData` return type is an assertion rather than a conversion —
|
|
846
|
-
* numeric values such as `page` are still numbers at runtime, and are
|
|
847
|
-
* stringified later by `HttpClient`.
|
|
848
|
-
*/
|
|
849
|
-
getQueryParams(): OutFilterData;
|
|
850
|
-
/**
|
|
851
|
-
* Runs the staged query and pushes the outcome through {@link results},
|
|
852
|
-
* {@link meta} and {@link loading}.
|
|
853
|
-
*
|
|
854
|
-
* The one method that talks to the network. Call it after each change to the
|
|
855
|
-
* filter/sort/page state; subscribers of `results` do not need to resubscribe,
|
|
856
|
-
* they simply receive the new page. The returned observable is `results`
|
|
857
|
-
* itself, so subscribing to the return value is a convenience, not a
|
|
858
|
-
* requirement — though something must subscribe for the request to be sent.
|
|
859
|
-
*
|
|
860
|
-
* @param refresh when `false`, an already-fetched queryset (see
|
|
861
|
-
* {@link pristine}) short-circuits and hands back the cached `results`
|
|
862
|
-
* without any request. Use it where a component may be re-entered and should
|
|
863
|
-
* reuse what is already loaded. A pristine queryset always fetches, whatever
|
|
864
|
-
* this says.
|
|
865
|
-
* @param sync adds `db=sync` to the query, asking the API to read from its
|
|
866
|
-
* primary rather than a replica — for the read-after-write case where
|
|
867
|
-
* replication lag would otherwise return stale rows
|
|
868
|
-
*
|
|
869
|
-
* @example
|
|
870
|
-
* ```ts
|
|
871
|
-
* qs.get().subscribe(); // always refetches
|
|
872
|
-
* qs.get(false).subscribe(); // reuses results if already loaded once
|
|
873
|
-
* ```
|
|
874
|
-
*/
|
|
875
|
-
get(refresh?: boolean, sync?: boolean): Observable<T[]>;
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
/** HTTP verbs this library issues. */
|
|
879
|
-
type IHttpMethod = 'POST' | 'GET' | 'DELETE' | 'PUT' | 'PATCH';
|
|
880
|
-
/**
|
|
881
|
-
* Per-request options shared by every {@link Collection} and {@link DataBackend}
|
|
882
|
-
* call: body, headers and query parameters.
|
|
883
|
-
*
|
|
884
|
-
* All members are optional, so `{}` is a valid "nothing special" argument.
|
|
885
|
-
*/
|
|
886
|
-
interface IActionParams {
|
|
887
|
-
/** JSON body; ignored by GET/DELETE requests. */
|
|
888
|
-
body?: any;
|
|
889
|
-
/** Extra headers, merged on top of whatever the backend's `headers()` adds. */
|
|
890
|
-
headers?: {
|
|
891
|
-
[index: string]: string;
|
|
892
|
-
};
|
|
893
|
-
/** Query string parameters. */
|
|
894
|
-
params?: {
|
|
895
|
-
[index: string]: string;
|
|
896
|
-
};
|
|
897
|
-
/**
|
|
898
|
-
* Expected response type. Note that the backend does not currently read this:
|
|
899
|
-
* `DataBackend.action()` always parses JSON and `DataBackend.blob()` always
|
|
900
|
-
* requests a blob. Use `Collection.blob()` to get binary data.
|
|
901
|
-
*/
|
|
902
|
-
responseType?: 'json' | 'blob';
|
|
903
|
-
}
|
|
904
|
-
/**
|
|
905
|
-
* Shape for describing per-collection cache tuning.
|
|
906
|
-
*
|
|
907
|
-
* Currently unused by the runtime — TransferState behaviour is driven by
|
|
908
|
-
* `Collection.useTransferState` plus the `DATA_MAX_TRANSFERSTATE_TIME` token.
|
|
909
|
-
*/
|
|
910
|
-
interface ICollectionCacheParams {
|
|
911
|
-
transferState?: {
|
|
912
|
-
enabled: boolean;
|
|
913
|
-
maxTime: number;
|
|
914
|
-
maxCount: number;
|
|
915
|
-
};
|
|
916
|
-
}
|
|
917
|
-
/**
|
|
918
|
-
* Constructor signature of a model class, letting a collection instantiate `T`
|
|
919
|
-
* without knowing it — this is the `model` argument passed to
|
|
920
|
-
* {@link Collection}'s constructor.
|
|
921
|
-
*/
|
|
922
|
-
type DataModelType<T extends DataModel> = new (_coll?: Collection<T>) => T;
|
|
923
|
-
/**
|
|
924
|
-
* Binds a {@link DataModel} class to a REST endpoint and provides the CRUD
|
|
925
|
-
* operations over it.
|
|
926
|
-
*
|
|
927
|
-
* A collection is the seam between models and HTTP: it knows the path, builds
|
|
928
|
-
* URLs, hands raw JSON to the model for deserialization, and returns typed
|
|
929
|
-
* instances that carry a back-reference to it (so `thing.save()` works). One
|
|
930
|
-
* collection per endpoint, normally declared as a root-provided service.
|
|
931
|
-
*
|
|
932
|
-
* For anything involving filtering, sorting or pagination, go through
|
|
933
|
-
* {@link queryset} rather than {@link list}.
|
|
934
|
-
*
|
|
935
|
-
* The endpoint is assumed to follow Django REST Framework conventions:
|
|
936
|
-
* `/path` for the list, `/path/<id>` for a record, `/path/<id>/<action>` for
|
|
937
|
-
* custom actions, and a *paginated* list response (see {@link list}).
|
|
938
|
-
*
|
|
939
|
-
* @example
|
|
940
|
-
* ```ts
|
|
941
|
-
* @Injectable({ providedIn: 'root' })
|
|
942
|
-
* export class ThingService extends Collection<Thing> {
|
|
943
|
-
* constructor() {
|
|
944
|
-
* super(inject(DataBackend), '/path/to/things', Thing);
|
|
945
|
-
* }
|
|
946
|
-
* }
|
|
947
|
-
*
|
|
948
|
-
* // then
|
|
949
|
-
* things.fetch(1).subscribe((thing) => ...);
|
|
950
|
-
* things.queryset().filter({ status: 'active' }).get().subscribe((list) => ...);
|
|
951
|
-
* ```
|
|
952
|
-
*/
|
|
953
|
-
declare class Collection<T extends DataModel> {
|
|
954
|
-
protected backend: DataBackend;
|
|
955
|
-
protected path: string;
|
|
956
|
-
model: DataModelType<T>;
|
|
957
|
-
/**
|
|
958
|
-
* Whether GET responses for this collection may be served from / stored in
|
|
959
|
-
* Angular's `TransferState` during SSR hydration.
|
|
960
|
-
*
|
|
961
|
-
* On by default, but only ever takes effect when `DATA_MAX_TRANSFERSTATE_TIME`
|
|
962
|
-
* is provided and greater than zero. Set it to `false` on collections whose
|
|
963
|
-
* data is user-specific or must not be embedded in the server-rendered HTML.
|
|
964
|
-
*/
|
|
965
|
-
useTransferState: boolean;
|
|
966
|
-
/**
|
|
967
|
-
* @param backend HTTP layer; supplies the API base URL and applies auth headers
|
|
968
|
-
* @param path endpoint path appended to the backend's `apiUrl`, leading slash
|
|
969
|
-
* included and trailing slash omitted (e.g. `'/path/to/things'`)
|
|
970
|
-
* @param model model class this collection instantiates
|
|
971
|
-
*/
|
|
972
|
-
constructor(backend: DataBackend, path: string, model: DataModelType<T>);
|
|
973
|
-
/**
|
|
974
|
-
* Builds a new, unsaved model instance attached to this collection.
|
|
975
|
-
*
|
|
976
|
-
* Use it to back a creation form: the returned instance has no `id`, so the
|
|
977
|
-
* first `save()` POSTs it. Values passed in `data` go through the field
|
|
978
|
-
* managers' deserializers, exactly as if they had come from the API.
|
|
979
|
-
*
|
|
980
|
-
* @param data initial field values; omit for an empty instance
|
|
981
|
-
*
|
|
982
|
-
* @example
|
|
983
|
-
* ```ts
|
|
984
|
-
* const thing = things.create({ name: 'draft' });
|
|
985
|
-
* thing.save().subscribe(); // POST /path/to/things
|
|
986
|
-
* ```
|
|
987
|
-
*/
|
|
988
|
-
create(data?: Partial<T>): T;
|
|
989
|
-
/**
|
|
990
|
-
* Turns raw API JSON into model instances attached to this collection.
|
|
991
|
-
*
|
|
992
|
-
* Every read path funnels through here, and the attachment is the point: the
|
|
993
|
-
* resulting instances can `save()`/`update()`/`action()` themselves. Call it
|
|
994
|
-
* directly when you have JSON from somewhere other than this collection's own
|
|
995
|
-
* requests (a websocket push, an embedded payload, a fixture).
|
|
996
|
-
*
|
|
997
|
-
* @param data one JSON object, or an array of them
|
|
998
|
-
*/
|
|
999
|
-
fromJson(data: Partial<T>): T;
|
|
1000
|
-
fromJson(data: Partial<T>[]): T[];
|
|
1001
|
-
/**
|
|
1002
|
-
* Opens a filterable, sortable, paginated view over this collection.
|
|
1003
|
-
*
|
|
1004
|
-
* The normal way to read lists: a {@link Queryset} accumulates query state and
|
|
1005
|
-
* exposes results/loading/meta as observables suitable for binding straight
|
|
1006
|
-
* into a template. Each call returns an independent queryset, so a component
|
|
1007
|
-
* showing two filtered lists of the same endpoint creates two.
|
|
1008
|
-
*
|
|
1009
|
-
* @param options queryset behaviour; see {@link IQuerysetOptions}
|
|
1010
|
-
*/
|
|
1011
|
-
queryset(options?: IQuerysetOptions): Queryset<T>;
|
|
1012
|
-
/**
|
|
1013
|
-
* Retrieves a single record by primary key and returns it as a model.
|
|
1014
|
-
*
|
|
1015
|
-
* @param id primary key
|
|
1016
|
-
* @param prefix inserted between the collection path and the id, for endpoints
|
|
1017
|
-
* nested under a segment
|
|
1018
|
-
* @param suffix appended after the id, e.g. `'/detail'`
|
|
1019
|
-
* @param params query parameters
|
|
1020
|
-
* @param headers extra headers
|
|
1021
|
-
*
|
|
1022
|
-
* @example
|
|
1023
|
-
* ```ts
|
|
1024
|
-
* things.fetch(42).subscribe((thing) => ...); // GET /path/to/things/42
|
|
1025
|
-
* ```
|
|
1026
|
-
*/
|
|
1027
|
-
fetch(id: number, { prefix, suffix, params, headers, }?: {
|
|
1028
|
-
prefix?: string;
|
|
1029
|
-
suffix?: string;
|
|
1030
|
-
params?: {
|
|
1031
|
-
[_index: string]: string;
|
|
1032
|
-
};
|
|
1033
|
-
headers?: {
|
|
1034
|
-
[_index: string]: string;
|
|
1035
|
-
};
|
|
1036
|
-
}): Observable<T>;
|
|
1037
|
-
/**
|
|
1038
|
-
* Calls a custom (non-CRUD) endpoint on this collection, either on one record
|
|
1039
|
-
* or on the collection as a whole, and returns the raw JSON response.
|
|
1040
|
-
*
|
|
1041
|
-
* This is the DRF `@action` convention. `DataModel.action()` delegates here;
|
|
1042
|
-
* call this directly for collection-level actions, which have no model.
|
|
481
|
+
* This is the DRF `@action` convention. `DataModel.action()` delegates here;
|
|
482
|
+
* call this directly for collection-level actions, which have no model.
|
|
1043
483
|
*
|
|
1044
484
|
* @param model record to act on, targeting `/path/to/things/<id>/<action>`, or
|
|
1045
485
|
* `null` for a collection-level action targeting `/path/to/things/<action>`
|
|
@@ -1085,116 +525,668 @@ declare class Collection<T extends DataModel> {
|
|
|
1085
525
|
* Deletes a record on the server. The local instance is left untouched — it is
|
|
1086
526
|
* the caller's job to drop it from whatever list holds it.
|
|
1087
527
|
*
|
|
1088
|
-
* @param model record to delete; its `id` builds the URL, so an unsaved model
|
|
1089
|
-
* would produce a request against the list URL
|
|
1090
|
-
* @param params query parameters
|
|
1091
|
-
* @param headers extra headers
|
|
528
|
+
* @param model record to delete; its `id` builds the URL, so an unsaved model
|
|
529
|
+
* would produce a request against the list URL
|
|
530
|
+
* @param params query parameters
|
|
531
|
+
* @param headers extra headers
|
|
532
|
+
*/
|
|
533
|
+
delete(model: T, { params, headers }?: IActionParams): Observable<unknown>;
|
|
534
|
+
/**
|
|
535
|
+
* Fetches a list of records in one shot, discarding pagination metadata.
|
|
536
|
+
*
|
|
537
|
+
* A shortcut for the simple cases (a dropdown's options, a small fixed set).
|
|
538
|
+
* When you need paging, sorting, loading state or the result count, use
|
|
539
|
+
* {@link queryset} instead.
|
|
540
|
+
*
|
|
541
|
+
* **The response must be paginated**: this reads `result.results` and returns
|
|
542
|
+
* that array, so a DRF endpoint with pagination disabled — which answers with a
|
|
543
|
+
* bare JSON array — yields an error rather than a list. The endpoint's page size
|
|
544
|
+
* therefore also caps what you get back here; there is currently no way to point
|
|
545
|
+
* this at a different response key (see the `FIXME` in the implementation).
|
|
546
|
+
*
|
|
547
|
+
* @param query filter parameters
|
|
548
|
+
* @param prefix inserted before the suffix in the list URL
|
|
549
|
+
* @param suffix appended to the list URL, for sub-endpoints
|
|
550
|
+
* @param params extra query parameters, merged over `query`
|
|
551
|
+
* @param headers extra headers
|
|
552
|
+
*/
|
|
553
|
+
list(query?: FilterData, { prefix, suffix, params, headers, }?: {
|
|
554
|
+
prefix?: string;
|
|
555
|
+
suffix?: string;
|
|
556
|
+
params?: Record<string, string>;
|
|
557
|
+
headers?: Record<string, string>;
|
|
558
|
+
}): Observable<T[]>;
|
|
559
|
+
/**
|
|
560
|
+
* Calls a collection-level endpoint and returns the response body **unparsed**,
|
|
561
|
+
* without turning it into models.
|
|
562
|
+
*
|
|
563
|
+
* The escape hatch for responses that are not a list of records: aggregates,
|
|
564
|
+
* stats, export summaries. It is also what {@link Queryset} uses internally,
|
|
565
|
+
* since a queryset needs the pagination envelope that {@link list} throws away.
|
|
566
|
+
*
|
|
567
|
+
* @param method HTTP method; defaults to GET
|
|
568
|
+
* @param prefix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
569
|
+
* @param suffix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
570
|
+
* @param params query parameters
|
|
571
|
+
* @param body accepted but **not currently sent** — the implementation does not
|
|
572
|
+
* forward it to the backend, so non-GET calls needing a body must go through
|
|
573
|
+
* {@link action}
|
|
574
|
+
* @param headers extra headers
|
|
575
|
+
*/
|
|
576
|
+
raw<RT>({ method, prefix, suffix, params, body: _body, headers, }?: {
|
|
577
|
+
method?: IHttpMethod;
|
|
578
|
+
prefix?: string;
|
|
579
|
+
suffix?: string;
|
|
580
|
+
body?: unknown;
|
|
581
|
+
params?: Record<string, string>;
|
|
582
|
+
headers?: Record<string, string>;
|
|
583
|
+
}): Observable<RT>;
|
|
584
|
+
/**
|
|
585
|
+
* Calls a collection-level endpoint and returns the response as a `Blob`.
|
|
586
|
+
*
|
|
587
|
+
* Use it for binary or file downloads (CSV/XLSX/PDF exports) where the response
|
|
588
|
+
* must not be parsed as JSON.
|
|
589
|
+
*
|
|
590
|
+
* @param method HTTP method; defaults to GET
|
|
591
|
+
* @param prefix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
592
|
+
* @param suffix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
593
|
+
* @param params query parameters
|
|
594
|
+
* @param body accepted but **not currently sent** — the implementation does not
|
|
595
|
+
* forward it to the backend
|
|
596
|
+
* @param headers extra headers
|
|
597
|
+
*/
|
|
598
|
+
blob<RT>({ method, prefix, suffix, params, body: _body, headers, }?: {
|
|
599
|
+
method?: IHttpMethod;
|
|
600
|
+
prefix?: string;
|
|
601
|
+
suffix?: string;
|
|
602
|
+
body?: unknown;
|
|
603
|
+
params?: Record<string, string>;
|
|
604
|
+
headers?: Record<string, string>;
|
|
605
|
+
}): Observable<Blob>;
|
|
606
|
+
/**
|
|
607
|
+
* Builds the absolute URL for this collection or one of its records.
|
|
608
|
+
*
|
|
609
|
+
* Every request the collection makes goes through here, so overriding it is the
|
|
610
|
+
* supported way to bend URL construction (versioned or nested endpoints).
|
|
611
|
+
*
|
|
612
|
+
* Layout is `apiUrl + path` for the list, `apiUrl + path + '/' + prefix + id +
|
|
613
|
+
* suffix` for a record, and `apiUrl + path + '/' + prefix + suffix` for the list
|
|
614
|
+
* with affixes. Note the separating slash is only emitted when there is
|
|
615
|
+
* something after it, so a plain list URL has no trailing slash.
|
|
616
|
+
*
|
|
617
|
+
* @param id primary key for a detail URL; `undefined` or `null` yields the list URL
|
|
618
|
+
* @param prefix inserted just before the id (or before the suffix)
|
|
619
|
+
* @param suffix appended at the very end
|
|
620
|
+
*/
|
|
621
|
+
getUrl(id?: number | null, { prefix, suffix }?: {
|
|
622
|
+
prefix?: string;
|
|
623
|
+
suffix?: string;
|
|
624
|
+
}): string;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Filter criteria as authored by the caller, keyed by the query parameter the API
|
|
629
|
+
* expects (`{ status: 'active', min_price: 10 }`).
|
|
630
|
+
*
|
|
631
|
+
* `undefined` and `null` are meaningful here: passing either for a key *removes*
|
|
632
|
+
* that filter, which is what lets a form bind a cleared control straight to a
|
|
633
|
+
* queryset filter.
|
|
634
|
+
*/
|
|
635
|
+
/**
|
|
636
|
+
* A value a filter can hold: whatever goes on the wire for that field. A scalar
|
|
637
|
+
* for most filters, an array for the multi-valued ones, `null` for "cleared".
|
|
638
|
+
*/
|
|
639
|
+
type FilterValue = string | number | boolean | null | undefined | (string | number)[];
|
|
640
|
+
type FilterData = Record<string, string | number | boolean | undefined | null>;
|
|
641
|
+
/**
|
|
642
|
+
* Filter criteria flattened to strings, as they go on the wire. This is what
|
|
643
|
+
* {@link Queryset.getQueryParams} produces.
|
|
644
|
+
*/
|
|
645
|
+
type OutFilterData = Record<string, string>;
|
|
646
|
+
/**
|
|
647
|
+
* A single ordering term: a field name, optionally prefixed with `-` to reverse
|
|
648
|
+
* it (`'name'`, `'-created'`) — the DRF `ordering` convention.
|
|
649
|
+
*/
|
|
650
|
+
type SortData = string;
|
|
651
|
+
/**
|
|
652
|
+
* Construction options for a {@link Queryset}, passed through
|
|
653
|
+
* `Collection.queryset()`.
|
|
654
|
+
*/
|
|
655
|
+
interface IQuerysetOptions {
|
|
656
|
+
/**
|
|
657
|
+
* Whether the selected field list is sent to the API as a `fields` query
|
|
658
|
+
* parameter, letting the server return only those columns. Defaults to `true`;
|
|
659
|
+
* set it to `false` against an endpoint that does not understand `fields`.
|
|
660
|
+
*/
|
|
661
|
+
emitFields?: boolean;
|
|
662
|
+
/** Identifier for this queryset, used to tell several of them apart. */
|
|
663
|
+
name?: string;
|
|
664
|
+
/**
|
|
665
|
+
* Intended to let the queryset sync its state with the URL. Currently inert —
|
|
666
|
+
* nothing in the implementation reads it (the router code in `setPage` is
|
|
667
|
+
* commented out).
|
|
668
|
+
*/
|
|
669
|
+
route?: ActivatedRoute;
|
|
670
|
+
/**
|
|
671
|
+
* Intended to let the queryset push page changes into the URL. Currently inert
|
|
672
|
+
* — see the commented-out block in `setPage`.
|
|
673
|
+
*/
|
|
674
|
+
router?: Router;
|
|
675
|
+
/**
|
|
676
|
+
* Intended as the URL fragment identifying this queryset when several share a
|
|
677
|
+
* page. Currently inert.
|
|
678
|
+
*/
|
|
679
|
+
hash?: string;
|
|
680
|
+
}
|
|
681
|
+
/** Pagination request parameters: which page, and how many rows on it. */
|
|
682
|
+
interface IQueryNav {
|
|
683
|
+
page: number;
|
|
684
|
+
page_size: number;
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Pagination state as reported by the API, and what a paginator component binds
|
|
688
|
+
* to: total row count, current page, total pages, and the neighbouring page
|
|
689
|
+
* numbers (`null` at either end).
|
|
690
|
+
*/
|
|
691
|
+
interface IQueryMetaNav {
|
|
692
|
+
/** Total number of rows matching the filters, across all pages. */
|
|
693
|
+
count: number;
|
|
694
|
+
/** Next page number, or `null` on the last page. */
|
|
695
|
+
next: number | null;
|
|
696
|
+
/** Current page number. */
|
|
697
|
+
page: number;
|
|
698
|
+
/** Total number of pages. */
|
|
699
|
+
pages: number;
|
|
700
|
+
/** Previous page number, or `null` on the first page. */
|
|
701
|
+
prev: number | null;
|
|
702
|
+
/** Rows per page. */
|
|
703
|
+
size: number;
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Names the API uses for its pagination query parameters, echoed back so a client
|
|
707
|
+
* can build page links without hard-coding them.
|
|
708
|
+
*/
|
|
709
|
+
interface IQueryMetaNavParams {
|
|
710
|
+
page: string;
|
|
711
|
+
page_size: string;
|
|
712
|
+
}
|
|
713
|
+
/** Everything a list response says about itself apart from the rows. */
|
|
714
|
+
interface IQueryMeta {
|
|
715
|
+
nav: IQueryMetaNav;
|
|
716
|
+
parameters: IQueryMetaNavParams;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Full shape of a paginated list response: the rows under `results`, alongside
|
|
720
|
+
* the {@link IQueryMeta} envelope. This is the contract {@link Queryset} expects
|
|
721
|
+
* of every list endpoint it reads.
|
|
722
|
+
*/
|
|
723
|
+
interface IQueryFullResponse<T> extends IQueryMeta {
|
|
724
|
+
results: T[];
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* A filtered, sorted, paginated view over a {@link Collection}, exposing its
|
|
728
|
+
* results as observables ready to bind in a template.
|
|
729
|
+
*
|
|
730
|
+
* Obtained from `Collection.queryset()`. The mutators ({@link filter},
|
|
731
|
+
* {@link sort}, {@link paginateBy}, {@link setPage}, {@link setFields}) are
|
|
732
|
+
* chainable and only accumulate state locally — **nothing is requested until
|
|
733
|
+
* {@link get} is called**, and calling `get()` again after changing filters is
|
|
734
|
+
* what re-runs the query.
|
|
735
|
+
*
|
|
736
|
+
* Consumers normally subscribe to {@link results} (or {@link full}) once and keep
|
|
737
|
+
* that subscription for the component's lifetime, then call `get()` on each
|
|
738
|
+
* change: the observables are `ReplaySubject`-backed, so every new emission flows
|
|
739
|
+
* to the existing subscribers and late subscribers immediately get the last value.
|
|
740
|
+
*
|
|
741
|
+
* @example
|
|
742
|
+
* ```ts
|
|
743
|
+
* const qs = things.queryset();
|
|
744
|
+
* qs.results.subscribe((things) => (this.things = things));
|
|
745
|
+
* qs.filter({ status: 'active' }).sort('-created').paginateBy(20).get().subscribe();
|
|
746
|
+
* ```
|
|
747
|
+
*/
|
|
748
|
+
declare class Queryset<T extends DataModel> {
|
|
749
|
+
protected _coll: Collection<T>;
|
|
750
|
+
/** Filters currently staged, as last set by {@link filter}. */
|
|
751
|
+
filterData: FilterData;
|
|
752
|
+
/** Ordering terms currently staged, as last set by {@link sort}. */
|
|
753
|
+
sortData: SortData[];
|
|
754
|
+
/**
|
|
755
|
+
* Field names to request from the API, as last set by {@link setFields}. Only
|
|
756
|
+
* sent when `options.emitFields` is on and the list is non-empty.
|
|
757
|
+
*/
|
|
758
|
+
fields: string[];
|
|
759
|
+
/**
|
|
760
|
+
* Rows per page. Note the default is 500, not the API's own default: a queryset
|
|
761
|
+
* you never call {@link paginateBy} on asks for a large page rather than a
|
|
762
|
+
* small one.
|
|
763
|
+
*/
|
|
764
|
+
pageSize: number;
|
|
765
|
+
/** Page number to request, 1-based. */
|
|
766
|
+
page: number;
|
|
767
|
+
/** Options this queryset was built with, merged over the defaults. */
|
|
768
|
+
options: IQuerysetOptions;
|
|
769
|
+
private _loading;
|
|
770
|
+
/**
|
|
771
|
+
* Emits `true` when a fetch starts and `false` when its results have been
|
|
772
|
+
* processed — bind it to a spinner. Nothing is emitted before the first
|
|
773
|
+
* {@link get}, and note that a failed request leaves this at `true`.
|
|
774
|
+
*/
|
|
775
|
+
loading: Observable<boolean>;
|
|
776
|
+
private _meta;
|
|
777
|
+
/**
|
|
778
|
+
* Emits the pagination envelope of each response — row count, page, total
|
|
779
|
+
* pages. This is what a paginator component binds to, since {@link results}
|
|
780
|
+
* only carries the current page's rows.
|
|
781
|
+
*/
|
|
782
|
+
meta: Observable<IQueryMeta>;
|
|
783
|
+
private _results;
|
|
784
|
+
/**
|
|
785
|
+
* Emits the current page's rows as model instances on every successful fetch.
|
|
786
|
+
* The main output of a queryset. Being replayed, a late subscriber immediately
|
|
787
|
+
* receives the most recent page rather than waiting for the next `get()`.
|
|
788
|
+
*/
|
|
789
|
+
results: Observable<T[]>;
|
|
790
|
+
private _full;
|
|
791
|
+
/**
|
|
792
|
+
* The three streams combined into `[results, loading, meta]`, for templates
|
|
793
|
+
* that would otherwise need three `async` pipes.
|
|
794
|
+
*
|
|
795
|
+
* Being a `combineLatest`, it emits nothing until all three have produced a
|
|
796
|
+
* value — i.e. not until the first fetch completes — and then emits once per
|
|
797
|
+
* change of any of them, so a single fetch produces several tuples as loading
|
|
798
|
+
* flips and results land.
|
|
799
|
+
*/
|
|
800
|
+
full: Observable<[T[], boolean, IQueryMeta]>;
|
|
801
|
+
/**
|
|
802
|
+
* @param _coll collection this queryset reads from
|
|
803
|
+
* @param options queryset options, merged over the defaults (`emitFields: true`)
|
|
804
|
+
*/
|
|
805
|
+
constructor(_coll: Collection<T>, options?: IQuerysetOptions);
|
|
806
|
+
private _pristine;
|
|
807
|
+
/**
|
|
808
|
+
* `true` until the first successful fetch, `false` forever after.
|
|
809
|
+
*
|
|
810
|
+
* Distinguishes "no results yet" from "no results found", which a bare empty
|
|
811
|
+
* array cannot: use it to choose between a loading placeholder and an empty
|
|
812
|
+
* state. It is also what makes `get(false)` decide whether it may serve the
|
|
813
|
+
* cached results.
|
|
814
|
+
*/
|
|
815
|
+
get pristine(): boolean;
|
|
816
|
+
/**
|
|
817
|
+
* Stages the filters for the next {@link get}. Chainable; issues no request.
|
|
818
|
+
*
|
|
819
|
+
* @param params filter criteria. A key whose value is `null` or `undefined` is
|
|
820
|
+
* *removed* rather than sent, so a cleared form control can be passed
|
|
821
|
+
* straight through.
|
|
822
|
+
* @param update when `true`, merge into the existing filters; when `false` (the
|
|
823
|
+
* default), replace them wholesale
|
|
824
|
+
*
|
|
825
|
+
* @example
|
|
826
|
+
* ```ts
|
|
827
|
+
* qs.filter({ status: 'active' }); // replaces all filters
|
|
828
|
+
* qs.filter({ q: search || null }, true); // merges; drops `q` when empty
|
|
829
|
+
* ```
|
|
830
|
+
*/
|
|
831
|
+
filter(params?: FilterData, update?: boolean): Queryset<T>;
|
|
832
|
+
/**
|
|
833
|
+
* Stages the ordering for the next {@link get}. Chainable; issues no request.
|
|
834
|
+
*
|
|
835
|
+
* Terms are sent joined into a single `ordering` query parameter, in the order
|
|
836
|
+
* given, so the first term is the primary sort key.
|
|
837
|
+
*
|
|
838
|
+
* @param sorting field names, `-` prefixed to reverse; replaces any previous
|
|
839
|
+
* ordering, and calling with no arguments clears it
|
|
840
|
+
*
|
|
841
|
+
* @example
|
|
842
|
+
* ```ts
|
|
843
|
+
* qs.sort('-created', 'name').get().subscribe();
|
|
844
|
+
* ```
|
|
845
|
+
*/
|
|
846
|
+
sort(...sorting: string[]): Queryset<T>;
|
|
847
|
+
/**
|
|
848
|
+
* Stages the page size for the next {@link get}. Chainable; issues no request.
|
|
849
|
+
*
|
|
850
|
+
* Does not reset {@link page}, so changing the size while on a high page number
|
|
851
|
+
* can land past the end of the result set — call `setPage(1)` alongside it.
|
|
852
|
+
*
|
|
853
|
+
* @param pageSize rows per page; defaults to 20 when called with no argument,
|
|
854
|
+
* which is *not* the queryset's own default of 500
|
|
855
|
+
*/
|
|
856
|
+
paginateBy(pageSize?: number): Queryset<T>;
|
|
857
|
+
/**
|
|
858
|
+
* Stages the page number for the next {@link get}. Chainable; issues no
|
|
859
|
+
* request, so a paginator must call {@link get} afterwards.
|
|
860
|
+
*
|
|
861
|
+
* @param page 1-based page number
|
|
862
|
+
* @param _fragment currently ignored; reserved for the URL-syncing behaviour
|
|
863
|
+
* that is commented out in the implementation
|
|
864
|
+
*/
|
|
865
|
+
setPage(page?: number, _fragment?: string): Queryset<T>;
|
|
866
|
+
/**
|
|
867
|
+
* Stages which fields the API should return. Chainable; issues no request.
|
|
868
|
+
*
|
|
869
|
+
* Lets a list view ask only for the columns it actually shows, which matters on
|
|
870
|
+
* wide models. Sent as a `fields` query parameter, and only when
|
|
871
|
+
* `options.emitFields` is on — with it off, this is recorded but never
|
|
872
|
+
* transmitted.
|
|
873
|
+
*
|
|
874
|
+
* @param fields field names to request; an empty array means "no restriction"
|
|
875
|
+
*/
|
|
876
|
+
setFields(fields: string[]): Queryset<T>;
|
|
877
|
+
/**
|
|
878
|
+
* Flattens the staged filter/sort/page/fields state into the query parameters
|
|
879
|
+
* that will actually be sent.
|
|
880
|
+
*
|
|
881
|
+
* Exposed mainly for debugging and for building links that mirror the current
|
|
882
|
+
* view; {@link get} calls it itself. Ordering goes out as `ordering`, paging as
|
|
883
|
+
* `page`/`page_size`, and the field selection as `fields`.
|
|
884
|
+
*
|
|
885
|
+
* The `OutFilterData` return type is an assertion rather than a conversion —
|
|
886
|
+
* numeric values such as `page` are still numbers at runtime, and are
|
|
887
|
+
* stringified later by `HttpClient`.
|
|
888
|
+
*/
|
|
889
|
+
getQueryParams(): OutFilterData;
|
|
890
|
+
/**
|
|
891
|
+
* Runs the staged query and pushes the outcome through {@link results},
|
|
892
|
+
* {@link meta} and {@link loading}.
|
|
893
|
+
*
|
|
894
|
+
* The one method that talks to the network. Call it after each change to the
|
|
895
|
+
* filter/sort/page state; subscribers of `results` do not need to resubscribe,
|
|
896
|
+
* they simply receive the new page. The returned observable is `results`
|
|
897
|
+
* itself, so subscribing to the return value is a convenience, not a
|
|
898
|
+
* requirement — though something must subscribe for the request to be sent.
|
|
899
|
+
*
|
|
900
|
+
* @param refresh when `false`, an already-fetched queryset (see
|
|
901
|
+
* {@link pristine}) short-circuits and hands back the cached `results`
|
|
902
|
+
* without any request. Use it where a component may be re-entered and should
|
|
903
|
+
* reuse what is already loaded. A pristine queryset always fetches, whatever
|
|
904
|
+
* this says.
|
|
905
|
+
* @param sync adds `db=sync` to the query, asking the API to read from its
|
|
906
|
+
* primary rather than a replica — for the read-after-write case where
|
|
907
|
+
* replication lag would otherwise return stale rows
|
|
908
|
+
*
|
|
909
|
+
* @example
|
|
910
|
+
* ```ts
|
|
911
|
+
* qs.get().subscribe(); // always refetches
|
|
912
|
+
* qs.get(false).subscribe(); // reuses results if already loaded once
|
|
913
|
+
* ```
|
|
914
|
+
*/
|
|
915
|
+
get(refresh?: boolean, sync?: boolean): Observable<T[]>;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
/**
|
|
919
|
+
* A single selectable option for a `select` editor or a `choice` display.
|
|
920
|
+
*
|
|
921
|
+
* `value` is what is written to the model field; `desc` is the human-readable
|
|
922
|
+
* label rendered in the dropdown or in display mode. Choices come either from
|
|
923
|
+
* the field manager (e.g. a `charField` declared with `choices`) or from the
|
|
924
|
+
* `[choices]` input of {@link DispeditComponent}, which overrides the manager.
|
|
925
|
+
*/
|
|
926
|
+
interface IDispEditChoice {
|
|
927
|
+
/** Human-readable label shown to the user. */
|
|
928
|
+
desc: string;
|
|
929
|
+
/** Raw value written to the model field when the option is picked. */
|
|
930
|
+
value: FilterValue;
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* Every editor widget {@link DispeditComponent} knows how to render.
|
|
934
|
+
*
|
|
935
|
+
* A field manager advertises one of these through its `editorType` property,
|
|
936
|
+
* which is how declaring the model is enough to get the right editor. The
|
|
937
|
+
* `[editor]` input of {@link DispeditComponent} overrides that choice.
|
|
938
|
+
*
|
|
939
|
+
* - `input.text` / `input.email` / `input.password`: matching `<input>` type,
|
|
940
|
+
* with min/max length and pattern validation feedback.
|
|
941
|
+
* - `input.number`: numeric `<input>`, value used as-is.
|
|
942
|
+
* - `input.decimal`: numeric `<input>` for a `decimalField`; the value is
|
|
943
|
+
* divided by the manager's `factor` on load and multiplied back on save.
|
|
944
|
+
* - `input.date` / `input.datetime`: native date / datetime-local `<input>`.
|
|
945
|
+
* - `input.checkbox`: a Oui/Non button group (not an actual checkbox).
|
|
946
|
+
* - `textarea`: multi-line `<textarea>`.
|
|
947
|
+
* - `select`: `<select>` built from the resolved choices. Automatically used
|
|
948
|
+
* whenever choices are available, whatever the manager advertises.
|
|
949
|
+
* - `fkselect`: `<data-fkselect>` typeahead, set by `ForeignKeyFieldManager`.
|
|
950
|
+
* - `m2mselect`: `<data-m2mselect>` multi-value typeahead, set by
|
|
951
|
+
* `ManyToManyFieldManager`.
|
|
952
|
+
*/
|
|
953
|
+
type DISPEDIT_EDITOR_TYPES = 'input.text' | 'input.email' | 'input.number' | 'input.decimal' | 'input.datetime' | 'input.date' | 'input.checkbox' | 'input.password' | 'textarea' | 'select' | 'fkselect' | 'm2mselect';
|
|
954
|
+
/**
|
|
955
|
+
* Every read-only renderer {@link DispeditComponent} knows how to produce.
|
|
956
|
+
*
|
|
957
|
+
* A field manager advertises one of these through its `displayType` property;
|
|
958
|
+
* the `[viewer]` input of {@link DispeditComponent} overrides it. Booleans and
|
|
959
|
+
* null values are short-circuited before the display type is consulted, and
|
|
960
|
+
* rendered as `OUI` / `NON` / `non défini`.
|
|
961
|
+
*
|
|
962
|
+
* - `text`: raw value interpolated as a string. The default.
|
|
963
|
+
* - `choice`: the `desc` of the matching {@link IDispEditChoice}. Automatically
|
|
964
|
+
* used whenever choices are available.
|
|
965
|
+
* - `boolean`: `OUI` / `NON`.
|
|
966
|
+
* - `decimal`: the value divided by the `decimalField` manager's `factor`.
|
|
967
|
+
* - `fkdetails`: the `_display` of the `<field>_details` sibling property.
|
|
968
|
+
* - `m2mdetails`: one line per item, each rendered via its `_display`.
|
|
969
|
+
* - `datetime` / `date`: value passed through Angular's `date` pipe (`short`
|
|
970
|
+
* and `shortDate` respectively).
|
|
971
|
+
* - `html`: the value injected as trusted HTML. For rich text and markdown
|
|
972
|
+
* fields, whose rendered form is stored alongside the source — point the
|
|
973
|
+
* dispedit at that `…_html` field and set `[viewer]="'html'"`. **The value is
|
|
974
|
+
* not sanitized**; the value goes through `SafeHtmlPipe`.
|
|
975
|
+
*/
|
|
976
|
+
type DISPEDIT_DISPLAY_TYPES = 'text' | 'choice' | 'boolean' | 'decimal' | 'fkdetails' | 'm2mdetails' | 'datetime' | 'date' | 'html';
|
|
977
|
+
|
|
978
|
+
/**
|
|
979
|
+
* Options common to every field decorator. All are optional; each concrete
|
|
980
|
+
* field type extends this with its own (`ICharFieldMetadata`, etc.).
|
|
981
|
+
*
|
|
982
|
+
* Whatever you pass to a decorator is copied verbatim onto the field's manager
|
|
983
|
+
* instance, so these names double as the manager's public properties.
|
|
984
|
+
*
|
|
985
|
+
* @typeParam FT the JavaScript type the field holds on the model
|
|
986
|
+
*/
|
|
987
|
+
interface IFieldMetadata<FT> {
|
|
988
|
+
/**
|
|
989
|
+
* Wire name of the field: the key used in the JSON payload. Defaults to the
|
|
990
|
+
* decorated property name, so it only needs setting when the API name and
|
|
991
|
+
* the TypeScript property name differ.
|
|
992
|
+
*/
|
|
993
|
+
name?: string;
|
|
994
|
+
/** Short hint shown next to the editor. Defaults to an empty string. */
|
|
995
|
+
help?: string;
|
|
996
|
+
/**
|
|
997
|
+
* Human-readable label used for column titles, form labels and hover
|
|
998
|
+
* details. Defaults to {@link IFieldMetadata.name} when omitted.
|
|
999
|
+
*/
|
|
1000
|
+
description?: string;
|
|
1001
|
+
/**
|
|
1002
|
+
* Marks the field as mandatory: adds `Validators.required` and forces a
|
|
1003
|
+
* value to be present on save.
|
|
1004
|
+
*
|
|
1005
|
+
* Beware: combining `required: true` with no `defaultValue` throws at class
|
|
1006
|
+
* definition time — see {@link BaseFieldManager.getDefaultValue}.
|
|
1007
|
+
*/
|
|
1008
|
+
required?: boolean;
|
|
1009
|
+
/**
|
|
1010
|
+
* Field is display-only: it is excluded from generated form groups and never
|
|
1011
|
+
* pushed back to the API. Typical for server-maintained columns and for the
|
|
1012
|
+
* `*_details` half of a relation.
|
|
1013
|
+
*/
|
|
1014
|
+
readonly?: boolean;
|
|
1015
|
+
/**
|
|
1016
|
+
* Value used when the model has no value for this field — either a constant
|
|
1017
|
+
* or a factory `(args) => FT` evaluated on each call, which is how you get a
|
|
1018
|
+
* fresh array/date per instance instead of a shared one.
|
|
1019
|
+
*/
|
|
1020
|
+
defaultValue?: FT | ((args: FieldDefaultArgs) => FT) | null;
|
|
1021
|
+
/**
|
|
1022
|
+
* Display ordering weight: **higher is shown first**. `id` uses `1000`.
|
|
1023
|
+
*
|
|
1024
|
+
* `priority: -1` is the established idiom for "deserialise this field but
|
|
1025
|
+
* never offer it in the UI" — negative-priority fields are dropped from the
|
|
1026
|
+
* default column set. It is used for the id half of every relation, whose
|
|
1027
|
+
* `*_details` twin is what a human is meant to see.
|
|
1028
|
+
*/
|
|
1029
|
+
priority?: number;
|
|
1030
|
+
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Runtime behaviour of a single field: one manager instance is built per
|
|
1033
|
+
* decorated property, at class definition time, and cached in the prototype's
|
|
1034
|
+
* metadata map. Everything the library does with a field — serialise it,
|
|
1035
|
+
* validate it, build its form control, pick its widget — goes through here.
|
|
1036
|
+
*
|
|
1037
|
+
* Subclass it only to add a genuinely new field type; the shipped managers
|
|
1038
|
+
* (`CharFieldManager`, `ForeignKeyFieldManager`, ...) cover the usual cases.
|
|
1039
|
+
* Override `fromJson`/`toJson` to change the wire mapping and
|
|
1040
|
+
* `getValidators()` to add constraints.
|
|
1041
|
+
*/
|
|
1042
|
+
declare class BaseFieldManager<FT> implements IFieldMetadata<FT> {
|
|
1043
|
+
/** Name is mandatory in a field manager. It is given by
|
|
1044
|
+
* field decorator if not directly given in field manager. */
|
|
1045
|
+
name: string;
|
|
1046
|
+
/** Human-readable label; falls back to {@link name} when not given. */
|
|
1047
|
+
description: string;
|
|
1048
|
+
/** Input hint; normalised to `''` when not given. */
|
|
1049
|
+
help: string;
|
|
1050
|
+
/** Whether a value must be present. Adds `Validators.required`. */
|
|
1051
|
+
required: boolean;
|
|
1052
|
+
/** Whether the field is excluded from forms and never written back. */
|
|
1053
|
+
readonly: boolean;
|
|
1054
|
+
/**
|
|
1055
|
+
* Set to `true` only by `ComputedFieldManager`. `DataModel.setFV` skips
|
|
1056
|
+
* assignment entirely for computed fields, making them permanently
|
|
1057
|
+
* read-only in the eyes of the model.
|
|
1058
|
+
*/
|
|
1059
|
+
computed: boolean;
|
|
1060
|
+
/** Display ordering weight; higher is shown first. See {@link IFieldMetadata.priority}. */
|
|
1061
|
+
priority: number;
|
|
1062
|
+
/** Constant or factory used when the model has no value. */
|
|
1063
|
+
defaultValue?: FT | ((args: FieldDefaultArgs) => FT);
|
|
1064
|
+
/**
|
|
1065
|
+
* Which editor widget `dispedit` renders for this field in edit mode.
|
|
1066
|
+
*
|
|
1067
|
+
* This is the library's central idea: **declaring the model configures the
|
|
1068
|
+
* UI**. Managers set this themselves from what you declared — `charField`
|
|
1069
|
+
* flips to `'select'` as soon as `choices` is present, `foreignKeyField`
|
|
1070
|
+
* uses `'fkselect'`, `manyToManyField` `'m2mselect'` — so a correct model
|
|
1071
|
+
* yields the right editor with no per-template wiring.
|
|
1072
|
+
*/
|
|
1073
|
+
editorType: DISPEDIT_EDITOR_TYPES;
|
|
1074
|
+
/**
|
|
1075
|
+
* Which read-only renderer `dispedit` uses for this field. Chosen by the
|
|
1076
|
+
* manager the same way as {@link editorType} (`'fkdetails'` for a foreign
|
|
1077
|
+
* key, `'m2mdetails'` for a m2m, `'decimal'` for `decimalField`, ...).
|
|
1078
|
+
*/
|
|
1079
|
+
displayType: DISPEDIT_DISPLAY_TYPES;
|
|
1080
|
+
/**
|
|
1081
|
+
* Copies `params` onto the instance, fills in `name`/`description`/`help`
|
|
1082
|
+
* defaults, then eagerly resolves the default value — which means a
|
|
1083
|
+
* `required` field with no `defaultValue` throws here, at decoration time.
|
|
1084
|
+
*
|
|
1085
|
+
* @param params metadata as passed to the decorator
|
|
1086
|
+
*/
|
|
1087
|
+
constructor(params: IFieldMetadata<FT>);
|
|
1088
|
+
/**
|
|
1089
|
+
* Angular validators for this field, rebuilt on each access. Subclasses
|
|
1090
|
+
* override this getter (not {@link getValidators}) to append their own —
|
|
1091
|
+
* `CharFieldManager` adds length/pattern, `IntegerFieldManager` min/max.
|
|
1092
|
+
*/
|
|
1093
|
+
get validators(): ValidatorFn[];
|
|
1094
|
+
/**
|
|
1095
|
+
* The bare property name, stripped of any `Model__` prefix: splits
|
|
1096
|
+
* {@link name} on `'__'` and returns the second segment, or the whole name
|
|
1097
|
+
* when there is no separator.
|
|
1098
|
+
*/
|
|
1099
|
+
get fname(): string;
|
|
1100
|
+
/**
|
|
1101
|
+
* Builds a typed `FormControl` for this field on a given model instance,
|
|
1102
|
+
* seeded with the instance's current value and falling back to the default
|
|
1103
|
+
* value, and wired with {@link validators}.
|
|
1104
|
+
*
|
|
1105
|
+
* Note the seed uses `||`, so falsy current values (`0`, `''`, `false`) fall
|
|
1106
|
+
* back to the default rather than being kept.
|
|
1107
|
+
*
|
|
1108
|
+
* @param instance model whose value seeds the control
|
|
1092
1109
|
*/
|
|
1093
|
-
|
|
1110
|
+
formControl(instance: DataModel): FormControl<FT | null>;
|
|
1094
1111
|
/**
|
|
1095
|
-
*
|
|
1096
|
-
*
|
|
1097
|
-
*
|
|
1098
|
-
*
|
|
1099
|
-
* {@link queryset} instead.
|
|
1100
|
-
*
|
|
1101
|
-
* **The response must be paginated**: this reads `result.results` and returns
|
|
1102
|
-
* that array, so a DRF endpoint with pagination disabled — which answers with a
|
|
1103
|
-
* bare JSON array — yields an error rather than a list. The endpoint's page size
|
|
1104
|
-
* therefore also caps what you get back here; there is currently no way to point
|
|
1105
|
-
* this at a different response key (see the `FIXME` in the implementation).
|
|
1112
|
+
* Converts a raw JSON value coming from the API into the model value.
|
|
1113
|
+
* The base implementation passes the data straight through; typed managers
|
|
1114
|
+
* override it to coerce (`boolean`), parse (`date`) or instantiate
|
|
1115
|
+
* (`details`).
|
|
1106
1116
|
*
|
|
1107
|
-
* @param
|
|
1108
|
-
* @param prefix inserted before the suffix in the list URL
|
|
1109
|
-
* @param suffix appended to the list URL, for sub-endpoints
|
|
1110
|
-
* @param params extra query parameters, merged over `query`
|
|
1111
|
-
* @param headers extra headers
|
|
1117
|
+
* @param data raw value read from the JSON payload
|
|
1112
1118
|
*/
|
|
1113
|
-
|
|
1114
|
-
prefix?: string;
|
|
1115
|
-
suffix?: string;
|
|
1116
|
-
params?: {
|
|
1117
|
-
[_index: string]: string;
|
|
1118
|
-
};
|
|
1119
|
-
headers?: {
|
|
1120
|
-
[_index: string]: string;
|
|
1121
|
-
};
|
|
1122
|
-
}): Observable<T[]>;
|
|
1119
|
+
fromJson(data: unknown): FT;
|
|
1123
1120
|
/**
|
|
1124
|
-
*
|
|
1125
|
-
*
|
|
1126
|
-
*
|
|
1127
|
-
* The escape hatch for responses that are not a list of records: aggregates,
|
|
1128
|
-
* stats, export summaries. It is also what {@link Queryset} uses internally,
|
|
1129
|
-
* since a queryset needs the pagination envelope that {@link list} throws away.
|
|
1121
|
+
* Converts the model value back into its JSON representation for save.
|
|
1122
|
+
* The base implementation passes the data straight through.
|
|
1130
1123
|
*
|
|
1131
|
-
* @param
|
|
1132
|
-
* @param prefix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
1133
|
-
* @param suffix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
1134
|
-
* @param params query parameters
|
|
1135
|
-
* @param body accepted but **not currently sent** — the implementation does not
|
|
1136
|
-
* forward it to the backend, so non-GET calls needing a body must go through
|
|
1137
|
-
* {@link action}
|
|
1138
|
-
* @param headers extra headers
|
|
1124
|
+
* @param data current model value
|
|
1139
1125
|
*/
|
|
1140
|
-
|
|
1141
|
-
method?: IHttpMethod;
|
|
1142
|
-
prefix?: string;
|
|
1143
|
-
suffix?: string;
|
|
1144
|
-
body?: any;
|
|
1145
|
-
params?: {
|
|
1146
|
-
[_index: string]: string;
|
|
1147
|
-
};
|
|
1148
|
-
headers?: {
|
|
1149
|
-
[_index: string]: string;
|
|
1150
|
-
};
|
|
1151
|
-
}): Observable<RT>;
|
|
1126
|
+
toJson(data: FT): unknown;
|
|
1152
1127
|
/**
|
|
1153
|
-
*
|
|
1128
|
+
* Renders the value for display. The base implementation is plain string
|
|
1129
|
+
* interpolation.
|
|
1154
1130
|
*
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1131
|
+
* @param data value to render
|
|
1132
|
+
* @param _format reserved; ignored by the base implementation
|
|
1133
|
+
*/
|
|
1134
|
+
toString(data: FT, _format?: string): string;
|
|
1135
|
+
/**
|
|
1136
|
+
* Public accessor for this field's default value, invoking the
|
|
1137
|
+
* `defaultValue` factory with `args` when one was declared.
|
|
1157
1138
|
*
|
|
1158
|
-
* @param
|
|
1159
|
-
* @param prefix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
1160
|
-
* @param suffix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
1161
|
-
* @param params query parameters
|
|
1162
|
-
* @param body accepted but **not currently sent** — the implementation does not
|
|
1163
|
-
* forward it to the backend
|
|
1164
|
-
* @param headers extra headers
|
|
1139
|
+
* @param args passed through to a `defaultValue` function
|
|
1165
1140
|
*/
|
|
1166
|
-
|
|
1167
|
-
method?: IHttpMethod;
|
|
1168
|
-
prefix?: string;
|
|
1169
|
-
suffix?: string;
|
|
1170
|
-
body?: any;
|
|
1171
|
-
params?: {
|
|
1172
|
-
[_index: string]: string;
|
|
1173
|
-
};
|
|
1174
|
-
headers?: {
|
|
1175
|
-
[_index: string]: string;
|
|
1176
|
-
};
|
|
1177
|
-
}): Observable<Blob>;
|
|
1141
|
+
default(args?: FieldDefaultArgs): FT | undefined;
|
|
1178
1142
|
/**
|
|
1179
|
-
* Builds the
|
|
1143
|
+
* Builds the base validator list: `Validators.required` when the field is
|
|
1144
|
+
* required, nothing otherwise. Subclasses call it and push their own.
|
|
1180
1145
|
*
|
|
1181
|
-
*
|
|
1182
|
-
|
|
1146
|
+
* @protected
|
|
1147
|
+
*/
|
|
1148
|
+
protected getValidators(): ValidatorFn[];
|
|
1149
|
+
/**
|
|
1150
|
+
* Resolves the default value: calls `defaultValue` when it is a function,
|
|
1151
|
+
* otherwise returns it as-is.
|
|
1183
1152
|
*
|
|
1184
|
-
*
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1187
|
-
*
|
|
1153
|
+
* **Throws** when the field is `required` and no `defaultValue` was given.
|
|
1154
|
+
* Because the constructor calls this, the error surfaces when the class is
|
|
1155
|
+
* defined (module evaluation), not when a model is instantiated — a
|
|
1156
|
+
* `required` field without a default breaks the app at import time.
|
|
1188
1157
|
*
|
|
1189
|
-
* @param
|
|
1190
|
-
* @
|
|
1191
|
-
* @
|
|
1158
|
+
* @param args passed through to a `defaultValue` function
|
|
1159
|
+
* @throws Error if `required` is set and `defaultValue` is `undefined`
|
|
1160
|
+
* @protected
|
|
1192
1161
|
*/
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1162
|
+
protected getDefaultValue(args?: FieldDefaultArgs): FT | undefined;
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* What is actually kept in a model's metadata map: the options you passed to
|
|
1166
|
+
* the decorator, plus the four entries the decorator computes. This is the
|
|
1167
|
+
* shape returned by {@link getFieldsMetadata}.
|
|
1168
|
+
*/
|
|
1169
|
+
interface IFieldStoredMetadata<FT> extends IFieldMetadata<FT> {
|
|
1170
|
+
/** Map key of this entry: `` `${__name}__${propertyKey}` ``. */
|
|
1171
|
+
self: string;
|
|
1172
|
+
/** Wire name; defaulted to the decorated property name. */
|
|
1173
|
+
name: string;
|
|
1174
|
+
/** Field type code, e.g. `'charField'`, `'foreignKeyField'`. */
|
|
1175
|
+
type: string;
|
|
1176
|
+
/** The live manager instance built for this field. */
|
|
1177
|
+
manager: BaseFieldManager<FT>;
|
|
1197
1178
|
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Arguments handed to a `defaultValue` factory. Free-form: callers pass
|
|
1181
|
+
* whatever the factory needs, and the factory knows what to expect.
|
|
1182
|
+
*/
|
|
1183
|
+
type FieldDefaultArgs = Record<string, unknown>;
|
|
1184
|
+
/**
|
|
1185
|
+
* Shape of every field decorator returned by {@link genericDataField}: a plain
|
|
1186
|
+
* property decorator, applied for its side effect on the prototype's metadata
|
|
1187
|
+
* map.
|
|
1188
|
+
*/
|
|
1189
|
+
type FieldDecoratorFn = (target: object, propertyKey: string | symbol) => void;
|
|
1198
1190
|
|
|
1199
1191
|
/**
|
|
1200
1192
|
* Resolved field metadata of a model instance, keyed by field name.
|
|
@@ -1204,7 +1196,7 @@ declare class Collection<T extends DataModel> {
|
|
|
1204
1196
|
* filters, `dispedit`) read this map to render themselves without knowing the
|
|
1205
1197
|
* concrete model.
|
|
1206
1198
|
*/
|
|
1207
|
-
type DataModelFields = Readonly<Map<string, IFieldStoredMetadata<
|
|
1199
|
+
type DataModelFields = Readonly<Map<string, IFieldStoredMetadata<unknown>>>;
|
|
1208
1200
|
/**
|
|
1209
1201
|
* Base class for every model in the library: a plain class whose fields are
|
|
1210
1202
|
* declared with field decorators, which turns it into something the rest of the
|
|
@@ -1335,9 +1327,7 @@ declare class DataModel {
|
|
|
1335
1327
|
* offending field names to their `ValidationErrors`. Note that valid fields
|
|
1336
1328
|
* are still applied even when others fail — this reports, it does not roll back.
|
|
1337
1329
|
*/
|
|
1338
|
-
fromJson(data: {
|
|
1339
|
-
[index: string]: any;
|
|
1340
|
-
}, { partial, check }?: {
|
|
1330
|
+
fromJson(data: object, { partial, check }?: {
|
|
1341
1331
|
partial?: boolean;
|
|
1342
1332
|
check?: boolean;
|
|
1343
1333
|
}): null | ValidationErrors;
|
|
@@ -1378,21 +1368,13 @@ declare class DataModel {
|
|
|
1378
1368
|
* @returns an observable of the **raw response body**, not of this model, even
|
|
1379
1369
|
* when `update` is `true`
|
|
1380
1370
|
*/
|
|
1381
|
-
action<T, RT extends {
|
|
1382
|
-
|
|
1383
|
-
}>(method: 'POST' | 'PATCH' | 'GET' | 'DELETE' | 'PUT', name: string, { body, update, updatePartial, updateCheck, params, headers, }?: {
|
|
1384
|
-
body?: {
|
|
1385
|
-
[_index: string]: any;
|
|
1386
|
-
};
|
|
1371
|
+
action<T, RT extends object>(method: 'POST' | 'PATCH' | 'GET' | 'DELETE' | 'PUT', name: string, { body, update, updatePartial, updateCheck, params, headers, }?: {
|
|
1372
|
+
body?: object;
|
|
1387
1373
|
update?: boolean;
|
|
1388
1374
|
updatePartial?: boolean;
|
|
1389
1375
|
updateCheck?: boolean;
|
|
1390
|
-
params?:
|
|
1391
|
-
|
|
1392
|
-
};
|
|
1393
|
-
headers?: {
|
|
1394
|
-
[_index: string]: string;
|
|
1395
|
-
};
|
|
1376
|
+
params?: Record<string, string>;
|
|
1377
|
+
headers?: Record<string, string>;
|
|
1396
1378
|
}): Observable<RT>;
|
|
1397
1379
|
/**
|
|
1398
1380
|
* Returns a field's manager — the object holding its metadata and its
|
|
@@ -1503,6 +1485,36 @@ declare class DataModel {
|
|
|
1503
1485
|
}): Observable<this>;
|
|
1504
1486
|
}
|
|
1505
1487
|
|
|
1488
|
+
/**
|
|
1489
|
+
* A model seen as the untyped property bag it also is.
|
|
1490
|
+
*
|
|
1491
|
+
* Fields are declared by decorators and reached by name at runtime — `dispedit`
|
|
1492
|
+
* reads `<field>_details`, filters read `filter.field` — so the data layer
|
|
1493
|
+
* constantly indexes models with a string the compiler cannot resolve. This is
|
|
1494
|
+
* the one sanctioned way to do it: it yields `unknown`, so the value has to be
|
|
1495
|
+
* narrowed where it is used instead of silently becoming `any` and disabling
|
|
1496
|
+
* type-checking for the rest of the expression.
|
|
1497
|
+
*
|
|
1498
|
+
* ```ts
|
|
1499
|
+
* const details = fieldValues(model)[`${field}_details`] as R[] | undefined;
|
|
1500
|
+
* fieldValues(model)[field] = event.id;
|
|
1501
|
+
* ```
|
|
1502
|
+
*
|
|
1503
|
+
* @param target model (or any object) to index by field name
|
|
1504
|
+
*/
|
|
1505
|
+
declare function fieldValues(target: object): Record<string, unknown>;
|
|
1506
|
+
/**
|
|
1507
|
+
* Renders an unknown value as display text.
|
|
1508
|
+
*
|
|
1509
|
+
* `String(value)` is not enough here: values read through {@link fieldValues}
|
|
1510
|
+
* can be objects, and `String({})` yields `[object Object]`. Nullish becomes an
|
|
1511
|
+
* empty string, objects are JSON-encoded, everything else goes through
|
|
1512
|
+
* `String`.
|
|
1513
|
+
*
|
|
1514
|
+
* @param value value read off a model, a form or a payload
|
|
1515
|
+
*/
|
|
1516
|
+
declare function asText(value: unknown): string;
|
|
1517
|
+
|
|
1506
1518
|
/**
|
|
1507
1519
|
* One column of a list: a model field (or a {@link CustomField}) together with
|
|
1508
1520
|
* its display state.
|
|
@@ -1517,7 +1529,7 @@ interface ModelListField {
|
|
|
1517
1529
|
/** The user may enable it from the field selector. */
|
|
1518
1530
|
allowed: boolean;
|
|
1519
1531
|
/** The field's current value/manager, `null` for custom columns. */
|
|
1520
|
-
field:
|
|
1532
|
+
field: unknown;
|
|
1521
1533
|
/** Sort key for display order, renumbered in steps of 10 on every change. */
|
|
1522
1534
|
position: number;
|
|
1523
1535
|
/** Ordering weight from the field metadata, higher first; `-1` means "never shown by default". */
|
|
@@ -1620,7 +1632,7 @@ declare class ModelListFields<T extends DataModel> {
|
|
|
1620
1632
|
* @param position new sort key
|
|
1621
1633
|
* @returns current enabled fields
|
|
1622
1634
|
*/
|
|
1623
|
-
setPosition(fname:
|
|
1635
|
+
setPosition(fname: string, position: number): string[];
|
|
1624
1636
|
private _update;
|
|
1625
1637
|
}
|
|
1626
1638
|
|
|
@@ -1857,19 +1869,19 @@ interface ModelListFilterParams {
|
|
|
1857
1869
|
* Not read by the constructor. {@link ModelListFilter} initialises its value
|
|
1858
1870
|
* from {@link default} instead; see the `FIXME` in the constructor body.
|
|
1859
1871
|
*/
|
|
1860
|
-
value?:
|
|
1872
|
+
value?: FilterValue;
|
|
1861
1873
|
/**
|
|
1862
1874
|
* Free-form description used as the `title` (native tooltip) of this filter's
|
|
1863
1875
|
* entry in the `data-model-list-filters-select` picker. It has no effect on
|
|
1864
1876
|
* the query.
|
|
1865
1877
|
*/
|
|
1866
|
-
desc?:
|
|
1878
|
+
desc?: string;
|
|
1867
1879
|
/**
|
|
1868
1880
|
* Initial value applied at construction time. Only some subclasses act on it
|
|
1869
1881
|
* (text, select and select-multi); the others ignore it. Its expected shape
|
|
1870
1882
|
* depends on the subclass.
|
|
1871
1883
|
*/
|
|
1872
|
-
default?:
|
|
1884
|
+
default?: unknown;
|
|
1873
1885
|
/**
|
|
1874
1886
|
* CSS classes applied to the filter's container element, overriding the
|
|
1875
1887
|
* `classes` input passed by the host component. Use it to give one filter a
|
|
@@ -1928,9 +1940,9 @@ declare class ModelListFilter implements ModelListFilterParams {
|
|
|
1928
1940
|
/** Help/placeholder text. Defaults to a French string set by each subclass. */
|
|
1929
1941
|
help: string;
|
|
1930
1942
|
/** Tooltip text for the filter picker entry; does not affect the query. */
|
|
1931
|
-
desc?:
|
|
1943
|
+
desc?: string;
|
|
1932
1944
|
/** Initial value, applied at construction by the subclasses that support it. */
|
|
1933
|
-
default?:
|
|
1945
|
+
default?: unknown;
|
|
1934
1946
|
/** Discriminator telling {@link ModelListFiltersComponent} which widget to render. */
|
|
1935
1947
|
type: FILTER_TYPE;
|
|
1936
1948
|
/**
|
|
@@ -2029,7 +2041,7 @@ declare class ModelListFilter implements ModelListFilterParams {
|
|
|
2029
2041
|
* @returns `true` when the value actually changed, `false` when it was
|
|
2030
2042
|
* already set. Callers use this to avoid re-querying the list needlessly.
|
|
2031
2043
|
*/
|
|
2032
|
-
set(value:
|
|
2044
|
+
set(value: FilterValue, desc: string, notify?: boolean): boolean;
|
|
2033
2045
|
/**
|
|
2034
2046
|
* Removes `value` from the filter. On a multi-valued filter only that value
|
|
2035
2047
|
* is dropped, which is what the chips' delete buttons call; on a
|
|
@@ -2040,7 +2052,7 @@ declare class ModelListFilter implements ModelListFilterParams {
|
|
|
2040
2052
|
* @param notify Whether to emit on the value stream.
|
|
2041
2053
|
* @returns `true` when something was actually removed.
|
|
2042
2054
|
*/
|
|
2043
|
-
unset(value:
|
|
2055
|
+
unset(value: FilterValue, desc: string, notify?: boolean): boolean;
|
|
2044
2056
|
/**
|
|
2045
2057
|
* Adds `value` if absent, removes it if present. Convenient for checkbox-like
|
|
2046
2058
|
* widgets where the same gesture selects and deselects.
|
|
@@ -2050,7 +2062,7 @@ declare class ModelListFilter implements ModelListFilterParams {
|
|
|
2050
2062
|
* @param notify Whether to emit on the value stream.
|
|
2051
2063
|
* @returns Always `true`.
|
|
2052
2064
|
*/
|
|
2053
|
-
toggle(value:
|
|
2065
|
+
toggle(value: FilterValue, desc: string, notify?: boolean): boolean;
|
|
2054
2066
|
/**
|
|
2055
2067
|
* The current single value, stringified, as sent to the server. Only
|
|
2056
2068
|
* meaningful for single-valued filters.
|
|
@@ -2205,9 +2217,7 @@ interface CustomField {
|
|
|
2205
2217
|
* This is scoping/context (the current tenant, the parent object of a nested
|
|
2206
2218
|
* list), not user-facing filtering — see {@link ModelListParams.filter}.
|
|
2207
2219
|
*/
|
|
2208
|
-
|
|
2209
|
-
[index: string]: string | number | undefined;
|
|
2210
|
-
}
|
|
2220
|
+
type FilterDefaults = Record<string, string | number | undefined>;
|
|
2211
2221
|
/**
|
|
2212
2222
|
* Initial sort keys, as `field` / `+field` (ascending) or `-field` (descending).
|
|
2213
2223
|
*/
|
|
@@ -2512,7 +2522,7 @@ declare class ModelListFieldsSelectorComponent<T extends DataModel> implements O
|
|
|
2512
2522
|
/** Open the field selector panel. */
|
|
2513
2523
|
open(): void;
|
|
2514
2524
|
/** Reorder the dropped column, placing it between its new neighbours. */
|
|
2515
|
-
drop($event: CdkDragDrop<T,
|
|
2525
|
+
drop($event: CdkDragDrop<T, T>): void;
|
|
2516
2526
|
/** Show or hide column `f`, depending on its current state. */
|
|
2517
2527
|
toggle(f: ModelListField): void;
|
|
2518
2528
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListFieldsSelectorComponent<any>, never>;
|
|
@@ -2550,11 +2560,11 @@ declare class ModelListFieldHeaderComponent<T extends DataModel> implements OnIn
|
|
|
2550
2560
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ModelListFieldHeaderComponent<any>, "data-model-list-field-header", never, { "list": { "alias": "list"; "required": true; "isSignal": true; }; "field": { "alias": "field"; "required": true; "isSignal": true; }; "sort": { "alias": "sort"; "required": false; "isSignal": true; }; "sortField": { "alias": "sortField"; "required": false; "isSignal": true; }; "menuMode": { "alias": "menuMode"; "required": false; "isSignal": true; }; "sortMode": { "alias": "sortMode"; "required": false; "isSignal": true; }; "display": { "alias": "display"; "required": false; "isSignal": true; }; }, { "display": "displayChange"; }, never, ["*"], true, never>;
|
|
2551
2561
|
}
|
|
2552
2562
|
|
|
2553
|
-
declare class ModelListSorterComponent {
|
|
2563
|
+
declare class ModelListSorterComponent<T extends DataModel = DataModel> {
|
|
2554
2564
|
/**
|
|
2555
2565
|
* ModelList reference.
|
|
2556
2566
|
*/
|
|
2557
|
-
list: _angular_core.InputSignal<ModelList<
|
|
2567
|
+
list: _angular_core.InputSignal<ModelList<T>>;
|
|
2558
2568
|
/**
|
|
2559
2569
|
* Sort field name.
|
|
2560
2570
|
*/
|
|
@@ -2578,13 +2588,13 @@ declare class ModelListSorterComponent {
|
|
|
2578
2588
|
cancel(): void;
|
|
2579
2589
|
private getIsDown;
|
|
2580
2590
|
private getIsUp;
|
|
2581
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListSorterComponent
|
|
2582
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ModelListSorterComponent
|
|
2591
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListSorterComponent<any>, never>;
|
|
2592
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ModelListSorterComponent<any>, "data-model-list-sorter", never, { "list": { "alias": "list"; "required": true; "isSignal": true; }; "field": { "alias": "field"; "required": true; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
2583
2593
|
}
|
|
2584
2594
|
|
|
2585
|
-
declare class ModelListFiltersSelectComponent implements OnInit {
|
|
2595
|
+
declare class ModelListFiltersSelectComponent<T extends DataModel = DataModel> implements OnInit {
|
|
2586
2596
|
/** The list whose filters can be toggled. Required. */
|
|
2587
|
-
list: _angular_core.InputSignal<ModelList<
|
|
2597
|
+
list: _angular_core.InputSignal<ModelList<T>>;
|
|
2588
2598
|
/** CSS classes for the element wrapping the picker. */
|
|
2589
2599
|
containerClasses: _angular_core.InputSignal<string | string[]>;
|
|
2590
2600
|
/** CSS classes for an enabled filter's badge, in the badge modes. */
|
|
@@ -2611,8 +2621,8 @@ declare class ModelListFiltersSelectComponent implements OnInit {
|
|
|
2611
2621
|
* it and resets the control, leaving the dropdown ready for the next pick.
|
|
2612
2622
|
*/
|
|
2613
2623
|
ngOnInit(): void;
|
|
2614
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListFiltersSelectComponent
|
|
2615
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ModelListFiltersSelectComponent
|
|
2624
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListFiltersSelectComponent<any>, never>;
|
|
2625
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ModelListFiltersSelectComponent<any>, "data-model-list-filters-select", never, { "list": { "alias": "list"; "required": true; "isSignal": true; }; "containerClasses": { "alias": "containerClasses"; "required": false; "isSignal": true; }; "itemActiveClasses": { "alias": "itemActiveClasses"; "required": false; "isSignal": true; }; "itemInactiveClasses": { "alias": "itemInactiveClasses"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
2616
2626
|
}
|
|
2617
2627
|
|
|
2618
2628
|
/**
|
|
@@ -2629,9 +2639,9 @@ declare class ModelListFiltersSelectComponent implements OnInit {
|
|
|
2629
2639
|
* <data-model-list-filters [list]="list" itemClasses="col-4" />
|
|
2630
2640
|
* ```
|
|
2631
2641
|
*/
|
|
2632
|
-
declare class ModelListFiltersComponent {
|
|
2642
|
+
declare class ModelListFiltersComponent<T extends DataModel = DataModel> {
|
|
2633
2643
|
/** The list whose filters are displayed. Required. */
|
|
2634
|
-
list: _angular_core.InputSignal<ModelList<
|
|
2644
|
+
list: _angular_core.InputSignal<ModelList<T>>;
|
|
2635
2645
|
/** CSS classes for the element wrapping all the filter widgets. */
|
|
2636
2646
|
containerClasses: _angular_core.InputSignal<string | string[]>;
|
|
2637
2647
|
/**
|
|
@@ -2639,8 +2649,8 @@ declare class ModelListFiltersComponent {
|
|
|
2639
2649
|
* declaring `displayClasses` overrides this for itself.
|
|
2640
2650
|
*/
|
|
2641
2651
|
itemClasses: _angular_core.InputSignal<string | string[]>;
|
|
2642
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListFiltersComponent
|
|
2643
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ModelListFiltersComponent
|
|
2652
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListFiltersComponent<any>, never>;
|
|
2653
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ModelListFiltersComponent<any>, "data-model-list-filters", never, { "list": { "alias": "list"; "required": true; "isSignal": true; }; "containerClasses": { "alias": "containerClasses"; "required": false; "isSignal": true; }; "itemClasses": { "alias": "itemClasses"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
2644
2654
|
}
|
|
2645
2655
|
|
|
2646
2656
|
/**
|
|
@@ -2679,22 +2689,27 @@ declare class FkselectComponent<T extends DataModel, R extends DataModel> implem
|
|
|
2679
2689
|
search: _angular_core.InputSignal<string>;
|
|
2680
2690
|
/** Label shown next to the control. */
|
|
2681
2691
|
label: _angular_core.InputSignal<string>;
|
|
2692
|
+
/**
|
|
2693
|
+
* Id put on the search input, and pointed at by `[label]`'s `for`. Defaults
|
|
2694
|
+
* to a generated one; dispedit passes its own so its label drives this input.
|
|
2695
|
+
*/
|
|
2696
|
+
inputId: _angular_core.InputSignal<string>;
|
|
2682
2697
|
/** Placeholder for the search input. */
|
|
2683
2698
|
placeholder: _angular_core.InputSignal<string>;
|
|
2684
2699
|
/** CSS classes applied to the search input. */
|
|
2685
2700
|
inputClasses: _angular_core.InputSignal<string | string[]>;
|
|
2686
2701
|
/** Emits the instance the user picked from the dropdown. */
|
|
2687
|
-
selected: _angular_core.OutputEmitterRef<
|
|
2702
|
+
selected: _angular_core.OutputEmitterRef<R>;
|
|
2688
2703
|
/** Emits when the user aborts editing (escape). */
|
|
2689
2704
|
cancelled: _angular_core.OutputEmitterRef<void>;
|
|
2690
2705
|
/** Emits when the user clears the selection, via {@link clearAction}. */
|
|
2691
2706
|
cleared: _angular_core.OutputEmitterRef<void>;
|
|
2692
2707
|
/** Form control backing the typeahead search input. */
|
|
2693
|
-
fc:
|
|
2708
|
+
fc: FormControl<R | null>;
|
|
2694
2709
|
/** Search callback handed to ng-bootstrap's typeahead. */
|
|
2695
|
-
searchFn: (text$: Observable<string>) => Observable<
|
|
2710
|
+
searchFn: (text$: Observable<string>) => Observable<R[]>;
|
|
2696
2711
|
/** Option formatter handed to ng-bootstrap's typeahead. */
|
|
2697
|
-
displayFn: (x:
|
|
2712
|
+
displayFn: (x: R | null | undefined) => string;
|
|
2698
2713
|
private _tpl;
|
|
2699
2714
|
private destroy$;
|
|
2700
2715
|
/**
|
|
@@ -2718,7 +2733,7 @@ declare class FkselectComponent<T extends DataModel, R extends DataModel> implem
|
|
|
2718
2733
|
*/
|
|
2719
2734
|
private _search;
|
|
2720
2735
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FkselectComponent<any, any>, never>;
|
|
2721
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FkselectComponent<any, any>, "data-fkselect", never, { "model": { "alias": "model"; "required": false; "isSignal": true; }; "field": { "alias": "field"; "required": false; "isSignal": true; }; "edit": { "alias": "edit"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "queryset": { "alias": "queryset"; "required": false; "isSignal": true; }; "collection": { "alias": "collection"; "required": false; "isSignal": true; }; "update": { "alias": "update"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "display": { "alias": "display"; "required": false; "isSignal": true; }; "search": { "alias": "search"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "inputClasses": { "alias": "inputClasses"; "required": false; "isSignal": true; }; }, { "queryset": "querysetChange"; "collection": "collectionChange"; "selected": "selected"; "cancelled": "cancelled"; "cleared": "cleared"; }, never, never, true, never>;
|
|
2736
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FkselectComponent<any, any>, "data-fkselect", never, { "model": { "alias": "model"; "required": false; "isSignal": true; }; "field": { "alias": "field"; "required": false; "isSignal": true; }; "edit": { "alias": "edit"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "queryset": { "alias": "queryset"; "required": false; "isSignal": true; }; "collection": { "alias": "collection"; "required": false; "isSignal": true; }; "update": { "alias": "update"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "display": { "alias": "display"; "required": false; "isSignal": true; }; "search": { "alias": "search"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "inputClasses": { "alias": "inputClasses"; "required": false; "isSignal": true; }; }, { "queryset": "querysetChange"; "collection": "collectionChange"; "selected": "selected"; "cancelled": "cancelled"; "cleared": "cleared"; }, never, never, true, never>;
|
|
2722
2737
|
}
|
|
2723
2738
|
|
|
2724
2739
|
interface ModelListAutocompleteParams<T extends DataModel> extends ModelListFilterParams {
|
|
@@ -3263,6 +3278,8 @@ declare class ModelListSelectMultiFilter<T extends DataModel> extends ModelListS
|
|
|
3263
3278
|
* choice. The parent constructor has already resolved the choices and
|
|
3264
3279
|
* enforced the `choices`-or-`model` requirement.
|
|
3265
3280
|
*/
|
|
3281
|
+
/** The options selected from the start, as full choice objects. */
|
|
3282
|
+
default?: IDispEditChoice[];
|
|
3266
3283
|
constructor(params: ModelListMultiSelectFilterParams<T>);
|
|
3267
3284
|
}
|
|
3268
3285
|
|
|
@@ -3516,7 +3533,7 @@ declare class PChoicePipe<T extends DataModel> implements PipeTransform {
|
|
|
3516
3533
|
* @param mode `desc` for the label alone, `code` for the raw value alone,
|
|
3517
3534
|
* `both` for `[code] label`.
|
|
3518
3535
|
*/
|
|
3519
|
-
transform(value:
|
|
3536
|
+
transform(value: unknown, model: T, field: string, mode?: 'code' | 'desc' | 'both'): string;
|
|
3520
3537
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PChoicePipe<any>, never>;
|
|
3521
3538
|
static ɵpipe: _angular_core.ɵɵPipeDeclaration<PChoicePipe<any>, "pchoice", true>;
|
|
3522
3539
|
}
|
|
@@ -3615,7 +3632,7 @@ declare class FactorcPipe<T extends DataModel> implements PipeTransform {
|
|
|
3615
3632
|
* @param digitsInfo digit format, as accepted by Angular's `currency` pipe.
|
|
3616
3633
|
* @param locale locale to format in; defaults to the ambient `LOCALE_ID`.
|
|
3617
3634
|
*/
|
|
3618
|
-
transform(value: T | null, field: string, currencyCode?: string, display?: 'code' | 'symbol' | 'symbol-narrow' | string, digitsInfo?: string, locale?: string): string | null;
|
|
3635
|
+
transform(value: T | null, field: string, currencyCode?: string, display?: 'code' | 'symbol' | 'symbol-narrow' | (string & {}), digitsInfo?: string, locale?: string): string | null;
|
|
3619
3636
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FactorcPipe<any>, never>;
|
|
3620
3637
|
static ɵpipe: _angular_core.ɵɵPipeDeclaration<FactorcPipe<any>, "factorc", true>;
|
|
3621
3638
|
}
|
|
@@ -3644,7 +3661,7 @@ declare class PFactorcPipe<T extends DataModel> implements PipeTransform {
|
|
|
3644
3661
|
* @param digitsInfo digit format, as accepted by Angular's `currency` pipe.
|
|
3645
3662
|
* @param locale locale to format in; defaults to the ambient `LOCALE_ID`.
|
|
3646
3663
|
*/
|
|
3647
|
-
transform(value: number | string | undefined | null, model: T | null, field: string, currencyCode?: string, display?: 'code' | 'symbol' | 'symbol-narrow' | string, digitsInfo?: string, locale?: string): string | null;
|
|
3664
|
+
transform(value: number | string | undefined | null, model: T | null, field: string, currencyCode?: string, display?: 'code' | 'symbol' | 'symbol-narrow' | (string & {}), digitsInfo?: string, locale?: string): string | null;
|
|
3648
3665
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PFactorcPipe<any>, never>;
|
|
3649
3666
|
static ɵpipe: _angular_core.ɵɵPipeDeclaration<PFactorcPipe<any>, "pfactorc", true>;
|
|
3650
3667
|
}
|
|
@@ -3662,6 +3679,8 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3662
3679
|
* the model, and nothing checks it at compile time.
|
|
3663
3680
|
*/
|
|
3664
3681
|
field: _angular_core.InputSignal<string>;
|
|
3682
|
+
/** Id tying the label to whichever control the editor renders. */
|
|
3683
|
+
readonly inputId: string;
|
|
3665
3684
|
/**
|
|
3666
3685
|
* External form group, for `inline` / `form` modes.
|
|
3667
3686
|
*
|
|
@@ -3722,8 +3741,8 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3722
3741
|
/**
|
|
3723
3742
|
* Forces a display renderer, bypassing the field manager's `displayType`.
|
|
3724
3743
|
*
|
|
3725
|
-
* Writable
|
|
3726
|
-
*
|
|
3744
|
+
* Writable so that cross-input consistency rules can settle on a renderer;
|
|
3745
|
+
* see {@link _checks}.
|
|
3727
3746
|
*/
|
|
3728
3747
|
viewer: _angular_core.ModelSignal<DISPEDIT_DISPLAY_TYPES | undefined>;
|
|
3729
3748
|
/**
|
|
@@ -3731,7 +3750,7 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3731
3750
|
*
|
|
3732
3751
|
* The reset control only appears in edit mode when this is not undefined.
|
|
3733
3752
|
*/
|
|
3734
|
-
default: _angular_core.InputSignal<
|
|
3753
|
+
default: _angular_core.InputSignal<unknown>;
|
|
3735
3754
|
/** Input placeholder. Falls back to the field manager's `description`. */
|
|
3736
3755
|
placeholder: _angular_core.InputSignal<string>;
|
|
3737
3756
|
/** Help text shown under the editor. Falls back to the manager's `help`. */
|
|
@@ -3783,7 +3802,7 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3783
3802
|
/** Display renderer actually in use, after manager lookup and overrides. */
|
|
3784
3803
|
realDisplay: _angular_core.WritableSignal<DISPEDIT_DISPLAY_TYPES>;
|
|
3785
3804
|
/** Raw field value backing the current display, before formatting. */
|
|
3786
|
-
dispValue: _angular_core.WritableSignal<
|
|
3805
|
+
dispValue: _angular_core.WritableSignal<unknown>;
|
|
3787
3806
|
/** Choices actually in use, or undefined when the field has none. */
|
|
3788
3807
|
realChoices: _angular_core.WritableSignal<IDispEditChoice[] | undefined>;
|
|
3789
3808
|
/** Help text actually shown, after the manager fallback. */
|
|
@@ -3793,9 +3812,9 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3793
3812
|
/** Whether the manager declares the field required. */
|
|
3794
3813
|
required: _angular_core.WritableSignal<boolean>;
|
|
3795
3814
|
/** Default value actually applied by {@link setDefault}. */
|
|
3796
|
-
realDefault: _angular_core.WritableSignal<
|
|
3815
|
+
realDefault: _angular_core.WritableSignal<unknown>;
|
|
3797
3816
|
/** Latest M2M instances reported by the child select, used for display. */
|
|
3798
|
-
m2mValues?:
|
|
3817
|
+
m2mValues?: DataModel[];
|
|
3799
3818
|
/** Form group driving the editor: the external `[form]`, or a local one. */
|
|
3800
3819
|
fg: _angular_core.WritableSignal<UntypedFormGroup | undefined>;
|
|
3801
3820
|
/** Resolved display function for FK / M2M options, built from `display`. */
|
|
@@ -3880,7 +3899,7 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3880
3899
|
*
|
|
3881
3900
|
* @param $event selected instance, or null when the selection was cleared.
|
|
3882
3901
|
*/
|
|
3883
|
-
selectedRefItem($event:
|
|
3902
|
+
selectedRefItem($event: R | null): Promise<void>;
|
|
3884
3903
|
/**
|
|
3885
3904
|
* Cache the M2M instances reported by the child select.
|
|
3886
3905
|
*
|
|
@@ -3889,8 +3908,14 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3889
3908
|
*
|
|
3890
3909
|
* @param v current list of selected instances.
|
|
3891
3910
|
*/
|
|
3892
|
-
onM2MValuesChanges(v:
|
|
3893
|
-
/**
|
|
3911
|
+
onM2MValuesChanges(v: DataModel[]): void;
|
|
3912
|
+
/**
|
|
3913
|
+
* Apply cross-input consistency rules.
|
|
3914
|
+
*
|
|
3915
|
+
* Nothing to reconcile at the moment: the one rule that lived here paired the
|
|
3916
|
+
* `quill` editor with the `quill` viewer, and neither exists any more. Kept
|
|
3917
|
+
* as the place such rules belong, since `_init` already calls it.
|
|
3918
|
+
*/
|
|
3894
3919
|
private _checks;
|
|
3895
3920
|
/**
|
|
3896
3921
|
* Save value to database, only if model have an id.
|
|
@@ -3945,6 +3970,11 @@ declare class M2mselectComponent<T extends DataModel, R extends DataModel> imple
|
|
|
3945
3970
|
search: _angular_core.InputSignal<string>;
|
|
3946
3971
|
/** Label shown next to the control. */
|
|
3947
3972
|
label: _angular_core.InputSignal<string>;
|
|
3973
|
+
/**
|
|
3974
|
+
* Id put on the search input, and pointed at by `[label]`'s `for`. Defaults
|
|
3975
|
+
* to a generated one; dispedit passes its own so its label drives this input.
|
|
3976
|
+
*/
|
|
3977
|
+
inputId: _angular_core.InputSignal<string>;
|
|
3948
3978
|
/** Placeholder for the search input. */
|
|
3949
3979
|
placeholder: _angular_core.InputSignal<string>;
|
|
3950
3980
|
/** Text shown when nothing is selected. */
|
|
@@ -3966,17 +3996,17 @@ declare class M2mselectComponent<T extends DataModel, R extends DataModel> imple
|
|
|
3966
3996
|
/** Form control backing the typeahead search input. */
|
|
3967
3997
|
fc: UntypedFormControl;
|
|
3968
3998
|
/** Search callback handed to ng-bootstrap's typeahead. */
|
|
3969
|
-
searchFn: (text$: Observable<string>) => Observable<
|
|
3999
|
+
searchFn: (text$: Observable<string>) => Observable<R[]>;
|
|
3970
4000
|
/** Option formatter handed to ng-bootstrap's typeahead. */
|
|
3971
|
-
displayFn: (x:
|
|
4001
|
+
displayFn: (x: R | null | undefined) => string;
|
|
3972
4002
|
private touched;
|
|
3973
4003
|
private _tpl;
|
|
3974
4004
|
private destroy$;
|
|
3975
4005
|
/**
|
|
3976
4006
|
* Control value accessor onChange dummy callback;
|
|
3977
|
-
* @param
|
|
4007
|
+
* @param _fks
|
|
3978
4008
|
*/
|
|
3979
|
-
onChange: (
|
|
4009
|
+
onChange: (_fks: number[]) => void;
|
|
3980
4010
|
/**
|
|
3981
4011
|
* Control value accessor onTouched dummy callback;
|
|
3982
4012
|
*/
|
|
@@ -3985,18 +4015,18 @@ declare class M2mselectComponent<T extends DataModel, R extends DataModel> imple
|
|
|
3985
4015
|
* OnChange register from controlValueAccessor
|
|
3986
4016
|
* @param onChange callback
|
|
3987
4017
|
*/
|
|
3988
|
-
registerOnChange(onChange:
|
|
4018
|
+
registerOnChange(onChange: (fks: number[]) => void): void;
|
|
3989
4019
|
/**
|
|
3990
4020
|
* OnTouched register from controlValueAccessor
|
|
3991
4021
|
* @param onTouched callback
|
|
3992
4022
|
*/
|
|
3993
|
-
registerOnTouched(onTouched:
|
|
4023
|
+
registerOnTouched(onTouched: () => void): void;
|
|
3994
4024
|
/**
|
|
3995
4025
|
* OnInit :
|
|
3996
4026
|
* - ensures queryset is available
|
|
3997
4027
|
* - creates form control for input
|
|
3998
4028
|
* - creates display function
|
|
3999
|
-
* - ensure values are set from
|
|
4029
|
+
* - ensure values are set from whichever source is available
|
|
4000
4030
|
*/
|
|
4001
4031
|
ngOnInit(): void;
|
|
4002
4032
|
/**
|
|
@@ -4049,7 +4079,7 @@ declare class M2mselectComponent<T extends DataModel, R extends DataModel> imple
|
|
|
4049
4079
|
*/
|
|
4050
4080
|
private _search;
|
|
4051
4081
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<M2mselectComponent<any, any>, never>;
|
|
4052
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<M2mselectComponent<any, any>, "data-m2mselect", never, { "model": { "alias": "model"; "required": false; "isSignal": true; }; "field": { "alias": "field"; "required": false; "isSignal": true; }; "edit": { "alias": "edit"; "required": false; "isSignal": true; }; "values": { "alias": "values"; "required": false; "isSignal": true; }; "queryset": { "alias": "queryset"; "required": false; "isSignal": true; }; "collection": { "alias": "collection"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "display": { "alias": "display"; "required": false; "isSignal": true; }; "search": { "alias": "search"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "inputClasses": { "alias": "inputClasses"; "required": false; "isSignal": true; }; }, { "values": "valuesChange"; "queryset": "querysetChange"; "collection": "collectionChange"; "added": "added"; "removed": "removed"; "cancelled": "cancelled"; "cleared": "cleared"; "detailsChanged": "detailsChanged"; "changed": "changed"; }, never, never, true, never>;
|
|
4082
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<M2mselectComponent<any, any>, "data-m2mselect", never, { "model": { "alias": "model"; "required": false; "isSignal": true; }; "field": { "alias": "field"; "required": false; "isSignal": true; }; "edit": { "alias": "edit"; "required": false; "isSignal": true; }; "values": { "alias": "values"; "required": false; "isSignal": true; }; "queryset": { "alias": "queryset"; "required": false; "isSignal": true; }; "collection": { "alias": "collection"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "display": { "alias": "display"; "required": false; "isSignal": true; }; "search": { "alias": "search"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "inputClasses": { "alias": "inputClasses"; "required": false; "isSignal": true; }; }, { "values": "valuesChange"; "queryset": "querysetChange"; "collection": "collectionChange"; "added": "added"; "removed": "removed"; "cancelled": "cancelled"; "cleared": "cleared"; "detailsChanged": "detailsChanged"; "changed": "changed"; }, never, never, true, never>;
|
|
4053
4083
|
}
|
|
4054
4084
|
|
|
4055
4085
|
/**
|
|
@@ -4096,9 +4126,9 @@ declare class FlagsComponent<T extends DataModel> implements OnInit {
|
|
|
4096
4126
|
*/
|
|
4097
4127
|
action: _angular_core.InputSignal<boolean>;
|
|
4098
4128
|
/** Control for the free-text "new flag" input. */
|
|
4099
|
-
ft: FormControl
|
|
4129
|
+
ft: FormControl<string | null>;
|
|
4100
4130
|
/** Control for the known-flags dropdown; selecting a value adds it. */
|
|
4101
|
-
fs: FormControl
|
|
4131
|
+
fs: FormControl<string | null>;
|
|
4102
4132
|
/** Flags currently on the model, rendered as badges. */
|
|
4103
4133
|
curflags: _angular_core.WritableSignal<string[]>;
|
|
4104
4134
|
/** Unused; kept for backwards compatibility. */
|
|
@@ -4114,9 +4144,9 @@ declare class FlagsComponent<T extends DataModel> implements OnInit {
|
|
|
4114
4144
|
* from the model field, and wire the dropdown so that selecting a value adds
|
|
4115
4145
|
* the flag (debounced 250ms).
|
|
4116
4146
|
*/
|
|
4117
|
-
ngOnInit():
|
|
4147
|
+
ngOnInit(): void;
|
|
4118
4148
|
/** Add the flag currently typed in the free-text input. */
|
|
4119
|
-
addFreeFlag(): Promise<
|
|
4149
|
+
addFreeFlag(): Promise<void>;
|
|
4120
4150
|
/**
|
|
4121
4151
|
* Add a flag and persist, unless it is already present.
|
|
4122
4152
|
*
|
|
@@ -4125,12 +4155,12 @@ declare class FlagsComponent<T extends DataModel> implements OnInit {
|
|
|
4125
4155
|
*
|
|
4126
4156
|
* @param flag flag value to add.
|
|
4127
4157
|
*/
|
|
4128
|
-
addFlag(flag: string): Promise<
|
|
4158
|
+
addFlag(flag: string): Promise<void>;
|
|
4129
4159
|
/**
|
|
4130
4160
|
* Write the current flags back to the model field and save it, then reset
|
|
4131
4161
|
* both inputs. Reports success or failure through the message service.
|
|
4132
4162
|
*/
|
|
4133
|
-
update(): Promise<
|
|
4163
|
+
update(): Promise<void>;
|
|
4134
4164
|
/**
|
|
4135
4165
|
* Whether the flag is already on the model.
|
|
4136
4166
|
*
|
|
@@ -4143,7 +4173,7 @@ declare class FlagsComponent<T extends DataModel> implements OnInit {
|
|
|
4143
4173
|
*
|
|
4144
4174
|
* @param flag flag value to remove.
|
|
4145
4175
|
*/
|
|
4146
|
-
removeFlag(flag: string): Promise<
|
|
4176
|
+
removeFlag(flag: string): Promise<void>;
|
|
4147
4177
|
/**
|
|
4148
4178
|
* Switch between badge display and the editor.
|
|
4149
4179
|
*
|
|
@@ -4175,9 +4205,7 @@ declare class SafeDeleteComponent<T extends DataModel> {
|
|
|
4175
4205
|
success: boolean;
|
|
4176
4206
|
}>) | undefined>;
|
|
4177
4207
|
/** Translations of database objects names to human names */
|
|
4178
|
-
checks: _angular_core.InputSignal<
|
|
4179
|
-
[index: string]: string;
|
|
4180
|
-
}>;
|
|
4208
|
+
checks: _angular_core.InputSignal<Record<string, string>>;
|
|
4181
4209
|
/** Messages to be displayed on success or error, default messages are used if not provided */
|
|
4182
4210
|
messages: _angular_core.InputSignal<{
|
|
4183
4211
|
success?: string;
|
|
@@ -4203,9 +4231,9 @@ declare class SafeDeleteComponent<T extends DataModel> {
|
|
|
4203
4231
|
* First step: run the dry-run delete and open the confirmation panel with its
|
|
4204
4232
|
* result. Nothing is destroyed here.
|
|
4205
4233
|
*
|
|
4206
|
-
* @param
|
|
4234
|
+
* @param _model unused; the component always acts on its own `[model]` input.
|
|
4207
4235
|
*/
|
|
4208
|
-
checkDelete(
|
|
4236
|
+
checkDelete(_model: DataModel): Promise<void>;
|
|
4209
4237
|
/**
|
|
4210
4238
|
* Second step: perform the actual deletion once the user has confirmed, then
|
|
4211
4239
|
* close the panel and emit {@link deleted} with the dry-run result.
|
|
@@ -4456,7 +4484,7 @@ interface IDetailsFieldMetadata<T> extends IFieldMetadata<T> {
|
|
|
4456
4484
|
* `forwardRef`, not a lambda). This is the real link of a relation: it is
|
|
4457
4485
|
* what instantiates and populates the nested payload.
|
|
4458
4486
|
*/
|
|
4459
|
-
model?:
|
|
4487
|
+
model?: DataModelType<DataModel>;
|
|
4460
4488
|
/**
|
|
4461
4489
|
* Custom deserialiser, taking precedence over `model`. Use it for payloads
|
|
4462
4490
|
* that are not models — a plain shape, or a value needing transformation.
|
|
@@ -4531,7 +4559,7 @@ declare const reverseForeignKeyField: (updates: IReverseForeignKeyFieldMetadata)
|
|
|
4531
4559
|
* @detailsField({ description: 'Labels', readonly: true })
|
|
4532
4560
|
* public labels_details?: string[];
|
|
4533
4561
|
*/
|
|
4534
|
-
declare const detailsField: (meta?: IDetailsFieldMetadata<
|
|
4562
|
+
declare const detailsField: (meta?: IDetailsFieldMetadata<unknown>) => FieldDecoratorFn;
|
|
4535
4563
|
/**
|
|
4536
4564
|
* Declares the id half of a many-to-many relation: an array of ids, rendered
|
|
4537
4565
|
* as a multi-select. Pairs with a `many: true` {@link detailsField} named
|
|
@@ -4710,7 +4738,7 @@ interface IComputedFieldMetadata<T> extends IFieldMetadata<T> {
|
|
|
4710
4738
|
* }
|
|
4711
4739
|
* }
|
|
4712
4740
|
*/
|
|
4713
|
-
declare const computedField: (meta?: IComputedFieldMetadata<
|
|
4741
|
+
declare const computedField: (meta?: IComputedFieldMetadata<unknown>) => FieldDecoratorFn;
|
|
4714
4742
|
|
|
4715
4743
|
/** Severity of a {@link Message}; drives both the CSS classes and the default lifetime. */
|
|
4716
4744
|
declare const enum TYPE {
|
|
@@ -4735,9 +4763,7 @@ declare enum STATUS {
|
|
|
4735
4763
|
/**
|
|
4736
4764
|
* Maps a sound key (`success`, `info`, `warning`, `error`, `notify`) to an audio file url.
|
|
4737
4765
|
*/
|
|
4738
|
-
|
|
4739
|
-
[index: string]: string;
|
|
4740
|
-
}
|
|
4766
|
+
type ISoundTypes = Record<string, string>;
|
|
4741
4767
|
/**
|
|
4742
4768
|
* Optional per-severity notification sounds ({@link ISoundTypes}) played by
|
|
4743
4769
|
* {@link DataMessageService.play}.
|
|
@@ -4758,11 +4784,11 @@ declare class Message {
|
|
|
4758
4784
|
title: string;
|
|
4759
4785
|
type: TYPE;
|
|
4760
4786
|
message: string;
|
|
4761
|
-
trace:
|
|
4787
|
+
trace: unknown;
|
|
4762
4788
|
ttl: number;
|
|
4763
4789
|
status: string;
|
|
4764
4790
|
showTrace: boolean;
|
|
4765
|
-
constructor(title: string, type?: TYPE, message?: string, trace?:
|
|
4791
|
+
constructor(title: string, type?: TYPE, message?: string, trace?: unknown, ttl?: number);
|
|
4766
4792
|
/** Bootstrap alert classes matching this message's severity, bound by the message zone template. */
|
|
4767
4793
|
get style(): string;
|
|
4768
4794
|
/** Marks the message as dismissed so it is filtered out of the next emission. Prefer {@link DataMessageService.ack}, which also refreshes the stream. */
|
|
@@ -4806,22 +4832,22 @@ declare class DataMessageService {
|
|
|
4806
4832
|
*/
|
|
4807
4833
|
close(): void;
|
|
4808
4834
|
/** Reports a completed operation. Short-lived by default (3 s) and plays the `success` sound if configured. */
|
|
4809
|
-
success(title: string, message?: string, trace?:
|
|
4835
|
+
success(title: string, message?: string, trace?: unknown, timeout?: number): void;
|
|
4810
4836
|
/** Reports neutral information the user does not have to act on. Defaults to a 4 s lifetime. */
|
|
4811
|
-
info(title: string, message?: string, trace?:
|
|
4837
|
+
info(title: string, message?: string, trace?: unknown, timeout?: number): void;
|
|
4812
4838
|
/** Reports a problem the user should notice but that did not abort the operation. Stays 10 s by default. */
|
|
4813
|
-
warning(title: string, message?: string, trace?:
|
|
4839
|
+
warning(title: string, message?: string, trace?: unknown, timeout?: number): void;
|
|
4814
4840
|
/**
|
|
4815
4841
|
* Reports a failure, with the longest lifetime (30 s) and the `error` sound.
|
|
4816
4842
|
*
|
|
4817
4843
|
* Note that the `timeout` argument is currently ignored: the message is always created
|
|
4818
4844
|
* with {@link DEFAULT_TIMEOUTS.DANGER}.
|
|
4819
4845
|
*/
|
|
4820
|
-
danger(title: string, message?: string, trace?:
|
|
4846
|
+
danger(title: string, message?: string, trace?: unknown, timeout?: number): void;
|
|
4821
4847
|
/** Alias for {@link danger}, for callers that think in terms of "error" rather than severity. */
|
|
4822
|
-
error(title: string, message?: string, trace?:
|
|
4848
|
+
error(title: string, message?: string, trace?: unknown): void;
|
|
4823
4849
|
/** Logs to the console only — nothing is shown to the user and no message is queued. */
|
|
4824
|
-
debug(title: string, message?: string, trace?:
|
|
4850
|
+
debug(title: string, message?: string, trace?: unknown): void;
|
|
4825
4851
|
/**
|
|
4826
4852
|
* Dismisses a message on the user's behalf and immediately re-emits the list, so the
|
|
4827
4853
|
* message zone drops it without waiting for its ttl. Bound to the close button of
|
|
@@ -4925,13 +4951,13 @@ declare class QuerysetMock<T extends DataModel> {
|
|
|
4925
4951
|
/** `[results, loading, meta]` combined, mirroring `Queryset.full`. */
|
|
4926
4952
|
get full(): Observable<[T[], boolean, IQueryMeta]>;
|
|
4927
4953
|
/** No-op returning `this`; the filter is discarded. See the class-level caveat. */
|
|
4928
|
-
filter(
|
|
4954
|
+
filter(_params?: FilterData): QuerysetMock<T>;
|
|
4929
4955
|
/** No-op returning `this`; the ordering is discarded. See the class-level caveat. */
|
|
4930
|
-
sort(...
|
|
4956
|
+
sort(..._sorting: string[]): QuerysetMock<T>;
|
|
4931
4957
|
/** No-op returning `this`; {@link pageSize} is left untouched. */
|
|
4932
|
-
paginateBy(
|
|
4958
|
+
paginateBy(_pageSize?: number): QuerysetMock<T>;
|
|
4933
4959
|
/** No-op returning `this`; {@link page} is left untouched. */
|
|
4934
|
-
setPage(
|
|
4960
|
+
setPage(_page: number): QuerysetMock<T>;
|
|
4935
4961
|
/** Always returns `{}`, since no query state is retained. */
|
|
4936
4962
|
getQueryParams(): FilterData;
|
|
4937
4963
|
/**
|
|
@@ -4993,13 +5019,13 @@ declare class CollectionMock<T extends DataModel> {
|
|
|
4993
5019
|
* id, so a test that fetches two different ids gets the same instance back.
|
|
4994
5020
|
* Reassign `mockValue` between calls if that matters.
|
|
4995
5021
|
*/
|
|
4996
|
-
fetch(
|
|
5022
|
+
fetch(_id: number, _suffix?: string): Observable<T>;
|
|
4997
5023
|
/**
|
|
4998
5024
|
* Returns {@link actionValue}, ignoring the arguments. Since it does not record
|
|
4999
5025
|
* the call, assert on the effects rather than on the invocation, or spy on this
|
|
5000
5026
|
* method when you need to check what was requested.
|
|
5001
5027
|
*/
|
|
5002
|
-
action(
|
|
5028
|
+
action(_model: T | null, _method: IHttpMethod, _action: string, _params: IActionParams): Observable<any>;
|
|
5003
5029
|
/**
|
|
5004
5030
|
* Opens a {@link QuerysetMock} backed by this mock, mirroring
|
|
5005
5031
|
* `Collection.queryset()`. With no `mockData` set on it, the queryset falls
|
|
@@ -5011,9 +5037,7 @@ declare class CollectionMock<T extends DataModel> {
|
|
|
5011
5037
|
* real `Collection.list()` unwraps. Arguments are ignored, so filters are not
|
|
5012
5038
|
* applied; set {@link mockValues} to whatever the filtered result should be.
|
|
5013
5039
|
*/
|
|
5014
|
-
list(
|
|
5015
|
-
[index: string]: string;
|
|
5016
|
-
}, suffix?: string): Observable<any>;
|
|
5040
|
+
list(_query?: Record<string, string>, _suffix?: string): Observable<any>;
|
|
5017
5041
|
/**
|
|
5018
5042
|
* Builds real model instances from JSON, exactly as a live collection would —
|
|
5019
5043
|
* this is the method you use to prepare {@link mockValue}/{@link mockValues}.
|
|
@@ -5027,7 +5051,7 @@ declare class CollectionMock<T extends DataModel> {
|
|
|
5027
5051
|
* @param data JSON object or array of them
|
|
5028
5052
|
* @param many set to `true` when `data` is an array
|
|
5029
5053
|
*/
|
|
5030
|
-
fromJson(data: any, many?: boolean):
|
|
5054
|
+
fromJson(data: any, many?: boolean): any;
|
|
5031
5055
|
}
|
|
5032
5056
|
|
|
5033
5057
|
/**
|
|
@@ -5092,16 +5116,15 @@ interface UploadFile {
|
|
|
5092
5116
|
/** Live status and throughput figures, updated as the transfer progresses. */
|
|
5093
5117
|
progress: UploadProgress;
|
|
5094
5118
|
/** Response body, parsed as JSON when possible and left as raw text otherwise. Set once done. */
|
|
5095
|
-
response?:
|
|
5119
|
+
response?: unknown;
|
|
5096
5120
|
/** HTTP status code of the response. Set once done — note that a 4xx/5xx still completes as `done`. */
|
|
5097
5121
|
responseStatus?: number;
|
|
5098
|
-
|
|
5122
|
+
/** Subscription of the in-flight request, used to cancel it. */
|
|
5123
|
+
sub?: Subscription;
|
|
5099
5124
|
/** The underlying browser `File`, i.e. what is actually transferred. */
|
|
5100
5125
|
nativeFile?: File;
|
|
5101
5126
|
/** Response headers, parsed into a plain object. Set once done. */
|
|
5102
|
-
responseHeaders?:
|
|
5103
|
-
[key: string]: string;
|
|
5104
|
-
};
|
|
5127
|
+
responseHeaders?: Record<string, string>;
|
|
5105
5128
|
}
|
|
5106
5129
|
/**
|
|
5107
5130
|
* An event emitted by the uploader on the `uploadOutput` output of the directives.
|
|
@@ -5112,7 +5135,7 @@ interface UploadFile {
|
|
|
5112
5135
|
* `dragOver`/`dragOut`/`drop` for drop-zone hover states.
|
|
5113
5136
|
*/
|
|
5114
5137
|
interface UploadOutput {
|
|
5115
|
-
type:
|
|
5138
|
+
type: 'addedToQueue' | 'allAddedToQueue' | 'uploading' | 'done' | 'start' | 'cancelled' | 'dragOver' | 'dragOut' | 'drop' | 'removed' | 'removedAll' | 'rejected';
|
|
5116
5139
|
file?: UploadFile;
|
|
5117
5140
|
nativeFile?: File;
|
|
5118
5141
|
}
|
|
@@ -5124,7 +5147,7 @@ interface UploadOutput {
|
|
|
5124
5147
|
* data); the queue-management commands only need `type` and, where relevant, `id`.
|
|
5125
5148
|
*/
|
|
5126
5149
|
interface UploadInput {
|
|
5127
|
-
type:
|
|
5150
|
+
type: 'uploadAll' | 'uploadFile' | 'cancel' | 'cancelAll' | 'remove' | 'removeAll';
|
|
5128
5151
|
/** Target endpoint for `uploadAll`/`uploadFile`. Defaults to an empty string, which posts to the current url. */
|
|
5129
5152
|
url?: string;
|
|
5130
5153
|
/** HTTP method to use; defaults to `POST`. */
|
|
@@ -5137,13 +5160,9 @@ interface UploadInput {
|
|
|
5137
5160
|
/** The queued file to send with `uploadFile`; matched by identity against the queue. */
|
|
5138
5161
|
file?: UploadFile;
|
|
5139
5162
|
/** Extra form fields appended to the multipart body alongside the file. */
|
|
5140
|
-
data?:
|
|
5141
|
-
[key: string]: string | Blob;
|
|
5142
|
-
};
|
|
5163
|
+
data?: Record<string, string | Blob>;
|
|
5143
5164
|
/** Extra request headers. Note the uploader uses `XMLHttpRequest` directly, so Angular HTTP interceptors — including the auth interceptor — do not apply; add any `Authorization` header here yourself. */
|
|
5144
|
-
headers?:
|
|
5145
|
-
[key: string]: string;
|
|
5146
|
-
};
|
|
5165
|
+
headers?: Record<string, string>;
|
|
5147
5166
|
includeWebKitFormBoundary?: boolean;
|
|
5148
5167
|
/** Sends credentials (cookies) cross-origin; defaults to `false`. */
|
|
5149
5168
|
withCredentials?: boolean;
|
|
@@ -5273,7 +5292,7 @@ declare class NgFileDropDirective implements OnInit, OnDestroy {
|
|
|
5273
5292
|
ngOnDestroy(): void;
|
|
5274
5293
|
stopEvent: (e: Event) => void;
|
|
5275
5294
|
/** Handles a drop: emits `drop`, then screens and queues the dropped files. Bound to the host `drop` event. */
|
|
5276
|
-
onDrop(e:
|
|
5295
|
+
onDrop(e: DragEvent): void;
|
|
5277
5296
|
/** Emits `dragOver` while a drag hovers the zone, for highlighting it. Bound to the host `dragover` event. */
|
|
5278
5297
|
onDragOver(e: Event): void;
|
|
5279
5298
|
/** Emits `dragOut` when a drag leaves the zone, to clear the highlight. Bound to the host `dragleave` event. */
|
|
@@ -5286,7 +5305,7 @@ declare class NgFileSelectDirective implements OnInit, OnDestroy {
|
|
|
5286
5305
|
/** Queue limits ({@link UploaderOptions}). Read once in `ngOnInit`; later changes have no effect. */
|
|
5287
5306
|
options: _angular_core.InputSignal<UploaderOptions | undefined>;
|
|
5288
5307
|
/** Command channel: emit {@link UploadInput}s on it to start, cancel or clear uploads. */
|
|
5289
|
-
uploadInput: _angular_core.InputSignal<EventEmitter<
|
|
5308
|
+
uploadInput: _angular_core.InputSignal<EventEmitter<UploadInput> | undefined>;
|
|
5290
5309
|
/** Queue and transfer events ({@link UploadOutput}) for this input. */
|
|
5291
5310
|
uploadOutput: _angular_core.OutputEmitterRef<UploadOutput>;
|
|
5292
5311
|
/** The queue backing this input, created in `ngOnInit`. */
|
|
@@ -5449,7 +5468,7 @@ declare const DATA_AUTH_PARAMS: InjectionToken<AuthParams>;
|
|
|
5449
5468
|
* Using `useClass` here would give the auth layer a private instance whose cache and
|
|
5450
5469
|
* state diverge from the one the rest of the application uses.
|
|
5451
5470
|
*/
|
|
5452
|
-
declare const DATA_AUTH_USER_SERVICE: InjectionToken<Collection<
|
|
5471
|
+
declare const DATA_AUTH_USER_SERVICE: InjectionToken<Collection<DataModel>>;
|
|
5453
5472
|
/**
|
|
5454
5473
|
* Generic JWT authentication service, meant to be **extended** by the application.
|
|
5455
5474
|
*
|
|
@@ -5495,11 +5514,6 @@ declare const DATA_AUTH_USER_SERVICE: InjectionToken<Collection<any>>;
|
|
|
5495
5514
|
* @typeParam UserData - the decoded JWT payload, at least an {@link IJwtBaseData}.
|
|
5496
5515
|
*/
|
|
5497
5516
|
declare class AuthServiceBase<User extends DataModel, UserService extends Collection<User>, UserData extends IJwtBaseData> {
|
|
5498
|
-
userService: UserService;
|
|
5499
|
-
private _params;
|
|
5500
|
-
private _router;
|
|
5501
|
-
private _http;
|
|
5502
|
-
private _msgs;
|
|
5503
5517
|
/**
|
|
5504
5518
|
* Emits every time {@link logout} runs, whether triggered by the user, by a failed
|
|
5505
5519
|
* token refresh, or by a login error.
|
|
@@ -5514,7 +5528,13 @@ declare class AuthServiceBase<User extends DataModel, UserService extends Collec
|
|
|
5514
5528
|
private _user$;
|
|
5515
5529
|
private _token;
|
|
5516
5530
|
private _fetched?;
|
|
5517
|
-
|
|
5531
|
+
/** Collection used to fetch the logged-in user, from {@link DATA_AUTH_USER_SERVICE}. */
|
|
5532
|
+
userService: UserService;
|
|
5533
|
+
private _params;
|
|
5534
|
+
private _router;
|
|
5535
|
+
private _http;
|
|
5536
|
+
private _msgs;
|
|
5537
|
+
constructor();
|
|
5518
5538
|
/** True when no access token is held, i.e. no session is active. Checked by {@link AuthInterceptor} before attaching a token. */
|
|
5519
5539
|
get isAnonymous(): boolean;
|
|
5520
5540
|
/** Current raw access token, or `null` when anonymous. Read by {@link AuthInterceptor} to build the `Authorization` header. */
|
|
@@ -5572,7 +5592,7 @@ declare class AuthServiceBase<User extends DataModel, UserService extends Collec
|
|
|
5572
5592
|
* `'error'` when none is available), so callers can branch on the emitted string
|
|
5573
5593
|
* rather than on an error callback.
|
|
5574
5594
|
*/
|
|
5575
|
-
login(username: string, password: string): Observable<'success' | 'error' | 'invalid_token' | string>;
|
|
5595
|
+
login(username: string, password: string): Observable<'success' | 'error' | 'invalid_token' | (string & {})>;
|
|
5576
5596
|
/**
|
|
5577
5597
|
* Opens a session from an already-obtained token pair instead of credentials, for
|
|
5578
5598
|
* flows where the tokens arrive out of band (SSO callback, impersonation, tests).
|
|
@@ -5580,7 +5600,7 @@ declare class AuthServiceBase<User extends DataModel, UserService extends Collec
|
|
|
5580
5600
|
* Like {@link login}, it fetches the user, saves the session and reports failures as
|
|
5581
5601
|
* an emitted code rather than an error.
|
|
5582
5602
|
*/
|
|
5583
|
-
loginWithToken(accessToken: string, refreshToken: string): Observable<'success' | 'error' | 'invalid_token' | string>;
|
|
5603
|
+
loginWithToken(accessToken: string, refreshToken: string): Observable<'success' | 'error' | 'invalid_token' | (string & {})>;
|
|
5584
5604
|
/**
|
|
5585
5605
|
* Asks the backend to send an account reactivation token to the given user.
|
|
5586
5606
|
*
|
|
@@ -5697,7 +5717,7 @@ declare class AuthInterceptor implements HttpInterceptor {
|
|
|
5697
5717
|
* {@link DATA_AUTH_URLS}. Authenticated requests additionally get 401 handling with
|
|
5698
5718
|
* automatic token refresh and replay.
|
|
5699
5719
|
*/
|
|
5700
|
-
intercept(req: HttpRequest<
|
|
5720
|
+
intercept(req: HttpRequest<unknown>, next: HttpHandler): rxjs.Observable<_angular_common_http.HttpEvent<any>>;
|
|
5701
5721
|
private _handle401Error;
|
|
5702
5722
|
private _addToken;
|
|
5703
5723
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AuthInterceptor, never>;
|
|
@@ -5730,6 +5750,10 @@ interface BaseRouteParams {
|
|
|
5730
5750
|
/**
|
|
5731
5751
|
* Route function type.
|
|
5732
5752
|
* Takes parameters, return a route.
|
|
5753
|
+
*
|
|
5754
|
+
* The parameters are `any` on purpose: a route builder is written against the
|
|
5755
|
+
* models it links to (`(product: Product) => [...]`), and such a function is not
|
|
5756
|
+
* assignable to one declared over `unknown[]`.
|
|
5733
5757
|
*/
|
|
5734
5758
|
type RouteFn = (...args: any[]) => (string | number)[];
|
|
5735
5759
|
/**
|
|
@@ -5753,18 +5777,14 @@ declare function RData<T extends BaseRouteParams>(value: T): T;
|
|
|
5753
5777
|
* A map of route names to their {@link RouteConfigItem}, keyed by a string-literal union
|
|
5754
5778
|
* so that every name is known statically and typos are compile errors.
|
|
5755
5779
|
*/
|
|
5756
|
-
type RoutesConfig<T extends string> =
|
|
5757
|
-
readonly [Property in T]: RouteConfigItem;
|
|
5758
|
-
};
|
|
5780
|
+
type RoutesConfig<T extends string> = Readonly<Record<T, RouteConfigItem>>;
|
|
5759
5781
|
/** An Angular {@link Route} whose `data` is mandatory and typed as {@link BaseRouteParams}. */
|
|
5760
5782
|
interface StrictRoutes extends Route {
|
|
5761
5783
|
data: BaseRouteParams;
|
|
5762
5784
|
}
|
|
5763
5785
|
/** A route table built from {@link StrictRoutes}, i.e. where every route carries breadcrumb metadata. */
|
|
5764
5786
|
type RoutesDefinition = StrictRoutes[];
|
|
5765
|
-
|
|
5766
|
-
[index: string]: T;
|
|
5767
|
-
}
|
|
5787
|
+
type RouteArg<T> = Record<string, T>;
|
|
5768
5788
|
/**
|
|
5769
5789
|
* A bound, reusable reference to a route: it pairs a {@link RouteConfigItem} with a
|
|
5770
5790
|
* context object from which the route's named parameters are read.
|
|
@@ -5787,7 +5807,7 @@ declare class Link<T> {
|
|
|
5787
5807
|
* later. A missing `config` is tolerated (it warns and produces an inert link) so that
|
|
5788
5808
|
* a partially-initialised template does not crash.
|
|
5789
5809
|
*/
|
|
5790
|
-
constructor(config?: RouteConfigItem, context?:
|
|
5810
|
+
constructor(config?: RouteConfigItem, context?: object, router?: Router);
|
|
5791
5811
|
private _name;
|
|
5792
5812
|
/** Name of the underlying route config item, or an empty string when the link was built without config. */
|
|
5793
5813
|
get name(): string;
|
|
@@ -5796,7 +5816,7 @@ declare class Link<T> {
|
|
|
5796
5816
|
* context. Only the parameters declared by the route config are picked up; those
|
|
5797
5817
|
* missing from `ctx` are reset to `null`, not left over from the previous context.
|
|
5798
5818
|
*/
|
|
5799
|
-
context(ctx:
|
|
5819
|
+
context(ctx: object): void;
|
|
5800
5820
|
/**
|
|
5801
5821
|
* Builds the router commands array, resolving each declared parameter from `params`
|
|
5802
5822
|
* first and falling back to the bound context.
|
|
@@ -5813,9 +5833,7 @@ declare class Link<T> {
|
|
|
5813
5833
|
* Resolves to `false` without navigating when no router is available from either
|
|
5814
5834
|
* source; otherwise it resolves with the router's own result.
|
|
5815
5835
|
*/
|
|
5816
|
-
navigate(params?:
|
|
5817
|
-
[index: string]: T;
|
|
5818
|
-
}, router?: Router): Promise<boolean>;
|
|
5836
|
+
navigate(params?: Record<string, T>, router?: Router): Promise<boolean>;
|
|
5819
5837
|
}
|
|
5820
5838
|
|
|
5821
5839
|
/** One rendered breadcrumb entry: its absolute path, label, icon classes, and whether it is the active leaf. */
|
|
@@ -5848,7 +5866,7 @@ declare class BreadcrumbComponent implements OnInit {
|
|
|
5848
5866
|
/**
|
|
5849
5867
|
* Additional data to be used in titleTemplate
|
|
5850
5868
|
*/
|
|
5851
|
-
data: _angular_core.InputSignal<
|
|
5869
|
+
data: _angular_core.InputSignal<object | undefined>;
|
|
5852
5870
|
/**
|
|
5853
5871
|
* Do we display icons ?
|
|
5854
5872
|
*/
|
|
@@ -5965,6 +5983,197 @@ declare class TabMemoryService {
|
|
|
5965
5983
|
*/
|
|
5966
5984
|
declare const slugify: (str: string) => string;
|
|
5967
5985
|
|
|
5986
|
+
/**
|
|
5987
|
+
* Returns a document-unique DOM id, as `<prefix>-<n>`.
|
|
5988
|
+
*
|
|
5989
|
+
* Used to wire a `<label [attr.for]>` to the control its template owns: the
|
|
5990
|
+
* widgets in this library are instantiated repeatedly on the same page, so a
|
|
5991
|
+
* hard-coded id would collide and silently break the association.
|
|
5992
|
+
*
|
|
5993
|
+
* The counter is module-level and starts at zero in each JS context, so a
|
|
5994
|
+
* server-rendered page and its client hydration agree as long as components are
|
|
5995
|
+
* created in the same order — which is what Angular does.
|
|
5996
|
+
*
|
|
5997
|
+
* @param prefix identifies the widget, e.g. `data-filter`
|
|
5998
|
+
*/
|
|
5999
|
+
declare function uniqueId(prefix: string): string;
|
|
6000
|
+
|
|
6001
|
+
/**
|
|
6002
|
+
* Teach jsdom the layout APIs CodeMirror and ProseMirror expect.
|
|
6003
|
+
*
|
|
6004
|
+
* Both editors measure the document to place the caret and decide what to
|
|
6005
|
+
* render, and jsdom has no layout engine: `getClientRects()` returns an empty
|
|
6006
|
+
* list and `elementFromPoint` does not exist at all. Zeroed rectangles are
|
|
6007
|
+
* enough — nothing in a spec depends on real geometry, it just has to not throw.
|
|
6008
|
+
*
|
|
6009
|
+
* Call it from `beforeEach` in any spec that instantiates an editor view. It is
|
|
6010
|
+
* idempotent, and only patches what is missing.
|
|
6011
|
+
*/
|
|
6012
|
+
declare function installEditorDomShims(): void;
|
|
6013
|
+
|
|
6014
|
+
/**
|
|
6015
|
+
* The behaviour `<data-richedit>` and `<data-mdedit>` share with
|
|
6016
|
+
* `<data-dispedit>`: show the value, click to edit, save explicitly.
|
|
6017
|
+
*
|
|
6018
|
+
* It lives in the primary entry point so both editors can extend it — they
|
|
6019
|
+
* import `@solidev/data`, and the reverse would be a circular dependency
|
|
6020
|
+
* between entry points. Everything here is engine-agnostic: resolving which
|
|
6021
|
+
* field to read, which control to bind, when to show the editor, and how to
|
|
6022
|
+
* persist. The subclass owns its template and its editor widget.
|
|
6023
|
+
*
|
|
6024
|
+
* ## The source / rendered pair
|
|
6025
|
+
*
|
|
6026
|
+
* Long text is rarely one column. A markdown field is stored as its source
|
|
6027
|
+
* plus the HTML the server rendered from it, and this base follows that shape
|
|
6028
|
+
* by convention: given `field="description"` it edits `description_src` and
|
|
6029
|
+
* displays `description_html` **when the model declares them**, and falls back
|
|
6030
|
+
* to `description` for both when it does not. `[htmlField]` overrides the
|
|
6031
|
+
* display half outright. A `field` that already ends in `_src` is understood,
|
|
6032
|
+
* so `field="description_src"` resolves the same pair.
|
|
6033
|
+
*/
|
|
6034
|
+
declare abstract class FieldEditorBase<FT, T extends DataModel> implements OnInit {
|
|
6035
|
+
/** Id tying the label to the editor. */
|
|
6036
|
+
readonly inputId: string;
|
|
6037
|
+
/** Id of the label element, wired to the editor through `aria-labelledby`. */
|
|
6038
|
+
readonly labelId: string;
|
|
6039
|
+
/** Model instance holding the field. */
|
|
6040
|
+
model: _angular_core.InputSignal<T | undefined>;
|
|
6041
|
+
/**
|
|
6042
|
+
* Field to edit, or the base name of a source / rendered pair.
|
|
6043
|
+
*
|
|
6044
|
+
* See the class description for how `<field>_src` and `<field>_html` are
|
|
6045
|
+
* resolved.
|
|
6046
|
+
*/
|
|
6047
|
+
field: _angular_core.InputSignal<string | undefined>;
|
|
6048
|
+
/** Overrides the field read for the read-only display. */
|
|
6049
|
+
htmlField: _angular_core.InputSignal<string | undefined>;
|
|
6050
|
+
/** Whether {@link toggleEdit} is allowed to reveal the editor. */
|
|
6051
|
+
editable: _angular_core.InputSignal<boolean>;
|
|
6052
|
+
/**
|
|
6053
|
+
* Whether the editor is showing, in `dd` mode.
|
|
6054
|
+
*
|
|
6055
|
+
* Defaults to false: the value renders and a click reveals the editor, the
|
|
6056
|
+
* way `<data-dispedit>` behaves. `inline` and `form` modes ignore this and
|
|
6057
|
+
* follow {@link showEditor}.
|
|
6058
|
+
*/
|
|
6059
|
+
edit: _angular_core.ModelSignal<boolean>;
|
|
6060
|
+
/**
|
|
6061
|
+
* Layout, and whether {@link save} persists.
|
|
6062
|
+
*
|
|
6063
|
+
* `dd` renders a `<dt>`/`<dd>` block and is the only mode that saves to the
|
|
6064
|
+
* API; `inline` and `form` render a label plus the editor and leave saving to
|
|
6065
|
+
* the caller.
|
|
6066
|
+
*/
|
|
6067
|
+
mode: _angular_core.InputSignal<"inline" | "dd" | "form">;
|
|
6068
|
+
/** Hide label (for inline forms). */
|
|
6069
|
+
hideLabel: _angular_core.InputSignal<boolean>;
|
|
6070
|
+
/**
|
|
6071
|
+
* Hide the built-in save button, for callers driving persistence themselves
|
|
6072
|
+
* from the {@link changed} output.
|
|
6073
|
+
*/
|
|
6074
|
+
hideButton: _angular_core.InputSignal<boolean>;
|
|
6075
|
+
/**
|
|
6076
|
+
* Form control backing the editor.
|
|
6077
|
+
*
|
|
6078
|
+
* When supplied, the component uses it as-is and skips its own setup — no
|
|
6079
|
+
* field manager lookup, no seeding from the model, and no {@link changed}
|
|
6080
|
+
* emissions. Takes precedence over `[form]`.
|
|
6081
|
+
*/
|
|
6082
|
+
fc: _angular_core.InputSignal<FormControl<string | null> | undefined>;
|
|
6083
|
+
/**
|
|
6084
|
+
* External form group to register into, the way `<data-dispedit>` does.
|
|
6085
|
+
*
|
|
6086
|
+
* A control named after the resolved source field is added to it, seeded
|
|
6087
|
+
* from the model. Ignored when `[fc]` is supplied.
|
|
6088
|
+
*/
|
|
6089
|
+
form: _angular_core.InputSignal<UntypedFormGroup | undefined>;
|
|
6090
|
+
/** Emits the value on every change. Not wired for a caller-supplied `[fc]`. */
|
|
6091
|
+
changed: _angular_core.OutputEmitterRef<string | null>;
|
|
6092
|
+
/** Field manager for the source field; only resolved when `fc` is created here. */
|
|
6093
|
+
manager?: BaseFieldManager<FT>;
|
|
6094
|
+
/** Whether the manager declares the field required. */
|
|
6095
|
+
readonly required: _angular_core.WritableSignal<boolean>;
|
|
6096
|
+
/** The control actually in use. */
|
|
6097
|
+
control: FormControl<string | null>;
|
|
6098
|
+
/** The base name of the pair, with any trailing `_src` removed. */
|
|
6099
|
+
private readonly baseField;
|
|
6100
|
+
/** The field actually edited. */
|
|
6101
|
+
readonly sourceField: _angular_core.Signal<string>;
|
|
6102
|
+
/** The field actually displayed in read-only mode. */
|
|
6103
|
+
readonly displayField: _angular_core.Signal<string>;
|
|
6104
|
+
/**
|
|
6105
|
+
* Whether the editor is showing rather than the rendered value.
|
|
6106
|
+
*
|
|
6107
|
+
* The rule is `<data-dispedit>`'s: `dd` follows `[edit]`, `inline` shows the
|
|
6108
|
+
* editor unless the field is not editable, and `form` always shows it — a
|
|
6109
|
+
* form control that renders as static text would be a surprise.
|
|
6110
|
+
*/
|
|
6111
|
+
readonly showEditor: _angular_core.Signal<boolean>;
|
|
6112
|
+
/**
|
|
6113
|
+
* Resolve the control: the supplied `[fc]`, one registered into `[form]`, or
|
|
6114
|
+
* one of our own seeded from the model.
|
|
6115
|
+
*/
|
|
6116
|
+
ngOnInit(): void;
|
|
6117
|
+
/**
|
|
6118
|
+
* Switch between the rendered value and the editor.
|
|
6119
|
+
* Does nothing when `[editable]` is false.
|
|
6120
|
+
*/
|
|
6121
|
+
toggleEdit(): void;
|
|
6122
|
+
/**
|
|
6123
|
+
* The rendered value, as stored on the display field.
|
|
6124
|
+
*
|
|
6125
|
+
* Templates pass it through {@link SafeHtmlPipe} to inject it — **trusted,
|
|
6126
|
+
* not sanitized**, because Angular's sanitizer allow-list has no `style` and
|
|
6127
|
+
* would drop the alignment and colours the rich text editor writes. Point
|
|
6128
|
+
* these components at fields your own editor produced and your own API
|
|
6129
|
+
* stored.
|
|
6130
|
+
*/
|
|
6131
|
+
displayValue(): string;
|
|
6132
|
+
/**
|
|
6133
|
+
* Write the editor content back to the model's source field, and persist it
|
|
6134
|
+
* in `dd` mode only.
|
|
6135
|
+
*
|
|
6136
|
+
* In `inline` / `form` modes the model is updated in memory but no request is
|
|
6137
|
+
* sent, leaving the save to the surrounding form. Does nothing without both a
|
|
6138
|
+
* `[model]` and a `[field]`.
|
|
6139
|
+
*/
|
|
6140
|
+
save(): Promise<void>;
|
|
6141
|
+
/** Whether the model declares a property under that name. */
|
|
6142
|
+
private modelHas;
|
|
6143
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FieldEditorBase<any, any>, never>;
|
|
6144
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<FieldEditorBase<any, any>, never, never, { "model": { "alias": "model"; "required": false; "isSignal": true; }; "field": { "alias": "field"; "required": false; "isSignal": true; }; "htmlField": { "alias": "htmlField"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "edit": { "alias": "edit"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "hideButton": { "alias": "hideButton"; "required": false; "isSignal": true; }; "fc": { "alias": "fc"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; }, { "edit": "editChange"; "changed": "changed"; }, never, never, true, never>;
|
|
6145
|
+
}
|
|
6146
|
+
|
|
6147
|
+
/**
|
|
6148
|
+
* Marks HTML as trusted, so `[innerHTML]` renders it as-is.
|
|
6149
|
+
*
|
|
6150
|
+
* Meant for the rendered half of a rich text field — the `<field>_html` column
|
|
6151
|
+
* the server produces from the markdown or HTML source. Angular's sanitizer
|
|
6152
|
+
* builds its allow-list from `URI_ATTRS + HTML_ATTRS + ARIA_ATTRS`, and `style`
|
|
6153
|
+
* is in none of them, so a plain `[innerHTML]` silently drops every
|
|
6154
|
+
* `text-align` and every colour `<data-richedit>` writes: read-only mode ends
|
|
6155
|
+
* up looking nothing like the editor.
|
|
6156
|
+
*
|
|
6157
|
+
* **Only use it on HTML the server produced.** The value is inserted without
|
|
6158
|
+
* any filtering, and trusted HTML executes scripts — pointing this at a string
|
|
6159
|
+
* a user of another system can influence is an XSS vector.
|
|
6160
|
+
*
|
|
6161
|
+
* @example
|
|
6162
|
+
* ```html
|
|
6163
|
+
* <div [innerHTML]="product.description_html | safeHtml"></div>
|
|
6164
|
+
* ```
|
|
6165
|
+
*/
|
|
6166
|
+
declare class SafeHtmlPipe implements PipeTransform {
|
|
6167
|
+
private _sanitizer;
|
|
6168
|
+
/**
|
|
6169
|
+
* @param value HTML to trust; null for a nullish or empty input, which
|
|
6170
|
+
* `[innerHTML]` renders as nothing.
|
|
6171
|
+
*/
|
|
6172
|
+
transform(value: string | null | undefined): SafeHtml | null;
|
|
6173
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SafeHtmlPipe, never>;
|
|
6174
|
+
static ɵpipe: _angular_core.ɵɵPipeDeclaration<SafeHtmlPipe, "safeHtml", true>;
|
|
6175
|
+
}
|
|
6176
|
+
|
|
5968
6177
|
/**
|
|
5969
6178
|
* Compiles (and optionally renders) an Underscore-style string template, using ERB
|
|
5970
6179
|
* delimiters: `<%= expr %>` interpolates, `<% code %>` evaluates, and a `print()` helper
|
|
@@ -5980,7 +6189,15 @@ declare const slugify: (str: string) => string;
|
|
|
5980
6189
|
* Policy without `unsafe-eval`; and the escaping delimiter `<%- expr %>` is not usable,
|
|
5981
6190
|
* as the code it emits calls `_.escape` while no `_` is in scope.
|
|
5982
6191
|
*/
|
|
5983
|
-
|
|
6192
|
+
/**
|
|
6193
|
+
* A template compiled by {@link tmpl} but not yet rendered: call it with the
|
|
6194
|
+
* data. `source` carries the generated JS, which is handy when debugging.
|
|
6195
|
+
*/
|
|
6196
|
+
type CompiledTemplate = ((data: object) => string) & {
|
|
6197
|
+
source?: string;
|
|
6198
|
+
};
|
|
6199
|
+
declare function tmpl(text: string, data: object, objectName?: string): string;
|
|
6200
|
+
declare function tmpl(text: string, data?: undefined, objectName?: string): CompiledTemplate;
|
|
5984
6201
|
|
|
5985
6202
|
/**
|
|
5986
6203
|
* Watches the service worker for a newly deployed version and exposes it as a simple
|
|
@@ -5993,11 +6210,17 @@ declare const tmpl: (text: string, data?: any, objectName?: string) => any;
|
|
|
5993
6210
|
* Harmless without a service worker: the checks fail and are logged as warnings.
|
|
5994
6211
|
*/
|
|
5995
6212
|
declare class UpdateService {
|
|
6213
|
+
private stable;
|
|
5996
6214
|
private appRef;
|
|
5997
6215
|
private swUpdate;
|
|
5998
|
-
|
|
5999
|
-
constructor(appRef: ApplicationRef, swUpdate: SwUpdate);
|
|
6216
|
+
constructor();
|
|
6000
6217
|
private _available$;
|
|
6218
|
+
/**
|
|
6219
|
+
* Asks the service worker whether a new version is available. Swallows the
|
|
6220
|
+
* failure raised when no service worker is registered, which is the normal
|
|
6221
|
+
* case in development.
|
|
6222
|
+
*/
|
|
6223
|
+
private _checkForUpdate;
|
|
6001
6224
|
/**
|
|
6002
6225
|
* Whether a new version is ready to be activated. Starts at `false`, becomes `true` on
|
|
6003
6226
|
* `VERSION_READY`, and returns to `false` once the user activates or dismisses it.
|
|
@@ -6024,5 +6247,5 @@ declare class UpdateComponent {
|
|
|
6024
6247
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UpdateComponent, "data-update", never, {}, {}, never, never, true, never>;
|
|
6025
6248
|
}
|
|
6026
6249
|
|
|
6027
|
-
export { AuthInterceptor, AuthServiceBase, BanAdapter, BaseFieldManager, BootstrapDataDisplayConfig, BreadcrumbComponent, ChoicePipe, Collection, CollectionMock, DATA_API_URL, DATA_AUTH_PARAMS, DATA_AUTH_SERVICE, DATA_AUTH_URLS, DATA_AUTH_USER_SERVICE, DATA_DISPLAY_CONFIG, DATA_MAX_TRANSFERSTATE_TIME, DATA_MESSAGE_SOUNDS, DEFAULT_TIMEOUTS, DataBackend, DataMessageService, DataModel, DataUploaderService, DispeditComponent, FactorPipe, FactorcPipe, FkselectComponent, FlagsComponent, Jwt, Link, M2mselectComponent, Message, MessageZoneComponent, ModelList, ModelListAutocompleteFilter, ModelListAutocompleteMultiFilter, ModelListDateFilter, ModelListDatetimeFilter, ModelListDatetimerangeFilter, ModelListFieldHeaderComponent, ModelListFieldsSelectorComponent, ModelListFilter, ModelListFilterGroup, ModelListFilters, ModelListFiltersComponent, ModelListFiltersSelectComponent, ModelListFlagsFilter, ModelListGeodistanceFilter, ModelListNumberFilter, ModelListNumberOperations, ModelListPaginatorComponent, ModelListSelectFilter, ModelListSelectMultiFilter, ModelListService, ModelListSorterComponent, ModelListTextFilter, ModelListTreeFilter, NavDriver, NgFileDropDirective, NgFileSelectDirective, NgxUploaderModule, PChoicePipe, PFactorPipe, PFactorcPipe, Queryset, RData, STATUS, SafeDeleteComponent, TYPE, TabMemoryService, UpdateComponent, UpdateService, UploadStatus, booleanField, charField, computedField, dateField, datetimeField, decimalField, detailsField, emailField, floatField, foreignKeyField, humanizeBytes, integerField, isValue, manyToManyField, passwordField, primaryField, reverseForeignKeyField, slugify, strToNumber, textField, tmpl };
|
|
6028
|
-
export type { AuthParams, BanResults, BaseRouteParams, BlobFile, CustomField, DataDisplayConfig, DataModelFields, DataModelType, FakeDeleteResult, FieldsParams, FilterData, FilterDefaults, FiltersParams, GeoSearchResult, GetFlagsResult, IActionParams, ICollectionCacheParams, IFlagItem, IHttpMethod, IJwtBaseData, IJwtRefreshResponseJson, IJwtResponseJson, IModelListMessage, IPathTreeItem, IQueryFullResponse, IQueryMeta, IQueryMetaNav, IQueryMetaNavParams, IQueryNav, IQuerysetOptions, ISoundTypes, ModelListAutocompleteMultiParams, ModelListAutocompleteParams, ModelListFilterParams, ModelListFlagsFilterParams, ModelListGeodistanceFilterParams, ModelListMultiSelectFilterParams, ModelListNumberFilterParams, ModelListParams, ModelListSelectFilterParams, ModelListTreeParams, OutFilterData, PaginationParams, RouteConfigItem, RouteFn, RoutesConfig, RoutesDefinition, SortData, SorterDefaults, StrictRoutes, TplFn, TplFun, UploadFile, UploadInput, UploadOutput, UploadProgress, UploaderOptions };
|
|
6250
|
+
export { AuthInterceptor, AuthServiceBase, BanAdapter, BaseFieldManager, BootstrapDataDisplayConfig, BreadcrumbComponent, ChoicePipe, Collection, CollectionMock, DATA_API_URL, DATA_AUTH_PARAMS, DATA_AUTH_SERVICE, DATA_AUTH_URLS, DATA_AUTH_USER_SERVICE, DATA_DISPLAY_CONFIG, DATA_MAX_TRANSFERSTATE_TIME, DATA_MESSAGE_SOUNDS, DEFAULT_TIMEOUTS, DataBackend, DataMessageService, DataModel, DataUploaderService, DispeditComponent, FactorPipe, FactorcPipe, FieldEditorBase, FkselectComponent, FlagsComponent, Jwt, Link, M2mselectComponent, Message, MessageZoneComponent, ModelList, ModelListAutocompleteFilter, ModelListAutocompleteMultiFilter, ModelListDateFilter, ModelListDatetimeFilter, ModelListDatetimerangeFilter, ModelListFieldHeaderComponent, ModelListFieldsSelectorComponent, ModelListFilter, ModelListFilterGroup, ModelListFilters, ModelListFiltersComponent, ModelListFiltersSelectComponent, ModelListFlagsFilter, ModelListGeodistanceFilter, ModelListNumberFilter, ModelListNumberOperations, ModelListPaginatorComponent, ModelListSelectFilter, ModelListSelectMultiFilter, ModelListService, ModelListSorterComponent, ModelListTextFilter, ModelListTreeFilter, NavDriver, NgFileDropDirective, NgFileSelectDirective, NgxUploaderModule, PChoicePipe, PFactorPipe, PFactorcPipe, Queryset, RData, STATUS, SafeDeleteComponent, SafeHtmlPipe, TYPE, TabMemoryService, UpdateComponent, UpdateService, UploadStatus, asText, booleanField, charField, computedField, dateField, datetimeField, decimalField, detailsField, emailField, fieldValues, floatField, foreignKeyField, humanizeBytes, installEditorDomShims, integerField, isValue, manyToManyField, passwordField, primaryField, reverseForeignKeyField, slugify, strToNumber, textField, tmpl, uniqueId };
|
|
6251
|
+
export type { AuthParams, BanResults, BaseRouteParams, BlobFile, CompiledTemplate, CustomField, DataDisplayConfig, DataModelFields, DataModelType, FakeDeleteResult, FieldsParams, FilterData, FilterDefaults, FilterValue, FiltersParams, GeoSearchResult, GetFlagsResult, IActionParams, ICollectionCacheParams, IFlagItem, IHttpMethod, IJwtBaseData, IJwtRefreshResponseJson, IJwtResponseJson, IModelListMessage, IPathTreeItem, IQueryFullResponse, IQueryMeta, IQueryMetaNav, IQueryMetaNavParams, IQueryNav, IQuerysetOptions, ISoundTypes, ModelListAutocompleteMultiParams, ModelListAutocompleteParams, ModelListFilterParams, ModelListFlagsFilterParams, ModelListGeodistanceFilterParams, ModelListMultiSelectFilterParams, ModelListNumberFilterParams, ModelListParams, ModelListSelectFilterParams, ModelListTreeParams, OutFilterData, PaginationParams, RouteConfigItem, RouteFn, RoutesConfig, RoutesDefinition, SortData, SorterDefaults, StrictRoutes, TplFn, TplFun, UploadFile, UploadInput, UploadOutput, UploadProgress, UploaderOptions };
|