@solidev/data 1.0.0 → 1.1.0
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 +27 -0
- package/README.md +40 -44
- package/fesm2022/solidev-data-mdedit.mjs +668 -0
- package/fesm2022/solidev-data-mdedit.mjs.map +1 -0
- package/fesm2022/solidev-data-richedit.mjs +1119 -36
- package/fesm2022/solidev-data-richedit.mjs.map +1 -1
- package/fesm2022/solidev-data.mjs +832 -721
- package/fesm2022/solidev-data.mjs.map +1 -1
- package/package.json +20 -2
- package/types/solidev-data-mdedit.d.ts +277 -0
- package/types/solidev-data-richedit.d.ts +283 -9
- package/types/solidev-data.d.ts +832 -781
package/types/solidev-data.d.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
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';
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* Base URL of the REST API every {@link Collection} builds its endpoints on.
|
|
@@ -70,15 +69,13 @@ interface DataDisplayConfig {
|
|
|
70
69
|
* `"inline"` renders the value in flow, `"dd"` renders it as a definition
|
|
71
70
|
* list entry.
|
|
72
71
|
*/
|
|
73
|
-
defaultMode:
|
|
72
|
+
defaultMode: 'inline' | 'dd';
|
|
74
73
|
/**
|
|
75
74
|
* Class string per editor type, keyed by the editor names used in
|
|
76
75
|
* `DISPEDIT_EDITOR_TYPES` (e.g. `"input.text"`, `"select"`). A missing key
|
|
77
76
|
* simply yields no class.
|
|
78
77
|
*/
|
|
79
|
-
inputClasses:
|
|
80
|
-
[index: string]: string;
|
|
81
|
-
};
|
|
78
|
+
inputClasses: Record<string, string>;
|
|
82
79
|
};
|
|
83
80
|
}
|
|
84
81
|
/**
|
|
@@ -113,476 +110,517 @@ declare const BootstrapDataDisplayConfig: DataDisplayConfig;
|
|
|
113
110
|
declare const DATA_DISPLAY_CONFIG: InjectionToken<DataDisplayConfig>;
|
|
114
111
|
|
|
115
112
|
/**
|
|
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.
|
|
113
|
+
* The HTTP layer every {@link Collection} sits on: it owns the API base URL,
|
|
114
|
+
* decides the headers, and optionally serves GET responses out of Angular's
|
|
115
|
+
* `TransferState` during SSR hydration.
|
|
131
116
|
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
117
|
+
* Collections never touch `HttpClient` directly, which makes this the one place
|
|
118
|
+
* to hook cross-cutting request concerns. The usual reason to care about this
|
|
119
|
+
* class is {@link headers}: subclass it, override that method to inject an auth
|
|
120
|
+
* token, and provide the subclass in place of the default.
|
|
135
121
|
*
|
|
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.
|
|
122
|
+
* Requires {@link DATA_API_URL}. TransferState caching applies to GET only, and
|
|
123
|
+
* only when {@link DATA_MAX_TRANSFERSTATE_TIME} is provided and greater than
|
|
124
|
+
* zero — see {@link _cachedGet} for the exact conditions.
|
|
154
125
|
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
126
|
+
* Dependencies are resolved with `inject()`, so a subclass declares **no
|
|
127
|
+
* constructor**. To point one at a different API — a second backend alongside
|
|
128
|
+
* the main one — override {@link apiUrl} rather than passing a URL through
|
|
129
|
+
* `super()`; {@link maxTransferstateTime} is overridable the same way.
|
|
159
130
|
*
|
|
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.).
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* @Injectable({ providedIn: 'root' })
|
|
134
|
+
* export class AuthBackend extends DataBackend {
|
|
135
|
+
* protected override headers(headers: { [k: string]: string }) {
|
|
136
|
+
* return { ...super.headers(headers), Authorization: `Bearer ${token}` };
|
|
137
|
+
* }
|
|
138
|
+
* }
|
|
176
139
|
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
140
|
+
* @Injectable({ providedIn: 'root' })
|
|
141
|
+
* export class SupportBackend extends DataBackend {
|
|
142
|
+
* public override get apiUrl(): string {
|
|
143
|
+
* return 'https://support.example.com/api';
|
|
144
|
+
* }
|
|
145
|
+
* }
|
|
179
146
|
*
|
|
180
|
-
*
|
|
147
|
+
* providers: [
|
|
148
|
+
* { provide: DATA_API_URL, useValue: 'https://api.example.com' },
|
|
149
|
+
* { provide: DataBackend, useClass: AuthBackend },
|
|
150
|
+
* ];
|
|
151
|
+
* ```
|
|
181
152
|
*/
|
|
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;
|
|
153
|
+
declare class DataBackend {
|
|
196
154
|
/**
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
* Beware: combining `required: true` with no `defaultValue` throws at class
|
|
201
|
-
* definition time — see {@link BaseFieldManager.getDefaultValue}.
|
|
155
|
+
* Instantiation timestamp, used as the origin of the TransferState validity
|
|
156
|
+
* window (see {@link _cachedGet}) — the window runs from backend creation, not
|
|
157
|
+
* from each entry's insertion.
|
|
202
158
|
*/
|
|
203
|
-
|
|
159
|
+
private _created;
|
|
160
|
+
private _http;
|
|
161
|
+
private _transferState;
|
|
162
|
+
private _platform;
|
|
163
|
+
private _apiUrl;
|
|
164
|
+
private _maxTransferstateTime;
|
|
204
165
|
/**
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
166
|
+
* Base URL every collection URL is built on, as provided via
|
|
167
|
+
* {@link DATA_API_URL}. Read by `Collection.getUrl()`; exposed so custom
|
|
168
|
+
* collections can build URLs the same way.
|
|
208
169
|
*/
|
|
209
|
-
|
|
170
|
+
get apiUrl(): string;
|
|
210
171
|
/**
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* fresh array/date per instance instead of a shared one.
|
|
172
|
+
* TransferState window in ms, from {@link DATA_MAX_TRANSFERSTATE_TIME}; `0`
|
|
173
|
+
* disables the cache. Overridable for the same reason as {@link apiUrl}.
|
|
214
174
|
*/
|
|
215
|
-
|
|
175
|
+
protected get maxTransferstateTime(): number;
|
|
216
176
|
/**
|
|
217
|
-
*
|
|
177
|
+
* Issues an arbitrary request and returns the parsed JSON body.
|
|
218
178
|
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
179
|
+
* The general-purpose entry point, used by `Collection.action()` and
|
|
180
|
+
* `Collection.raw()`. GET requests are routed through {@link _cachedGet} and so
|
|
181
|
+
* may be answered from TransferState; every other method goes straight to the
|
|
182
|
+
* network and carries the body.
|
|
183
|
+
*
|
|
184
|
+
* @param collection collection the request belongs to; consulted for its
|
|
185
|
+
* `useTransferState` flag
|
|
186
|
+
* @param method HTTP method
|
|
187
|
+
* @param url absolute URL, normally from `Collection.getUrl()`
|
|
188
|
+
* @param body JSON body; ignored for GET
|
|
189
|
+
* @param params query parameters
|
|
190
|
+
* @param headers extra headers, passed through {@link headers}
|
|
191
|
+
*
|
|
192
|
+
* @return an observable of the response body
|
|
223
193
|
*/
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Runtime behaviour of a single field: one manager instance is built per
|
|
228
|
-
* decorated property, at class definition time, and cached in the prototype's
|
|
229
|
-
* metadata map. Everything the library does with a field — serialise it,
|
|
230
|
-
* validate it, build its form control, pick its widget — goes through here.
|
|
231
|
-
*
|
|
232
|
-
* Subclass it only to add a genuinely new field type; the shipped managers
|
|
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;
|
|
194
|
+
action<T extends DataModel, RT>(collection: Collection<T>, method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', url: string, { body, params, headers }?: IActionParams): Observable<RT>;
|
|
249
195
|
/**
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
196
|
+
* Issues a request whose response is taken as binary rather than JSON.
|
|
197
|
+
*
|
|
198
|
+
* Backs `Collection.blob()`; use that instead of calling this directly. Never
|
|
199
|
+
* cached through TransferState, whatever the method.
|
|
200
|
+
*
|
|
201
|
+
* @param collection collection the request belongs to; not used by this method
|
|
202
|
+
* @param method HTTP method
|
|
203
|
+
* @param url absolute URL
|
|
204
|
+
* @param body JSON body
|
|
205
|
+
* @param params query parameters
|
|
206
|
+
* @param headers extra headers, passed through {@link headers}
|
|
207
|
+
*
|
|
208
|
+
* @return an observable of the response as a `Blob`
|
|
253
209
|
*/
|
|
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);
|
|
210
|
+
blob<T extends DataModel>(collection: Collection<T>, method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', url: string, { body, params, headers }?: IActionParams): Observable<Blob>;
|
|
259
211
|
/**
|
|
260
|
-
*
|
|
212
|
+
* Full-replacement write (HTTP PUT). Provided for completeness — the CRUD path
|
|
213
|
+
* in `Collection` uses {@link post}/{@link patch} instead, so this is only
|
|
214
|
+
* reached by callers that need PUT semantics explicitly.
|
|
261
215
|
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
216
|
+
* @param collection collection the request belongs to; not used by this method
|
|
217
|
+
* @param url absolute URL
|
|
218
|
+
* @param body JSON body
|
|
219
|
+
* @param params query parameters
|
|
220
|
+
* @param headers extra headers, passed through {@link headers}
|
|
267
221
|
*/
|
|
268
|
-
|
|
222
|
+
put<T extends DataModel>(collection: Collection<T>, url: string, { body, params, headers }?: IActionParams): Observable<T>;
|
|
269
223
|
/**
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
224
|
+
* Creates a record (HTTP POST). Chosen by `Collection.save()`/`update()` when
|
|
225
|
+
* the model has no `id`.
|
|
226
|
+
*
|
|
227
|
+
* @param collection collection the request belongs to; not used by this method
|
|
228
|
+
* @param url absolute URL, normally the collection's list URL
|
|
229
|
+
* @param body JSON body
|
|
230
|
+
* @param params query parameters
|
|
231
|
+
* @param headers extra headers, passed through {@link headers}
|
|
232
|
+
* @returns the created record's JSON, expected to include the assigned `id`
|
|
273
233
|
*/
|
|
274
|
-
|
|
234
|
+
post<T extends DataModel>(collection: Collection<T>, url: string, { body, params, headers }?: IActionParams): Observable<Partial<T>>;
|
|
275
235
|
/**
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
* `required` field with no `defaultValue` throws here, at decoration time.
|
|
236
|
+
* Partially updates a record (HTTP PATCH). Chosen by
|
|
237
|
+
* `Collection.save()`/`update()` when the model already has an `id`.
|
|
279
238
|
*
|
|
280
|
-
* @param
|
|
239
|
+
* @param collection collection the request belongs to; not used by this method
|
|
240
|
+
* @param url absolute URL, normally the record's detail URL
|
|
241
|
+
* @param body JSON body, holding only the fields to change
|
|
242
|
+
* @param params query parameters
|
|
243
|
+
* @param headers extra headers, passed through {@link headers}
|
|
281
244
|
*/
|
|
282
|
-
|
|
245
|
+
patch<T extends DataModel>(collection: Collection<T>, url: string, { body, params, headers }?: IActionParams): Observable<Partial<T>>;
|
|
283
246
|
/**
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
247
|
+
* Deletes a record (HTTP DELETE). Backs `Collection.delete()`.
|
|
248
|
+
*
|
|
249
|
+
* @param collection collection the request belongs to; not used by this method
|
|
250
|
+
* @param url absolute URL of the record
|
|
251
|
+
* @param params query parameters
|
|
252
|
+
* @param headers extra headers, passed through {@link headers}
|
|
287
253
|
*/
|
|
288
|
-
|
|
254
|
+
delete<T extends DataModel, R>(collection: Collection<T>, url: string, { params, headers }?: IActionParams): Observable<R>;
|
|
289
255
|
/**
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
* when there is no separator.
|
|
293
|
-
*/
|
|
294
|
-
get fname(): string;
|
|
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}.
|
|
256
|
+
* Performs a GET, transparently replaying the server-rendered response from
|
|
257
|
+
* `TransferState` when that is still allowed.
|
|
299
258
|
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
259
|
+
* This is what stops an SSR app from re-fetching, in the browser, everything it
|
|
260
|
+
* already fetched on the server to render the page. Entries are keyed on URL +
|
|
261
|
+
* params + resolved headers, so requests differing in any of those do not share
|
|
262
|
+
* a slot.
|
|
302
263
|
*
|
|
303
|
-
*
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
* override it to coerce (`boolean`), parse (`date`) or instantiate
|
|
310
|
-
* (`details`).
|
|
264
|
+
* A cached value is **read** only when all of these hold: the collection has
|
|
265
|
+
* `useTransferState`, {@link DATA_MAX_TRANSFERSTATE_TIME} is greater than zero,
|
|
266
|
+
* the key is present, and less than that many milliseconds have passed since
|
|
267
|
+
* *this backend instance was created*. That last condition makes the window a
|
|
268
|
+
* one-shot hydration budget rather than a per-entry TTL: once it lapses, nothing
|
|
269
|
+
* is served from TransferState again for the life of the backend.
|
|
311
270
|
*
|
|
312
|
-
*
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Converts the model value back into its JSON representation for save.
|
|
317
|
-
* The base implementation passes the data straight through.
|
|
271
|
+
* A value is **written** only when the collection has `useTransferState`, the
|
|
272
|
+
* code is running on the server, and the window is greater than zero. So in the
|
|
273
|
+
* browser this degrades to a plain, uncached `HttpClient.get`.
|
|
318
274
|
*
|
|
319
|
-
* @param
|
|
275
|
+
* @param collection collection the request belongs to; consulted for `useTransferState`
|
|
276
|
+
* @param url absolute URL
|
|
277
|
+
* @param params query parameters
|
|
278
|
+
* @param headers extra headers, passed through {@link headers}
|
|
320
279
|
*/
|
|
321
|
-
|
|
280
|
+
_cachedGet<T extends DataModel, RT>(collection: Collection<T>, url: string, { params, headers }?: IActionParams): Observable<RT>;
|
|
322
281
|
/**
|
|
323
|
-
*
|
|
324
|
-
*
|
|
282
|
+
* Fetches a single record's JSON. Backs `Collection.fetch()`, and is
|
|
283
|
+
* TransferState-cacheable via {@link _cachedGet}.
|
|
325
284
|
*
|
|
326
|
-
* @param
|
|
327
|
-
* @param
|
|
285
|
+
* @param collection collection the request belongs to
|
|
286
|
+
* @param url absolute URL of the record
|
|
287
|
+
* @param params query parameters
|
|
288
|
+
* @param headers extra headers
|
|
328
289
|
*/
|
|
329
|
-
|
|
290
|
+
get<T extends DataModel>(collection: Collection<T>, url: string, { params, headers }?: IActionParams): Observable<Partial<T>>;
|
|
330
291
|
/**
|
|
331
|
-
*
|
|
332
|
-
* `
|
|
292
|
+
* Fetches a list endpoint's raw JSON — including the pagination envelope, which
|
|
293
|
+
* `Collection.list()` then unwraps. Identical to {@link get} apart from the
|
|
294
|
+
* declared return type; both funnel into {@link _cachedGet}.
|
|
333
295
|
*
|
|
334
|
-
* @param
|
|
296
|
+
* @param collection collection the request belongs to
|
|
297
|
+
* @param url absolute URL of the list endpoint
|
|
298
|
+
* @param params query parameters, typically the queryset's filters and paging
|
|
299
|
+
* @param headers extra headers
|
|
335
300
|
*/
|
|
336
|
-
|
|
301
|
+
list<T extends DataModel>(collection: Collection<T>, url: string, { params, headers }?: IActionParams): Observable<{
|
|
302
|
+
results: Partial<T>[];
|
|
303
|
+
}>;
|
|
337
304
|
/**
|
|
338
|
-
*
|
|
339
|
-
* required, nothing otherwise. Subclasses call it and push their own.
|
|
305
|
+
* Resolves the headers actually sent with a request.
|
|
340
306
|
*
|
|
341
|
-
*
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
*
|
|
346
|
-
*
|
|
307
|
+
* **The designated extension point of this class.** The base implementation
|
|
308
|
+
* just copies what it is given; subclasses override it to add headers that
|
|
309
|
+
* every request needs — most often an `Authorization` token — and then get
|
|
310
|
+
* provided in place of `DataBackend`. Doing it here rather than in an HTTP
|
|
311
|
+
* interceptor keeps the headers part of the TransferState cache key, so
|
|
312
|
+
* responses fetched under different credentials do not collide.
|
|
347
313
|
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
* defined (module evaluation), not when a model is instantiated — a
|
|
351
|
-
* `required` field without a default breaks the app at import time.
|
|
314
|
+
* Implementations should stay pure and synchronous: this is called once per
|
|
315
|
+
* request, and for GETs its result feeds the cache key.
|
|
352
316
|
*
|
|
353
|
-
* @param
|
|
354
|
-
* @
|
|
355
|
-
* @protected
|
|
317
|
+
* @param headers per-request headers supplied by the caller
|
|
318
|
+
* @returns the complete header set to send
|
|
356
319
|
*/
|
|
357
|
-
protected
|
|
320
|
+
protected headers(headers: Record<string, string>): Record<string, string>;
|
|
321
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataBackend, never>;
|
|
322
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<DataBackend>;
|
|
358
323
|
}
|
|
324
|
+
|
|
325
|
+
/** HTTP verbs this library issues. */
|
|
326
|
+
type IHttpMethod = 'POST' | 'GET' | 'DELETE' | 'PUT' | 'PATCH';
|
|
359
327
|
/**
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
328
|
+
* Per-request options shared by every {@link Collection} and {@link DataBackend}
|
|
329
|
+
* call: body, headers and query parameters.
|
|
330
|
+
*
|
|
331
|
+
* All members are optional, so `{}` is a valid "nothing special" argument.
|
|
363
332
|
*/
|
|
364
|
-
interface
|
|
365
|
-
/**
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
|
|
333
|
+
interface IActionParams {
|
|
334
|
+
/** JSON body; ignored by GET/DELETE requests. */
|
|
335
|
+
body?: unknown;
|
|
336
|
+
/** Extra headers, merged on top of whatever the backend's `headers()` adds. */
|
|
337
|
+
headers?: Record<string, string>;
|
|
338
|
+
/** Query string parameters. */
|
|
339
|
+
params?: Record<string, string>;
|
|
340
|
+
/**
|
|
341
|
+
* Expected response type. Note that the backend does not currently read this:
|
|
342
|
+
* `DataBackend.action()` always parses JSON and `DataBackend.blob()` always
|
|
343
|
+
* requests a blob. Use `Collection.blob()` to get binary data.
|
|
344
|
+
*/
|
|
345
|
+
responseType?: 'json' | 'blob';
|
|
373
346
|
}
|
|
374
347
|
/**
|
|
375
|
-
* Shape
|
|
376
|
-
*
|
|
377
|
-
*
|
|
348
|
+
* Shape for describing per-collection cache tuning.
|
|
349
|
+
*
|
|
350
|
+
* Currently unused by the runtime — TransferState behaviour is driven by
|
|
351
|
+
* `Collection.useTransferState` plus the `DATA_MAX_TRANSFERSTATE_TIME` token.
|
|
378
352
|
*/
|
|
379
|
-
|
|
380
|
-
|
|
353
|
+
interface ICollectionCacheParams {
|
|
354
|
+
transferState?: {
|
|
355
|
+
enabled: boolean;
|
|
356
|
+
maxTime: number;
|
|
357
|
+
maxCount: number;
|
|
358
|
+
};
|
|
359
|
+
}
|
|
381
360
|
/**
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
361
|
+
* Constructor signature of a model class, letting a collection instantiate `T`
|
|
362
|
+
* without knowing it — this is the `model` argument passed to
|
|
363
|
+
* {@link Collection}'s constructor.
|
|
364
|
+
*/
|
|
365
|
+
type DataModelType<T extends DataModel> = new (_coll?: Collection<T>) => T;
|
|
366
|
+
/**
|
|
367
|
+
* Binds a {@link DataModel} class to a REST endpoint and provides the CRUD
|
|
368
|
+
* operations over it.
|
|
385
369
|
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
370
|
+
* A collection is the seam between models and HTTP: it knows the path, builds
|
|
371
|
+
* URLs, hands raw JSON to the model for deserialization, and returns typed
|
|
372
|
+
* instances that carry a back-reference to it (so `thing.save()` works). One
|
|
373
|
+
* collection per endpoint, normally declared as a root-provided service.
|
|
390
374
|
*
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
375
|
+
* For anything involving filtering, sorting or pagination, go through
|
|
376
|
+
* {@link queryset} rather than {@link list}.
|
|
377
|
+
*
|
|
378
|
+
* The endpoint is assumed to follow Django REST Framework conventions:
|
|
379
|
+
* `/path` for the list, `/path/<id>` for a record, `/path/<id>/<action>` for
|
|
380
|
+
* custom actions, and a *paginated* list response (see {@link list}).
|
|
394
381
|
*
|
|
395
382
|
* @example
|
|
396
383
|
* ```ts
|
|
397
384
|
* @Injectable({ providedIn: 'root' })
|
|
398
|
-
* export class
|
|
399
|
-
*
|
|
400
|
-
*
|
|
385
|
+
* export class ThingService extends Collection<Thing> {
|
|
386
|
+
* constructor() {
|
|
387
|
+
* super(inject(DataBackend), '/path/to/things', Thing);
|
|
401
388
|
* }
|
|
402
389
|
* }
|
|
403
390
|
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
* ];
|
|
391
|
+
* // then
|
|
392
|
+
* things.fetch(1).subscribe((thing) => ...);
|
|
393
|
+
* things.queryset().filter({ status: 'active' }).get().subscribe((list) => ...);
|
|
408
394
|
* ```
|
|
409
395
|
*/
|
|
410
|
-
declare class
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
private _apiUrl;
|
|
415
|
-
private _maxTransferstateTime;
|
|
396
|
+
declare class Collection<T extends DataModel> {
|
|
397
|
+
protected backend: DataBackend;
|
|
398
|
+
protected path: string;
|
|
399
|
+
model: DataModelType<T>;
|
|
416
400
|
/**
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
401
|
+
* Whether GET responses for this collection may be served from / stored in
|
|
402
|
+
* Angular's `TransferState` during SSR hydration.
|
|
403
|
+
*
|
|
404
|
+
* On by default, but only ever takes effect when `DATA_MAX_TRANSFERSTATE_TIME`
|
|
405
|
+
* is provided and greater than zero. Set it to `false` on collections whose
|
|
406
|
+
* data is user-specific or must not be embedded in the server-rendered HTML.
|
|
420
407
|
*/
|
|
421
|
-
|
|
408
|
+
useTransferState: boolean;
|
|
422
409
|
/**
|
|
423
|
-
* @param
|
|
424
|
-
* @param
|
|
425
|
-
*
|
|
426
|
-
* @param
|
|
427
|
-
* @param _maxTransferstateTime TransferState window in ms; optional, `0`
|
|
428
|
-
* (the default) disables caching entirely
|
|
410
|
+
* @param backend HTTP layer; supplies the API base URL and applies auth headers
|
|
411
|
+
* @param path endpoint path appended to the backend's `apiUrl`, leading slash
|
|
412
|
+
* included and trailing slash omitted (e.g. `'/path/to/things'`)
|
|
413
|
+
* @param model model class this collection instantiates
|
|
429
414
|
*/
|
|
430
|
-
constructor(
|
|
415
|
+
constructor(backend: DataBackend, path: string, model: DataModelType<T>);
|
|
431
416
|
/**
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
417
|
+
* Builds a new, unsaved model instance attached to this collection.
|
|
418
|
+
*
|
|
419
|
+
* Use it to back a creation form: the returned instance has no `id`, so the
|
|
420
|
+
* first `save()` POSTs it. Values passed in `data` go through the field
|
|
421
|
+
* managers' deserializers, exactly as if they had come from the API.
|
|
422
|
+
*
|
|
423
|
+
* @param data initial field values; omit for an empty instance
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```ts
|
|
427
|
+
* const thing = things.create({ name: 'draft' });
|
|
428
|
+
* thing.save().subscribe(); // POST /path/to/things
|
|
429
|
+
* ```
|
|
435
430
|
*/
|
|
436
|
-
|
|
431
|
+
create(data?: Partial<T>): T;
|
|
437
432
|
/**
|
|
438
|
-
*
|
|
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.
|
|
433
|
+
* Turns raw API JSON into model instances attached to this collection.
|
|
444
434
|
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
* @param body JSON body; ignored for GET
|
|
450
|
-
* @param params query parameters
|
|
451
|
-
* @param headers extra headers, passed through {@link headers}
|
|
435
|
+
* Every read path funnels through here, and the attachment is the point: the
|
|
436
|
+
* resulting instances can `save()`/`update()`/`action()` themselves. Call it
|
|
437
|
+
* directly when you have JSON from somewhere other than this collection's own
|
|
438
|
+
* requests (a websocket push, an embedded payload, a fixture).
|
|
452
439
|
*
|
|
453
|
-
* @
|
|
440
|
+
* @param data one JSON object, or an array of them
|
|
454
441
|
*/
|
|
455
|
-
|
|
442
|
+
fromJson(data: Partial<T>): T;
|
|
443
|
+
fromJson(data: Partial<T>[]): T[];
|
|
456
444
|
/**
|
|
457
|
-
*
|
|
445
|
+
* Opens a filterable, sortable, paginated view over this collection.
|
|
458
446
|
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
447
|
+
* The normal way to read lists: a {@link Queryset} accumulates query state and
|
|
448
|
+
* exposes results/loading/meta as observables suitable for binding straight
|
|
449
|
+
* into a template. Each call returns an independent queryset, so a component
|
|
450
|
+
* showing two filtered lists of the same endpoint creates two.
|
|
461
451
|
*
|
|
462
|
-
* @param
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
452
|
+
* @param options queryset behaviour; see {@link IQuerysetOptions}
|
|
453
|
+
*/
|
|
454
|
+
queryset(options?: IQuerysetOptions): Queryset<T>;
|
|
455
|
+
/**
|
|
456
|
+
* Retrieves a single record by primary key and returns it as a model.
|
|
457
|
+
*
|
|
458
|
+
* @param id primary key
|
|
459
|
+
* @param prefix inserted between the collection path and the id, for endpoints
|
|
460
|
+
* nested under a segment
|
|
461
|
+
* @param suffix appended after the id, e.g. `'/detail'`
|
|
466
462
|
* @param params query parameters
|
|
467
|
-
* @param headers extra headers
|
|
463
|
+
* @param headers extra headers
|
|
468
464
|
*
|
|
469
|
-
* @
|
|
465
|
+
* @example
|
|
466
|
+
* ```ts
|
|
467
|
+
* things.fetch(42).subscribe((thing) => ...); // GET /path/to/things/42
|
|
468
|
+
* ```
|
|
470
469
|
*/
|
|
471
|
-
|
|
470
|
+
fetch(id: number, { prefix, suffix, params, headers, }?: {
|
|
471
|
+
prefix?: string;
|
|
472
|
+
suffix?: string;
|
|
473
|
+
params?: Record<string, string>;
|
|
474
|
+
headers?: Record<string, string>;
|
|
475
|
+
}): Observable<T>;
|
|
472
476
|
/**
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
* reached by callers that need PUT semantics explicitly.
|
|
477
|
+
* Calls a custom (non-CRUD) endpoint on this collection, either on one record
|
|
478
|
+
* or on the collection as a whole, and returns the raw JSON response.
|
|
476
479
|
*
|
|
477
|
-
*
|
|
478
|
-
*
|
|
480
|
+
* This is the DRF `@action` convention. `DataModel.action()` delegates here;
|
|
481
|
+
* call this directly for collection-level actions, which have no model.
|
|
482
|
+
*
|
|
483
|
+
* @param model record to act on, targeting `/path/to/things/<id>/<action>`, or
|
|
484
|
+
* `null` for a collection-level action targeting `/path/to/things/<action>`
|
|
485
|
+
* @param method HTTP method
|
|
486
|
+
* @param action action name
|
|
479
487
|
* @param body JSON body
|
|
480
488
|
* @param params query parameters
|
|
481
|
-
* @param headers extra headers
|
|
489
|
+
* @param headers extra headers
|
|
482
490
|
*/
|
|
483
|
-
|
|
491
|
+
action<RT>(model: T | null, method: IHttpMethod, action: string, { body, params, headers }?: IActionParams): Observable<RT>;
|
|
484
492
|
/**
|
|
485
|
-
*
|
|
486
|
-
*
|
|
493
|
+
* Writes a whole record: POST to the list URL when the model has no `id`,
|
|
494
|
+
* PATCH to its detail URL when it does.
|
|
487
495
|
*
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
* @param
|
|
492
|
-
* @param
|
|
493
|
-
*
|
|
496
|
+
* Sends `model.toJson()`, i.e. every non-readonly field. Usually reached via
|
|
497
|
+
* `model.save()` rather than called directly.
|
|
498
|
+
*
|
|
499
|
+
* @param model record to persist
|
|
500
|
+
* @param updateModel feed the server's response back into `model` (defaults to
|
|
501
|
+
* `true`), which is how a freshly created record gets its `id`. The returned
|
|
502
|
+
* observable always emits a **separate** instance built from the response
|
|
503
|
+
* either way.
|
|
494
504
|
*/
|
|
495
|
-
|
|
505
|
+
save(model: T, { updateModel }?: {
|
|
506
|
+
updateModel?: boolean;
|
|
507
|
+
}): Observable<T>;
|
|
496
508
|
/**
|
|
497
|
-
*
|
|
498
|
-
*
|
|
509
|
+
* Writes only the named fields of a record, dispatching POST/PATCH on `id`
|
|
510
|
+
* exactly like {@link save}.
|
|
499
511
|
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
* @param
|
|
504
|
-
* @param
|
|
512
|
+
* Sends `model.toJson(fields)`, which restricts the payload to `fields` and
|
|
513
|
+
* does **not** filter readonly ones. Usually reached via `model.update()`.
|
|
514
|
+
*
|
|
515
|
+
* @param model record to persist
|
|
516
|
+
* @param fields field names to send; an empty list (the default) sends every
|
|
517
|
+
* non-readonly field, making this equivalent to {@link save}
|
|
518
|
+
* @param updateModel feed the server's response back into `model` (defaults to `true`)
|
|
505
519
|
*/
|
|
506
|
-
|
|
520
|
+
update(model: T, fields?: string[], { updateModel }?: {
|
|
521
|
+
updateModel?: boolean;
|
|
522
|
+
}): Observable<T>;
|
|
507
523
|
/**
|
|
508
|
-
* Deletes a record
|
|
524
|
+
* Deletes a record on the server. The local instance is left untouched — it is
|
|
525
|
+
* the caller's job to drop it from whatever list holds it.
|
|
509
526
|
*
|
|
510
|
-
* @param
|
|
511
|
-
*
|
|
527
|
+
* @param model record to delete; its `id` builds the URL, so an unsaved model
|
|
528
|
+
* would produce a request against the list URL
|
|
512
529
|
* @param params query parameters
|
|
513
|
-
* @param headers extra headers
|
|
530
|
+
* @param headers extra headers
|
|
514
531
|
*/
|
|
515
|
-
delete
|
|
532
|
+
delete(model: T, { params, headers }?: IActionParams): Observable<unknown>;
|
|
516
533
|
/**
|
|
517
|
-
*
|
|
518
|
-
* `TransferState` when that is still allowed.
|
|
519
|
-
*
|
|
520
|
-
* This is what stops an SSR app from re-fetching, in the browser, everything it
|
|
521
|
-
* already fetched on the server to render the page. Entries are keyed on URL +
|
|
522
|
-
* params + resolved headers, so requests differing in any of those do not share
|
|
523
|
-
* a slot.
|
|
534
|
+
* Fetches a list of records in one shot, discarding pagination metadata.
|
|
524
535
|
*
|
|
525
|
-
* A
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
* *this backend instance was created*. That last condition makes the window a
|
|
529
|
-
* one-shot hydration budget rather than a per-entry TTL: once it lapses, nothing
|
|
530
|
-
* is served from TransferState again for the life of the backend.
|
|
536
|
+
* A shortcut for the simple cases (a dropdown's options, a small fixed set).
|
|
537
|
+
* When you need paging, sorting, loading state or the result count, use
|
|
538
|
+
* {@link queryset} instead.
|
|
531
539
|
*
|
|
532
|
-
*
|
|
533
|
-
*
|
|
534
|
-
*
|
|
540
|
+
* **The response must be paginated**: this reads `result.results` and returns
|
|
541
|
+
* that array, so a DRF endpoint with pagination disabled — which answers with a
|
|
542
|
+
* bare JSON array — yields an error rather than a list. The endpoint's page size
|
|
543
|
+
* therefore also caps what you get back here; there is currently no way to point
|
|
544
|
+
* this at a different response key (see the `FIXME` in the implementation).
|
|
535
545
|
*
|
|
536
|
-
* @param
|
|
537
|
-
* @param
|
|
538
|
-
* @param
|
|
539
|
-
* @param
|
|
546
|
+
* @param query filter parameters
|
|
547
|
+
* @param prefix inserted before the suffix in the list URL
|
|
548
|
+
* @param suffix appended to the list URL, for sub-endpoints
|
|
549
|
+
* @param params extra query parameters, merged over `query`
|
|
550
|
+
* @param headers extra headers
|
|
540
551
|
*/
|
|
541
|
-
|
|
552
|
+
list(query?: FilterData, { prefix, suffix, params, headers, }?: {
|
|
553
|
+
prefix?: string;
|
|
554
|
+
suffix?: string;
|
|
555
|
+
params?: Record<string, string>;
|
|
556
|
+
headers?: Record<string, string>;
|
|
557
|
+
}): Observable<T[]>;
|
|
542
558
|
/**
|
|
543
|
-
*
|
|
544
|
-
*
|
|
559
|
+
* Calls a collection-level endpoint and returns the response body **unparsed**,
|
|
560
|
+
* without turning it into models.
|
|
545
561
|
*
|
|
546
|
-
*
|
|
547
|
-
*
|
|
562
|
+
* The escape hatch for responses that are not a list of records: aggregates,
|
|
563
|
+
* stats, export summaries. It is also what {@link Queryset} uses internally,
|
|
564
|
+
* since a queryset needs the pagination envelope that {@link list} throws away.
|
|
565
|
+
*
|
|
566
|
+
* @param method HTTP method; defaults to GET
|
|
567
|
+
* @param prefix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
568
|
+
* @param suffix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
548
569
|
* @param params query parameters
|
|
570
|
+
* @param body accepted but **not currently sent** — the implementation does not
|
|
571
|
+
* forward it to the backend, so non-GET calls needing a body must go through
|
|
572
|
+
* {@link action}
|
|
549
573
|
* @param headers extra headers
|
|
550
574
|
*/
|
|
551
|
-
|
|
575
|
+
raw<RT>({ method, prefix, suffix, params, body: _body, headers, }?: {
|
|
576
|
+
method?: IHttpMethod;
|
|
577
|
+
prefix?: string;
|
|
578
|
+
suffix?: string;
|
|
579
|
+
body?: unknown;
|
|
580
|
+
params?: Record<string, string>;
|
|
581
|
+
headers?: Record<string, string>;
|
|
582
|
+
}): Observable<RT>;
|
|
552
583
|
/**
|
|
553
|
-
*
|
|
554
|
-
* `Collection.list()` then unwraps. Identical to {@link get} apart from the
|
|
555
|
-
* declared return type; both funnel into {@link _cachedGet}.
|
|
584
|
+
* Calls a collection-level endpoint and returns the response as a `Blob`.
|
|
556
585
|
*
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
*
|
|
586
|
+
* Use it for binary or file downloads (CSV/XLSX/PDF exports) where the response
|
|
587
|
+
* must not be parsed as JSON.
|
|
588
|
+
*
|
|
589
|
+
* @param method HTTP method; defaults to GET
|
|
590
|
+
* @param prefix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
591
|
+
* @param suffix inserted in the URL as `collection_url/PREFIXSUFFIX`
|
|
592
|
+
* @param params query parameters
|
|
593
|
+
* @param body accepted but **not currently sent** — the implementation does not
|
|
594
|
+
* forward it to the backend
|
|
560
595
|
* @param headers extra headers
|
|
561
596
|
*/
|
|
562
|
-
|
|
597
|
+
blob<RT>({ method, prefix, suffix, params, body: _body, headers, }?: {
|
|
598
|
+
method?: IHttpMethod;
|
|
599
|
+
prefix?: string;
|
|
600
|
+
suffix?: string;
|
|
601
|
+
body?: unknown;
|
|
602
|
+
params?: Record<string, string>;
|
|
603
|
+
headers?: Record<string, string>;
|
|
604
|
+
}): Observable<Blob>;
|
|
563
605
|
/**
|
|
564
|
-
*
|
|
606
|
+
* Builds the absolute URL for this collection or one of its records.
|
|
565
607
|
*
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
* every request needs — most often an `Authorization` token — and then get
|
|
569
|
-
* provided in place of `DataBackend`. Doing it here rather than in an HTTP
|
|
570
|
-
* interceptor keeps the headers part of the TransferState cache key, so
|
|
571
|
-
* responses fetched under different credentials do not collide.
|
|
608
|
+
* Every request the collection makes goes through here, so overriding it is the
|
|
609
|
+
* supported way to bend URL construction (versioned or nested endpoints).
|
|
572
610
|
*
|
|
573
|
-
*
|
|
574
|
-
*
|
|
611
|
+
* Layout is `apiUrl + path` for the list, `apiUrl + path + '/' + prefix + id +
|
|
612
|
+
* suffix` for a record, and `apiUrl + path + '/' + prefix + suffix` for the list
|
|
613
|
+
* with affixes. Note the separating slash is only emitted when there is
|
|
614
|
+
* something after it, so a plain list URL has no trailing slash.
|
|
575
615
|
*
|
|
576
|
-
* @param
|
|
577
|
-
* @
|
|
616
|
+
* @param id primary key for a detail URL; `undefined` or `null` yields the list URL
|
|
617
|
+
* @param prefix inserted just before the id (or before the suffix)
|
|
618
|
+
* @param suffix appended at the very end
|
|
578
619
|
*/
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
};
|
|
584
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataBackend, [null, null, null, null, { optional: true; }]>;
|
|
585
|
-
static ɵprov: _angular_core.ɵɵInjectableDeclaration<DataBackend>;
|
|
620
|
+
getUrl(id?: number | null, { prefix, suffix }?: {
|
|
621
|
+
prefix?: string;
|
|
622
|
+
suffix?: string;
|
|
623
|
+
}): string;
|
|
586
624
|
}
|
|
587
625
|
|
|
588
626
|
/**
|
|
@@ -593,16 +631,17 @@ declare class DataBackend {
|
|
|
593
631
|
* that filter, which is what lets a form bind a cleared control straight to a
|
|
594
632
|
* queryset filter.
|
|
595
633
|
*/
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
634
|
+
/**
|
|
635
|
+
* A value a filter can hold: whatever goes on the wire for that field. A scalar
|
|
636
|
+
* for most filters, an array for the multi-valued ones, `null` for "cleared".
|
|
637
|
+
*/
|
|
638
|
+
type FilterValue = string | number | boolean | null | undefined | (string | number)[];
|
|
639
|
+
type FilterData = Record<string, string | number | boolean | undefined | null>;
|
|
599
640
|
/**
|
|
600
641
|
* Filter criteria flattened to strings, as they go on the wire. This is what
|
|
601
642
|
* {@link Queryset.getQueryParams} produces.
|
|
602
643
|
*/
|
|
603
|
-
|
|
604
|
-
[index: string]: string;
|
|
605
|
-
}
|
|
644
|
+
type OutFilterData = Record<string, string>;
|
|
606
645
|
/**
|
|
607
646
|
* A single ordering term: a field name, optionally prefixed with `-` to reverse
|
|
608
647
|
* it (`'name'`, `'-created'`) — the DRF `ordering` convention.
|
|
@@ -819,10 +858,10 @@ declare class Queryset<T extends DataModel> {
|
|
|
819
858
|
* request, so a paginator must call {@link get} afterwards.
|
|
820
859
|
*
|
|
821
860
|
* @param page 1-based page number
|
|
822
|
-
* @param
|
|
861
|
+
* @param _fragment currently ignored; reserved for the URL-syncing behaviour
|
|
823
862
|
* that is commented out in the implementation
|
|
824
863
|
*/
|
|
825
|
-
setPage(page?: number,
|
|
864
|
+
setPage(page?: number, _fragment?: string): Queryset<T>;
|
|
826
865
|
/**
|
|
827
866
|
* Stages which fields the API should return. Chainable; issues no request.
|
|
828
867
|
*
|
|
@@ -875,326 +914,276 @@ declare class Queryset<T extends DataModel> {
|
|
|
875
914
|
get(refresh?: boolean, sync?: boolean): Observable<T[]>;
|
|
876
915
|
}
|
|
877
916
|
|
|
878
|
-
/** HTTP verbs this library issues. */
|
|
879
|
-
type IHttpMethod = 'POST' | 'GET' | 'DELETE' | 'PUT' | 'PATCH';
|
|
880
917
|
/**
|
|
881
|
-
*
|
|
882
|
-
* call: body, headers and query parameters.
|
|
918
|
+
* A single selectable option for a `select` editor or a `choice` display.
|
|
883
919
|
*
|
|
884
|
-
*
|
|
920
|
+
* `value` is what is written to the model field; `desc` is the human-readable
|
|
921
|
+
* label rendered in the dropdown or in display mode. Choices come either from
|
|
922
|
+
* the field manager (e.g. a `charField` declared with `choices`) or from the
|
|
923
|
+
* `[choices]` input of {@link DispeditComponent}, which overrides the manager.
|
|
885
924
|
*/
|
|
886
|
-
interface
|
|
887
|
-
/**
|
|
888
|
-
|
|
889
|
-
/**
|
|
890
|
-
|
|
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';
|
|
925
|
+
interface IDispEditChoice {
|
|
926
|
+
/** Human-readable label shown to the user. */
|
|
927
|
+
desc: string;
|
|
928
|
+
/** Raw value written to the model field when the option is picked. */
|
|
929
|
+
value: FilterValue;
|
|
903
930
|
}
|
|
904
931
|
/**
|
|
905
|
-
*
|
|
932
|
+
* Every editor widget {@link DispeditComponent} knows how to render.
|
|
906
933
|
*
|
|
907
|
-
*
|
|
908
|
-
*
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
*
|
|
919
|
-
*
|
|
920
|
-
*
|
|
934
|
+
* A field manager advertises one of these through its `editorType` property,
|
|
935
|
+
* which is how declaring the model is enough to get the right editor. The
|
|
936
|
+
* `[editor]` input of {@link DispeditComponent} overrides that choice.
|
|
937
|
+
*
|
|
938
|
+
* - `input.text` / `input.email` / `input.password`: matching `<input>` type,
|
|
939
|
+
* with min/max length and pattern validation feedback.
|
|
940
|
+
* - `input.number`: numeric `<input>`, value used as-is.
|
|
941
|
+
* - `input.decimal`: numeric `<input>` for a `decimalField`; the value is
|
|
942
|
+
* divided by the manager's `factor` on load and multiplied back on save.
|
|
943
|
+
* - `input.date` / `input.datetime`: native date / datetime-local `<input>`.
|
|
944
|
+
* - `input.checkbox`: a Oui/Non button group (not an actual checkbox).
|
|
945
|
+
* - `textarea`: multi-line `<textarea>`.
|
|
946
|
+
* - `select`: `<select>` built from the resolved choices. Automatically used
|
|
947
|
+
* whenever choices are available, whatever the manager advertises.
|
|
948
|
+
* - `quill`: rich text editor (rendered by the caller's own integration).
|
|
949
|
+
* - `fkselect`: `<data-fkselect>` typeahead, set by `ForeignKeyFieldManager`.
|
|
950
|
+
* - `m2mselect`: `<data-m2mselect>` multi-value typeahead, set by
|
|
951
|
+
* `ManyToManyFieldManager`.
|
|
921
952
|
*/
|
|
922
|
-
type
|
|
953
|
+
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';
|
|
923
954
|
/**
|
|
924
|
-
*
|
|
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.
|
|
955
|
+
* Every read-only renderer {@link DispeditComponent} knows how to produce.
|
|
931
956
|
*
|
|
932
|
-
*
|
|
933
|
-
*
|
|
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`.
|
|
934
961
|
*
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
*
|
|
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
|
+
* - `quill`: rich text, rendered as HTML by the caller's integration.
|
|
972
|
+
*/
|
|
973
|
+
type DISPEDIT_DISPLAY_TYPES = 'text' | 'choice' | 'boolean' | 'decimal' | 'fkdetails' | 'm2mdetails' | 'datetime' | 'date' | 'quill';
|
|
974
|
+
|
|
975
|
+
/**
|
|
976
|
+
* Options common to every field decorator. All are optional; each concrete
|
|
977
|
+
* field type extends this with its own (`ICharFieldMetadata`, etc.).
|
|
938
978
|
*
|
|
939
|
-
*
|
|
940
|
-
*
|
|
941
|
-
* @Injectable({ providedIn: 'root' })
|
|
942
|
-
* export class ThingService extends Collection<Thing> {
|
|
943
|
-
* constructor() {
|
|
944
|
-
* super(inject(DataBackend), '/path/to/things', Thing);
|
|
945
|
-
* }
|
|
946
|
-
* }
|
|
979
|
+
* Whatever you pass to a decorator is copied verbatim onto the field's manager
|
|
980
|
+
* instance, so these names double as the manager's public properties.
|
|
947
981
|
*
|
|
948
|
-
*
|
|
949
|
-
* things.fetch(1).subscribe((thing) => ...);
|
|
950
|
-
* things.queryset().filter({ status: 'active' }).get().subscribe((list) => ...);
|
|
951
|
-
* ```
|
|
982
|
+
* @typeParam FT the JavaScript type the field holds on the model
|
|
952
983
|
*/
|
|
953
|
-
|
|
954
|
-
protected backend: DataBackend;
|
|
955
|
-
protected path: string;
|
|
956
|
-
model: DataModelType<T>;
|
|
984
|
+
interface IFieldMetadata<FT> {
|
|
957
985
|
/**
|
|
958
|
-
*
|
|
959
|
-
*
|
|
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.
|
|
986
|
+
* Wire name of the field: the key used in the JSON payload. Defaults to the
|
|
987
|
+
* decorated property name, so it only needs setting when the API name and
|
|
988
|
+
* the TypeScript property name differ.
|
|
964
989
|
*/
|
|
965
|
-
|
|
990
|
+
name?: string;
|
|
991
|
+
/** Short hint shown next to the editor. Defaults to an empty string. */
|
|
992
|
+
help?: string;
|
|
966
993
|
/**
|
|
967
|
-
*
|
|
968
|
-
*
|
|
969
|
-
* included and trailing slash omitted (e.g. `'/path/to/things'`)
|
|
970
|
-
* @param model model class this collection instantiates
|
|
994
|
+
* Human-readable label used for column titles, form labels and hover
|
|
995
|
+
* details. Defaults to {@link IFieldMetadata.name} when omitted.
|
|
971
996
|
*/
|
|
972
|
-
|
|
997
|
+
description?: string;
|
|
973
998
|
/**
|
|
974
|
-
*
|
|
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
|
|
999
|
+
* Marks the field as mandatory: adds `Validators.required` and forces a
|
|
1000
|
+
* value to be present on save.
|
|
981
1001
|
*
|
|
982
|
-
*
|
|
983
|
-
*
|
|
984
|
-
* const thing = things.create({ name: 'draft' });
|
|
985
|
-
* thing.save().subscribe(); // POST /path/to/things
|
|
986
|
-
* ```
|
|
1002
|
+
* Beware: combining `required: true` with no `defaultValue` throws at class
|
|
1003
|
+
* definition time — see {@link BaseFieldManager.getDefaultValue}.
|
|
987
1004
|
*/
|
|
988
|
-
|
|
1005
|
+
required?: boolean;
|
|
989
1006
|
/**
|
|
990
|
-
*
|
|
991
|
-
*
|
|
992
|
-
*
|
|
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
|
|
1007
|
+
* Field is display-only: it is excluded from generated form groups and never
|
|
1008
|
+
* pushed back to the API. Typical for server-maintained columns and for the
|
|
1009
|
+
* `*_details` half of a relation.
|
|
998
1010
|
*/
|
|
999
|
-
|
|
1000
|
-
fromJson(data: Partial<T>[]): T[];
|
|
1011
|
+
readonly?: boolean;
|
|
1001
1012
|
/**
|
|
1002
|
-
*
|
|
1003
|
-
*
|
|
1004
|
-
*
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1013
|
+
* Value used when the model has no value for this field — either a constant
|
|
1014
|
+
* or a factory `(args) => FT` evaluated on each call, which is how you get a
|
|
1015
|
+
* fresh array/date per instance instead of a shared one.
|
|
1016
|
+
*/
|
|
1017
|
+
defaultValue?: FT | ((args: FieldDefaultArgs) => FT) | null;
|
|
1018
|
+
/**
|
|
1019
|
+
* Display ordering weight: **higher is shown first**. `id` uses `1000`.
|
|
1008
1020
|
*
|
|
1009
|
-
*
|
|
1021
|
+
* `priority: -1` is the established idiom for "deserialise this field but
|
|
1022
|
+
* never offer it in the UI" — negative-priority fields are dropped from the
|
|
1023
|
+
* default column set. It is used for the id half of every relation, whose
|
|
1024
|
+
* `*_details` twin is what a human is meant to see.
|
|
1010
1025
|
*/
|
|
1011
|
-
|
|
1026
|
+
priority?: number;
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Runtime behaviour of a single field: one manager instance is built per
|
|
1030
|
+
* decorated property, at class definition time, and cached in the prototype's
|
|
1031
|
+
* metadata map. Everything the library does with a field — serialise it,
|
|
1032
|
+
* validate it, build its form control, pick its widget — goes through here.
|
|
1033
|
+
*
|
|
1034
|
+
* Subclass it only to add a genuinely new field type; the shipped managers
|
|
1035
|
+
* (`CharFieldManager`, `ForeignKeyFieldManager`, ...) cover the usual cases.
|
|
1036
|
+
* Override `fromJson`/`toJson` to change the wire mapping and
|
|
1037
|
+
* `getValidators()` to add constraints.
|
|
1038
|
+
*/
|
|
1039
|
+
declare class BaseFieldManager<FT> implements IFieldMetadata<FT> {
|
|
1040
|
+
/** Name is mandatory in a field manager. It is given by
|
|
1041
|
+
* field decorator if not directly given in field manager. */
|
|
1042
|
+
name: string;
|
|
1043
|
+
/** Human-readable label; falls back to {@link name} when not given. */
|
|
1044
|
+
description: string;
|
|
1045
|
+
/** Input hint; normalised to `''` when not given. */
|
|
1046
|
+
help: string;
|
|
1047
|
+
/** Whether a value must be present. Adds `Validators.required`. */
|
|
1048
|
+
required: boolean;
|
|
1049
|
+
/** Whether the field is excluded from forms and never written back. */
|
|
1050
|
+
readonly: boolean;
|
|
1012
1051
|
/**
|
|
1013
|
-
*
|
|
1052
|
+
* Set to `true` only by `ComputedFieldManager`. `DataModel.setFV` skips
|
|
1053
|
+
* assignment entirely for computed fields, making them permanently
|
|
1054
|
+
* read-only in the eyes of the model.
|
|
1055
|
+
*/
|
|
1056
|
+
computed: boolean;
|
|
1057
|
+
/** Display ordering weight; higher is shown first. See {@link IFieldMetadata.priority}. */
|
|
1058
|
+
priority: number;
|
|
1059
|
+
/** Constant or factory used when the model has no value. */
|
|
1060
|
+
defaultValue?: FT | ((args: FieldDefaultArgs) => FT);
|
|
1061
|
+
/**
|
|
1062
|
+
* Which editor widget `dispedit` renders for this field in edit mode.
|
|
1014
1063
|
*
|
|
1015
|
-
*
|
|
1016
|
-
*
|
|
1017
|
-
*
|
|
1018
|
-
*
|
|
1019
|
-
*
|
|
1020
|
-
|
|
1064
|
+
* This is the library's central idea: **declaring the model configures the
|
|
1065
|
+
* UI**. Managers set this themselves from what you declared — `charField`
|
|
1066
|
+
* flips to `'select'` as soon as `choices` is present, `foreignKeyField`
|
|
1067
|
+
* uses `'fkselect'`, `manyToManyField` `'m2mselect'` — so a correct model
|
|
1068
|
+
* yields the right editor with no per-template wiring.
|
|
1069
|
+
*/
|
|
1070
|
+
editorType: DISPEDIT_EDITOR_TYPES;
|
|
1071
|
+
/**
|
|
1072
|
+
* Which read-only renderer `dispedit` uses for this field. Chosen by the
|
|
1073
|
+
* manager the same way as {@link editorType} (`'fkdetails'` for a foreign
|
|
1074
|
+
* key, `'m2mdetails'` for a m2m, `'decimal'` for `decimalField`, ...).
|
|
1075
|
+
*/
|
|
1076
|
+
displayType: DISPEDIT_DISPLAY_TYPES;
|
|
1077
|
+
/**
|
|
1078
|
+
* Copies `params` onto the instance, fills in `name`/`description`/`help`
|
|
1079
|
+
* defaults, then eagerly resolves the default value — which means a
|
|
1080
|
+
* `required` field with no `defaultValue` throws here, at decoration time.
|
|
1021
1081
|
*
|
|
1022
|
-
* @
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1082
|
+
* @param params metadata as passed to the decorator
|
|
1083
|
+
*/
|
|
1084
|
+
constructor(params: IFieldMetadata<FT>);
|
|
1085
|
+
/**
|
|
1086
|
+
* Angular validators for this field, rebuilt on each access. Subclasses
|
|
1087
|
+
* override this getter (not {@link getValidators}) to append their own —
|
|
1088
|
+
* `CharFieldManager` adds length/pattern, `IntegerFieldManager` min/max.
|
|
1026
1089
|
*/
|
|
1027
|
-
|
|
1028
|
-
prefix?: string;
|
|
1029
|
-
suffix?: string;
|
|
1030
|
-
params?: {
|
|
1031
|
-
[_index: string]: string;
|
|
1032
|
-
};
|
|
1033
|
-
headers?: {
|
|
1034
|
-
[_index: string]: string;
|
|
1035
|
-
};
|
|
1036
|
-
}): Observable<T>;
|
|
1090
|
+
get validators(): ValidatorFn[];
|
|
1037
1091
|
/**
|
|
1038
|
-
*
|
|
1039
|
-
*
|
|
1040
|
-
*
|
|
1041
|
-
* This is the DRF `@action` convention. `DataModel.action()` delegates here;
|
|
1042
|
-
* call this directly for collection-level actions, which have no model.
|
|
1043
|
-
*
|
|
1044
|
-
* @param model record to act on, targeting `/path/to/things/<id>/<action>`, or
|
|
1045
|
-
* `null` for a collection-level action targeting `/path/to/things/<action>`
|
|
1046
|
-
* @param method HTTP method
|
|
1047
|
-
* @param action action name
|
|
1048
|
-
* @param body JSON body
|
|
1049
|
-
* @param params query parameters
|
|
1050
|
-
* @param headers extra headers
|
|
1092
|
+
* The bare property name, stripped of any `Model__` prefix: splits
|
|
1093
|
+
* {@link name} on `'__'` and returns the second segment, or the whole name
|
|
1094
|
+
* when there is no separator.
|
|
1051
1095
|
*/
|
|
1052
|
-
|
|
1096
|
+
get fname(): string;
|
|
1053
1097
|
/**
|
|
1054
|
-
*
|
|
1055
|
-
*
|
|
1098
|
+
* Builds a typed `FormControl` for this field on a given model instance,
|
|
1099
|
+
* seeded with the instance's current value and falling back to the default
|
|
1100
|
+
* value, and wired with {@link validators}.
|
|
1056
1101
|
*
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
1102
|
+
* Note the seed uses `||`, so falsy current values (`0`, `''`, `false`) fall
|
|
1103
|
+
* back to the default rather than being kept.
|
|
1059
1104
|
*
|
|
1060
|
-
* @param model
|
|
1061
|
-
* @param updateModel feed the server's response back into `model` (defaults to
|
|
1062
|
-
* `true`), which is how a freshly created record gets its `id`. The returned
|
|
1063
|
-
* observable always emits a **separate** instance built from the response
|
|
1064
|
-
* either way.
|
|
1105
|
+
* @param instance model whose value seeds the control
|
|
1065
1106
|
*/
|
|
1066
|
-
|
|
1067
|
-
updateModel?: boolean;
|
|
1068
|
-
}): Observable<T>;
|
|
1107
|
+
formControl(instance: DataModel): FormControl<FT | null>;
|
|
1069
1108
|
/**
|
|
1070
|
-
*
|
|
1071
|
-
*
|
|
1072
|
-
*
|
|
1073
|
-
*
|
|
1074
|
-
* does **not** filter readonly ones. Usually reached via `model.update()`.
|
|
1109
|
+
* Converts a raw JSON value coming from the API into the model value.
|
|
1110
|
+
* The base implementation passes the data straight through; typed managers
|
|
1111
|
+
* override it to coerce (`boolean`), parse (`date`) or instantiate
|
|
1112
|
+
* (`details`).
|
|
1075
1113
|
*
|
|
1076
|
-
* @param
|
|
1077
|
-
* @param fields field names to send; an empty list (the default) sends every
|
|
1078
|
-
* non-readonly field, making this equivalent to {@link save}
|
|
1079
|
-
* @param updateModel feed the server's response back into `model` (defaults to `true`)
|
|
1114
|
+
* @param data raw value read from the JSON payload
|
|
1080
1115
|
*/
|
|
1081
|
-
|
|
1082
|
-
updateModel?: boolean;
|
|
1083
|
-
}): Observable<T>;
|
|
1116
|
+
fromJson(data: unknown): FT;
|
|
1084
1117
|
/**
|
|
1085
|
-
*
|
|
1086
|
-
*
|
|
1118
|
+
* Converts the model value back into its JSON representation for save.
|
|
1119
|
+
* The base implementation passes the data straight through.
|
|
1087
1120
|
*
|
|
1088
|
-
* @param
|
|
1089
|
-
* would produce a request against the list URL
|
|
1090
|
-
* @param params query parameters
|
|
1091
|
-
* @param headers extra headers
|
|
1121
|
+
* @param data current model value
|
|
1092
1122
|
*/
|
|
1093
|
-
|
|
1123
|
+
toJson(data: FT): unknown;
|
|
1094
1124
|
/**
|
|
1095
|
-
*
|
|
1096
|
-
*
|
|
1097
|
-
* A shortcut for the simple cases (a dropdown's options, a small fixed set).
|
|
1098
|
-
* When you need paging, sorting, loading state or the result count, use
|
|
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).
|
|
1125
|
+
* Renders the value for display. The base implementation is plain string
|
|
1126
|
+
* interpolation.
|
|
1106
1127
|
*
|
|
1107
|
-
* @param
|
|
1108
|
-
* @param
|
|
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
|
|
1128
|
+
* @param data value to render
|
|
1129
|
+
* @param _format reserved; ignored by the base implementation
|
|
1112
1130
|
*/
|
|
1113
|
-
|
|
1114
|
-
prefix?: string;
|
|
1115
|
-
suffix?: string;
|
|
1116
|
-
params?: {
|
|
1117
|
-
[_index: string]: string;
|
|
1118
|
-
};
|
|
1119
|
-
headers?: {
|
|
1120
|
-
[_index: string]: string;
|
|
1121
|
-
};
|
|
1122
|
-
}): Observable<T[]>;
|
|
1131
|
+
toString(data: FT, _format?: string): string;
|
|
1123
1132
|
/**
|
|
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.
|
|
1133
|
+
* Public accessor for this field's default value, invoking the
|
|
1134
|
+
* `defaultValue` factory with `args` when one was declared.
|
|
1130
1135
|
*
|
|
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
|
|
1136
|
+
* @param args passed through to a `defaultValue` function
|
|
1139
1137
|
*/
|
|
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>;
|
|
1138
|
+
default(args?: FieldDefaultArgs): FT | undefined;
|
|
1152
1139
|
/**
|
|
1153
|
-
*
|
|
1154
|
-
*
|
|
1155
|
-
* Use it for binary or file downloads (CSV/XLSX/PDF exports) where the response
|
|
1156
|
-
* must not be parsed as JSON.
|
|
1140
|
+
* Builds the base validator list: `Validators.required` when the field is
|
|
1141
|
+
* required, nothing otherwise. Subclasses call it and push their own.
|
|
1157
1142
|
*
|
|
1158
|
-
* @
|
|
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
|
|
1143
|
+
* @protected
|
|
1165
1144
|
*/
|
|
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>;
|
|
1145
|
+
protected getValidators(): ValidatorFn[];
|
|
1178
1146
|
/**
|
|
1179
|
-
*
|
|
1180
|
-
*
|
|
1181
|
-
* Every request the collection makes goes through here, so overriding it is the
|
|
1182
|
-
* supported way to bend URL construction (versioned or nested endpoints).
|
|
1147
|
+
* Resolves the default value: calls `defaultValue` when it is a function,
|
|
1148
|
+
* otherwise returns it as-is.
|
|
1183
1149
|
*
|
|
1184
|
-
*
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1187
|
-
*
|
|
1150
|
+
* **Throws** when the field is `required` and no `defaultValue` was given.
|
|
1151
|
+
* Because the constructor calls this, the error surfaces when the class is
|
|
1152
|
+
* defined (module evaluation), not when a model is instantiated — a
|
|
1153
|
+
* `required` field without a default breaks the app at import time.
|
|
1188
1154
|
*
|
|
1189
|
-
* @param
|
|
1190
|
-
* @
|
|
1191
|
-
* @
|
|
1155
|
+
* @param args passed through to a `defaultValue` function
|
|
1156
|
+
* @throws Error if `required` is set and `defaultValue` is `undefined`
|
|
1157
|
+
* @protected
|
|
1192
1158
|
*/
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1159
|
+
protected getDefaultValue(args?: FieldDefaultArgs): FT | undefined;
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* What is actually kept in a model's metadata map: the options you passed to
|
|
1163
|
+
* the decorator, plus the four entries the decorator computes. This is the
|
|
1164
|
+
* shape returned by {@link getFieldsMetadata}.
|
|
1165
|
+
*/
|
|
1166
|
+
interface IFieldStoredMetadata<FT> extends IFieldMetadata<FT> {
|
|
1167
|
+
/** Map key of this entry: `` `${__name}__${propertyKey}` ``. */
|
|
1168
|
+
self: string;
|
|
1169
|
+
/** Wire name; defaulted to the decorated property name. */
|
|
1170
|
+
name: string;
|
|
1171
|
+
/** Field type code, e.g. `'charField'`, `'foreignKeyField'`. */
|
|
1172
|
+
type: string;
|
|
1173
|
+
/** The live manager instance built for this field. */
|
|
1174
|
+
manager: BaseFieldManager<FT>;
|
|
1197
1175
|
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Arguments handed to a `defaultValue` factory. Free-form: callers pass
|
|
1178
|
+
* whatever the factory needs, and the factory knows what to expect.
|
|
1179
|
+
*/
|
|
1180
|
+
type FieldDefaultArgs = Record<string, unknown>;
|
|
1181
|
+
/**
|
|
1182
|
+
* Shape of every field decorator returned by {@link genericDataField}: a plain
|
|
1183
|
+
* property decorator, applied for its side effect on the prototype's metadata
|
|
1184
|
+
* map.
|
|
1185
|
+
*/
|
|
1186
|
+
type FieldDecoratorFn = (target: object, propertyKey: string | symbol) => void;
|
|
1198
1187
|
|
|
1199
1188
|
/**
|
|
1200
1189
|
* Resolved field metadata of a model instance, keyed by field name.
|
|
@@ -1204,7 +1193,7 @@ declare class Collection<T extends DataModel> {
|
|
|
1204
1193
|
* filters, `dispedit`) read this map to render themselves without knowing the
|
|
1205
1194
|
* concrete model.
|
|
1206
1195
|
*/
|
|
1207
|
-
type DataModelFields = Readonly<Map<string, IFieldStoredMetadata<
|
|
1196
|
+
type DataModelFields = Readonly<Map<string, IFieldStoredMetadata<unknown>>>;
|
|
1208
1197
|
/**
|
|
1209
1198
|
* Base class for every model in the library: a plain class whose fields are
|
|
1210
1199
|
* declared with field decorators, which turns it into something the rest of the
|
|
@@ -1335,9 +1324,7 @@ declare class DataModel {
|
|
|
1335
1324
|
* offending field names to their `ValidationErrors`. Note that valid fields
|
|
1336
1325
|
* are still applied even when others fail — this reports, it does not roll back.
|
|
1337
1326
|
*/
|
|
1338
|
-
fromJson(data: {
|
|
1339
|
-
[index: string]: any;
|
|
1340
|
-
}, { partial, check }?: {
|
|
1327
|
+
fromJson(data: object, { partial, check }?: {
|
|
1341
1328
|
partial?: boolean;
|
|
1342
1329
|
check?: boolean;
|
|
1343
1330
|
}): null | ValidationErrors;
|
|
@@ -1378,21 +1365,13 @@ declare class DataModel {
|
|
|
1378
1365
|
* @returns an observable of the **raw response body**, not of this model, even
|
|
1379
1366
|
* when `update` is `true`
|
|
1380
1367
|
*/
|
|
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
|
-
};
|
|
1368
|
+
action<T, RT extends object>(method: 'POST' | 'PATCH' | 'GET' | 'DELETE' | 'PUT', name: string, { body, update, updatePartial, updateCheck, params, headers, }?: {
|
|
1369
|
+
body?: object;
|
|
1387
1370
|
update?: boolean;
|
|
1388
1371
|
updatePartial?: boolean;
|
|
1389
1372
|
updateCheck?: boolean;
|
|
1390
|
-
params?:
|
|
1391
|
-
|
|
1392
|
-
};
|
|
1393
|
-
headers?: {
|
|
1394
|
-
[_index: string]: string;
|
|
1395
|
-
};
|
|
1373
|
+
params?: Record<string, string>;
|
|
1374
|
+
headers?: Record<string, string>;
|
|
1396
1375
|
}): Observable<RT>;
|
|
1397
1376
|
/**
|
|
1398
1377
|
* Returns a field's manager — the object holding its metadata and its
|
|
@@ -1503,6 +1482,36 @@ declare class DataModel {
|
|
|
1503
1482
|
}): Observable<this>;
|
|
1504
1483
|
}
|
|
1505
1484
|
|
|
1485
|
+
/**
|
|
1486
|
+
* A model seen as the untyped property bag it also is.
|
|
1487
|
+
*
|
|
1488
|
+
* Fields are declared by decorators and reached by name at runtime — `dispedit`
|
|
1489
|
+
* reads `<field>_details`, filters read `filter.field` — so the data layer
|
|
1490
|
+
* constantly indexes models with a string the compiler cannot resolve. This is
|
|
1491
|
+
* the one sanctioned way to do it: it yields `unknown`, so the value has to be
|
|
1492
|
+
* narrowed where it is used instead of silently becoming `any` and disabling
|
|
1493
|
+
* type-checking for the rest of the expression.
|
|
1494
|
+
*
|
|
1495
|
+
* ```ts
|
|
1496
|
+
* const details = fieldValues(model)[`${field}_details`] as R[] | undefined;
|
|
1497
|
+
* fieldValues(model)[field] = event.id;
|
|
1498
|
+
* ```
|
|
1499
|
+
*
|
|
1500
|
+
* @param target model (or any object) to index by field name
|
|
1501
|
+
*/
|
|
1502
|
+
declare function fieldValues(target: object): Record<string, unknown>;
|
|
1503
|
+
/**
|
|
1504
|
+
* Renders an unknown value as display text.
|
|
1505
|
+
*
|
|
1506
|
+
* `String(value)` is not enough here: values read through {@link fieldValues}
|
|
1507
|
+
* can be objects, and `String({})` yields `[object Object]`. Nullish becomes an
|
|
1508
|
+
* empty string, objects are JSON-encoded, everything else goes through
|
|
1509
|
+
* `String`.
|
|
1510
|
+
*
|
|
1511
|
+
* @param value value read off a model, a form or a payload
|
|
1512
|
+
*/
|
|
1513
|
+
declare function asText(value: unknown): string;
|
|
1514
|
+
|
|
1506
1515
|
/**
|
|
1507
1516
|
* One column of a list: a model field (or a {@link CustomField}) together with
|
|
1508
1517
|
* its display state.
|
|
@@ -1517,7 +1526,7 @@ interface ModelListField {
|
|
|
1517
1526
|
/** The user may enable it from the field selector. */
|
|
1518
1527
|
allowed: boolean;
|
|
1519
1528
|
/** The field's current value/manager, `null` for custom columns. */
|
|
1520
|
-
field:
|
|
1529
|
+
field: unknown;
|
|
1521
1530
|
/** Sort key for display order, renumbered in steps of 10 on every change. */
|
|
1522
1531
|
position: number;
|
|
1523
1532
|
/** Ordering weight from the field metadata, higher first; `-1` means "never shown by default". */
|
|
@@ -1620,7 +1629,7 @@ declare class ModelListFields<T extends DataModel> {
|
|
|
1620
1629
|
* @param position new sort key
|
|
1621
1630
|
* @returns current enabled fields
|
|
1622
1631
|
*/
|
|
1623
|
-
setPosition(fname:
|
|
1632
|
+
setPosition(fname: string, position: number): string[];
|
|
1624
1633
|
private _update;
|
|
1625
1634
|
}
|
|
1626
1635
|
|
|
@@ -1857,19 +1866,19 @@ interface ModelListFilterParams {
|
|
|
1857
1866
|
* Not read by the constructor. {@link ModelListFilter} initialises its value
|
|
1858
1867
|
* from {@link default} instead; see the `FIXME` in the constructor body.
|
|
1859
1868
|
*/
|
|
1860
|
-
value?:
|
|
1869
|
+
value?: FilterValue;
|
|
1861
1870
|
/**
|
|
1862
1871
|
* Free-form description used as the `title` (native tooltip) of this filter's
|
|
1863
1872
|
* entry in the `data-model-list-filters-select` picker. It has no effect on
|
|
1864
1873
|
* the query.
|
|
1865
1874
|
*/
|
|
1866
|
-
desc?:
|
|
1875
|
+
desc?: string;
|
|
1867
1876
|
/**
|
|
1868
1877
|
* Initial value applied at construction time. Only some subclasses act on it
|
|
1869
1878
|
* (text, select and select-multi); the others ignore it. Its expected shape
|
|
1870
1879
|
* depends on the subclass.
|
|
1871
1880
|
*/
|
|
1872
|
-
default?:
|
|
1881
|
+
default?: unknown;
|
|
1873
1882
|
/**
|
|
1874
1883
|
* CSS classes applied to the filter's container element, overriding the
|
|
1875
1884
|
* `classes` input passed by the host component. Use it to give one filter a
|
|
@@ -1928,9 +1937,9 @@ declare class ModelListFilter implements ModelListFilterParams {
|
|
|
1928
1937
|
/** Help/placeholder text. Defaults to a French string set by each subclass. */
|
|
1929
1938
|
help: string;
|
|
1930
1939
|
/** Tooltip text for the filter picker entry; does not affect the query. */
|
|
1931
|
-
desc?:
|
|
1940
|
+
desc?: string;
|
|
1932
1941
|
/** Initial value, applied at construction by the subclasses that support it. */
|
|
1933
|
-
default?:
|
|
1942
|
+
default?: unknown;
|
|
1934
1943
|
/** Discriminator telling {@link ModelListFiltersComponent} which widget to render. */
|
|
1935
1944
|
type: FILTER_TYPE;
|
|
1936
1945
|
/**
|
|
@@ -2029,7 +2038,7 @@ declare class ModelListFilter implements ModelListFilterParams {
|
|
|
2029
2038
|
* @returns `true` when the value actually changed, `false` when it was
|
|
2030
2039
|
* already set. Callers use this to avoid re-querying the list needlessly.
|
|
2031
2040
|
*/
|
|
2032
|
-
set(value:
|
|
2041
|
+
set(value: FilterValue, desc: string, notify?: boolean): boolean;
|
|
2033
2042
|
/**
|
|
2034
2043
|
* Removes `value` from the filter. On a multi-valued filter only that value
|
|
2035
2044
|
* is dropped, which is what the chips' delete buttons call; on a
|
|
@@ -2040,7 +2049,7 @@ declare class ModelListFilter implements ModelListFilterParams {
|
|
|
2040
2049
|
* @param notify Whether to emit on the value stream.
|
|
2041
2050
|
* @returns `true` when something was actually removed.
|
|
2042
2051
|
*/
|
|
2043
|
-
unset(value:
|
|
2052
|
+
unset(value: FilterValue, desc: string, notify?: boolean): boolean;
|
|
2044
2053
|
/**
|
|
2045
2054
|
* Adds `value` if absent, removes it if present. Convenient for checkbox-like
|
|
2046
2055
|
* widgets where the same gesture selects and deselects.
|
|
@@ -2050,7 +2059,7 @@ declare class ModelListFilter implements ModelListFilterParams {
|
|
|
2050
2059
|
* @param notify Whether to emit on the value stream.
|
|
2051
2060
|
* @returns Always `true`.
|
|
2052
2061
|
*/
|
|
2053
|
-
toggle(value:
|
|
2062
|
+
toggle(value: FilterValue, desc: string, notify?: boolean): boolean;
|
|
2054
2063
|
/**
|
|
2055
2064
|
* The current single value, stringified, as sent to the server. Only
|
|
2056
2065
|
* meaningful for single-valued filters.
|
|
@@ -2205,9 +2214,7 @@ interface CustomField {
|
|
|
2205
2214
|
* This is scoping/context (the current tenant, the parent object of a nested
|
|
2206
2215
|
* list), not user-facing filtering — see {@link ModelListParams.filter}.
|
|
2207
2216
|
*/
|
|
2208
|
-
|
|
2209
|
-
[index: string]: string | number | undefined;
|
|
2210
|
-
}
|
|
2217
|
+
type FilterDefaults = Record<string, string | number | undefined>;
|
|
2211
2218
|
/**
|
|
2212
2219
|
* Initial sort keys, as `field` / `+field` (ascending) or `-field` (descending).
|
|
2213
2220
|
*/
|
|
@@ -2512,7 +2519,7 @@ declare class ModelListFieldsSelectorComponent<T extends DataModel> implements O
|
|
|
2512
2519
|
/** Open the field selector panel. */
|
|
2513
2520
|
open(): void;
|
|
2514
2521
|
/** Reorder the dropped column, placing it between its new neighbours. */
|
|
2515
|
-
drop($event: CdkDragDrop<T,
|
|
2522
|
+
drop($event: CdkDragDrop<T, T>): void;
|
|
2516
2523
|
/** Show or hide column `f`, depending on its current state. */
|
|
2517
2524
|
toggle(f: ModelListField): void;
|
|
2518
2525
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListFieldsSelectorComponent<any>, never>;
|
|
@@ -2550,11 +2557,11 @@ declare class ModelListFieldHeaderComponent<T extends DataModel> implements OnIn
|
|
|
2550
2557
|
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
2558
|
}
|
|
2552
2559
|
|
|
2553
|
-
declare class ModelListSorterComponent {
|
|
2560
|
+
declare class ModelListSorterComponent<T extends DataModel = DataModel> {
|
|
2554
2561
|
/**
|
|
2555
2562
|
* ModelList reference.
|
|
2556
2563
|
*/
|
|
2557
|
-
list: _angular_core.InputSignal<ModelList<
|
|
2564
|
+
list: _angular_core.InputSignal<ModelList<T>>;
|
|
2558
2565
|
/**
|
|
2559
2566
|
* Sort field name.
|
|
2560
2567
|
*/
|
|
@@ -2578,13 +2585,13 @@ declare class ModelListSorterComponent {
|
|
|
2578
2585
|
cancel(): void;
|
|
2579
2586
|
private getIsDown;
|
|
2580
2587
|
private getIsUp;
|
|
2581
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListSorterComponent
|
|
2582
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ModelListSorterComponent
|
|
2588
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListSorterComponent<any>, never>;
|
|
2589
|
+
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
2590
|
}
|
|
2584
2591
|
|
|
2585
|
-
declare class ModelListFiltersSelectComponent implements OnInit {
|
|
2592
|
+
declare class ModelListFiltersSelectComponent<T extends DataModel = DataModel> implements OnInit {
|
|
2586
2593
|
/** The list whose filters can be toggled. Required. */
|
|
2587
|
-
list: _angular_core.InputSignal<ModelList<
|
|
2594
|
+
list: _angular_core.InputSignal<ModelList<T>>;
|
|
2588
2595
|
/** CSS classes for the element wrapping the picker. */
|
|
2589
2596
|
containerClasses: _angular_core.InputSignal<string | string[]>;
|
|
2590
2597
|
/** CSS classes for an enabled filter's badge, in the badge modes. */
|
|
@@ -2611,8 +2618,8 @@ declare class ModelListFiltersSelectComponent implements OnInit {
|
|
|
2611
2618
|
* it and resets the control, leaving the dropdown ready for the next pick.
|
|
2612
2619
|
*/
|
|
2613
2620
|
ngOnInit(): void;
|
|
2614
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListFiltersSelectComponent
|
|
2615
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ModelListFiltersSelectComponent
|
|
2621
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListFiltersSelectComponent<any>, never>;
|
|
2622
|
+
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
2623
|
}
|
|
2617
2624
|
|
|
2618
2625
|
/**
|
|
@@ -2629,9 +2636,9 @@ declare class ModelListFiltersSelectComponent implements OnInit {
|
|
|
2629
2636
|
* <data-model-list-filters [list]="list" itemClasses="col-4" />
|
|
2630
2637
|
* ```
|
|
2631
2638
|
*/
|
|
2632
|
-
declare class ModelListFiltersComponent {
|
|
2639
|
+
declare class ModelListFiltersComponent<T extends DataModel = DataModel> {
|
|
2633
2640
|
/** The list whose filters are displayed. Required. */
|
|
2634
|
-
list: _angular_core.InputSignal<ModelList<
|
|
2641
|
+
list: _angular_core.InputSignal<ModelList<T>>;
|
|
2635
2642
|
/** CSS classes for the element wrapping all the filter widgets. */
|
|
2636
2643
|
containerClasses: _angular_core.InputSignal<string | string[]>;
|
|
2637
2644
|
/**
|
|
@@ -2639,8 +2646,8 @@ declare class ModelListFiltersComponent {
|
|
|
2639
2646
|
* declaring `displayClasses` overrides this for itself.
|
|
2640
2647
|
*/
|
|
2641
2648
|
itemClasses: _angular_core.InputSignal<string | string[]>;
|
|
2642
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListFiltersComponent
|
|
2643
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ModelListFiltersComponent
|
|
2649
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ModelListFiltersComponent<any>, never>;
|
|
2650
|
+
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
2651
|
}
|
|
2645
2652
|
|
|
2646
2653
|
/**
|
|
@@ -2679,22 +2686,27 @@ declare class FkselectComponent<T extends DataModel, R extends DataModel> implem
|
|
|
2679
2686
|
search: _angular_core.InputSignal<string>;
|
|
2680
2687
|
/** Label shown next to the control. */
|
|
2681
2688
|
label: _angular_core.InputSignal<string>;
|
|
2689
|
+
/**
|
|
2690
|
+
* Id put on the search input, and pointed at by `[label]`'s `for`. Defaults
|
|
2691
|
+
* to a generated one; dispedit passes its own so its label drives this input.
|
|
2692
|
+
*/
|
|
2693
|
+
inputId: _angular_core.InputSignal<string>;
|
|
2682
2694
|
/** Placeholder for the search input. */
|
|
2683
2695
|
placeholder: _angular_core.InputSignal<string>;
|
|
2684
2696
|
/** CSS classes applied to the search input. */
|
|
2685
2697
|
inputClasses: _angular_core.InputSignal<string | string[]>;
|
|
2686
2698
|
/** Emits the instance the user picked from the dropdown. */
|
|
2687
|
-
selected: _angular_core.OutputEmitterRef<
|
|
2699
|
+
selected: _angular_core.OutputEmitterRef<R>;
|
|
2688
2700
|
/** Emits when the user aborts editing (escape). */
|
|
2689
2701
|
cancelled: _angular_core.OutputEmitterRef<void>;
|
|
2690
2702
|
/** Emits when the user clears the selection, via {@link clearAction}. */
|
|
2691
2703
|
cleared: _angular_core.OutputEmitterRef<void>;
|
|
2692
2704
|
/** Form control backing the typeahead search input. */
|
|
2693
|
-
fc:
|
|
2705
|
+
fc: FormControl<R | null>;
|
|
2694
2706
|
/** Search callback handed to ng-bootstrap's typeahead. */
|
|
2695
|
-
searchFn: (text$: Observable<string>) => Observable<
|
|
2707
|
+
searchFn: (text$: Observable<string>) => Observable<R[]>;
|
|
2696
2708
|
/** Option formatter handed to ng-bootstrap's typeahead. */
|
|
2697
|
-
displayFn: (x:
|
|
2709
|
+
displayFn: (x: R | null | undefined) => string;
|
|
2698
2710
|
private _tpl;
|
|
2699
2711
|
private destroy$;
|
|
2700
2712
|
/**
|
|
@@ -2718,7 +2730,7 @@ declare class FkselectComponent<T extends DataModel, R extends DataModel> implem
|
|
|
2718
2730
|
*/
|
|
2719
2731
|
private _search;
|
|
2720
2732
|
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>;
|
|
2733
|
+
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
2734
|
}
|
|
2723
2735
|
|
|
2724
2736
|
interface ModelListAutocompleteParams<T extends DataModel> extends ModelListFilterParams {
|
|
@@ -3263,6 +3275,8 @@ declare class ModelListSelectMultiFilter<T extends DataModel> extends ModelListS
|
|
|
3263
3275
|
* choice. The parent constructor has already resolved the choices and
|
|
3264
3276
|
* enforced the `choices`-or-`model` requirement.
|
|
3265
3277
|
*/
|
|
3278
|
+
/** The options selected from the start, as full choice objects. */
|
|
3279
|
+
default?: IDispEditChoice[];
|
|
3266
3280
|
constructor(params: ModelListMultiSelectFilterParams<T>);
|
|
3267
3281
|
}
|
|
3268
3282
|
|
|
@@ -3516,7 +3530,7 @@ declare class PChoicePipe<T extends DataModel> implements PipeTransform {
|
|
|
3516
3530
|
* @param mode `desc` for the label alone, `code` for the raw value alone,
|
|
3517
3531
|
* `both` for `[code] label`.
|
|
3518
3532
|
*/
|
|
3519
|
-
transform(value:
|
|
3533
|
+
transform(value: unknown, model: T, field: string, mode?: 'code' | 'desc' | 'both'): string;
|
|
3520
3534
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PChoicePipe<any>, never>;
|
|
3521
3535
|
static ɵpipe: _angular_core.ɵɵPipeDeclaration<PChoicePipe<any>, "pchoice", true>;
|
|
3522
3536
|
}
|
|
@@ -3615,7 +3629,7 @@ declare class FactorcPipe<T extends DataModel> implements PipeTransform {
|
|
|
3615
3629
|
* @param digitsInfo digit format, as accepted by Angular's `currency` pipe.
|
|
3616
3630
|
* @param locale locale to format in; defaults to the ambient `LOCALE_ID`.
|
|
3617
3631
|
*/
|
|
3618
|
-
transform(value: T | null, field: string, currencyCode?: string, display?: 'code' | 'symbol' | 'symbol-narrow' | string, digitsInfo?: string, locale?: string): string | null;
|
|
3632
|
+
transform(value: T | null, field: string, currencyCode?: string, display?: 'code' | 'symbol' | 'symbol-narrow' | (string & {}), digitsInfo?: string, locale?: string): string | null;
|
|
3619
3633
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FactorcPipe<any>, never>;
|
|
3620
3634
|
static ɵpipe: _angular_core.ɵɵPipeDeclaration<FactorcPipe<any>, "factorc", true>;
|
|
3621
3635
|
}
|
|
@@ -3644,7 +3658,7 @@ declare class PFactorcPipe<T extends DataModel> implements PipeTransform {
|
|
|
3644
3658
|
* @param digitsInfo digit format, as accepted by Angular's `currency` pipe.
|
|
3645
3659
|
* @param locale locale to format in; defaults to the ambient `LOCALE_ID`.
|
|
3646
3660
|
*/
|
|
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;
|
|
3661
|
+
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
3662
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PFactorcPipe<any>, never>;
|
|
3649
3663
|
static ɵpipe: _angular_core.ɵɵPipeDeclaration<PFactorcPipe<any>, "pfactorc", true>;
|
|
3650
3664
|
}
|
|
@@ -3662,6 +3676,8 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3662
3676
|
* the model, and nothing checks it at compile time.
|
|
3663
3677
|
*/
|
|
3664
3678
|
field: _angular_core.InputSignal<string>;
|
|
3679
|
+
/** Id tying the label to whichever control the editor renders. */
|
|
3680
|
+
readonly inputId: string;
|
|
3665
3681
|
/**
|
|
3666
3682
|
* External form group, for `inline` / `form` modes.
|
|
3667
3683
|
*
|
|
@@ -3731,7 +3747,7 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3731
3747
|
*
|
|
3732
3748
|
* The reset control only appears in edit mode when this is not undefined.
|
|
3733
3749
|
*/
|
|
3734
|
-
default: _angular_core.InputSignal<
|
|
3750
|
+
default: _angular_core.InputSignal<unknown>;
|
|
3735
3751
|
/** Input placeholder. Falls back to the field manager's `description`. */
|
|
3736
3752
|
placeholder: _angular_core.InputSignal<string>;
|
|
3737
3753
|
/** Help text shown under the editor. Falls back to the manager's `help`. */
|
|
@@ -3783,7 +3799,7 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3783
3799
|
/** Display renderer actually in use, after manager lookup and overrides. */
|
|
3784
3800
|
realDisplay: _angular_core.WritableSignal<DISPEDIT_DISPLAY_TYPES>;
|
|
3785
3801
|
/** Raw field value backing the current display, before formatting. */
|
|
3786
|
-
dispValue: _angular_core.WritableSignal<
|
|
3802
|
+
dispValue: _angular_core.WritableSignal<unknown>;
|
|
3787
3803
|
/** Choices actually in use, or undefined when the field has none. */
|
|
3788
3804
|
realChoices: _angular_core.WritableSignal<IDispEditChoice[] | undefined>;
|
|
3789
3805
|
/** Help text actually shown, after the manager fallback. */
|
|
@@ -3793,9 +3809,9 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3793
3809
|
/** Whether the manager declares the field required. */
|
|
3794
3810
|
required: _angular_core.WritableSignal<boolean>;
|
|
3795
3811
|
/** Default value actually applied by {@link setDefault}. */
|
|
3796
|
-
realDefault: _angular_core.WritableSignal<
|
|
3812
|
+
realDefault: _angular_core.WritableSignal<unknown>;
|
|
3797
3813
|
/** Latest M2M instances reported by the child select, used for display. */
|
|
3798
|
-
m2mValues?:
|
|
3814
|
+
m2mValues?: DataModel[];
|
|
3799
3815
|
/** Form group driving the editor: the external `[form]`, or a local one. */
|
|
3800
3816
|
fg: _angular_core.WritableSignal<UntypedFormGroup | undefined>;
|
|
3801
3817
|
/** Resolved display function for FK / M2M options, built from `display`. */
|
|
@@ -3880,7 +3896,7 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3880
3896
|
*
|
|
3881
3897
|
* @param $event selected instance, or null when the selection was cleared.
|
|
3882
3898
|
*/
|
|
3883
|
-
selectedRefItem($event:
|
|
3899
|
+
selectedRefItem($event: R | null): Promise<void>;
|
|
3884
3900
|
/**
|
|
3885
3901
|
* Cache the M2M instances reported by the child select.
|
|
3886
3902
|
*
|
|
@@ -3889,7 +3905,7 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
|
|
|
3889
3905
|
*
|
|
3890
3906
|
* @param v current list of selected instances.
|
|
3891
3907
|
*/
|
|
3892
|
-
onM2MValuesChanges(v:
|
|
3908
|
+
onM2MValuesChanges(v: DataModel[]): void;
|
|
3893
3909
|
/** Apply cross-input consistency rules (a quill editor implies a quill viewer). */
|
|
3894
3910
|
private _checks;
|
|
3895
3911
|
/**
|
|
@@ -3945,6 +3961,11 @@ declare class M2mselectComponent<T extends DataModel, R extends DataModel> imple
|
|
|
3945
3961
|
search: _angular_core.InputSignal<string>;
|
|
3946
3962
|
/** Label shown next to the control. */
|
|
3947
3963
|
label: _angular_core.InputSignal<string>;
|
|
3964
|
+
/**
|
|
3965
|
+
* Id put on the search input, and pointed at by `[label]`'s `for`. Defaults
|
|
3966
|
+
* to a generated one; dispedit passes its own so its label drives this input.
|
|
3967
|
+
*/
|
|
3968
|
+
inputId: _angular_core.InputSignal<string>;
|
|
3948
3969
|
/** Placeholder for the search input. */
|
|
3949
3970
|
placeholder: _angular_core.InputSignal<string>;
|
|
3950
3971
|
/** Text shown when nothing is selected. */
|
|
@@ -3966,17 +3987,17 @@ declare class M2mselectComponent<T extends DataModel, R extends DataModel> imple
|
|
|
3966
3987
|
/** Form control backing the typeahead search input. */
|
|
3967
3988
|
fc: UntypedFormControl;
|
|
3968
3989
|
/** Search callback handed to ng-bootstrap's typeahead. */
|
|
3969
|
-
searchFn: (text$: Observable<string>) => Observable<
|
|
3990
|
+
searchFn: (text$: Observable<string>) => Observable<R[]>;
|
|
3970
3991
|
/** Option formatter handed to ng-bootstrap's typeahead. */
|
|
3971
|
-
displayFn: (x:
|
|
3992
|
+
displayFn: (x: R | null | undefined) => string;
|
|
3972
3993
|
private touched;
|
|
3973
3994
|
private _tpl;
|
|
3974
3995
|
private destroy$;
|
|
3975
3996
|
/**
|
|
3976
3997
|
* Control value accessor onChange dummy callback;
|
|
3977
|
-
* @param
|
|
3998
|
+
* @param _fks
|
|
3978
3999
|
*/
|
|
3979
|
-
onChange: (
|
|
4000
|
+
onChange: (_fks: number[]) => void;
|
|
3980
4001
|
/**
|
|
3981
4002
|
* Control value accessor onTouched dummy callback;
|
|
3982
4003
|
*/
|
|
@@ -3985,18 +4006,18 @@ declare class M2mselectComponent<T extends DataModel, R extends DataModel> imple
|
|
|
3985
4006
|
* OnChange register from controlValueAccessor
|
|
3986
4007
|
* @param onChange callback
|
|
3987
4008
|
*/
|
|
3988
|
-
registerOnChange(onChange:
|
|
4009
|
+
registerOnChange(onChange: (fks: number[]) => void): void;
|
|
3989
4010
|
/**
|
|
3990
4011
|
* OnTouched register from controlValueAccessor
|
|
3991
4012
|
* @param onTouched callback
|
|
3992
4013
|
*/
|
|
3993
|
-
registerOnTouched(onTouched:
|
|
4014
|
+
registerOnTouched(onTouched: () => void): void;
|
|
3994
4015
|
/**
|
|
3995
4016
|
* OnInit :
|
|
3996
4017
|
* - ensures queryset is available
|
|
3997
4018
|
* - creates form control for input
|
|
3998
4019
|
* - creates display function
|
|
3999
|
-
* - ensure values are set from
|
|
4020
|
+
* - ensure values are set from whichever source is available
|
|
4000
4021
|
*/
|
|
4001
4022
|
ngOnInit(): void;
|
|
4002
4023
|
/**
|
|
@@ -4049,7 +4070,7 @@ declare class M2mselectComponent<T extends DataModel, R extends DataModel> imple
|
|
|
4049
4070
|
*/
|
|
4050
4071
|
private _search;
|
|
4051
4072
|
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>;
|
|
4073
|
+
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
4074
|
}
|
|
4054
4075
|
|
|
4055
4076
|
/**
|
|
@@ -4096,9 +4117,9 @@ declare class FlagsComponent<T extends DataModel> implements OnInit {
|
|
|
4096
4117
|
*/
|
|
4097
4118
|
action: _angular_core.InputSignal<boolean>;
|
|
4098
4119
|
/** Control for the free-text "new flag" input. */
|
|
4099
|
-
ft: FormControl
|
|
4120
|
+
ft: FormControl<string | null>;
|
|
4100
4121
|
/** Control for the known-flags dropdown; selecting a value adds it. */
|
|
4101
|
-
fs: FormControl
|
|
4122
|
+
fs: FormControl<string | null>;
|
|
4102
4123
|
/** Flags currently on the model, rendered as badges. */
|
|
4103
4124
|
curflags: _angular_core.WritableSignal<string[]>;
|
|
4104
4125
|
/** Unused; kept for backwards compatibility. */
|
|
@@ -4114,9 +4135,9 @@ declare class FlagsComponent<T extends DataModel> implements OnInit {
|
|
|
4114
4135
|
* from the model field, and wire the dropdown so that selecting a value adds
|
|
4115
4136
|
* the flag (debounced 250ms).
|
|
4116
4137
|
*/
|
|
4117
|
-
ngOnInit():
|
|
4138
|
+
ngOnInit(): void;
|
|
4118
4139
|
/** Add the flag currently typed in the free-text input. */
|
|
4119
|
-
addFreeFlag(): Promise<
|
|
4140
|
+
addFreeFlag(): Promise<void>;
|
|
4120
4141
|
/**
|
|
4121
4142
|
* Add a flag and persist, unless it is already present.
|
|
4122
4143
|
*
|
|
@@ -4125,12 +4146,12 @@ declare class FlagsComponent<T extends DataModel> implements OnInit {
|
|
|
4125
4146
|
*
|
|
4126
4147
|
* @param flag flag value to add.
|
|
4127
4148
|
*/
|
|
4128
|
-
addFlag(flag: string): Promise<
|
|
4149
|
+
addFlag(flag: string): Promise<void>;
|
|
4129
4150
|
/**
|
|
4130
4151
|
* Write the current flags back to the model field and save it, then reset
|
|
4131
4152
|
* both inputs. Reports success or failure through the message service.
|
|
4132
4153
|
*/
|
|
4133
|
-
update(): Promise<
|
|
4154
|
+
update(): Promise<void>;
|
|
4134
4155
|
/**
|
|
4135
4156
|
* Whether the flag is already on the model.
|
|
4136
4157
|
*
|
|
@@ -4143,7 +4164,7 @@ declare class FlagsComponent<T extends DataModel> implements OnInit {
|
|
|
4143
4164
|
*
|
|
4144
4165
|
* @param flag flag value to remove.
|
|
4145
4166
|
*/
|
|
4146
|
-
removeFlag(flag: string): Promise<
|
|
4167
|
+
removeFlag(flag: string): Promise<void>;
|
|
4147
4168
|
/**
|
|
4148
4169
|
* Switch between badge display and the editor.
|
|
4149
4170
|
*
|
|
@@ -4175,9 +4196,7 @@ declare class SafeDeleteComponent<T extends DataModel> {
|
|
|
4175
4196
|
success: boolean;
|
|
4176
4197
|
}>) | undefined>;
|
|
4177
4198
|
/** Translations of database objects names to human names */
|
|
4178
|
-
checks: _angular_core.InputSignal<
|
|
4179
|
-
[index: string]: string;
|
|
4180
|
-
}>;
|
|
4199
|
+
checks: _angular_core.InputSignal<Record<string, string>>;
|
|
4181
4200
|
/** Messages to be displayed on success or error, default messages are used if not provided */
|
|
4182
4201
|
messages: _angular_core.InputSignal<{
|
|
4183
4202
|
success?: string;
|
|
@@ -4203,9 +4222,9 @@ declare class SafeDeleteComponent<T extends DataModel> {
|
|
|
4203
4222
|
* First step: run the dry-run delete and open the confirmation panel with its
|
|
4204
4223
|
* result. Nothing is destroyed here.
|
|
4205
4224
|
*
|
|
4206
|
-
* @param
|
|
4225
|
+
* @param _model unused; the component always acts on its own `[model]` input.
|
|
4207
4226
|
*/
|
|
4208
|
-
checkDelete(
|
|
4227
|
+
checkDelete(_model: DataModel): Promise<void>;
|
|
4209
4228
|
/**
|
|
4210
4229
|
* Second step: perform the actual deletion once the user has confirmed, then
|
|
4211
4230
|
* close the panel and emit {@link deleted} with the dry-run result.
|
|
@@ -4456,7 +4475,7 @@ interface IDetailsFieldMetadata<T> extends IFieldMetadata<T> {
|
|
|
4456
4475
|
* `forwardRef`, not a lambda). This is the real link of a relation: it is
|
|
4457
4476
|
* what instantiates and populates the nested payload.
|
|
4458
4477
|
*/
|
|
4459
|
-
model?:
|
|
4478
|
+
model?: DataModelType<DataModel>;
|
|
4460
4479
|
/**
|
|
4461
4480
|
* Custom deserialiser, taking precedence over `model`. Use it for payloads
|
|
4462
4481
|
* that are not models — a plain shape, or a value needing transformation.
|
|
@@ -4531,7 +4550,7 @@ declare const reverseForeignKeyField: (updates: IReverseForeignKeyFieldMetadata)
|
|
|
4531
4550
|
* @detailsField({ description: 'Labels', readonly: true })
|
|
4532
4551
|
* public labels_details?: string[];
|
|
4533
4552
|
*/
|
|
4534
|
-
declare const detailsField: (meta?: IDetailsFieldMetadata<
|
|
4553
|
+
declare const detailsField: (meta?: IDetailsFieldMetadata<unknown>) => FieldDecoratorFn;
|
|
4535
4554
|
/**
|
|
4536
4555
|
* Declares the id half of a many-to-many relation: an array of ids, rendered
|
|
4537
4556
|
* as a multi-select. Pairs with a `many: true` {@link detailsField} named
|
|
@@ -4710,7 +4729,7 @@ interface IComputedFieldMetadata<T> extends IFieldMetadata<T> {
|
|
|
4710
4729
|
* }
|
|
4711
4730
|
* }
|
|
4712
4731
|
*/
|
|
4713
|
-
declare const computedField: (meta?: IComputedFieldMetadata<
|
|
4732
|
+
declare const computedField: (meta?: IComputedFieldMetadata<unknown>) => FieldDecoratorFn;
|
|
4714
4733
|
|
|
4715
4734
|
/** Severity of a {@link Message}; drives both the CSS classes and the default lifetime. */
|
|
4716
4735
|
declare const enum TYPE {
|
|
@@ -4735,9 +4754,7 @@ declare enum STATUS {
|
|
|
4735
4754
|
/**
|
|
4736
4755
|
* Maps a sound key (`success`, `info`, `warning`, `error`, `notify`) to an audio file url.
|
|
4737
4756
|
*/
|
|
4738
|
-
|
|
4739
|
-
[index: string]: string;
|
|
4740
|
-
}
|
|
4757
|
+
type ISoundTypes = Record<string, string>;
|
|
4741
4758
|
/**
|
|
4742
4759
|
* Optional per-severity notification sounds ({@link ISoundTypes}) played by
|
|
4743
4760
|
* {@link DataMessageService.play}.
|
|
@@ -4758,11 +4775,11 @@ declare class Message {
|
|
|
4758
4775
|
title: string;
|
|
4759
4776
|
type: TYPE;
|
|
4760
4777
|
message: string;
|
|
4761
|
-
trace:
|
|
4778
|
+
trace: unknown;
|
|
4762
4779
|
ttl: number;
|
|
4763
4780
|
status: string;
|
|
4764
4781
|
showTrace: boolean;
|
|
4765
|
-
constructor(title: string, type?: TYPE, message?: string, trace?:
|
|
4782
|
+
constructor(title: string, type?: TYPE, message?: string, trace?: unknown, ttl?: number);
|
|
4766
4783
|
/** Bootstrap alert classes matching this message's severity, bound by the message zone template. */
|
|
4767
4784
|
get style(): string;
|
|
4768
4785
|
/** 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 +4823,22 @@ declare class DataMessageService {
|
|
|
4806
4823
|
*/
|
|
4807
4824
|
close(): void;
|
|
4808
4825
|
/** Reports a completed operation. Short-lived by default (3 s) and plays the `success` sound if configured. */
|
|
4809
|
-
success(title: string, message?: string, trace?:
|
|
4826
|
+
success(title: string, message?: string, trace?: unknown, timeout?: number): void;
|
|
4810
4827
|
/** Reports neutral information the user does not have to act on. Defaults to a 4 s lifetime. */
|
|
4811
|
-
info(title: string, message?: string, trace?:
|
|
4828
|
+
info(title: string, message?: string, trace?: unknown, timeout?: number): void;
|
|
4812
4829
|
/** 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?:
|
|
4830
|
+
warning(title: string, message?: string, trace?: unknown, timeout?: number): void;
|
|
4814
4831
|
/**
|
|
4815
4832
|
* Reports a failure, with the longest lifetime (30 s) and the `error` sound.
|
|
4816
4833
|
*
|
|
4817
4834
|
* Note that the `timeout` argument is currently ignored: the message is always created
|
|
4818
4835
|
* with {@link DEFAULT_TIMEOUTS.DANGER}.
|
|
4819
4836
|
*/
|
|
4820
|
-
danger(title: string, message?: string, trace?:
|
|
4837
|
+
danger(title: string, message?: string, trace?: unknown, timeout?: number): void;
|
|
4821
4838
|
/** Alias for {@link danger}, for callers that think in terms of "error" rather than severity. */
|
|
4822
|
-
error(title: string, message?: string, trace?:
|
|
4839
|
+
error(title: string, message?: string, trace?: unknown): void;
|
|
4823
4840
|
/** Logs to the console only — nothing is shown to the user and no message is queued. */
|
|
4824
|
-
debug(title: string, message?: string, trace?:
|
|
4841
|
+
debug(title: string, message?: string, trace?: unknown): void;
|
|
4825
4842
|
/**
|
|
4826
4843
|
* Dismisses a message on the user's behalf and immediately re-emits the list, so the
|
|
4827
4844
|
* message zone drops it without waiting for its ttl. Bound to the close button of
|
|
@@ -4925,13 +4942,13 @@ declare class QuerysetMock<T extends DataModel> {
|
|
|
4925
4942
|
/** `[results, loading, meta]` combined, mirroring `Queryset.full`. */
|
|
4926
4943
|
get full(): Observable<[T[], boolean, IQueryMeta]>;
|
|
4927
4944
|
/** No-op returning `this`; the filter is discarded. See the class-level caveat. */
|
|
4928
|
-
filter(
|
|
4945
|
+
filter(_params?: FilterData): QuerysetMock<T>;
|
|
4929
4946
|
/** No-op returning `this`; the ordering is discarded. See the class-level caveat. */
|
|
4930
|
-
sort(...
|
|
4947
|
+
sort(..._sorting: string[]): QuerysetMock<T>;
|
|
4931
4948
|
/** No-op returning `this`; {@link pageSize} is left untouched. */
|
|
4932
|
-
paginateBy(
|
|
4949
|
+
paginateBy(_pageSize?: number): QuerysetMock<T>;
|
|
4933
4950
|
/** No-op returning `this`; {@link page} is left untouched. */
|
|
4934
|
-
setPage(
|
|
4951
|
+
setPage(_page: number): QuerysetMock<T>;
|
|
4935
4952
|
/** Always returns `{}`, since no query state is retained. */
|
|
4936
4953
|
getQueryParams(): FilterData;
|
|
4937
4954
|
/**
|
|
@@ -4993,13 +5010,13 @@ declare class CollectionMock<T extends DataModel> {
|
|
|
4993
5010
|
* id, so a test that fetches two different ids gets the same instance back.
|
|
4994
5011
|
* Reassign `mockValue` between calls if that matters.
|
|
4995
5012
|
*/
|
|
4996
|
-
fetch(
|
|
5013
|
+
fetch(_id: number, _suffix?: string): Observable<T>;
|
|
4997
5014
|
/**
|
|
4998
5015
|
* Returns {@link actionValue}, ignoring the arguments. Since it does not record
|
|
4999
5016
|
* the call, assert on the effects rather than on the invocation, or spy on this
|
|
5000
5017
|
* method when you need to check what was requested.
|
|
5001
5018
|
*/
|
|
5002
|
-
action(
|
|
5019
|
+
action(_model: T | null, _method: IHttpMethod, _action: string, _params: IActionParams): Observable<any>;
|
|
5003
5020
|
/**
|
|
5004
5021
|
* Opens a {@link QuerysetMock} backed by this mock, mirroring
|
|
5005
5022
|
* `Collection.queryset()`. With no `mockData` set on it, the queryset falls
|
|
@@ -5011,9 +5028,7 @@ declare class CollectionMock<T extends DataModel> {
|
|
|
5011
5028
|
* real `Collection.list()` unwraps. Arguments are ignored, so filters are not
|
|
5012
5029
|
* applied; set {@link mockValues} to whatever the filtered result should be.
|
|
5013
5030
|
*/
|
|
5014
|
-
list(
|
|
5015
|
-
[index: string]: string;
|
|
5016
|
-
}, suffix?: string): Observable<any>;
|
|
5031
|
+
list(_query?: Record<string, string>, _suffix?: string): Observable<any>;
|
|
5017
5032
|
/**
|
|
5018
5033
|
* Builds real model instances from JSON, exactly as a live collection would —
|
|
5019
5034
|
* this is the method you use to prepare {@link mockValue}/{@link mockValues}.
|
|
@@ -5027,7 +5042,7 @@ declare class CollectionMock<T extends DataModel> {
|
|
|
5027
5042
|
* @param data JSON object or array of them
|
|
5028
5043
|
* @param many set to `true` when `data` is an array
|
|
5029
5044
|
*/
|
|
5030
|
-
fromJson(data: any, many?: boolean):
|
|
5045
|
+
fromJson(data: any, many?: boolean): any;
|
|
5031
5046
|
}
|
|
5032
5047
|
|
|
5033
5048
|
/**
|
|
@@ -5092,16 +5107,15 @@ interface UploadFile {
|
|
|
5092
5107
|
/** Live status and throughput figures, updated as the transfer progresses. */
|
|
5093
5108
|
progress: UploadProgress;
|
|
5094
5109
|
/** Response body, parsed as JSON when possible and left as raw text otherwise. Set once done. */
|
|
5095
|
-
response?:
|
|
5110
|
+
response?: unknown;
|
|
5096
5111
|
/** HTTP status code of the response. Set once done — note that a 4xx/5xx still completes as `done`. */
|
|
5097
5112
|
responseStatus?: number;
|
|
5098
|
-
|
|
5113
|
+
/** Subscription of the in-flight request, used to cancel it. */
|
|
5114
|
+
sub?: Subscription;
|
|
5099
5115
|
/** The underlying browser `File`, i.e. what is actually transferred. */
|
|
5100
5116
|
nativeFile?: File;
|
|
5101
5117
|
/** Response headers, parsed into a plain object. Set once done. */
|
|
5102
|
-
responseHeaders?:
|
|
5103
|
-
[key: string]: string;
|
|
5104
|
-
};
|
|
5118
|
+
responseHeaders?: Record<string, string>;
|
|
5105
5119
|
}
|
|
5106
5120
|
/**
|
|
5107
5121
|
* An event emitted by the uploader on the `uploadOutput` output of the directives.
|
|
@@ -5112,7 +5126,7 @@ interface UploadFile {
|
|
|
5112
5126
|
* `dragOver`/`dragOut`/`drop` for drop-zone hover states.
|
|
5113
5127
|
*/
|
|
5114
5128
|
interface UploadOutput {
|
|
5115
|
-
type:
|
|
5129
|
+
type: 'addedToQueue' | 'allAddedToQueue' | 'uploading' | 'done' | 'start' | 'cancelled' | 'dragOver' | 'dragOut' | 'drop' | 'removed' | 'removedAll' | 'rejected';
|
|
5116
5130
|
file?: UploadFile;
|
|
5117
5131
|
nativeFile?: File;
|
|
5118
5132
|
}
|
|
@@ -5124,7 +5138,7 @@ interface UploadOutput {
|
|
|
5124
5138
|
* data); the queue-management commands only need `type` and, where relevant, `id`.
|
|
5125
5139
|
*/
|
|
5126
5140
|
interface UploadInput {
|
|
5127
|
-
type:
|
|
5141
|
+
type: 'uploadAll' | 'uploadFile' | 'cancel' | 'cancelAll' | 'remove' | 'removeAll';
|
|
5128
5142
|
/** Target endpoint for `uploadAll`/`uploadFile`. Defaults to an empty string, which posts to the current url. */
|
|
5129
5143
|
url?: string;
|
|
5130
5144
|
/** HTTP method to use; defaults to `POST`. */
|
|
@@ -5137,13 +5151,9 @@ interface UploadInput {
|
|
|
5137
5151
|
/** The queued file to send with `uploadFile`; matched by identity against the queue. */
|
|
5138
5152
|
file?: UploadFile;
|
|
5139
5153
|
/** Extra form fields appended to the multipart body alongside the file. */
|
|
5140
|
-
data?:
|
|
5141
|
-
[key: string]: string | Blob;
|
|
5142
|
-
};
|
|
5154
|
+
data?: Record<string, string | Blob>;
|
|
5143
5155
|
/** 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
|
-
};
|
|
5156
|
+
headers?: Record<string, string>;
|
|
5147
5157
|
includeWebKitFormBoundary?: boolean;
|
|
5148
5158
|
/** Sends credentials (cookies) cross-origin; defaults to `false`. */
|
|
5149
5159
|
withCredentials?: boolean;
|
|
@@ -5273,7 +5283,7 @@ declare class NgFileDropDirective implements OnInit, OnDestroy {
|
|
|
5273
5283
|
ngOnDestroy(): void;
|
|
5274
5284
|
stopEvent: (e: Event) => void;
|
|
5275
5285
|
/** Handles a drop: emits `drop`, then screens and queues the dropped files. Bound to the host `drop` event. */
|
|
5276
|
-
onDrop(e:
|
|
5286
|
+
onDrop(e: DragEvent): void;
|
|
5277
5287
|
/** Emits `dragOver` while a drag hovers the zone, for highlighting it. Bound to the host `dragover` event. */
|
|
5278
5288
|
onDragOver(e: Event): void;
|
|
5279
5289
|
/** Emits `dragOut` when a drag leaves the zone, to clear the highlight. Bound to the host `dragleave` event. */
|
|
@@ -5286,7 +5296,7 @@ declare class NgFileSelectDirective implements OnInit, OnDestroy {
|
|
|
5286
5296
|
/** Queue limits ({@link UploaderOptions}). Read once in `ngOnInit`; later changes have no effect. */
|
|
5287
5297
|
options: _angular_core.InputSignal<UploaderOptions | undefined>;
|
|
5288
5298
|
/** Command channel: emit {@link UploadInput}s on it to start, cancel or clear uploads. */
|
|
5289
|
-
uploadInput: _angular_core.InputSignal<EventEmitter<
|
|
5299
|
+
uploadInput: _angular_core.InputSignal<EventEmitter<UploadInput> | undefined>;
|
|
5290
5300
|
/** Queue and transfer events ({@link UploadOutput}) for this input. */
|
|
5291
5301
|
uploadOutput: _angular_core.OutputEmitterRef<UploadOutput>;
|
|
5292
5302
|
/** The queue backing this input, created in `ngOnInit`. */
|
|
@@ -5449,7 +5459,7 @@ declare const DATA_AUTH_PARAMS: InjectionToken<AuthParams>;
|
|
|
5449
5459
|
* Using `useClass` here would give the auth layer a private instance whose cache and
|
|
5450
5460
|
* state diverge from the one the rest of the application uses.
|
|
5451
5461
|
*/
|
|
5452
|
-
declare const DATA_AUTH_USER_SERVICE: InjectionToken<Collection<
|
|
5462
|
+
declare const DATA_AUTH_USER_SERVICE: InjectionToken<Collection<DataModel>>;
|
|
5453
5463
|
/**
|
|
5454
5464
|
* Generic JWT authentication service, meant to be **extended** by the application.
|
|
5455
5465
|
*
|
|
@@ -5495,11 +5505,6 @@ declare const DATA_AUTH_USER_SERVICE: InjectionToken<Collection<any>>;
|
|
|
5495
5505
|
* @typeParam UserData - the decoded JWT payload, at least an {@link IJwtBaseData}.
|
|
5496
5506
|
*/
|
|
5497
5507
|
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
5508
|
/**
|
|
5504
5509
|
* Emits every time {@link logout} runs, whether triggered by the user, by a failed
|
|
5505
5510
|
* token refresh, or by a login error.
|
|
@@ -5514,7 +5519,13 @@ declare class AuthServiceBase<User extends DataModel, UserService extends Collec
|
|
|
5514
5519
|
private _user$;
|
|
5515
5520
|
private _token;
|
|
5516
5521
|
private _fetched?;
|
|
5517
|
-
|
|
5522
|
+
/** Collection used to fetch the logged-in user, from {@link DATA_AUTH_USER_SERVICE}. */
|
|
5523
|
+
userService: UserService;
|
|
5524
|
+
private _params;
|
|
5525
|
+
private _router;
|
|
5526
|
+
private _http;
|
|
5527
|
+
private _msgs;
|
|
5528
|
+
constructor();
|
|
5518
5529
|
/** True when no access token is held, i.e. no session is active. Checked by {@link AuthInterceptor} before attaching a token. */
|
|
5519
5530
|
get isAnonymous(): boolean;
|
|
5520
5531
|
/** Current raw access token, or `null` when anonymous. Read by {@link AuthInterceptor} to build the `Authorization` header. */
|
|
@@ -5572,7 +5583,7 @@ declare class AuthServiceBase<User extends DataModel, UserService extends Collec
|
|
|
5572
5583
|
* `'error'` when none is available), so callers can branch on the emitted string
|
|
5573
5584
|
* rather than on an error callback.
|
|
5574
5585
|
*/
|
|
5575
|
-
login(username: string, password: string): Observable<'success' | 'error' | 'invalid_token' | string>;
|
|
5586
|
+
login(username: string, password: string): Observable<'success' | 'error' | 'invalid_token' | (string & {})>;
|
|
5576
5587
|
/**
|
|
5577
5588
|
* Opens a session from an already-obtained token pair instead of credentials, for
|
|
5578
5589
|
* flows where the tokens arrive out of band (SSO callback, impersonation, tests).
|
|
@@ -5580,7 +5591,7 @@ declare class AuthServiceBase<User extends DataModel, UserService extends Collec
|
|
|
5580
5591
|
* Like {@link login}, it fetches the user, saves the session and reports failures as
|
|
5581
5592
|
* an emitted code rather than an error.
|
|
5582
5593
|
*/
|
|
5583
|
-
loginWithToken(accessToken: string, refreshToken: string): Observable<'success' | 'error' | 'invalid_token' | string>;
|
|
5594
|
+
loginWithToken(accessToken: string, refreshToken: string): Observable<'success' | 'error' | 'invalid_token' | (string & {})>;
|
|
5584
5595
|
/**
|
|
5585
5596
|
* Asks the backend to send an account reactivation token to the given user.
|
|
5586
5597
|
*
|
|
@@ -5697,7 +5708,7 @@ declare class AuthInterceptor implements HttpInterceptor {
|
|
|
5697
5708
|
* {@link DATA_AUTH_URLS}. Authenticated requests additionally get 401 handling with
|
|
5698
5709
|
* automatic token refresh and replay.
|
|
5699
5710
|
*/
|
|
5700
|
-
intercept(req: HttpRequest<
|
|
5711
|
+
intercept(req: HttpRequest<unknown>, next: HttpHandler): rxjs.Observable<_angular_common_http.HttpEvent<any>>;
|
|
5701
5712
|
private _handle401Error;
|
|
5702
5713
|
private _addToken;
|
|
5703
5714
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AuthInterceptor, never>;
|
|
@@ -5730,6 +5741,10 @@ interface BaseRouteParams {
|
|
|
5730
5741
|
/**
|
|
5731
5742
|
* Route function type.
|
|
5732
5743
|
* Takes parameters, return a route.
|
|
5744
|
+
*
|
|
5745
|
+
* The parameters are `any` on purpose: a route builder is written against the
|
|
5746
|
+
* models it links to (`(product: Product) => [...]`), and such a function is not
|
|
5747
|
+
* assignable to one declared over `unknown[]`.
|
|
5733
5748
|
*/
|
|
5734
5749
|
type RouteFn = (...args: any[]) => (string | number)[];
|
|
5735
5750
|
/**
|
|
@@ -5753,18 +5768,14 @@ declare function RData<T extends BaseRouteParams>(value: T): T;
|
|
|
5753
5768
|
* A map of route names to their {@link RouteConfigItem}, keyed by a string-literal union
|
|
5754
5769
|
* so that every name is known statically and typos are compile errors.
|
|
5755
5770
|
*/
|
|
5756
|
-
type RoutesConfig<T extends string> =
|
|
5757
|
-
readonly [Property in T]: RouteConfigItem;
|
|
5758
|
-
};
|
|
5771
|
+
type RoutesConfig<T extends string> = Readonly<Record<T, RouteConfigItem>>;
|
|
5759
5772
|
/** An Angular {@link Route} whose `data` is mandatory and typed as {@link BaseRouteParams}. */
|
|
5760
5773
|
interface StrictRoutes extends Route {
|
|
5761
5774
|
data: BaseRouteParams;
|
|
5762
5775
|
}
|
|
5763
5776
|
/** A route table built from {@link StrictRoutes}, i.e. where every route carries breadcrumb metadata. */
|
|
5764
5777
|
type RoutesDefinition = StrictRoutes[];
|
|
5765
|
-
|
|
5766
|
-
[index: string]: T;
|
|
5767
|
-
}
|
|
5778
|
+
type RouteArg<T> = Record<string, T>;
|
|
5768
5779
|
/**
|
|
5769
5780
|
* A bound, reusable reference to a route: it pairs a {@link RouteConfigItem} with a
|
|
5770
5781
|
* context object from which the route's named parameters are read.
|
|
@@ -5787,7 +5798,7 @@ declare class Link<T> {
|
|
|
5787
5798
|
* later. A missing `config` is tolerated (it warns and produces an inert link) so that
|
|
5788
5799
|
* a partially-initialised template does not crash.
|
|
5789
5800
|
*/
|
|
5790
|
-
constructor(config?: RouteConfigItem, context?:
|
|
5801
|
+
constructor(config?: RouteConfigItem, context?: object, router?: Router);
|
|
5791
5802
|
private _name;
|
|
5792
5803
|
/** Name of the underlying route config item, or an empty string when the link was built without config. */
|
|
5793
5804
|
get name(): string;
|
|
@@ -5796,7 +5807,7 @@ declare class Link<T> {
|
|
|
5796
5807
|
* context. Only the parameters declared by the route config are picked up; those
|
|
5797
5808
|
* missing from `ctx` are reset to `null`, not left over from the previous context.
|
|
5798
5809
|
*/
|
|
5799
|
-
context(ctx:
|
|
5810
|
+
context(ctx: object): void;
|
|
5800
5811
|
/**
|
|
5801
5812
|
* Builds the router commands array, resolving each declared parameter from `params`
|
|
5802
5813
|
* first and falling back to the bound context.
|
|
@@ -5813,9 +5824,7 @@ declare class Link<T> {
|
|
|
5813
5824
|
* Resolves to `false` without navigating when no router is available from either
|
|
5814
5825
|
* source; otherwise it resolves with the router's own result.
|
|
5815
5826
|
*/
|
|
5816
|
-
navigate(params?:
|
|
5817
|
-
[index: string]: T;
|
|
5818
|
-
}, router?: Router): Promise<boolean>;
|
|
5827
|
+
navigate(params?: Record<string, T>, router?: Router): Promise<boolean>;
|
|
5819
5828
|
}
|
|
5820
5829
|
|
|
5821
5830
|
/** One rendered breadcrumb entry: its absolute path, label, icon classes, and whether it is the active leaf. */
|
|
@@ -5848,7 +5857,7 @@ declare class BreadcrumbComponent implements OnInit {
|
|
|
5848
5857
|
/**
|
|
5849
5858
|
* Additional data to be used in titleTemplate
|
|
5850
5859
|
*/
|
|
5851
|
-
data: _angular_core.InputSignal<
|
|
5860
|
+
data: _angular_core.InputSignal<object | undefined>;
|
|
5852
5861
|
/**
|
|
5853
5862
|
* Do we display icons ?
|
|
5854
5863
|
*/
|
|
@@ -5965,6 +5974,34 @@ declare class TabMemoryService {
|
|
|
5965
5974
|
*/
|
|
5966
5975
|
declare const slugify: (str: string) => string;
|
|
5967
5976
|
|
|
5977
|
+
/**
|
|
5978
|
+
* Returns a document-unique DOM id, as `<prefix>-<n>`.
|
|
5979
|
+
*
|
|
5980
|
+
* Used to wire a `<label [attr.for]>` to the control its template owns: the
|
|
5981
|
+
* widgets in this library are instantiated repeatedly on the same page, so a
|
|
5982
|
+
* hard-coded id would collide and silently break the association.
|
|
5983
|
+
*
|
|
5984
|
+
* The counter is module-level and starts at zero in each JS context, so a
|
|
5985
|
+
* server-rendered page and its client hydration agree as long as components are
|
|
5986
|
+
* created in the same order — which is what Angular does.
|
|
5987
|
+
*
|
|
5988
|
+
* @param prefix identifies the widget, e.g. `data-filter`
|
|
5989
|
+
*/
|
|
5990
|
+
declare function uniqueId(prefix: string): string;
|
|
5991
|
+
|
|
5992
|
+
/**
|
|
5993
|
+
* Teach jsdom the layout APIs CodeMirror and ProseMirror expect.
|
|
5994
|
+
*
|
|
5995
|
+
* Both editors measure the document to place the caret and decide what to
|
|
5996
|
+
* render, and jsdom has no layout engine: `getClientRects()` returns an empty
|
|
5997
|
+
* list and `elementFromPoint` does not exist at all. Zeroed rectangles are
|
|
5998
|
+
* enough — nothing in a spec depends on real geometry, it just has to not throw.
|
|
5999
|
+
*
|
|
6000
|
+
* Call it from `beforeEach` in any spec that instantiates an editor view. It is
|
|
6001
|
+
* idempotent, and only patches what is missing.
|
|
6002
|
+
*/
|
|
6003
|
+
declare function installEditorDomShims(): void;
|
|
6004
|
+
|
|
5968
6005
|
/**
|
|
5969
6006
|
* Compiles (and optionally renders) an Underscore-style string template, using ERB
|
|
5970
6007
|
* delimiters: `<%= expr %>` interpolates, `<% code %>` evaluates, and a `print()` helper
|
|
@@ -5980,7 +6017,15 @@ declare const slugify: (str: string) => string;
|
|
|
5980
6017
|
* Policy without `unsafe-eval`; and the escaping delimiter `<%- expr %>` is not usable,
|
|
5981
6018
|
* as the code it emits calls `_.escape` while no `_` is in scope.
|
|
5982
6019
|
*/
|
|
5983
|
-
|
|
6020
|
+
/**
|
|
6021
|
+
* A template compiled by {@link tmpl} but not yet rendered: call it with the
|
|
6022
|
+
* data. `source` carries the generated JS, which is handy when debugging.
|
|
6023
|
+
*/
|
|
6024
|
+
type CompiledTemplate = ((data: object) => string) & {
|
|
6025
|
+
source?: string;
|
|
6026
|
+
};
|
|
6027
|
+
declare function tmpl(text: string, data: object, objectName?: string): string;
|
|
6028
|
+
declare function tmpl(text: string, data?: undefined, objectName?: string): CompiledTemplate;
|
|
5984
6029
|
|
|
5985
6030
|
/**
|
|
5986
6031
|
* Watches the service worker for a newly deployed version and exposes it as a simple
|
|
@@ -5993,11 +6038,17 @@ declare const tmpl: (text: string, data?: any, objectName?: string) => any;
|
|
|
5993
6038
|
* Harmless without a service worker: the checks fail and are logged as warnings.
|
|
5994
6039
|
*/
|
|
5995
6040
|
declare class UpdateService {
|
|
6041
|
+
private stable;
|
|
5996
6042
|
private appRef;
|
|
5997
6043
|
private swUpdate;
|
|
5998
|
-
|
|
5999
|
-
constructor(appRef: ApplicationRef, swUpdate: SwUpdate);
|
|
6044
|
+
constructor();
|
|
6000
6045
|
private _available$;
|
|
6046
|
+
/**
|
|
6047
|
+
* Asks the service worker whether a new version is available. Swallows the
|
|
6048
|
+
* failure raised when no service worker is registered, which is the normal
|
|
6049
|
+
* case in development.
|
|
6050
|
+
*/
|
|
6051
|
+
private _checkForUpdate;
|
|
6001
6052
|
/**
|
|
6002
6053
|
* Whether a new version is ready to be activated. Starts at `false`, becomes `true` on
|
|
6003
6054
|
* `VERSION_READY`, and returns to `false` once the user activates or dismisses it.
|
|
@@ -6024,5 +6075,5 @@ declare class UpdateComponent {
|
|
|
6024
6075
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UpdateComponent, "data-update", never, {}, {}, never, never, true, never>;
|
|
6025
6076
|
}
|
|
6026
6077
|
|
|
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 };
|
|
6078
|
+
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, 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 };
|
|
6079
|
+
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 };
|