@mintplayer/ng-spark 22.23.0 → 22.25.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 (71) hide show
  1. package/README.md +196 -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 +310 -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-contributions.mjs +721 -0
  9. package/fesm2022/mintplayer-ng-spark-contributions.mjs.map +1 -0
  10. package/fesm2022/mintplayer-ng-spark-grid.mjs +2385 -1118
  11. package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
  12. package/fesm2022/mintplayer-ng-spark-history.mjs +598 -0
  13. package/fesm2022/mintplayer-ng-spark-history.mjs.map +1 -0
  14. package/fesm2022/mintplayer-ng-spark-icon.mjs +64 -27
  15. package/fesm2022/mintplayer-ng-spark-icon.mjs.map +1 -1
  16. package/fesm2022/mintplayer-ng-spark-models.mjs +405 -762
  17. package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
  18. package/fesm2022/mintplayer-ng-spark-moderation.mjs +1212 -0
  19. package/fesm2022/mintplayer-ng-spark-moderation.mjs.map +1 -0
  20. package/fesm2022/mintplayer-ng-spark-panels.mjs +60 -0
  21. package/fesm2022/mintplayer-ng-spark-panels.mjs.map +1 -0
  22. package/fesm2022/mintplayer-ng-spark-pipes.mjs +1158 -765
  23. package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
  24. package/fesm2022/mintplayer-ng-spark-po-create.mjs +273 -169
  25. package/fesm2022/mintplayer-ng-spark-po-create.mjs.map +1 -1
  26. package/fesm2022/mintplayer-ng-spark-po-detail.mjs +795 -410
  27. package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
  28. package/fesm2022/mintplayer-ng-spark-po-edit.mjs +1196 -280
  29. package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -1
  30. package/fesm2022/mintplayer-ng-spark-po-form.mjs +2244 -1224
  31. package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -1
  32. package/fesm2022/mintplayer-ng-spark-query-list.mjs +571 -303
  33. package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
  34. package/fesm2022/mintplayer-ng-spark-renderers.mjs +44 -55
  35. package/fesm2022/mintplayer-ng-spark-renderers.mjs.map +1 -1
  36. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +216 -177
  37. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs.map +1 -1
  38. package/fesm2022/mintplayer-ng-spark-routes.mjs +24 -28
  39. package/fesm2022/mintplayer-ng-spark-routes.mjs.map +1 -1
  40. package/fesm2022/mintplayer-ng-spark-services.mjs +625 -640
  41. package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
  42. package/fesm2022/mintplayer-ng-spark-shell.mjs +1031 -397
  43. package/fesm2022/mintplayer-ng-spark-shell.mjs.map +1 -1
  44. package/fesm2022/mintplayer-ng-spark-soft-delete.mjs +294 -0
  45. package/fesm2022/mintplayer-ng-spark-soft-delete.mjs.map +1 -0
  46. package/fesm2022/mintplayer-ng-spark.mjs +14 -48
  47. package/fesm2022/mintplayer-ng-spark.mjs.map +1 -1
  48. package/package.json +23 -2
  49. package/types/mintplayer-ng-spark-attribute-description.d.ts +25 -18
  50. package/types/mintplayer-ng-spark-client-operations.d.ts +139 -160
  51. package/types/mintplayer-ng-spark-column-filter.d.ts +73 -55
  52. package/types/mintplayer-ng-spark-contributions.d.ts +231 -0
  53. package/types/mintplayer-ng-spark-grid.d.ts +917 -448
  54. package/types/mintplayer-ng-spark-history.d.ts +216 -0
  55. package/types/mintplayer-ng-spark-icon.d.ts +15 -13
  56. package/types/mintplayer-ng-spark-models.d.ts +681 -573
  57. package/types/mintplayer-ng-spark-moderation.d.ts +402 -0
  58. package/types/mintplayer-ng-spark-panels.d.ts +143 -0
  59. package/types/mintplayer-ng-spark-pipes.d.ts +131 -149
  60. package/types/mintplayer-ng-spark-po-create.d.ts +46 -37
  61. package/types/mintplayer-ng-spark-po-detail.d.ts +180 -117
  62. package/types/mintplayer-ng-spark-po-edit.d.ts +367 -64
  63. package/types/mintplayer-ng-spark-po-form.d.ts +558 -373
  64. package/types/mintplayer-ng-spark-query-list.d.ts +143 -82
  65. package/types/mintplayer-ng-spark-renderers.d.ts +121 -85
  66. package/types/mintplayer-ng-spark-retry-action-modal.d.ts +31 -34
  67. package/types/mintplayer-ng-spark-routes.d.ts +7 -11
  68. package/types/mintplayer-ng-spark-services.d.ts +377 -261
  69. package/types/mintplayer-ng-spark-shell.d.ts +228 -132
  70. package/types/mintplayer-ng-spark-soft-delete.d.ts +90 -0
  71. package/types/mintplayer-ng-spark.d.ts +19 -12
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mintplayer/ng-spark",
3
3
  "private": false,
