@mintplayer/ng-spark 22.22.0 → 22.24.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.
Files changed (68) hide show
  1. package/README.md +181 -0
  2. package/fesm2022/mintplayer-ng-spark-attribute-description.mjs +100 -47
  3. package/fesm2022/mintplayer-ng-spark-attribute-description.mjs.map +1 -1
  4. package/fesm2022/mintplayer-ng-spark-client-operations.mjs +308 -329
  5. package/fesm2022/mintplayer-ng-spark-client-operations.mjs.map +1 -1
  6. package/fesm2022/mintplayer-ng-spark-column-filter.mjs +175 -135
  7. package/fesm2022/mintplayer-ng-spark-column-filter.mjs.map +1 -1
  8. package/fesm2022/mintplayer-ng-spark-grid.mjs +2259 -1117
  9. package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
  10. package/fesm2022/mintplayer-ng-spark-history.mjs +611 -0
  11. package/fesm2022/mintplayer-ng-spark-history.mjs.map +1 -0
  12. package/fesm2022/mintplayer-ng-spark-icon.mjs +64 -27
  13. package/fesm2022/mintplayer-ng-spark-icon.mjs.map +1 -1
  14. package/fesm2022/mintplayer-ng-spark-models.mjs +365 -753
  15. package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
  16. package/fesm2022/mintplayer-ng-spark-moderation.mjs +1212 -0
  17. package/fesm2022/mintplayer-ng-spark-moderation.mjs.map +1 -0
  18. package/fesm2022/mintplayer-ng-spark-panels.mjs +52 -0
  19. package/fesm2022/mintplayer-ng-spark-panels.mjs.map +1 -0
  20. package/fesm2022/mintplayer-ng-spark-pipes.mjs +1122 -765
  21. package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
  22. package/fesm2022/mintplayer-ng-spark-po-create.mjs +273 -169
  23. package/fesm2022/mintplayer-ng-spark-po-create.mjs.map +1 -1
  24. package/fesm2022/mintplayer-ng-spark-po-detail.mjs +786 -410
  25. package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
  26. package/fesm2022/mintplayer-ng-spark-po-edit.mjs +292 -284
  27. package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -1
  28. package/fesm2022/mintplayer-ng-spark-po-form.mjs +2187 -1225
  29. package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -1
  30. package/fesm2022/mintplayer-ng-spark-query-list.mjs +516 -303
  31. package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
  32. package/fesm2022/mintplayer-ng-spark-renderers.mjs +17 -55
  33. package/fesm2022/mintplayer-ng-spark-renderers.mjs.map +1 -1
  34. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +216 -177
  35. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs.map +1 -1
  36. package/fesm2022/mintplayer-ng-spark-routes.mjs +24 -28
  37. package/fesm2022/mintplayer-ng-spark-routes.mjs.map +1 -1
  38. package/fesm2022/mintplayer-ng-spark-services.mjs +625 -640
  39. package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
  40. package/fesm2022/mintplayer-ng-spark-shell.mjs +1013 -397
  41. package/fesm2022/mintplayer-ng-spark-shell.mjs.map +1 -1
  42. package/fesm2022/mintplayer-ng-spark-soft-delete.mjs +294 -0
  43. package/fesm2022/mintplayer-ng-spark-soft-delete.mjs.map +1 -0
  44. package/fesm2022/mintplayer-ng-spark.mjs +13 -50
  45. package/fesm2022/mintplayer-ng-spark.mjs.map +1 -1
  46. package/package.json +17 -1
  47. package/types/mintplayer-ng-spark-attribute-description.d.ts +25 -18
  48. package/types/mintplayer-ng-spark-client-operations.d.ts +133 -160
  49. package/types/mintplayer-ng-spark-column-filter.d.ts +73 -55
  50. package/types/mintplayer-ng-spark-grid.d.ts +885 -448
  51. package/types/mintplayer-ng-spark-history.d.ts +223 -0
  52. package/types/mintplayer-ng-spark-icon.d.ts +15 -13
  53. package/types/mintplayer-ng-spark-models.d.ts +624 -573
  54. package/types/mintplayer-ng-spark-moderation.d.ts +402 -0
  55. package/types/mintplayer-ng-spark-panels.d.ts +108 -0
  56. package/types/mintplayer-ng-spark-pipes.d.ts +120 -149
  57. package/types/mintplayer-ng-spark-po-create.d.ts +46 -37
  58. package/types/mintplayer-ng-spark-po-detail.d.ts +177 -117
  59. package/types/mintplayer-ng-spark-po-edit.d.ts +64 -65
  60. package/types/mintplayer-ng-spark-po-form.d.ts +507 -371
  61. package/types/mintplayer-ng-spark-query-list.d.ts +118 -82
  62. package/types/mintplayer-ng-spark-renderers.d.ts +79 -85
  63. package/types/mintplayer-ng-spark-retry-action-modal.d.ts +31 -34
  64. package/types/mintplayer-ng-spark-routes.d.ts +7 -11
  65. package/types/mintplayer-ng-spark-services.d.ts +377 -261
  66. package/types/mintplayer-ng-spark-shell.d.ts +209 -128
  67. package/types/mintplayer-ng-spark-soft-delete.d.ts +90 -0
  68. package/types/mintplayer-ng-spark.d.ts +7 -12
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mintplayer/ng-spark",
3
3
  "private": false,
