@mintplayer/ng-spark 22.26.0 → 22.28.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/README.md +6 -4
- package/fesm2022/mintplayer-ng-spark-grid.mjs +73 -50
- package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-history.mjs +1 -1
- package/fesm2022/mintplayer-ng-spark-history.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-models.mjs +19 -10
- package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-moderation.mjs +1 -1
- package/fesm2022/mintplayer-ng-spark-moderation.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-pipes.mjs +5 -2
- package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-create.mjs +16 -7
- package/fesm2022/mintplayer-ng-spark-po-create.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs +30 -14
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-edit.mjs +45 -15
- package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-form.mjs +4 -4
- package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-query-list.mjs +18 -2
- package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-renderers.mjs +2 -1
- package/fesm2022/mintplayer-ng-spark-renderers.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +0 -1
- package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-services.mjs +12 -9
- package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-soft-delete.mjs +4 -3
- package/fesm2022/mintplayer-ng-spark-soft-delete.mjs.map +1 -1
- package/package.json +3 -3
- package/types/mintplayer-ng-spark-grid.d.ts +50 -46
- package/types/mintplayer-ng-spark-models.d.ts +75 -40
- package/types/mintplayer-ng-spark-moderation.d.ts +8 -4
- package/types/mintplayer-ng-spark-pipes.d.ts +3 -0
- package/types/mintplayer-ng-spark-po-create.d.ts +4 -0
- package/types/mintplayer-ng-spark-po-detail.d.ts +12 -2
- package/types/mintplayer-ng-spark-po-edit.d.ts +16 -0
- package/types/mintplayer-ng-spark-po-form.d.ts +1 -0
- package/types/mintplayer-ng-spark-query-list.d.ts +11 -1
- package/types/mintplayer-ng-spark-services.d.ts +38 -9
- package/types/mintplayer-ng-spark-soft-delete.d.ts +1 -1
|
@@ -10,14 +10,6 @@ import { SparkQueryRowAction } from "@mintplayer/ng-spark/panels";
|
|
|
10
10
|
import { ReferenceChip } from "@mintplayer/ng-spark/pipes";
|
|
11
11
|
/** Page sizes offered by every Spark grid. */
|
|
12
12
|
export declare const SPARK_GRID_PAGE_SIZES: number[];
|
|
13
|
-
/**
|
|
14
|
-
* The attributes a grid shows, in display order.
|
|
15
|
-
*
|
|
16
|
-
* Shared so the two grids cannot disagree about what "visible" means — they each had their own
|
|
17
|
-
* copy of this expression, which is the kind of thing that stays identical right up until it
|
|
18
|
-
* doesn't.
|
|
19
|
-
*/
|
|
20
|
-
export declare function visibleGridAttributes(entityType: EntityType | null): EntityAttributeDefinition[];
|
|
21
13
|
/**
|
|
22
14
|
* Initial datatable settings for a query, seeded with the query's declared sort.
|
|
23
15
|
*
|
|
@@ -200,21 +192,21 @@ export declare class SparkQueryActionsContext {
|
|
|
200
192
|
query: SparkQuery | null;
|
|
201
193
|
}
|
|
202
194
|
/**
|
|
203
|
-
* One button of a query's toolbar (#460,
|
|
195
|
+
* One button of a query's toolbar (#460 M15, #467 R3): the built-in New, Edit or Delete, or a custom action.
|
|
204
196
|
*
|
|
205
197
|
* Built by `SparkQueryGridComponent.toolbarActions()` and rendered by every host of the grid — the
|
|
206
198
|
* query card's header and the query-list page's action bar — so both surfaces offer the same
|
|
207
199
|
* actions, enabled by the same rules.
|
|
208
200
|
*/
|
|
209
201
|
export interface SparkQueryToolbarAction {
|
|
210
|
-
kind: 'new' | 'delete' | 'custom' | 'addon';
|
|
202
|
+
kind: 'new' | 'edit' | 'delete' | 'custom' | 'addon';
|
|
211
203
|
/** For `addon` (row menu only): the add-on's entry (`SPARK_QUERY_ROW_ACTIONS`). */
|
|
212
204
|
addon?: SparkQueryRowAction;
|
|
213
205
|
/** The action's name, unique within the toolbar. */
|
|
214
206
|
name: string;
|
|
215
207
|
/** Its catalogue entry: label, icon, `selectionRule`, `variant`, confirmation. */
|
|
216
208
|
definition: CustomActionDefinition;
|
|
217
|
-
/** `*bsPriorityNavItem` priority: New first, then Delete, then custom actions by offset. */
|
|
209
|
+
/** `*bsPriorityNavItem` priority: New first, then Edit, then Delete, then custom actions by offset. */
|
|
218
210
|
priority: number;
|
|
219
211
|
}
|
|
220
212
|
/**
|
|
@@ -357,14 +349,13 @@ export declare class SparkQueryGridComponent {
|
|
|
357
349
|
}>;
|
|
358
350
|
/**
|
|
359
351
|
* A click anywhere on a row opens it, like its first-column link — the link used to be the only
|
|
360
|
-
* target, so a row whose first column was empty ("—") could not be opened at all.
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
352
|
+
* target, so a row whose first column was empty ("—") could not be opened at all. This holds on
|
|
353
|
+
* every list, selectable or not (#467, D9): only the checkbox cell selects, which the datatable's
|
|
354
|
+
* `'checkbox'` mode guarantees. Clicks on the link itself or on an interactive element inside the
|
|
355
|
+
* row (a vote button, a checkbox) are theirs, not the row's; a modified click (Ctrl, ⌘, Shift,
|
|
356
|
+
* middle) is left to the browser.
|
|
364
357
|
*/
|
|
365
358
|
protected onRowClick(event: BsDatatableRowEvent<unknown>): void;
|
|
366
|
-
protected onRowDblClick(event: BsDatatableRowEvent<unknown>): void;
|
|
367
|
-
private openRow;
|
|
368
359
|
/**
|
|
369
360
|
* Paging and sorting. Two-way, so a host driving `data` can sort those rows by whatever the
|
|
370
361
|
* user actually clicked — the datatable writes the new sort back through here.
|
|
@@ -449,45 +440,60 @@ export declare class SparkQueryGridComponent {
|
|
|
449
440
|
*/
|
|
450
441
|
errorMessage: import("@angular/core").WritableSignal<string | null>;
|
|
451
442
|
/**
|
|
452
|
-
* The
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
|
|
443
|
+
* The built-in actions this result offers (#467, R1(1–3)), each with its toolbar kind: listed for
|
|
444
|
+
* the caller (the right), on the query side (`defaultQueryActions` already filtered `showedOn`),
|
|
445
|
+
* not withheld by this result's `disabledActions` — Edit also not when `Save` is — and nothing in
|
|
446
|
+
* the recycle bin. New additionally needs the type's create right ({@link offersCreate}).
|
|
447
|
+
*/
|
|
448
|
+
readonly offeredDefaultActions: import("@angular/core").Signal<SparkQueryToolbarAction[]>;
|
|
449
|
+
/**
|
|
450
|
+
* The rendered selection mode (#467, R1): the host's override (a sub-query entry's
|
|
451
|
+
* `selectionMode`), else the query's own, else `'auto'` — derived from the EFFECTIVE action list
|
|
452
|
+
* (built-ins and custom actions alike), so a list is selectable exactly when the caller can use an
|
|
453
|
+
* action on ticked rows here. Recomputed whenever `disabledActions` or the deleted mode changes;
|
|
454
|
+
* the selection is cleared when the mode becomes `'none'`.
|
|
457
455
|
*/
|
|
458
456
|
selectionMode: import("@angular/core").Signal<import("@mintplayer/ng-spark/models").SparkSelectionMode>;
|
|
459
457
|
/**
|
|
460
|
-
* The actions a host renders in its toolbar, in one list (#460,
|
|
461
|
-
* actions, each with the rule that enables it. The query card and the query-list page
|
|
462
|
-
* same list, so the two surfaces cannot drift.
|
|
458
|
+
* The actions a host renders in its toolbar, in one list (#460 M15, #467 R3): New, Edit, Delete and
|
|
459
|
+
* the custom actions, each with the rule that enables it. The query card and the query-list page
|
|
460
|
+
* render this same list, so the two surfaces cannot drift. The same effective list decides
|
|
461
|
+
* {@link selectionMode}.
|
|
463
462
|
*
|
|
464
|
-
* - New:
|
|
465
|
-
*
|
|
466
|
-
* - Delete: likewise with `Delete/T` and `Delete`, and only while rows can be selected (otherwise
|
|
467
|
-
* it could never be enabled — the row menu offers it per row instead).
|
|
463
|
+
* - New, Edit, Delete: {@link offeredDefaultActions}. Edit and Delete act on ticked rows, so a list
|
|
464
|
+
* declared `'none'` leaves them to the row menu, where they would otherwise never be enabled.
|
|
468
465
|
* - Custom: `visibleCustomActions()`.
|
|
469
|
-
* - In the recycle bin ({@link recycleBin}) none
|
|
466
|
+
* - In the recycle bin ({@link recycleBin}) none: the list is empty.
|
|
470
467
|
*/
|
|
471
468
|
toolbarActions: import("@angular/core").Signal<SparkQueryToolbarAction[]>;
|
|
472
469
|
/**
|
|
473
|
-
* The per-row `⋮` menu: every offered action whose rule accepts exactly one row — Delete
|
|
474
|
-
* whatever the selection mode. An action without a rule acts on the query, not on a row,
|
|
475
|
-
* left to the toolbar.
|
|
470
|
+
* The per-row `⋮` menu: every offered action whose rule accepts exactly one row — Edit and Delete
|
|
471
|
+
* included, whatever the selection mode. An action without a rule acts on the query, not on a row,
|
|
472
|
+
* and is left to the toolbar.
|
|
476
473
|
*/
|
|
477
474
|
rowActions: import("@angular/core").Signal<SparkQueryToolbarAction[]>;
|
|
478
475
|
/** What an add-on row action is asked whether it is offered; null until the type resolved. */
|
|
479
476
|
private readonly rowActionScope;
|
|
480
|
-
/** The default Delete: not withheld by the result, and never in the recycle bin. */
|
|
481
|
-
private offersDelete;
|
|
482
477
|
/** Whether a toolbar action can run with the current selection. The server checks again. */
|
|
483
478
|
isToolbarActionEnabled(action: SparkQueryToolbarAction): boolean;
|
|
484
479
|
/** Runs a toolbar action on the current selection. */
|
|
485
480
|
runToolbarAction(action: SparkQueryToolbarAction): Promise<void>;
|
|
486
481
|
/**
|
|
487
|
-
* The
|
|
488
|
-
*
|
|
482
|
+
* The built-in Edit (#467, R2): it only navigates, to the row's edit page with this list as the
|
|
483
|
+
* return state. Get and Update enforce everything (row gate, `can`, etag, write shield); the `=1`
|
|
484
|
+
* rule is client-side only, since there is no bulk edit.
|
|
489
485
|
*/
|
|
486
|
+
editRow(row: QueryResultItem | undefined): void;
|
|
487
|
+
/** The chip's ⊗: drops the whole selection, ticked rows on other pages included. */
|
|
490
488
|
clearSelection(): void;
|
|
489
|
+
/** The ids of the rows on the page currently shown; the chip counts the ticked rows outside it. */
|
|
490
|
+
private readonly loadedIds;
|
|
491
|
+
/**
|
|
492
|
+
* Ticked rows that are not on the page shown (#467, D19): the selection survives paging, so the
|
|
493
|
+
* chip says how many of the rows an action will act on cannot be seen ("7 selected, 4 on other
|
|
494
|
+
* pages"). Actions always receive the whole `selection()`, which is what the chip counts.
|
|
495
|
+
*/
|
|
496
|
+
readonly offPageCount: import("@angular/core").Signal<number>;
|
|
491
497
|
/** The id of the row whose `⋮` menu is open; at most one is. */
|
|
492
498
|
readonly openRowMenu: import("@angular/core").WritableSignal<string | null>;
|
|
493
499
|
/** Below the toggle, right-aligned; above it when there is no room below. */
|
|
@@ -520,10 +526,11 @@ export declare class SparkQueryGridComponent {
|
|
|
520
526
|
*/
|
|
521
527
|
startNew(): void;
|
|
522
528
|
/**
|
|
523
|
-
* The default Delete on `
|
|
524
|
-
* entry's `
|
|
529
|
+
* The default Delete on `rows`: one request, all rows or none (#460, D18). Asks first — with the
|
|
530
|
+
* entry's `confirmation` (`{count}` substituted) — then clears the selection and refreshes. Each row
|
|
531
|
+
* goes with the `etag` it was listed with (#467, D14), so a row changed since is refused, not lost.
|
|
525
532
|
*/
|
|
526
|
-
deleteRows(
|
|
533
|
+
deleteRows(rows: QueryResultItem[], definition?: CustomActionDefinition): Promise<void>;
|
|
527
534
|
isVirtualScrolling: import("@angular/core").Signal<boolean>;
|
|
528
535
|
/**
|
|
529
536
|
* Columns as sent with the most recent fetched page.
|
|
@@ -532,14 +539,11 @@ export declare class SparkQueryGridComponent {
|
|
|
532
539
|
* snapshot carries them once, exactly as a paged result does.
|
|
533
540
|
*/
|
|
534
541
|
private readonly fetchedColumns;
|
|
535
|
-
/** Every column on the wire, drawn or not — what renderers and lookups resolve against. */
|
|
536
|
-
allColumns: import("@angular/core").Signal<QueryColumn[]>;
|
|
537
542
|
/**
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
* the field still draws everything.
|
|
543
|
+
* Every column on the wire — what the grid draws, and what renderers and lookups resolve against.
|
|
544
|
+
* Every column that ships is drawn (#264): there is no shipped-but-hidden column.
|
|
541
545
|
*/
|
|
542
|
-
|
|
546
|
+
allColumns: import("@angular/core").Signal<QueryColumn[]>;
|
|
543
547
|
/**
|
|
544
548
|
* True when rows do not come from this component's own fetch.
|
|
545
549
|
*
|
|
@@ -23,6 +23,11 @@ export interface ValidationErrorResponse {
|
|
|
23
23
|
* Values can be combined: ShowedOn.Query | ShowedOn.PersistentObject
|
|
24
24
|
*/
|
|
25
25
|
export declare enum ShowedOn {
|
|
26
|
+
/**
|
|
27
|
+
* Drawn on no page (#264; Vidyano's `Never`). The attribute still ships on the object, and an action can show
|
|
28
|
+
* it for one object through the runtime `showedOn` it sets on load, new or refresh.
|
|
29
|
+
*/
|
|
30
|
+
None = 0,
|
|
26
31
|
Query = 1,
|
|
27
32
|
PersistentObject = 2
|
|
28
33
|
}
|
|
@@ -86,7 +91,6 @@ export interface PersistentObjectAttribute {
|
|
|
86
91
|
dataType: string;
|
|
87
92
|
isArray?: boolean;
|
|
88
93
|
isRequired: boolean;
|
|
89
|
-
isVisible: boolean;
|
|
90
94
|
isReadOnly: boolean;
|
|
91
95
|
order: number;
|
|
92
96
|
query?: string;
|
|
@@ -128,51 +132,71 @@ export interface PersistentObjectAttribute {
|
|
|
128
132
|
*/
|
|
129
133
|
asDetailType?: string;
|
|
130
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* One action of the composed catalogue (#467, D7), as `/spark/actions/list` reports it for a type:
|
|
137
|
+
* a built-in (New, Edit, Delete) or a custom action, already narrowed to what the caller may run.
|
|
138
|
+
* Text arrives resolved by the server (D26).
|
|
139
|
+
*/
|
|
131
140
|
export interface CustomActionDefinition {
|
|
132
141
|
name: string;
|
|
133
|
-
|
|
142
|
+
/** `actions.{name}.label`, or the humanized name when untranslated. */
|
|
143
|
+
label: TranslatedString;
|
|
134
144
|
icon?: string;
|
|
135
|
-
description
|
|
145
|
+
/** `actions.{name}.description`; absent when untranslated. */
|
|
146
|
+
description?: TranslatedString;
|
|
136
147
|
showedOn: string;
|
|
137
148
|
selectionRule?: string;
|
|
138
149
|
refreshOnCompleted: boolean;
|
|
139
|
-
|
|
150
|
+
/**
|
|
151
|
+
* The confirmation to ask before running, `actions.{name}.confirmation` or the explicit key the
|
|
152
|
+
* catalogue names. May contain `{count}`, the number of rows about to be acted on. Absent: no prompt.
|
|
153
|
+
*/
|
|
154
|
+
confirmation?: TranslatedString;
|
|
140
155
|
/**
|
|
141
156
|
* How prominently, and how warily, to present the action: 'primary', 'secondary', 'danger',
|
|
142
157
|
* 'warning'. Undefined renders the neutral default.
|
|
143
158
|
*
|
|
144
159
|
* Presentation only — the server decides who may see and run an action. A 'danger' variant just
|
|
145
|
-
* asks the button to look like what it does; pair it with `
|
|
160
|
+
* asks the button to look like what it does; pair it with a `confirmation` for anything
|
|
146
161
|
* irreversible, because the colour warns and the prompt is what actually prevents the accident.
|
|
147
162
|
*/
|
|
148
163
|
variant?: string;
|
|
149
164
|
offset: number;
|
|
150
165
|
/**
|
|
151
|
-
* True for the framework's built-in `New` and `Delete` (#460,
|
|
152
|
-
* `showedOn` and a `selectionRule` like any custom action (
|
|
153
|
-
*
|
|
154
|
-
* `/po/delete-many`, never `/actions/execute`. Absent for a custom action.
|
|
166
|
+
* True for the framework's built-in `New`, `Edit` and `Delete` (#460 D18, #467 D7): catalogue
|
|
167
|
+
* entries with a `showedOn` and a `selectionRule` like any custom action (the core's
|
|
168
|
+
* `actions.json` ships them; an app overrides or removes them in its own), but run through
|
|
169
|
+
* `/po/new`, the edit page and `/po/delete-many`, never `/actions/execute`. Absent for a custom action.
|
|
155
170
|
*/
|
|
156
171
|
isDefault?: boolean;
|
|
157
172
|
}
|
|
158
|
-
/** How many rows a grid lets the user select — what `<bs-datatable>` renders. */
|
|
159
|
-
export type SparkSelectionMode = 'none' | 'single' | 'multiple';
|
|
160
173
|
/**
|
|
161
|
-
*
|
|
174
|
+
* Whether a grid lets the user tick rows — what `<bs-datatable>` renders. There is no single
|
|
175
|
+
* selection (#467, D10): a selectable list is a checkbox list, and actions whose rule does not
|
|
176
|
+
* match the count are disabled rather than the selection trimmed.
|
|
177
|
+
*/
|
|
178
|
+
export type SparkSelectionMode = 'none' | 'multiple';
|
|
179
|
+
/**
|
|
180
|
+
* What a query definition (or a sub-query entry) declares (#460 D17): a fixed mode, or `'auto'` —
|
|
162
181
|
* the default, and what an absent field means — to derive it from the actions offered.
|
|
163
182
|
*/
|
|
164
183
|
export type SparkSelectionModeSetting = 'auto' | SparkSelectionMode;
|
|
184
|
+
/** The largest selection the server accepts in one request (`SparkDefaultActions.MaxSelectedItems`). */
|
|
185
|
+
export declare const SPARK_MAX_SELECTED_ITEMS = 200;
|
|
165
186
|
/**
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
*
|
|
187
|
+
* Whether an action needs ticked rows (#467, R1(4)): it has a rule, and the rule accepts at least
|
|
188
|
+
* one row. `=0` accepts none, so an action that runs only without a selection never makes a list
|
|
189
|
+
* selectable; an action without a rule acts on the query, not on rows.
|
|
190
|
+
*/
|
|
191
|
+
export declare function needsSelection(action: CustomActionDefinition): boolean;
|
|
192
|
+
/**
|
|
193
|
+
* The selection mode a grid renders (#467, R1).
|
|
173
194
|
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
195
|
+
* A declared `'none'` or `'multiple'` wins outright. `'auto'` (or nothing) derives it from
|
|
196
|
+
* `actions`, which must already be the **effective** list for this result — listed for the caller
|
|
197
|
+
* (the right), shown on queries, not withheld by `disabledActions` and not hidden by the recycle
|
|
198
|
+
* bin. Built-in Edit and Delete count like any other action. `'multiple'` when at least one of them
|
|
199
|
+
* {@link needsSelection}, else `'none'`, so a read-only user sees a list with no checkbox column.
|
|
176
200
|
*/
|
|
177
201
|
export declare function selectionModeFor(actions: CustomActionDefinition[], declared?: SparkSelectionModeSetting | null): SparkSelectionMode;
|
|
178
202
|
/**
|
|
@@ -229,7 +253,6 @@ export interface EntityAttributeDefinition {
|
|
|
229
253
|
description?: TranslatedString;
|
|
230
254
|
dataType: string;
|
|
231
255
|
isRequired: boolean;
|
|
232
|
-
isVisible: boolean;
|
|
233
256
|
isReadOnly: boolean;
|
|
234
257
|
order: number;
|
|
235
258
|
query?: string;
|
|
@@ -293,7 +316,8 @@ export interface AttributeGroup {
|
|
|
293
316
|
export interface EntityType {
|
|
294
317
|
id: string;
|
|
295
318
|
name: string;
|
|
296
|
-
description
|
|
319
|
+
/** The type's display name, resolved by the server (#467, D6; formerly `description`). */
|
|
320
|
+
label?: TranslatedString;
|
|
297
321
|
/**
|
|
298
322
|
* The backing CLR type, or absent for a JSON-only virtual type (#325).
|
|
299
323
|
*
|
|
@@ -369,7 +393,8 @@ export interface SparkQuerySortColumn {
|
|
|
369
393
|
export interface SparkQuery {
|
|
370
394
|
id: string;
|
|
371
395
|
name: string;
|
|
372
|
-
description
|
|
396
|
+
/** The query's display name, resolved by the server (#467; formerly `description`). */
|
|
397
|
+
label?: TranslatedString;
|
|
373
398
|
source: string;
|
|
374
399
|
alias?: string;
|
|
375
400
|
sortColumns: SparkQuerySortColumn[];
|
|
@@ -456,7 +481,7 @@ export interface QueryColumn extends SparkCellColumn {
|
|
|
456
481
|
* header sortable anyway. Neither side read it. The attribute-level `isSortable` on `EntityType`
|
|
457
482
|
* is the drag-reorder flag and stays.
|
|
458
483
|
*
|
|
459
|
-
* Absent means sortable
|
|
484
|
+
* Absent means sortable: a server predating the field still draws arrows.
|
|
460
485
|
*/
|
|
461
486
|
canSort?: boolean;
|
|
462
487
|
/** Whether the grid draws a filter cell for this column. Absent means filterable. */
|
|
@@ -467,26 +492,26 @@ export interface QueryColumn extends SparkCellColumn {
|
|
|
467
492
|
* stronger disclosure than filtering by one already known.
|
|
468
493
|
*/
|
|
469
494
|
canListDistincts?: boolean;
|
|
470
|
-
/**
|
|
471
|
-
* Whether the grid draws this column. `false` means the row carries the value but no column is
|
|
472
|
-
* rendered — for a renderer that needs a sibling value (a lock glyph beside a name) without
|
|
473
|
-
* spending a column on it. `showedOn` decides what ships; this decides what is drawn.
|
|
474
|
-
*/
|
|
475
|
-
isVisible?: boolean;
|
|
476
495
|
/** The query backing a Reference column, by name — the client's option source. */
|
|
477
496
|
query?: string;
|
|
478
497
|
}
|
|
479
498
|
/**
|
|
480
499
|
* One row: an id, a display string, and a value per column.
|
|
481
500
|
*
|
|
482
|
-
* Deliberately too weak to act on — no attribute metadata, no `can` block,
|
|
483
|
-
*
|
|
501
|
+
* Deliberately too weak to act on — no attribute metadata, no `can` block, because neither can be
|
|
502
|
+
* trusted from a projection. It does carry its document's `etag` (#467, D14), a version rather than
|
|
503
|
+
* a judgement, so a delete from the list says which version it removes.
|
|
484
504
|
*/
|
|
485
505
|
export interface QueryResultItem {
|
|
486
506
|
/** Never null and unique within a result; the server refuses anything else. */
|
|
487
507
|
id: string;
|
|
488
508
|
/** What to show when the row is named rather than tabulated (a reference picker's value). */
|
|
489
509
|
breadcrumb?: string;
|
|
510
|
+
/**
|
|
511
|
+
* The document's change vector when the list loaded (#467, D14). A delete sends it back; a row
|
|
512
|
+
* changed since is a 409. Absent for a row with no document behind it.
|
|
513
|
+
*/
|
|
514
|
+
etag?: string;
|
|
490
515
|
values: QueryResultItemValue[];
|
|
491
516
|
/** Presentation hints for the whole row. Keys arrive lower-cased. */
|
|
492
517
|
typeHints?: Record<string, string>;
|
|
@@ -527,8 +552,8 @@ export type SparkRow = QueryResultItem | PersistentObject | Record<string, unkno
|
|
|
527
552
|
* for its `objectId` as for its text, and a helper that discarded it would have to be replaced the
|
|
528
553
|
* first time a renderer wanted to link somewhere. `?.value` is the cost, once per call site.
|
|
529
554
|
*
|
|
530
|
-
* ⚠️ A value only reaches a grid row if its attribute is on the **query surface
|
|
531
|
-
*
|
|
555
|
+
* ⚠️ A value only reaches a grid row if its attribute is on the **query surface**, which also makes it a
|
|
556
|
+
* column: there is no shipped-but-not-drawn value (#264). An
|
|
532
557
|
* attribute marked `"showedOn": "PersistentObject"` is absent from a row by design, and this returns
|
|
533
558
|
* `undefined` for it; that is the first thing to check when a sibling read comes back empty.
|
|
534
559
|
*/
|
|
@@ -926,6 +951,13 @@ export declare function comparableValue(attribute: PersistentObjectAttribute | u
|
|
|
926
951
|
export declare function comparableFormValue(value: unknown): string;
|
|
927
952
|
/** Whether two form-dict values hold the same content (see {@link comparableFormValue}). */
|
|
928
953
|
export declare function formValuesEqual(a: unknown, b: unknown): boolean;
|
|
954
|
+
/**
|
|
955
|
+
* The prompt to show before running `action` on `count` rows, with `{count}` substituted, or null
|
|
956
|
+
* when the action asks for no confirmation (#467, D7).
|
|
957
|
+
*/
|
|
958
|
+
export declare function confirmationText(action: CustomActionDefinition | undefined | null, count: number, lang?: string): string | null;
|
|
959
|
+
/** The built-in action named `name` (`New`, `Edit`, `Delete`) in `actions`, when the server listed it. */
|
|
960
|
+
export declare function builtInAction(actions: CustomActionDefinition[], name: 'New' | 'Edit' | 'Delete'): CustomActionDefinition | undefined;
|
|
929
961
|
/** Whether `showedOn` offers the action on a query: `"query"` or `"both"`, in any casing. */
|
|
930
962
|
export declare function isShowedOnQuery(showedOn: string | undefined | null): boolean;
|
|
931
963
|
/** Whether `showedOn` offers the action on a detail page: `"detail"` or `"both"`, in any casing. */
|
|
@@ -937,7 +969,7 @@ export declare function isShowedOnDetail(showedOn: string | undefined | null): b
|
|
|
937
969
|
* and `"both"` — as the server model and the custom-actions guide have always
|
|
938
970
|
* documented — compared case-insensitively (#460 M15: `"Both"` used to render nowhere).
|
|
939
971
|
*
|
|
940
|
-
* The built-in New and Delete (`isDefault`, #460 D18) are left out: they are not executed as
|
|
972
|
+
* The built-in New, Edit and Delete (`isDefault`, #460 D18, #467 D7) are left out: they are not executed as
|
|
941
973
|
* custom actions, and the grid offers them itself (see {@link defaultQueryActions}).
|
|
942
974
|
*
|
|
943
975
|
* ⚠️ This narrows what is DISPLAYED. It is NOT an authorization boundary: the grant
|
|
@@ -948,8 +980,8 @@ export declare function filterQueryActions(actions: CustomActionDefinition[]): C
|
|
|
948
980
|
/** The custom actions a detail page should offer — the detail-side counterpart of {@link filterQueryActions}. */
|
|
949
981
|
export declare function filterDetailActions(actions: CustomActionDefinition[]): CustomActionDefinition[];
|
|
950
982
|
/**
|
|
951
|
-
* The built-in New and Delete the server listed for this caller (#460,
|
|
952
|
-
* includes the query side. Present only when the caller holds `New/T` or `Delete/T`.
|
|
983
|
+
* The built-in New, Edit and Delete the server listed for this caller (#460 D18, #467 D7), when their `showedOn`
|
|
984
|
+
* includes the query side. Present only when the caller holds `New/T`, `Edit/T` or `Delete/T`.
|
|
953
985
|
*/
|
|
954
986
|
export declare function defaultQueryActions(actions: CustomActionDefinition[]): CustomActionDefinition[];
|
|
955
987
|
/**
|
|
@@ -991,7 +1023,8 @@ export interface RefreshedOption {
|
|
|
991
1023
|
export interface AttributeOverlay {
|
|
992
1024
|
isRequired?: boolean;
|
|
993
1025
|
isReadOnly?: boolean;
|
|
994
|
-
|
|
1026
|
+
/** Where the attribute is drawn for this object; an action sets it on load, new or refresh (#264). */
|
|
1027
|
+
showedOn?: ShowedOn | string;
|
|
995
1028
|
rules?: ValidationRule[];
|
|
996
1029
|
query?: string;
|
|
997
1030
|
/** `undefined` means the hook did not touch the options; an empty array means there are none. */
|
|
@@ -1001,7 +1034,9 @@ export type RefreshOverlay = Record<string, AttributeOverlay>;
|
|
|
1001
1034
|
/** Applies an overlay to one attribute definition, returning a new object when anything changed. */
|
|
1002
1035
|
export declare function applyOverlay(attr: EntityAttributeDefinition, overlay: AttributeOverlay | undefined): EntityAttributeDefinition;
|
|
1003
1036
|
/**
|
|
1004
|
-
* Reads a refresh response into an overlay
|
|
1037
|
+
* Reads a refresh response into an overlay — or a loaded or new object, whose attributes carry the same
|
|
1038
|
+
* server-owned presentation: what `OnLoadAsync`/`OnNewAsync` set (`showedOn`, `isRequired`, `isReadOnly`) applies
|
|
1039
|
+
* from the first render, not only after the first refresh (#264, G5/G7).
|
|
1005
1040
|
*
|
|
1006
1041
|
* Everything here is presentation the server owns outright, so it is taken verbatim — there is no
|
|
1007
1042
|
* merging to do on this half, only on values.
|
|
@@ -141,9 +141,9 @@ export declare class SparkModerationService {
|
|
|
141
141
|
}>;
|
|
142
142
|
/**
|
|
143
143
|
* The caller's own reputation, shared by every caller in flight at once: the badge and the
|
|
144
|
-
* review-queue link both re-read on the same navigation and cost one request.
|
|
144
|
+
* review-queue link both re-read on the same navigation and cost one request. `null` signed out.
|
|
145
145
|
*/
|
|
146
|
-
ownReputation(): Promise<ModerationReputation>;
|
|
146
|
+
ownReputation(): Promise<ModerationReputation | null>;
|
|
147
147
|
/** Casts (+1 / −1) or withdraws (0) the caller's vote; resolves to the target's new state. */
|
|
148
148
|
vote(type: string, id: string, direction: -1 | 0 | 1): Promise<ModerationVoteState>;
|
|
149
149
|
/**
|
|
@@ -159,8 +159,12 @@ export declare class SparkModerationService {
|
|
|
159
159
|
unlock(type: string, id: string): Promise<void>;
|
|
160
160
|
/** What the moderator panel shows about a target, including which tools the caller holds. */
|
|
161
161
|
status(type: string, id: string): Promise<ModerationStatus>;
|
|
162
|
-
/**
|
|
163
|
-
|
|
162
|
+
/**
|
|
163
|
+
* A user's reputation; the caller's own when `userId` is omitted (with privileges and suspension).
|
|
164
|
+
* `null` for an anonymous caller: the server answers it 200 with no result rather than 401, so a
|
|
165
|
+
* badge on a page anyone may read never sends the app to the sign-in page.
|
|
166
|
+
*/
|
|
167
|
+
reputation(userId?: string): Promise<ModerationReputation | null>;
|
|
164
168
|
/** The caller's own ledger, newest first. Voters are never named; a reversal reads "Voting corrected (−N)". */
|
|
165
169
|
history(take?: number): Promise<ModerationReputationLine[]>;
|
|
166
170
|
cases(status?: string, skip?: number, take?: number): Promise<ModerationCaseSummary[]>;
|
|
@@ -117,6 +117,9 @@ export declare class AsDetailTypePipe implements PipeTransform {
|
|
|
117
117
|
/**
|
|
118
118
|
* The columns of an AsDetail table: the row type's visible attributes, in order — minus those a
|
|
119
119
|
* registered row renderer draws (`rowComponent`), when the host passes its renderer registry.
|
|
120
|
+
*
|
|
121
|
+
* An attribute the row type's model draws nowhere (`showedOn: None`, #264) is not a column. Columns are per
|
|
122
|
+
* type, so they come from the model; a runtime `showedOn` on one row cannot add or remove a column.
|
|
120
123
|
*/
|
|
121
124
|
export declare class AsDetailColumnsPipe implements PipeTransform {
|
|
122
125
|
transform(attr: EntityAttributeDefinition, asDetailTypes: Record<string, EntityType>, renderers?: readonly SparkAttributeRendererRegistration[] | null): EntityAttributeDefinition[];
|
|
@@ -16,6 +16,10 @@ export declare class SparkPoCreateComponent {
|
|
|
16
16
|
validationErrors: import("@angular/core").WritableSignal<ValidationError[]>;
|
|
17
17
|
isSaving: import("@angular/core").WritableSignal<boolean>;
|
|
18
18
|
private allEntityTypes;
|
|
19
|
+
/**
|
|
20
|
+
* The errors the form cannot show next to a field: those with no attribute, and those on an attribute the
|
|
21
|
+
* form does not draw (#264, G6). Those used to be swallowed; Vidyano promotes them to a notification too.
|
|
22
|
+
*/
|
|
19
23
|
generalErrors: import("@angular/core").Signal<ValidationError[]>;
|
|
20
24
|
/**
|
|
21
25
|
* The parent a sub-query card's New passed in the URL (`parentId`, `parentType`, `queryId`), or
|
|
@@ -60,8 +60,12 @@ export declare class SparkPoDetailComponent {
|
|
|
60
60
|
asDetailReferenceOptions: import("@angular/core").WritableSignal<Record<string, Record<string, QueryResultItem[]>>>;
|
|
61
61
|
type: string;
|
|
62
62
|
id: string;
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
/** The catalogue's Edit (#467, D8) when this page offers it: listed for the caller, on the detail side, and allowed on this row. */
|
|
64
|
+
editAction: import("@angular/core").WritableSignal<CustomActionDefinition | null>;
|
|
65
|
+
/** The catalogue's Delete, on the same terms as {@link editAction}. */
|
|
66
|
+
deleteAction: import("@angular/core").WritableSignal<CustomActionDefinition | null>;
|
|
67
|
+
canEdit: import("@angular/core").Signal<boolean>;
|
|
68
|
+
canDelete: import("@angular/core").Signal<boolean>;
|
|
65
69
|
customActions: import("@angular/core").WritableSignal<CustomActionDefinition[]>;
|
|
66
70
|
/** Type-level rights, kept for the add-on context; null until loaded. */
|
|
67
71
|
permissions: import("@angular/core").WritableSignal<EntityPermissions | null>;
|
|
@@ -104,6 +108,10 @@ export declare class SparkPoDetailComponent {
|
|
|
104
108
|
private loadItem;
|
|
105
109
|
/** (Re)loads the object, its type, rights and actions. Also what add-ons call via `context.reload()`. */
|
|
106
110
|
load(): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Drawn from the loaded object's own `showedOn`, falling back to the model's (#264, G-Q3): an action sets
|
|
113
|
+
* it per object in `OnLoadAsync` — a stolen car's police report number is shown, the model says `None`.
|
|
114
|
+
*/
|
|
107
115
|
visibleAttributes: import("@angular/core").Signal<EntityAttributeDefinition[]>;
|
|
108
116
|
private static readonly DEFAULT_TAB;
|
|
109
117
|
ungroupedAttributes: import("@angular/core").Signal<EntityAttributeDefinition[]>;
|
|
@@ -125,6 +133,8 @@ export declare class SparkPoDetailComponent {
|
|
|
125
133
|
* a louder style. Restricted to a known set rather than interpolated, because the value arrives
|
|
126
134
|
* from a JSON file and must not be able to put arbitrary classes on the button.
|
|
127
135
|
*/
|
|
136
|
+
/** Edit's and Delete's button classes: the catalogue's variant, else the look they always had. */
|
|
137
|
+
protected builtInActionClass(action: CustomActionDefinition, fallback: 'primary' | 'danger'): string;
|
|
128
138
|
protected customActionClass(action: CustomActionDefinition): string;
|
|
129
139
|
/**
|
|
130
140
|
* The action currently running, or null. Drives the disabled state on every custom-action
|
|
@@ -147,6 +147,11 @@ export declare class SparkPoEditComponent {
|
|
|
147
147
|
* is not the question's author edits only its translations; the server drops the rest from the
|
|
148
148
|
* save anyway). Shared by the form and {@link getEditableAttributes}, so what is drawn, what is
|
|
149
149
|
* initialised and what is saved agree. A refresh overlay can still lift it.
|
|
150
|
+
* <para>
|
|
151
|
+
* The same goes for where an attribute is drawn and whether it is required (#264, G5/G7): an action
|
|
152
|
+
* sets the runtime `showedOn`/`isRequired` in `OnLoadAsync` (a stolen car shows its police report
|
|
153
|
+
* number, required), and the form honours that from its first render rather than after a refresh.
|
|
154
|
+
* </para>
|
|
150
155
|
*/
|
|
151
156
|
formEntityType: import("@angular/core").Signal<EntityType | null>;
|
|
152
157
|
type: string;
|
|
@@ -160,6 +165,10 @@ export declare class SparkPoEditComponent {
|
|
|
160
165
|
validationErrors: import("@angular/core").WritableSignal<ValidationError[]>;
|
|
161
166
|
isSaving: import("@angular/core").WritableSignal<boolean>;
|
|
162
167
|
private allEntityTypes;
|
|
168
|
+
/**
|
|
169
|
+
* The errors the form cannot show next to a field: those with no attribute, and those on an attribute the
|
|
170
|
+
* form does not draw (#264, G6). Those used to be swallowed; Vidyano promotes them to a notification too.
|
|
171
|
+
*/
|
|
163
172
|
generalErrors: import("@angular/core").Signal<ValidationError[]>;
|
|
164
173
|
/** After a 409 was merged: what they changed, and that nothing has been saved yet. */
|
|
165
174
|
private readonly conflictNoticeText;
|
|
@@ -212,6 +221,13 @@ export declare class SparkPoEditComponent {
|
|
|
212
221
|
* then dropped on the floor and refused by the server as missing — with no way out of the form.
|
|
213
222
|
* The overlay is the form's, bound two-way, so the two halves cannot drift again.
|
|
214
223
|
*/
|
|
224
|
+
/**
|
|
225
|
+
* The attributes {@link formDataFrom} gives a slot: the editable ones, plus those the model makes editable
|
|
226
|
+
* but this object's load made read-only (#264). A refresh can lift a load-time `isReadOnly` (a stolen car's
|
|
227
|
+
* plate, once the car is back in use), and the control must then show the loaded value, not an empty
|
|
228
|
+
* required field. Only {@link getEditableAttributes} decides what is saved, so a slot alone sends nothing.
|
|
229
|
+
*/
|
|
230
|
+
private formDataAttributes;
|
|
215
231
|
getEditableAttributes(): import("@mintplayer/ng-spark/models").EntityAttributeDefinition[];
|
|
216
232
|
onSave(): Promise<void>;
|
|
217
233
|
onCancel(): void;
|
|
@@ -514,6 +514,7 @@ export declare class SparkReferencePickerComponent {
|
|
|
514
514
|
pagination: import("@angular/core").WritableSignal<PaginationResponse<QueryResultItem> | undefined>;
|
|
515
515
|
settings: import("@angular/core").WritableSignal<DatatableSettings>;
|
|
516
516
|
searchTerm: string;
|
|
517
|
+
/** The picker lists query rows, so its columns are the query's: `showedOn` includes Query (#264; not None). */
|
|
517
518
|
visibleAttributes: import("@angular/core").Signal<import("@mintplayer/ng-spark/models").EntityAttributeDefinition[]>;
|
|
518
519
|
rows: import("@angular/core").Signal<QueryResultItem[]>;
|
|
519
520
|
displayValue: import("@angular/core").Signal<string>;
|
|
@@ -3,7 +3,7 @@ import { TemplateRef } from "@angular/core";
|
|
|
3
3
|
import { Color } from "@mintplayer/ng-bootstrap";
|
|
4
4
|
import { SparkLanguageService } from "@mintplayer/ng-spark/services";
|
|
5
5
|
import { SparkQueryToolbarAction } from "@mintplayer/ng-spark/grid";
|
|
6
|
-
import { CustomActionDefinition, QueryColumn, QueryColumnFilter, QueryResultItem, SparkDeletedFilter } from "@mintplayer/ng-spark/models";
|
|
6
|
+
import { CustomActionDefinition, QueryColumn, QueryColumnFilter, QueryResultItem, SparkDeletedFilter, SparkSelectionModeSetting } from "@mintplayer/ng-spark/models";
|
|
7
7
|
import { SparkQueryListContext } from "@mintplayer/ng-spark/panels";
|
|
8
8
|
/**
|
|
9
9
|
* The routed query page: chrome around one {@link SparkQueryGridComponent}.
|
|
@@ -31,6 +31,11 @@ export declare class SparkQueryListComponent {
|
|
|
31
31
|
protected readonly lang: SparkLanguageService;
|
|
32
32
|
extraActionsTemplate: import("@angular/core").InputSignal<TemplateRef<void> | null>;
|
|
33
33
|
showCustomActions: import("@angular/core").InputSignal<boolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Overrides the query's own `selectionMode` (#467, R3), as the sub-query card's input does: for a
|
|
36
|
+
* host that embeds this page and wants, say, `'none'` on a list the actions would make selectable.
|
|
37
|
+
*/
|
|
38
|
+
selectionMode: import("@angular/core").InputSignal<SparkSelectionModeSetting | null>;
|
|
34
39
|
/**
|
|
35
40
|
* Forwarded to the grid, so a query PAGE can replace its row links — the same reason the card
|
|
36
41
|
* forwards it. Without this the escape hatch existed only for a directly-embedded grid.
|
|
@@ -147,6 +152,11 @@ export declare class SparkQueryListComponent {
|
|
|
147
152
|
"required": false;
|
|
148
153
|
"isSignal": true;
|
|
149
154
|
};
|
|
155
|
+
"selectionMode": {
|
|
156
|
+
"alias": "selectionMode";
|
|
157
|
+
"required": false;
|
|
158
|
+
"isSignal": true;
|
|
159
|
+
};
|
|
150
160
|
"rowRoute": {
|
|
151
161
|
"alias": "rowRoute";
|
|
152
162
|
"required": false;
|