4
- "version": "22.23.0",
4
+ "version": "22.25.0",
5
5
  "description": "Angular component library for MintPlayer.Spark CRUD applications",
6
6
  "repository": {
7
7
  "type": "git",
@@ -14,7 +14,8 @@
14
14
  "@angular/common": "^22.0.0",
15
15
  "@angular/router": "^22.0.0",
16
16
  "@angular/forms": "^22.0.0",
17
- "@mintplayer/ng-bootstrap": "^22.19.0",
17
+ "@mintplayer/ng-bootstrap": "^22.20.0",
18
+ "@mintplayer/web-components": "^2.17.0",
18
19
  "@mintplayer/pagination": "*",
19
20
  "rxjs": "~7.8.0"
20
21
  },
@@ -41,10 +42,18 @@
41
42
  "types": "./types/mintplayer-ng-spark-column-filter.d.ts",
42
43
  "default": "./fesm2022/mintplayer-ng-spark-column-filter.mjs"
43
44
  },
45
+ "./contributions": {
46
+ "types": "./types/mintplayer-ng-spark-contributions.d.ts",
47
+ "default": "./fesm2022/mintplayer-ng-spark-contributions.mjs"
48
+ },
44
49
  "./grid": {
45
50
  "types": "./types/mintplayer-ng-spark-grid.d.ts",
46
51
  "default": "./fesm2022/mintplayer-ng-spark-grid.mjs"
47
52
  },
53
+ "./history": {
54
+ "types": "./types/mintplayer-ng-spark-history.d.ts",
55
+ "default": "./fesm2022/mintplayer-ng-spark-history.mjs"
56
+ },
48
57
  "./icon": {
49
58
  "types": "./types/mintplayer-ng-spark-icon.d.ts",
50
59
  "default": "./fesm2022/mintplayer-ng-spark-icon.mjs"
@@ -53,6 +62,14 @@
53
62
  "types": "./types/mintplayer-ng-spark-models.d.ts",
54
63
  "default": "./fesm2022/mintplayer-ng-spark-models.mjs"
55
64
  },
65
+ "./moderation": {
66
+ "types": "./types/mintplayer-ng-spark-moderation.d.ts",
67
+ "default": "./fesm2022/mintplayer-ng-spark-moderation.mjs"
68
+ },
69
+ "./panels": {
70
+ "types": "./types/mintplayer-ng-spark-panels.d.ts",
71
+ "default": "./fesm2022/mintplayer-ng-spark-panels.mjs"
72
+ },
56
73
  "./pipes": {
57
74
  "types": "./types/mintplayer-ng-spark-pipes.d.ts",
58
75
  "default": "./fesm2022/mintplayer-ng-spark-pipes.mjs"
@@ -96,6 +113,10 @@
96
113
  "./shell": {
97
114
  "types": "./types/mintplayer-ng-spark-shell.d.ts",
98
115
  "default": "./fesm2022/mintplayer-ng-spark-shell.mjs"
116
+ },
117
+ "./soft-delete": {
118
+ "types": "./types/mintplayer-ng-spark-soft-delete.d.ts",
119
+ "default": "./fesm2022/mintplayer-ng-spark-soft-delete.mjs"
99
120
  }
100
121
  },
101
122
  "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,77 @@
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, TranslatedString } 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
+ /** The text in the request's language (the browser's `Accept-Language`). */
19
+ message: string;
20
+ /**
21
+ * The text in every language, when the server has it. Shown in the language the user picked in
22
+ * the app (`SparkLanguageService`), which the server never learns; `message` is the fallback.
23
+ */
24
+ translatedMessage?: TranslatedString | null;
25
+ kind: NotificationKind;
26
+ durationMs?: number;
22
27
  }
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[];
28
+ export interface RefreshAttributeOperation {
29
+ type: 'refreshAttribute';
30
+ objectTypeId: string;
31
+ id: string;
32
+ attributeName: string;
33
+ value?: unknown;
34
+ /**
35
+ * Nested rows of an `AsDetail` attribute. A loaded AsDetail attribute carries its rows in
36
+ * `object` / `objects` and leaves `value` null, so a patch limited to `value` could never
37
+ * refresh a detail grid -- it always sent null, and a null over a null repaints nothing.
38
+ *
39
+ * An empty `objects` array means the grid is now empty, and is distinct from omitting it.
40
+ */
41
+ object?: unknown;
42
+ objects?: unknown[];
38
43
  }