4
- "version": "22.22.0",
4
+ "version": "22.24.0",
5
5
  "description": "Angular component library for MintPlayer.Spark CRUD applications",
6
6
  "repository": {
7
7
  "type": "git",
@@ -45,6 +45,10 @@
45
45
  "types": "./types/mintplayer-ng-spark-grid.d.ts",
46
46
  "default": "./fesm2022/mintplayer-ng-spark-grid.mjs"
47
47
  },
48
+ "./history": {
49
+ "types": "./types/mintplayer-ng-spark-history.d.ts",
50
+ "default": "./fesm2022/mintplayer-ng-spark-history.mjs"
51
+ },
48
52
  "./icon": {
49
53
  "types": "./types/mintplayer-ng-spark-icon.d.ts",
50
54
  "default": "./fesm2022/mintplayer-ng-spark-icon.mjs"
@@ -53,6 +57,14 @@
53
57
  "types": "./types/mintplayer-ng-spark-models.d.ts",
54
58
  "default": "./fesm2022/mintplayer-ng-spark-models.mjs"
55
59
  },
60
+ "./moderation": {
61
+ "types": "./types/mintplayer-ng-spark-moderation.d.ts",
62
+ "default": "./fesm2022/mintplayer-ng-spark-moderation.mjs"
63
+ },
64
+ "./panels": {
65
+ "types": "./types/mintplayer-ng-spark-panels.d.ts",
66
+ "default": "./fesm2022/mintplayer-ng-spark-panels.mjs"
67
+ },
56
68
  "./pipes": {
57
69
  "types": "./types/mintplayer-ng-spark-pipes.d.ts",
58
70
  "default": "./fesm2022/mintplayer-ng-spark-pipes.mjs"
@@ -96,6 +108,10 @@
96
108
  "./shell": {
97
109
  "types": "./types/mintplayer-ng-spark-shell.d.ts",
98
110
  "default": "./fesm2022/mintplayer-ng-spark-shell.mjs"
111
+ },
112
+ "./soft-delete": {
113
+ "types": "./types/mintplayer-ng-spark-soft-delete.d.ts",
114
+ "default": "./fesm2022/mintplayer-ng-spark-soft-delete.mjs"
99
115
  }
100
116
  },
101
117
  "type": "module",
@@ -1,7 +1,6 @@
1
- import * as _angular_core from '@angular/core';
2
- import { TranslatedString } from '@mintplayer/ng-spark/models';
3
-
4
- type SparkAttributeDescriptionPosition = 'top' | 'bottom' | 'start' | 'end';
1
+ import { TranslatedString } from "@mintplayer/ng-spark/models";
2
+ import * as i0 from "@angular/core";
3
+ export type SparkAttributeDescriptionPosition = 'top' | 'bottom' | 'start' | 'end';
5
4
  /**
6
5
  * The [i] beside an attribute label: a focusable button whose tooltip shows the attribute's
7
6
  * `description` (#348). Renders nothing when the model declares no description, so every label
@@ -14,17 +13,25 @@ type SparkAttributeDescriptionPosition = 'top' | 'bottom' | 'start' | 'end';
14
13
  * Clicks are stopped: the [i] lives inside sortable grid headers and `<label for>` elements, and
15
14
  * must neither toggle the sort nor move focus into the input.
16
15
  */
17
- declare class SparkAttributeDescriptionComponent {
18
- /** The attribute's `description`; `undefined` (the common case) renders nothing. */
19
- description: _angular_core.InputSignal<TranslatedString | undefined>;
20
- /** Where the tooltip opens relative to the [i]. */
21
- position: _angular_core.InputSignal<SparkAttributeDescriptionPosition>;
22
- /** Resolved for the current language; re-evaluates when the user switches language. */
23
- text: _angular_core.Signal<string>;
24
- onClick(event: MouseEvent): void;
25
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkAttributeDescriptionComponent, never>;
26
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SparkAttributeDescriptionComponent, "spark-attribute-description", never, { "description": { "alias": "description"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
27
- }
28
-
29
- export { SparkAttributeDescriptionComponent };
30
- export type { SparkAttributeDescriptionPosition };
16
+ export declare class SparkAttributeDescriptionComponent {
17
+ /** The attribute's `description`; `undefined` (the common case) renders nothing. */
18
+ description: import("@angular/core").InputSignal<TranslatedString | undefined>;
19
+ /** Where the tooltip opens relative to the [i]. */
20
+ position: import("@angular/core").InputSignal<SparkAttributeDescriptionPosition>;
21
+ /** Resolved for the current language; re-evaluates when the user switches language. */
22
+ text: import("@angular/core").Signal<string>;
23
+ onClick(event: MouseEvent): void;
24
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkAttributeDescriptionComponent, never>;
25
+ static ɵcmp: i0.ɵɵComponentDeclaration<SparkAttributeDescriptionComponent, "spark-attribute-description", never, {
26
+ "description": {
27
+ "alias": "description";
28
+ "required": false;
29
+ "isSignal": true;
30
+ };
31
+ "position": {
32
+ "alias": "position";
33
+ "required": false;
34
+ "isSignal": true;
35
+ };
36
+ }, {}, never, never, true, never>;
37
+ }
@@ -1,90 +1,71 @@
1
- import { PersistentObject } from '@mintplayer/ng-spark/models';
2
- import * as i0 from '@angular/core';
3
- import { InjectionToken, EnvironmentProviders } from '@angular/core';
4
-
5
- declare enum NotificationKind {
6
- Info = 0,
7
- Success = 1,
8
- Warning = 2,
9
- Error = 3
1
+ import { PersistentObject } from "@mintplayer/ng-spark/models";
2
+ import * as i0 from "@angular/core";
3
+ import { EnvironmentProviders, InjectionToken } from "@angular/core";
4
+ export declare enum NotificationKind {
5
+ Info = 0,
6
+ Success = 1,
7
+ Warning = 2,
8
+ Error = 3
10
9
  }
11
- interface NavigateOperation {
12
- type: 'navigate';
13
- objectTypeId?: string;
14
- id?: string;
15
- routeName?: string;
10
+ export interface NavigateOperation {
11
+ type: 'navigate';
12
+ objectTypeId?: string;
13
+ id?: string;
14
+ routeName?: string;
16
15
  }
17
- interface NotifyOperation {
18
- type: 'notify';
19
- message: string;
20
- kind: NotificationKind;
21
- durationMs?: number;
16
+ export interface NotifyOperation {
17
+ type: 'notify';
18
+ message: string;
19
+ kind: NotificationKind;
20
+ durationMs?: number;
22
21
  }
23
- interface RefreshAttributeOperation {
24
- type: 'refreshAttribute';
25
- objectTypeId: string;
26
- id: string;
27
- attributeName: string;
28
- value?: unknown;
29
- /**
30
- * Nested rows of an `AsDetail` attribute. A loaded AsDetail attribute carries its rows in
31
- * `object` / `objects` and leaves `value` null, so a patch limited to `value` could never
32
- * refresh a detail grid -- it always sent null, and a null over a null repaints nothing.
33
- *
34
- * An empty `objects` array means the grid is now empty, and is distinct from omitting it.
35
- */
36
- object?: unknown;
37
- objects?: unknown[];
22
+ export interface RefreshAttributeOperation {
23
+ type: 'refreshAttribute';
24
+ objectTypeId: string;
25
+ id: string;
26
+ attributeName: string;
27
+ value?: unknown;
28
+ /**
29
+ * Nested rows of an `AsDetail` attribute. A loaded AsDetail attribute carries its rows in
30
+ * `object` / `objects` and leaves `value` null, so a patch limited to `value` could never
31
+ * refresh a detail grid -- it always sent null, and a null over a null repaints nothing.
32
+ *
33
+ * An empty `objects` array means the grid is now empty, and is distinct from omitting it.
34
+ */
35
+ object?: unknown;
36
+ objects?: unknown[];
38
37
  }
39
- interface RefreshQueryOperation {
40
- type: 'refreshQuery';
41
- queryId: string;
38
+ export interface RefreshQueryOperation {
39
+ type: 'refreshQuery';
40
+ queryId: string;
42
41
  }
43
- type DisableTarget = {
44
- kind: 'persistentObject';
45
- objectTypeId: string;
46
- id: string;
47
- } | {
48
- kind: 'query';
49
- queryId: string;
50
- } | {
51
- kind: 'currentResponse';
52
- } | {
53
- kind: 'session';
54
- };
55
- interface DisableActionOperation {
56
- type: 'disableAction';
57
- actionName: string;
58
- target: DisableTarget;
59
- }
60
- interface RetryOperation {
61
- type: 'retry';
62
- step: number;
63
- title: string;
64
- options: string[];
65
- defaultOption?: string | null;
66
- persistentObject?: PersistentObject | null;
67
- message?: string | null;
42
+ export interface RetryOperation {
43
+ type: 'retry';
44
+ step: number;
45
+ title: string;
46
+ options: string[];
47
+ defaultOption?: string | null;
48
+ persistentObject?: PersistentObject | null;
49
+ message?: string | null;
68
50
  }
69
51
  /**
70
52
  * Discriminated union of known operation types, plus an open shape for unknown
71
53
  * future operations. Handlers should narrow via the `type` discriminator before
72
54
  * accessing fields specific to their operation type.
73
55
  */
74
- type ClientOperation = NavigateOperation | NotifyOperation | RefreshAttributeOperation | RefreshQueryOperation | DisableActionOperation | RetryOperation | {
75
- type: string;
76
- [key: string]: unknown;
56
+ export type ClientOperation = NavigateOperation | NotifyOperation | RefreshAttributeOperation | RefreshQueryOperation | RetryOperation | {
57
+ type: string;
58
+ [key: string]: unknown;
77
59
  };
78
60
  /**
79
61
  * Wire envelope returned by every action endpoint. `result` carries the primary
80
62
  * payload (the PersistentObject for a Create, the QueryResult for an Execute,
81
63
  * etc.); `operations` carries the side-effects the frontend dispatches.
82
64
  */
83
- interface ClientOperationEnvelope<T = unknown> {
84
- result: T | null;
85
- operations: ClientOperation[];
65
+ export interface ClientOperationEnvelope<T = unknown> {
66
+ result: T | null;
67
+ operations: ClientOperation[];
86
68
  }
87
-
88
69
  /**
89
70
  * Routes received operations to registered handlers. Unknown operation types
90
71
  * (no matching registration) are silently dropped — this is the forward-compat
@@ -105,41 +86,39 @@ interface ClientOperationEnvelope<T = unknown> {
105
86
  * built-in `notify` handler renders via Angular interpolation (escaped) so
106
87
  * it's safe to pass through, but anything more powerful must validate.
107
88
  */
108
- declare class SparkClientOperationDispatcher {
109
- private readonly handlerMap;
110
- constructor();
111
- dispatch(operations: readonly ClientOperation[] | null | undefined): void;
112
- static ɵfac: i0.ɵɵFactoryDeclaration<SparkClientOperationDispatcher, never>;
113
- static ɵprov: i0.ɵɵInjectableDeclaration<SparkClientOperationDispatcher>;
89
+ export declare class SparkClientOperationDispatcher {
90
+ private readonly handlerMap;
91
+ constructor();
92
+ dispatch(operations: readonly ClientOperation[] | null | undefined): void;
93
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkClientOperationDispatcher, never>;
94
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
114
95
  }
115
-
116
96
  /**
117
97
  * A handler for a specific operation type. Receives the operation and
118
98
  * executes the side-effect (e.g. show a toast, navigate, refresh a query).
119
99
  * Handlers should `as`-narrow the operation to the type they registered for.
120
100
  */
121
- type ClientOperationHandler = (operation: ClientOperation) => void;
101
+ export type ClientOperationHandler = (operation: ClientOperation) => void;
122
102
  /**
123
103
  * One entry in the multi-provider registration. Apps can register custom
124
104
  * handlers alongside the built-in ones to extend the operation set with
125
105
  * app-specific operation types.
126
106
  */
127
- interface ClientOperationHandlerRegistration {
128
- type: string;
129
- handler: ClientOperationHandler;
107
+ export interface ClientOperationHandlerRegistration {
108
+ type: string;
109
+ handler: ClientOperationHandler;
130
110
  }
131
111
  /**
132
112
  * Multi-provider token. `provideSparkClientOperations()` registers the
133
113
  * built-in handlers; apps can add their own with additional `multi: true`
134
114
  * providers using this token.
135
115
  */
136
- declare const SPARK_CLIENT_OPERATION_HANDLERS: InjectionToken<readonly ClientOperationHandlerRegistration[]>;
137
-
138
- interface SparkToast {
139
- id: string;
140
- message: string;
141
- kind: NotificationKind;
142
- durationMs: number;
116
+ export declare const SPARK_CLIENT_OPERATION_HANDLERS: InjectionToken<readonly ClientOperationHandlerRegistration[]>;
117
+ export interface SparkToast {
118
+ id: string;
119
+ message: string;
120
+ kind: NotificationKind;
121
+ durationMs: number;
143
122
  }
144
123
  /**
145
124
  * Holds the active toasts as a signal. The `<spark-toast-container>` component
@@ -148,23 +127,21 @@ interface SparkToast {
148
127
  * Auto-dismissal: each toast schedules its own removal after `durationMs`. Pass
149
128
  * `0` to make a toast sticky (manual dismissal only).
150
129
  */
151
- declare class SparkNotificationService {
152
- private readonly _toasts;
153
- readonly toasts: i0.Signal<readonly SparkToast[]>;
154
- show(message: string, kind?: NotificationKind, durationMs?: number): void;
155
- dismiss(id: string): void;
156
- clear(): void;
157
- static ɵfac: i0.ɵɵFactoryDeclaration<SparkNotificationService, never>;
158
- static ɵprov: i0.ɵɵInjectableDeclaration<SparkNotificationService>;
130
+ export declare class SparkNotificationService {
131
+ private readonly _toasts;
132
+ readonly toasts: import("@angular/core").Signal<readonly SparkToast[]>;
133
+ show(message: string, kind?: NotificationKind, durationMs?: number): void;
134
+ dismiss(id: string): void;
135
+ clear(): void;
136
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkNotificationService, never>;
137
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
159
138
  }
160
-
161
- declare class SparkToastContainerComponent {
162
- protected readonly notifications: SparkNotificationService;
163
- protected readonly Kind: typeof NotificationKind;
164
- static ɵfac: i0.ɵɵFactoryDeclaration<SparkToastContainerComponent, never>;
165
- static ɵcmp: i0.ɵɵComponentDeclaration<SparkToastContainerComponent, "spark-toast-container", never, {}, {}, never, never, true, never>;
139
+ export declare class SparkToastContainerComponent {
140
+ protected readonly notifications: SparkNotificationService;
141
+ protected readonly Kind: typeof NotificationKind;
142
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkToastContainerComponent, never>;
143
+ static ɵcmp: i0.ɵɵComponentDeclaration<SparkToastContainerComponent, "spark-toast-container", never, {}, {}, never, never, true, never>;
166
144
  }
167
-
168
145
  /**
169
146
  * Registers the built-in client-operation handlers: `notify`, `refreshQuery`,
170
147
  * `refreshAttribute` and `navigate`. Apps add this once in their bootstrap providers.
@@ -176,8 +153,9 @@ declare class SparkToastContainerComponent {
176
153
  * That happened twice more before anyone noticed. `refreshAttribute` and `navigate` were both
177
154
  * declared wire types with no handler anywhere in the repository: every
178
155
  * `IClientAccessor.RefreshAttribute` and `Navigate` call in every Spark application was
179
- * computed, serialised, sent and discarded. Both are registered below. The remaining gap is
180
- * `disableAction`, registered purely to log so that it stays visible rather than invisible.
156
+ * computed, serialised, sent and discarded. Both are registered below. The last gap,
157
+ * `disableAction`, was closed by deleting it (#460, D13): disabled actions travel on the object's
158
+ * or result's `disabledActions` and are enforced by the server at submit.
181
159
  *
182
160
  * The lesson worth keeping: a wire type in `operations.ts` is not a feature. Adding one without
183
161
  * a handler here produces a server API that appears to work and does nothing.
@@ -185,8 +163,7 @@ declare class SparkToastContainerComponent {
185
163
  * To register custom operation types alongside the built-ins, add additional
186
164
  * `multi: true` providers using <see cref="SPARK_CLIENT_OPERATION_HANDLERS" />.
187
165
  */
188
- declare function provideSparkClientOperations(): EnvironmentProviders;
189
-
166
+ export declare function provideSparkClientOperations(): EnvironmentProviders;
190
167
  /**
191
168
  * Carries a server-issued `refreshQuery` to whichever grids are showing that query.
192
169
  *
@@ -199,25 +176,24 @@ declare function provideSparkClientOperations(): EnvironmentProviders;
199
176
  * `notify` was registered, and unknown types are ignored silently — so `refreshOnCompleted`
200
177
  * on the server had no effect on any grid the action did not happen to be hosted in.
201
178
  */
202
- declare class SparkQueryRefreshService {
203
- private readonly tokens;
204
- /** Bumped every time the server asks for this query to refresh. */
205
- tokenFor(queryId: string | undefined): number;
206
- /**
207
- * Ask every grid showing `queryId` to re-fetch.
208
- *
209
- * Matched on the EXACT string a grid passes to {@link tokenFor} -- whichever of id or alias
210
- * its `queryId` input holds. A caller that knows only the other form will not reach it.
211
- *
212
- * Callers bumping several keys for one user action should do so in one synchronous run: the
213
- * signal coalesces bumps within a tick into a single effect run, and bumps split across an
214
- * await become one re-fetch each.
215
- */
216
- request(queryId: string): void;
217
- static ɵfac: i0.ɵɵFactoryDeclaration<SparkQueryRefreshService, never>;
218
- static ɵprov: i0.ɵɵInjectableDeclaration<SparkQueryRefreshService>;
179
+ export declare class SparkQueryRefreshService {
180
+ private readonly tokens;
181
+ /** Bumped every time the server asks for this query to refresh. */
182
+ tokenFor(queryId: string | undefined): number;
183
+ /**
184
+ * Ask every grid showing `queryId` to re-fetch.
185
+ *
186
+ * Matched on the EXACT string a grid passes to {@link tokenFor} -- whichever of id or alias
187
+ * its `queryId` input holds. A caller that knows only the other form will not reach it.
188
+ *
189
+ * Callers bumping several keys for one user action should do so in one synchronous run: the
190
+ * signal coalesces bumps within a tick into a single effect run, and bumps split across an
191
+ * await become one re-fetch each.
192
+ */
193
+ request(queryId: string): void;
194
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkQueryRefreshService, never>;
195
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
219
196
  }
220
-
221
197
  /**
222
198
  * Carries a server-issued `refreshAttribute` to whichever detail page is showing that object.
223
199
  *
@@ -246,40 +222,37 @@ declare class SparkQueryRefreshService {
246
222
  * Only the keys the server sent are present, and each is applied on its own. An `objects: []`
247
223
  * means the grid is now empty, which is why emptiness has to be distinguishable from absence.
248
224
  */
249
- interface SparkAttributePatch {
250
- value?: unknown;
251
- object?: unknown;
252
- objects?: unknown[];
253
- }
254
- declare class SparkAttributeRefreshService {
255
- private readonly tokens;
256
- private readonly patches;
257
- /**
258
- * Objects are keyed by type AND id: the same id can exist under two types, and a detail page
259
- * only ever wants the attributes meant for the object it is showing.
260
- */
261
- private static keyFor;
262
- /** Bumped every time the server patches an attribute of this object. */
263
- tokenFor(objectTypeId: string | undefined | null, id: string | undefined | null): number;
264
- /**
265
- * The newest value the server sent for each patched attribute of this object.
266
- *
267
- * Cumulative rather than drained on read: a detail page that mounts after the operation arrived
268
- * still sees the value, and two pages showing the same object both get it. Values are overwritten
269
- * by later patches, so this holds one entry per attribute, not a history.
270
- */
271
- patchesFor(objectTypeId: string | undefined | null, id: string | undefined | null): Record<string, SparkAttributePatch>;
272
- /**
273
- * Record a new value for one attribute and wake whoever is showing the object.
274
- *
275
- * Callers patching several attributes for one user action should do so in one synchronous run:
276
- * the signals coalesce within a tick into a single effect run, and patches split across an await
277
- * become one run each.
278
- */
279
- request(objectTypeId: string, id: string, attributeName: string, patch: SparkAttributePatch): void;
280
- static ɵfac: i0.ɵɵFactoryDeclaration<SparkAttributeRefreshService, never>;
281
- static ɵprov: i0.ɵɵInjectableDeclaration<SparkAttributeRefreshService>;
225
+ export interface SparkAttributePatch {
226
+ value?: unknown;
227
+ object?: unknown;
228
+ objects?: unknown[];
282
229
  }
283
-
284
- export { NotificationKind, SPARK_CLIENT_OPERATION_HANDLERS, SparkAttributeRefreshService, SparkClientOperationDispatcher, SparkNotificationService, SparkQueryRefreshService, SparkToastContainerComponent, provideSparkClientOperations };
285
- export type { ClientOperation, ClientOperationEnvelope, ClientOperationHandler, ClientOperationHandlerRegistration, DisableActionOperation, DisableTarget, NavigateOperation, NotifyOperation, RefreshAttributeOperation, RefreshQueryOperation, RetryOperation, SparkAttributePatch, SparkToast };
230
+ export declare class SparkAttributeRefreshService {
231
+ private readonly tokens;
232
+ private readonly patches;
233
+ /**
234
+ * Objects are keyed by type AND id: the same id can exist under two types, and a detail page
235
+ * only ever wants the attributes meant for the object it is showing.
236
+ */
237
+ private static keyFor;
238
+ /** Bumped every time the server patches an attribute of this object. */
239
+ tokenFor(objectTypeId: string | undefined | null, id: string | undefined | null): number;
240
+ /**
241
+ * The newest value the server sent for each patched attribute of this object.
242
+ *
243
+ * Cumulative rather than drained on read: a detail page that mounts after the operation arrived
244
+ * still sees the value, and two pages showing the same object both get it. Values are overwritten
245
+ * by later patches, so this holds one entry per attribute, not a history.
246
+ */
247
+ patchesFor(objectTypeId: string | undefined | null, id: string | undefined | null): Record<string, SparkAttributePatch>;
248
+ /**
249
+ * Record a new value for one attribute and wake whoever is showing the object.
250
+ *
251
+ * Callers patching several attributes for one user action should do so in one synchronous run:
252
+ * the signals coalesce within a tick into a single effect run, and patches split across an await
253
+ * become one run each.
254
+ */
255
+ request(objectTypeId: string, id: string, attributeName: string, patch: SparkAttributePatch): void;
256
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkAttributeRefreshService, never>;
257
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
258
+ }
@@ -1,7 +1,6 @@
1
- import * as _angular_core from '@angular/core';
2
- import { DistinctValues, FilterContext, DistinctValue } from '@mintplayer/ng-bootstrap/datatable';
3
- import { QueryColumn } from '@mintplayer/ng-spark/models';
4
-
1
+ import { DistinctValue, DistinctValues, FilterContext } from "@mintplayer/ng-bootstrap/datatable";
2
+ import { QueryColumn } from "@mintplayer/ng-spark/models";
3
+ import * as i0 from "@angular/core";
5
4
  /**
6
5
  * The contents of one column's filter panel (#431).
7
6
  *
@@ -24,54 +23,73 @@ import { QueryColumn } from '@mintplayer/ng-spark/models';
24
23
  * `.form-control` and `.btn` do not reach it — they are only styled inside `bs-*` components. Every
25
24
  * visual here is explicit.
26
25
  */
27
- declare class SparkColumnFilterPanelComponent {
28
- readonly column: _angular_core.InputSignal<QueryColumn>;
29
- /** The datatable's bucketed list, or null while nothing has loaded. */
30
- readonly values: _angular_core.InputSignal<DistinctValues | null>;
31
- readonly ctx: _angular_core.InputSignal<FilterContext>;
32
- /**
33
- * Optional relabelling for a column with a custom cell renderer.
34
- *
35
- * A renderer is a component that paints arbitrary DOM, and a distinct value has no row, so it
36
- * cannot be instantiated to produce text. The label therefore defaults to the server-computed cell
37
- * text — a status rendered as a coloured pill lists `Active`, a rating rendered as stars lists `3`.
38
- * This hook is the escape for the case where that is too raw: a pure function, no DOM, no row.
39
- */
40
- readonly filterLabel: _angular_core.InputSignal<((value: unknown) => string) | null>;
41
- /** Whether this column offers a value list at all, or only free text. */
42
- protected readonly listsDistincts: _angular_core.Signal<boolean>;
43
- /** Selected values, by value. Identity is the value, never the label — two rows may share text. */
44
- private readonly selected;
45
- protected readonly inverse: _angular_core.WritableSignal<boolean>;
46
- protected readonly freeText: _angular_core.WritableSignal<string>;
47
- protected readonly hasSelection: _angular_core.Signal<boolean>;
48
- protected readonly matching: _angular_core.Signal<DistinctValue[]>;
49
- protected readonly remaining: _angular_core.Signal<DistinctValue[]>;
50
- protected readonly hasMore: _angular_core.Signal<boolean>;
51
- /**
52
- * Whether to show the empty state.
53
- *
54
- * Covers three states on purpose: nothing loaded yet, nothing matched, and the distinct request
55
- * failed. The datatable swallows a rejected promise into a null list with no error, so the third
56
- * is not distinguishable here - and the server already refuses to distinguish "no values" from
57
- * "you may not list them".
58
- */
59
- protected readonly isEmpty: _angular_core.Signal<boolean>;
60
- protected labelFor(value: DistinctValue): string;
61
- protected isChecked(value: DistinctValue): boolean;
62
- protected toggle(value: DistinctValue, checked: boolean): void;
63
- protected toggleInverse(): void;
64
- protected onSearch(term: string): void;
65
- /**
66
- * Applies the free-text filter of a column whose values may not be enumerated.
67
- *
68
- * It goes through the same `apply` as a checkbox list, carrying one synthetic entry, so the grid
69
- * has exactly one event shape to translate and no second wire form to maintain.
70
- */
71
- protected applyFreeText(): void;
72
- protected clear(): void;
73
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkColumnFilterPanelComponent, never>;
74
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SparkColumnFilterPanelComponent, "spark-column-filter-panel", never, { "column": { "alias": "column"; "required": true; "isSignal": true; }; "values": { "alias": "values"; "required": false; "isSignal": true; }; "ctx": { "alias": "ctx"; "required": true; "isSignal": true; }; "filterLabel": { "alias": "filterLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
75
- }
76
-
77
- export { SparkColumnFilterPanelComponent };
26
+ export declare class SparkColumnFilterPanelComponent {
27
+ readonly column: import("@angular/core").InputSignal<QueryColumn>;
28
+ /** The datatable's bucketed list, or null while nothing has loaded. */
29
+ readonly values: import("@angular/core").InputSignal<DistinctValues | null>;
30
+ readonly ctx: import("@angular/core").InputSignal<FilterContext>;
31
+ /**
32
+ * Optional relabelling for a column with a custom cell renderer.
33
+ *
34
+ * A renderer is a component that paints arbitrary DOM, and a distinct value has no row, so it
35
+ * cannot be instantiated to produce text. The label therefore defaults to the server-computed cell
36
+ * text — a status rendered as a coloured pill lists `Active`, a rating rendered as stars lists `3`.
37
+ * This hook is the escape for the case where that is too raw: a pure function, no DOM, no row.
38
+ */
39
+ readonly filterLabel: import("@angular/core").InputSignal<((value: unknown) => string) | null>;
40
+ /** Whether this column offers a value list at all, or only free text. */
41
+ protected readonly listsDistincts: import("@angular/core").Signal<boolean>;
42
+ /** Selected values, by value. Identity is the value, never the label — two rows may share text. */
43
+ private readonly selected;
44
+ protected readonly inverse: import("@angular/core").WritableSignal<boolean>;
45
+ protected readonly freeText: import("@angular/core").WritableSignal<string>;
46
+ protected readonly hasSelection: import("@angular/core").Signal<boolean>;
47
+ protected readonly matching: import("@angular/core").Signal<DistinctValue[]>;
48
+ protected readonly remaining: import("@angular/core").Signal<DistinctValue[]>;
49
+ protected readonly hasMore: import("@angular/core").Signal<boolean>;
50
+ /**
51
+ * Whether to show the empty state.
52
+ *
53
+ * Covers three states on purpose: nothing loaded yet, nothing matched, and the distinct request
54
+ * failed. The datatable swallows a rejected promise into a null list with no error, so the third
55
+ * is not distinguishable here - and the server already refuses to distinguish "no values" from
56
+ * "you may not list them".
57
+ */
58
+ protected readonly isEmpty: import("@angular/core").Signal<boolean>;
59
+ protected labelFor(value: DistinctValue): string;
60
+ protected isChecked(value: DistinctValue): boolean;
61
+ protected toggle(value: DistinctValue, checked: boolean): void;
62
+ protected toggleInverse(): void;
63
+ protected onSearch(term: string): void;
64
+ /**
65
+ * Applies the free-text filter of a column whose values may not be enumerated.
66
+ *
67
+ * It goes through the same `apply` as a checkbox list, carrying one synthetic entry, so the grid
68
+ * has exactly one event shape to translate and no second wire form to maintain.
69
+ */
70
+ protected applyFreeText(): void;
71
+ protected clear(): void;
72
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkColumnFilterPanelComponent, never>;
73
+ static ɵcmp: i0.ɵɵComponentDeclaration<SparkColumnFilterPanelComponent, "spark-column-filter-panel", never, {
74
+ "column": {
75
+ "alias": "column";
76
+ "required": true;
77
+ "isSignal": true;
78
+ };
79
+ "values": {
80
+ "alias": "values";
81
+ "required": false;
82
+ "isSignal": true;
83
+ };
84
+ "ctx": {
85
+ "alias": "ctx";
86
+ "required": true;
87
+ "isSignal": true;
88
+ };
89
+ "filterLabel": {
90
+ "alias": "filterLabel";
91
+ "required": false;
92
+ "isSignal": true;
93
+ };
94
+ }, {}, never, never, true, never>;
95
+ }