39
- interface RefreshQueryOperation {
40
- type: 'refreshQuery';
41
- queryId: string;
44
+ export interface RefreshQueryOperation {
45
+ type: 'refreshQuery';
46
+ queryId: string;
42
47
  }
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;
48
+ export interface RetryOperation {
49
+ type: 'retry';
50
+ step: number;
51
+ title: string;
52
+ options: string[];
53
+ defaultOption?: string | null;
54
+ persistentObject?: PersistentObject | null;
55
+ message?: string | null;
68
56
  }
69
57
  /**
70
58
  * Discriminated union of known operation types, plus an open shape for unknown
71
59
  * future operations. Handlers should narrow via the `type` discriminator before
72
60
  * accessing fields specific to their operation type.
73
61
  */
74
- type ClientOperation = NavigateOperation | NotifyOperation | RefreshAttributeOperation | RefreshQueryOperation | DisableActionOperation | RetryOperation | {
75
- type: string;
76
- [key: string]: unknown;
62
+ export type ClientOperation = NavigateOperation | NotifyOperation | RefreshAttributeOperation | RefreshQueryOperation | RetryOperation | {
63
+ type: string;
64
+ [key: string]: unknown;
77
65
  };
78
66
  /**
79
67
  * Wire envelope returned by every action endpoint. `result` carries the primary
80
68
  * payload (the PersistentObject for a Create, the QueryResult for an Execute,
81
69
  * etc.); `operations` carries the side-effects the frontend dispatches.
82
70
  */
83
- interface ClientOperationEnvelope<T = unknown> {
84
- result: T | null;
85
- operations: ClientOperation[];
71
+ export interface ClientOperationEnvelope<T = unknown> {
72
+ result: T | null;
73
+ operations: ClientOperation[];
86
74
  }
87
-
88
75
  /**
89
76
  * Routes received operations to registered handlers. Unknown operation types
90
77
  * (no matching registration) are silently dropped — this is the forward-compat
@@ -105,41 +92,39 @@ interface ClientOperationEnvelope<T = unknown> {
105
92
  * built-in `notify` handler renders via Angular interpolation (escaped) so
106
93
  * it's safe to pass through, but anything more powerful must validate.
107
94
  */
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>;
95
+ export declare class SparkClientOperationDispatcher {
96
+ private readonly handlerMap;
97
+ constructor();
98
+ dispatch(operations: readonly ClientOperation[] | null | undefined): void;
99
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkClientOperationDispatcher, never>;
100
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
114
101
  }
115
-
116
102
  /**
117
103
  * A handler for a specific operation type. Receives the operation and
118
104
  * executes the side-effect (e.g. show a toast, navigate, refresh a query).
119
105
  * Handlers should `as`-narrow the operation to the type they registered for.
120
106
  */
121
- type ClientOperationHandler = (operation: ClientOperation) => void;
107
+ export type ClientOperationHandler = (operation: ClientOperation) => void;
122
108
  /**
123
109
  * One entry in the multi-provider registration. Apps can register custom
124
110
  * handlers alongside the built-in ones to extend the operation set with
125
111
  * app-specific operation types.
126
112
  */
127
- interface ClientOperationHandlerRegistration {
128
- type: string;
129
- handler: ClientOperationHandler;
113
+ export interface ClientOperationHandlerRegistration {
114
+ type: string;
115
+ handler: ClientOperationHandler;
130
116
  }
131
117
  /**
132
118
  * Multi-provider token. `provideSparkClientOperations()` registers the
133
119
  * built-in handlers; apps can add their own with additional `multi: true`
134
120
  * providers using this token.
135
121
  */
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;
122
+ export declare const SPARK_CLIENT_OPERATION_HANDLERS: InjectionToken<readonly ClientOperationHandlerRegistration[]>;
123
+ export interface SparkToast {
124
+ id: string;
125
+ message: string;
126
+ kind: NotificationKind;
127
+ durationMs: number;
143
128
  }
144
129
  /**
145
130
  * Holds the active toasts as a signal. The `<spark-toast-container>` component
@@ -148,23 +133,21 @@ interface SparkToast {
148
133
  * Auto-dismissal: each toast schedules its own removal after `durationMs`. Pass
149
134
  * `0` to make a toast sticky (manual dismissal only).
150
135
  */
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>;
136
+ export declare class SparkNotificationService {
137
+ private readonly _toasts;
138
+ readonly toasts: import("@angular/core").Signal<readonly SparkToast[]>;
139
+ show(message: string, kind?: NotificationKind, durationMs?: number): void;
140
+ dismiss(id: string): void;
141
+ clear(): void;
142
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkNotificationService, never>;
143
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
159
144
  }
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>;
145
+ export declare class SparkToastContainerComponent {
146
+ protected readonly notifications: SparkNotificationService;
147
+ protected readonly Kind: typeof NotificationKind;
148
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkToastContainerComponent, never>;
149
+ static ɵcmp: i0.ɵɵComponentDeclaration<SparkToastContainerComponent, "spark-toast-container", never, {}, {}, never, never, true, never>;
166
150
  }
167
-
168
151
  /**
169
152
  * Registers the built-in client-operation handlers: `notify`, `refreshQuery`,
170
153
  * `refreshAttribute` and `navigate`. Apps add this once in their bootstrap providers.
@@ -176,8 +159,9 @@ declare class SparkToastContainerComponent {
176
159
  * That happened twice more before anyone noticed. `refreshAttribute` and `navigate` were both
177
160
  * declared wire types with no handler anywhere in the repository: every
178
161
  * `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.
162
+ * computed, serialised, sent and discarded. Both are registered below. The last gap,
163
+ * `disableAction`, was closed by deleting it (#460, D13): disabled actions travel on the object's
164
+ * or result's `disabledActions` and are enforced by the server at submit.
181
165
  *
182
166
  * The lesson worth keeping: a wire type in `operations.ts` is not a feature. Adding one without
183
167
  * a handler here produces a server API that appears to work and does nothing.
@@ -185,8 +169,7 @@ declare class SparkToastContainerComponent {
185
169
  * To register custom operation types alongside the built-ins, add additional
186
170
  * `multi: true` providers using <see cref="SPARK_CLIENT_OPERATION_HANDLERS" />.
187
171
  */
188
- declare function provideSparkClientOperations(): EnvironmentProviders;
189
-
172
+ export declare function provideSparkClientOperations(): EnvironmentProviders;
190
173
  /**
191
174
  * Carries a server-issued `refreshQuery` to whichever grids are showing that query.
192
175
  *
@@ -199,25 +182,24 @@ declare function provideSparkClientOperations(): EnvironmentProviders;
199
182
  * `notify` was registered, and unknown types are ignored silently — so `refreshOnCompleted`
200
183
  * on the server had no effect on any grid the action did not happen to be hosted in.
201
184
  */
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>;
185
+ export declare class SparkQueryRefreshService {
186
+ private readonly tokens;
187
+ /** Bumped every time the server asks for this query to refresh. */
188
+ tokenFor(queryId: string | undefined): number;
189
+ /**
190
+ * Ask every grid showing `queryId` to re-fetch.
191
+ *
192
+ * Matched on the EXACT string a grid passes to {@link tokenFor} -- whichever of id or alias
193
+ * its `queryId` input holds. A caller that knows only the other form will not reach it.
194
+ *
195
+ * Callers bumping several keys for one user action should do so in one synchronous run: the
196
+ * signal coalesces bumps within a tick into a single effect run, and bumps split across an
197
+ * await become one re-fetch each.
198
+ */
199
+ request(queryId: string): void;
200
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkQueryRefreshService, never>;
201
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
219
202
  }
220
-
221
203
  /**
222
204
  * Carries a server-issued `refreshAttribute` to whichever detail page is showing that object.
223
205
  *
@@ -246,40 +228,37 @@ declare class SparkQueryRefreshService {
246
228
  * Only the keys the server sent are present, and each is applied on its own. An `objects: []`
247
229
  * means the grid is now empty, which is why emptiness has to be distinguishable from absence.
248
230
  */
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>;
231
+ export interface SparkAttributePatch {
232
+ value?: unknown;
233
+ object?: unknown;
234
+ objects?: unknown[];
282
235
  }
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 };
236
+ export declare class SparkAttributeRefreshService {
237
+ private readonly tokens;
238
+ private readonly patches;
239
+ /**
240
+ * Objects are keyed by type AND id: the same id can exist under two types, and a detail page
241
+ * only ever wants the attributes meant for the object it is showing.
242
+ */
243
+ private static keyFor;
244
+ /** Bumped every time the server patches an attribute of this object. */
245
+ tokenFor(objectTypeId: string | undefined | null, id: string | undefined | null): number;
246
+ /**
247
+ * The newest value the server sent for each patched attribute of this object.
248
+ *
249
+ * Cumulative rather than drained on read: a detail page that mounts after the operation arrived
250
+ * still sees the value, and two pages showing the same object both get it. Values are overwritten
251
+ * by later patches, so this holds one entry per attribute, not a history.
252
+ */
253
+ patchesFor(objectTypeId: string | undefined | null, id: string | undefined | null): Record<string, SparkAttributePatch>;
254
+ /**
255
+ * Record a new value for one attribute and wake whoever is showing the object.
256
+ *
257
+ * Callers patching several attributes for one user action should do so in one synchronous run:
258
+ * the signals coalesce within a tick into a single effect run, and patches split across an await
259
+ * become one run each.
260
+ */
261
+ request(objectTypeId: string, id: string, attributeName: string, patch: SparkAttributePatch): void;
262
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkAttributeRefreshService, never>;
263
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
264
+ }
@@ -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
+ }