@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
@@ -1,10 +1,10 @@
1
- import * as _mintplayer_ng_spark_models from '@mintplayer/ng-spark/models';
2
- import { QueryResultItem, CustomActionDefinition, QueryColumn } from '@mintplayer/ng-spark/models';
3
- import * as _angular_core from '@angular/core';
4
- import { TemplateRef } from '@angular/core';
5
- import { Color } from '@mintplayer/ng-bootstrap';
6
- import { SparkLanguageService } from '@mintplayer/ng-spark/services';
7
-
1
+ import * as i0 from "@angular/core";
2
+ import { TemplateRef } from "@angular/core";
3
+ import { Color } from "@mintplayer/ng-bootstrap";
4
+ import { SparkLanguageService } from "@mintplayer/ng-spark/services";
5
+ import { SparkQueryToolbarAction } from "@mintplayer/ng-spark/grid";
6
+ import { CustomActionDefinition, QueryColumn, QueryColumnFilter, QueryResultItem, SparkDeletedFilter } from "@mintplayer/ng-spark/models";
7
+ import { SparkQueryListContext } from "@mintplayer/ng-spark/panels";
8
8
  /**
9
9
  * The routed query page: chrome around one {@link SparkQueryGridComponent}.
10
10
  *
@@ -22,78 +22,139 @@ import { SparkLanguageService } from '@mintplayer/ng-spark/services';
22
22
  * is the shared component. This page previously wrote out `<bs-datatable>` twice, once per
23
23
  * transport, with a shared row template between them; both are gone.
24
24
  */
25
- declare class SparkQueryListComponent {
26
- private readonly route;
27
- private readonly router;
28
- private readonly sparkService;
29
- private readonly streamingService;
30
- private readonly destroyRef;
31
- protected readonly lang: SparkLanguageService;
32
- extraActionsTemplate: _angular_core.InputSignal<TemplateRef<void> | null>;
33
- showCustomActions: _angular_core.InputSignal<boolean>;
34
- /**
35
- * Forwarded to the grid, so a query PAGE can replace its row links — the same reason the card
36
- * forwards it. Without this the escape hatch existed only for a directly-embedded grid.
37
- */
38
- rowRoute: _angular_core.InputSignal<((row: QueryResultItem) => unknown[] | null) | null>;
39
- rowClicked: _angular_core.OutputEmitterRef<QueryResultItem>;
40
- createClicked: _angular_core.OutputEmitterRef<void>;
41
- customActionExecuted: _angular_core.OutputEmitterRef<{
42
- action: CustomActionDefinition;
43
- }>;
44
- colors: typeof Color;
45
- /** The query the grid should render, resolved from the route. Null until it is known. */
46
- queryId: _angular_core.WritableSignal<string | null>;
47
- errorMessage: _angular_core.WritableSignal<string | null>;
48
- searchTerm: _angular_core.WritableSignal<string>;
49
- private readonly grid;
50
- /**
51
- * Grid state, surfaced for this page's chrome.
52
- *
53
- * Optional `viewChild`, read defensively: the action bar and caption render above the grid, so
54
- * on the first change-detection pass the query has not resolved yet.
55
- */
56
- protected readonly query: _angular_core.Signal<_mintplayer_ng_spark_models.SparkQuery | null>;
57
- protected readonly entityType: _angular_core.Signal<_mintplayer_ng_spark_models.EntityType | null>;
58
- protected readonly customActions: _angular_core.Signal<CustomActionDefinition[]>;
59
- protected readonly canCreate: _angular_core.Signal<boolean>;
60
- protected readonly resultCount: _angular_core.Signal<number | null>;
61
- protected readonly isVirtualScrolling: _angular_core.Signal<boolean>;
62
- protected readonly gridError: _angular_core.Signal<string | null>;
63
- /** Whether an action's selection rule is satisfied. Delegated: the grid holds the selection. */
64
- /** @see SparkPoDetailComponent.customActionClass — same allow-list, same default. */
65
- protected customActionClass(action: CustomActionDefinition): string;
66
- protected isActionEnabled(action: CustomActionDefinition): boolean;
67
- isStreaming: _angular_core.WritableSignal<boolean>;
68
- private streamingSub;
69
- /** Columns as sent with the stream's snapshot; empty until it arrives. */
70
- protected readonly streamColumns: _angular_core.WritableSignal<QueryColumn[]>;
71
- private readonly allItems;
72
- private readonly streamItems;
73
- /**
74
- * Rows handed to the grid, or `null` to let it fetch for itself.
75
- *
76
- * Null for a normal query — an empty array would read as "here are no rows" and suppress the
77
- * fetch entirely.
78
- */
79
- protected readonly gridData: _angular_core.Signal<QueryResultItem[] | null>;
80
- constructor();
81
- private onParamsChange;
82
- /**
83
- * A load failure has to render, not just be swallowed: a denied query answers 404 (audit M-3, so
84
- * existence is not leaked), which is indistinguishable from a missing one — hence a deliberately
85
- * generic message rather than a guess at which it was.
86
- */
87
- private reportLoadFailure;
88
- protected onCustomAction(action: CustomActionDefinition): Promise<void>;
89
- protected onCreate(): void;
90
- protected clearSearch(): void;
91
- private connectStreaming;
92
- private disconnectStreaming;
93
- private handleStreamingMessage;
94
- private applyFilter;
95
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkQueryListComponent, never>;
96
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SparkQueryListComponent, "spark-query-list", never, { "extraActionsTemplate": { "alias": "extraActionsTemplate"; "required": false; "isSignal": true; }; "showCustomActions": { "alias": "showCustomActions"; "required": false; "isSignal": true; }; "rowRoute": { "alias": "rowRoute"; "required": false; "isSignal": true; }; }, { "rowClicked": "rowClicked"; "createClicked": "createClicked"; "customActionExecuted": "customActionExecuted"; }, never, never, true, never>;
97
- }
98
-
99
- export { SparkQueryListComponent };
25
+ export declare class SparkQueryListComponent {
26
+ private readonly route;
27
+ private readonly router;
28
+ private readonly sparkService;
29
+ private readonly streamingService;
30
+ private readonly destroyRef;
31
+ protected readonly lang: SparkLanguageService;
32
+ extraActionsTemplate: import("@angular/core").InputSignal<TemplateRef<void> | null>;
33
+ showCustomActions: import("@angular/core").InputSignal<boolean>;
34
+ /**
35
+ * Forwarded to the grid, so a query PAGE can replace its row links — the same reason the card
36
+ * forwards it. Without this the escape hatch existed only for a directly-embedded grid.
37
+ */
38
+ rowRoute: import("@angular/core").InputSignal<((row: QueryResultItem) => unknown[] | null) | null>;
39
+ rowClicked: import("@angular/core").OutputEmitterRef<QueryResultItem>;
40
+ createClicked: import("@angular/core").OutputEmitterRef<void>;
41
+ customActionExecuted: import("@angular/core").OutputEmitterRef<{
42
+ action: CustomActionDefinition;
43
+ }>;
44
+ colors: typeof Color;
45
+ /** The query the grid should render, resolved from the route. Null until it is known. */
46
+ queryId: import("@angular/core").WritableSignal<string | null>;
47
+ errorMessage: import("@angular/core").WritableSignal<string | null>;
48
+ searchTerm: import("@angular/core").WritableSignal<string>;
49
+ private readonly grid;
50
+ /**
51
+ * Grid state, surfaced for this page's chrome.
52
+ *
53
+ * Optional `viewChild`, read defensively: the action bar and caption render above the grid, so
54
+ * on the first change-detection pass the query has not resolved yet.
55
+ */
56
+ protected readonly query: import("@angular/core").Signal<import("@mintplayer/ng-spark/models").SparkQuery | null>;
57
+ protected readonly entityType: import("@angular/core").Signal<import("@mintplayer/ng-spark/models").EntityType | null>;
58
+ protected readonly customActions: import("@angular/core").Signal<CustomActionDefinition[]>;
59
+ protected readonly canCreate: import("@angular/core").Signal<boolean>;
60
+ protected readonly resultCount: import("@angular/core").Signal<number | null>;
61
+ protected readonly isVirtualScrolling: import("@angular/core").Signal<boolean>;
62
+ protected readonly gridError: import("@angular/core").Signal<string | null>;
63
+ protected readonly permissions: import("@angular/core").Signal<import("@mintplayer/ng-spark/models").EntityPermissions | null>;
64
+ /** Add-on buttons for the action bar (#460, `SPARK_QUERY_LIST_ACTIONS`), e.g. the Deleted toggle. */
65
+ protected readonly listActions: import("@mintplayer/ng-spark/panels").SparkQueryListAction[];
66
+ /**
67
+ * The soft-deletion mode (#460, T2), read from the route's `?deleted=` so the recycle bin survives
68
+ * a reload and the back button from a row opened in it. `exclude` unless the route says otherwise.
69
+ */
70
+ protected readonly deletedMode: import("@angular/core").WritableSignal<SparkDeletedFilter>;
71
+ /** Bumped by `context.reload()`; the grid treats any new value as "re-run the query". */
72
+ private readonly reloadToken;
73
+ protected readonly listContext: import("@angular/core").Signal<SparkQueryListContext | null>;
74
+ protected readonly gridReloadToken: import("@angular/core").Signal<number>;
75
+ private setDeleted;
76
+ /** Whether an action's selection rule is satisfied. Delegated: the grid holds the selection. */
77
+ /** @see SparkPoDetailComponent.customActionClass — same allow-list, same default. */
78
+ protected customActionClass(action: CustomActionDefinition): string;
79
+ /** The grid's toolbar model (#460, M15), the same list the sub-query card renders. */
80
+ protected readonly toolbarActions: import("@angular/core").Signal<SparkQueryToolbarAction[]>;
81
+ protected toolbarActionClass(action: SparkQueryToolbarAction): string;
82
+ protected isToolbarActionEnabled(action: SparkQueryToolbarAction): boolean;
83
+ protected runToolbarAction(action: SparkQueryToolbarAction): void;
84
+ protected isActionEnabled(action: CustomActionDefinition): boolean;
85
+ isStreaming: import("@angular/core").WritableSignal<boolean>;
86
+ private streamingSub;
87
+ /** Columns as sent with the stream's snapshot; empty until it arrives. */
88
+ protected readonly streamColumns: import("@angular/core").WritableSignal<QueryColumn[]>;
89
+ private readonly allItems;
90
+ private readonly streamItems;
91
+ /**
92
+ * Rows handed to the grid, or `null` to let it fetch for itself.
93
+ *
94
+ * Null for a normal query — an empty array would read as "here are no rows" and suppress the
95
+ * fetch entirely.
96
+ */
97
+ protected readonly gridData: import("@angular/core").Signal<QueryResultItem[] | null>;
98
+ constructor();
99
+ /**
100
+ * The parent the URL scopes the query to (`?parentId=…&parentType=…`), sent exactly as a sub-query
101
+ * sends its container. Both or neither: one without the other is ignored, as the server does.
102
+ */
103
+ protected readonly urlParentId: import("@angular/core").WritableSignal<string>;
104
+ protected readonly urlParentType: import("@angular/core").WritableSignal<string>;
105
+ /**
106
+ * Column filters from the URL: every other query-string parameter, `?Language=en&Script=Latn`
107
+ * (repeat a name for several values). The grid applies only those naming an attribute of the
108
+ * query's type; the rest are ignored. This is the contributions History link's shape, and works for
109
+ * any query.
110
+ */
111
+ protected readonly urlFilters: import("@angular/core").WritableSignal<QueryColumnFilter[]>;
112
+ /** The URL filters the grid applied, as removable chips. */
113
+ protected readonly activeUrlFilters: import("@angular/core").Signal<QueryColumnFilter[]>;
114
+ /** Query-string names the page or the row links own, never column filters. */
115
+ private static readonly reservedParams;
116
+ private applyUrlScope;
117
+ /** Drops one URL filter (its query-string parameter); the grid refetches. */
118
+ protected clearUrlFilter(name: string): void;
119
+ /** Drops the parent and every URL filter. */
120
+ protected clearUrlScope(): void;
121
+ protected filterValues(filter: QueryColumnFilter): string;
122
+ /** The column's label for a chip: the query's own column label, else the attribute's, else its name. */
123
+ protected filterLabel(name: string): string;
124
+ private onParamsChange;
125
+ /**
126
+ * A load failure has to render, not just be swallowed: a denied query answers 404 (audit M-3, so
127
+ * existence is not leaked), which is indistinguishable from a missing one — hence a deliberately
128
+ * generic message rather than a guess at which it was.
129
+ */
130
+ private reportLoadFailure;
131
+ protected onCustomAction(action: CustomActionDefinition): Promise<void>;
132
+ protected onCreate(): void;
133
+ protected clearSearch(): void;
134
+ private connectStreaming;
135
+ private disconnectStreaming;
136
+ private handleStreamingMessage;
137
+ private applyFilter;
138
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkQueryListComponent, never>;
139
+ static ɵcmp: i0.ɵɵComponentDeclaration<SparkQueryListComponent, "spark-query-list", never, {
140
+ "extraActionsTemplate": {
141
+ "alias": "extraActionsTemplate";
142
+ "required": false;
143
+ "isSignal": true;
144
+ };
145
+ "showCustomActions": {
146
+ "alias": "showCustomActions";
147
+ "required": false;
148
+ "isSignal": true;
149
+ };
150
+ "rowRoute": {
151
+ "alias": "rowRoute";
152
+ "required": false;
153
+ "isSignal": true;
154
+ };
155
+ }, {
156
+ "rowClicked": "rowClicked";
157
+ "createClicked": "createClicked";
158
+ "customActionExecuted": "customActionExecuted";
159
+ }, never, never, true, never>;
160
+ }
@@ -1,11 +1,10 @@
1
- import { Type, InputSignal, InjectionToken, Provider } from '@angular/core';
2
- import { QueryResultItemValue, PersistentObjectAttribute, SparkCellColumn, QueryResultItem, EntityAttributeDefinition, PersistentObject } from '@mintplayer/ng-spark/models';
3
-
1
+ import { InjectionToken, InputSignal, Provider, Type } from "@angular/core";
2
+ import { EntityAttributeDefinition, EntityType, PersistentObject, PersistentObjectAttribute, QueryResultItem, QueryResultItemValue, SparkCellColumn } from "@mintplayer/ng-spark/models";
4
3
  /**
5
4
  * Drops entries the component doesn't declare, so every contract member is
6
5
  * genuinely optional — NgComponentOutlet throws on an undeclared input.
7
6
  */
8
- declare function withDeclaredInputs(component: Type<any>, inputs: Record<string, any>): Record<string, any>;
7
+ export declare function withDeclaredInputs(component: Type<any>, inputs: Record<string, any>): Record<string, any>;
9
8
  /**
10
9
  * The renderer-facing value of an attribute: the flat value, or for AsDetail
11
10
  * attributes (whose flat value the server nulls on purpose) the nested
@@ -13,7 +12,7 @@ declare function withDeclaredInputs(component: Type<any>, inputs: Record<string,
13
12
  *
14
13
  * Used by the detail and edit paths, which still work in attributes.
15
14
  */
16
- declare function rendererValue(attr: PersistentObjectAttribute | undefined): any;
15
+ export declare function rendererValue(attr: PersistentObjectAttribute | undefined): any;
17
16
  /**
18
17
  * The renderer-facing value of a query-result cell.
19
18
  *
@@ -24,98 +23,121 @@ declare function rendererValue(attr: PersistentObjectAttribute | undefined): any
24
23
  * stops a renderer silently receiving `undefined` because it was written against the attribute
25
24
  * shape's `object` / `objects` fields, which a row does not carry.
26
25
  */
27
- declare function cellValue(value: QueryResultItemValue | undefined): any;
28
-
26
+ export declare function cellValue(value: QueryResultItemValue | undefined): any;
29
27
  /**
30
28
  * Contract for detail-page renderers (spark-po-detail).
31
29
  * Displays a single attribute value in the PO detail view.
32
30
  */
33
- interface SparkAttributeDetailRenderer {
34
- /**
35
- * The current attribute value. For an AsDetail attribute this is the nested
36
- * PersistentObject (single) or PersistentObject[] (array).
37
- */
38
- value?: InputSignal<any>;
39
- /** The attribute definition metadata */
40
- attribute?: InputSignal<EntityAttributeDefinition | undefined>;
41
- /** Renderer-specific options from rendererOptions */
42
- options?: InputSignal<Record<string, any> | undefined>;
43
- /** The full form data (for cross-field dependencies); AsDetail keys carry the nested PO(s) */
44
- formData?: InputSignal<Record<string, any>>;
45
- /** The full PersistentObject being displayed — ids/breadcrumbs the flattened formData drops */
46
- item?: InputSignal<PersistentObject | undefined>;
31
+ export interface SparkAttributeDetailRenderer {
32
+ /**
33
+ * The current attribute value. For an AsDetail attribute this is the nested
34
+ * PersistentObject (single) or PersistentObject[] (array).
35
+ */
36
+ value?: InputSignal<any>;
37
+ /** The attribute definition metadata */
38
+ attribute?: InputSignal<EntityAttributeDefinition | undefined>;
39
+ /** Renderer-specific options from rendererOptions */
40
+ options?: InputSignal<Record<string, any> | undefined>;
41
+ /** The full form data (for cross-field dependencies); AsDetail keys carry the nested PO(s) */
42
+ formData?: InputSignal<Record<string, any>>;
43
+ /** The full PersistentObject being displayed — ids/breadcrumbs the flattened formData drops */
44
+ item?: InputSignal<PersistentObject | undefined>;
47
45
  }
48
46
  /**
49
47
  * Contract for query-list column renderers (spark-query-list).
50
48
  * Displays a compact cell value in the list/grid view.
51
49
  */
52
- interface SparkAttributeColumnRenderer {
53
- /**
54
- * The cell value. For an AsDetail column this is the nested PersistentObject (single) /
55
- * PersistentObject[] (array) in an AsDetail sub-table, and the projected value in a query grid.
56
- */
57
- value?: InputSignal<any>;
58
- /**
59
- * The column being rendered.
60
- *
61
- * A query grid supplies a {@link SparkCellColumn} from the result own column metadata; an
62
- * AsDetail sub-table supplies its attribute definition, which satisfies the same shape. This
63
- * replaced an `attribute` input typed as the definition: a query result no longer carries
64
- * attribute metadata per row, so naming it `attribute` would promise something the grid cannot
65
- * deliver.
66
- */
67
- column?: InputSignal<SparkCellColumn | undefined>;
68
- /** Renderer-specific options from rendererOptions */
69
- options?: InputSignal<Record<string, any> | undefined>;
70
- /**
71
- * The row this cell belongs to: a {@link QueryResultItem} in a query grid, a plain record
72
- * (possibly including the reserved '__sparkBreadcrumbs' key) in AsDetail sub-tables. Passed
73
- * only when declared.
74
- */
75
- item?: InputSignal<QueryResultItem | Record<string, any> | undefined>;
50
+ export interface SparkAttributeColumnRenderer {
51
+ /**
52
+ * The cell value. For an AsDetail column this is the nested PersistentObject (single) /
53
+ * PersistentObject[] (array) in an AsDetail sub-table, and the projected value in a query grid.
54
+ */
55
+ value?: InputSignal<any>;
56
+ /**
57
+ * The column being rendered.
58
+ *
59
+ * A query grid supplies a {@link SparkCellColumn} from the result own column metadata; an
60
+ * AsDetail sub-table supplies its attribute definition, which satisfies the same shape. This
61
+ * replaced an `attribute` input typed as the definition: a query result no longer carries
62
+ * attribute metadata per row, so naming it `attribute` would promise something the grid cannot
63
+ * deliver.
64
+ */
65
+ column?: InputSignal<SparkCellColumn | undefined>;
66
+ /** Renderer-specific options from rendererOptions */
67
+ options?: InputSignal<Record<string, any> | undefined>;
68
+ /**
69
+ * The row this cell belongs to: a {@link QueryResultItem} in a query grid, a plain record
70
+ * (possibly including the reserved '__sparkBreadcrumbs' key) in AsDetail sub-tables. Passed
71
+ * only when declared.
72
+ */
73
+ item?: InputSignal<QueryResultItem | Record<string, any> | undefined>;
74
+ }
75
+ /**
76
+ * Contract for AsDetail **row** renderers (`rowComponent` of a registration): drawn once per row of an
77
+ * AsDetail table, on the detail page and in the edit form, for the row-type attributes carrying the
78
+ * renderer — which are then not drawn as columns.
79
+ */
80
+ export interface SparkAttributeRowRenderer {
81
+ /** The row: a flat record of the row's values (reserved `__spark…` keys included). */
82
+ row?: InputSignal<Record<string, any>>;
83
+ /** The row-type attributes carrying this renderer, in model order. */
84
+ attributes?: InputSignal<EntityAttributeDefinition[]>;
85
+ /** `rendererOptions` of the first of them. */
86
+ options?: InputSignal<Record<string, any> | undefined>;
87
+ /** The id of the object that owns the AsDetail list (undefined on a create page). */
88
+ ownerId?: InputSignal<string | undefined>;
76
89
  }
77
90
  /**
78
91
  * Contract for edit-form renderers (spark-po-form on create/edit pages).
79
92
  * Replaces the default <input> for this attribute.
80
93
  */
81
- interface SparkAttributeEditRenderer {
82
- /** The current attribute value */
83
- value?: InputSignal<any>;
84
- /** The attribute definition metadata */
85
- attribute?: InputSignal<EntityAttributeDefinition | undefined>;
86
- /** Renderer-specific options from rendererOptions */
87
- options?: InputSignal<Record<string, any> | undefined>;
88
- /**
89
- * Callback to notify parent form of value changes (since NgComponentOutlet
90
- * doesn't support outputs). Not declaring it disables write-back.
91
- */
92
- valueChange?: InputSignal<(value: any) => void>;
94
+ export interface SparkAttributeEditRenderer {
95
+ /** The current attribute value */
96
+ value?: InputSignal<any>;
97
+ /** The attribute definition metadata */
98
+ attribute?: InputSignal<EntityAttributeDefinition | undefined>;
99
+ /** Renderer-specific options from rendererOptions */
100
+ options?: InputSignal<Record<string, any> | undefined>;
101
+ /**
102
+ * Callback to notify parent form of value changes (since NgComponentOutlet
103
+ * doesn't support outputs). Not declaring it disables write-back.
104
+ */
105
+ valueChange?: InputSignal<(value: any) => void>;
93
106
  }
94
-
95
- interface SparkAttributeRendererRegistration {
96
- /** The renderer name (must match attr.renderer in model JSON) */
97
- name: string;
98
- /** Component for the PO detail page. Must implement SparkAttributeDetailRenderer. Omit for a column/edit-only renderer. */
99
- detailComponent?: Type<any> | null;
100
- /** Component for query-list column cells. Must implement SparkAttributeColumnRenderer. Omit for a detail/edit-only renderer. */
101
- columnComponent?: Type<any> | null;
102
- /** Optional component for create/edit forms. Must implement SparkAttributeEditRenderer. When omitted, the default input is used. */
103
- editComponent?: Type<any>;
104
- /**
105
- * Relabels this column's values in a filter panel (#431).
106
- *
107
- * A renderer is a component that paints arbitrary DOM, and a distinct value has no row, so it
108
- * cannot be instantiated to produce text for a filter list. The label therefore defaults to the
109
- * server-computed cell text: a status rendered as a coloured pill lists `Active`, a rating
110
- * rendered as stars lists `3`. This is the escape for when that is too raw — a value stored as
111
- * `2` whose cell reads "High priority".
112
- *
113
- * ⚠️ A **pure function**: no DOM, no component instantiation, no row context. There is no row to
114
- * give it, which is the whole reason the renderer itself cannot be used here.
115
- */
116
- filterLabel?: (value: unknown) => string;
107
+ export interface SparkAttributeRendererRegistration {
108
+ /** The renderer name (must match attr.renderer in model JSON) */
109
+ name: string;
110
+ /** Component for the PO detail page. Must implement SparkAttributeDetailRenderer. Omit for a column/edit-only renderer. */
111
+ detailComponent?: Type<any> | null;
112
+ /** Component for query-list column cells. Must implement SparkAttributeColumnRenderer. Omit for a detail/edit-only renderer. */
113
+ columnComponent?: Type<any> | null;
114
+ /** Optional component for create/edit forms. Must implement SparkAttributeEditRenderer. When omitted, the default input is used. */
115
+ editComponent?: Type<any>;
116
+ /**
117
+ * A **row** renderer for AsDetail tables (the PO detail page and the edit form). Attributes of a row
118
+ * type that carry this renderer are not drawn as columns; instead the component is drawn ONCE per
119
+ * row, under the row's first cell, given all of them. Must implement {@link SparkAttributeRowRenderer}.
120
+ *
121
+ * For facts about a row rather than columns of it — contributions' "by Alice · 3 days ago ·
122
+ * History (4)" line collapses three read-only attributes into one. `rendererOptions` are taken from
123
+ * the first such attribute (a library writes the same options on each).
124
+ */
125
+ rowComponent?: Type<any>;
126
+ /**
127
+ * Relabels this column's values in a filter panel (#431).
128
+ *
129
+ * A renderer is a component that paints arbitrary DOM, and a distinct value has no row, so it
130
+ * cannot be instantiated to produce text for a filter list. The label therefore defaults to the
131
+ * server-computed cell text: a status rendered as a coloured pill lists `Active`, a rating
132
+ * rendered as stars lists `3`. This is the escape for when that is too raw — a value stored as
133
+ * `2` whose cell reads "High priority".
134
+ *
135
+ * ⚠️ A **pure function**: no DOM, no component instantiation, no row context. There is no row to
136
+ * give it, which is the whole reason the renderer itself cannot be used here.
137
+ */
138
+ filterLabel?: (value: unknown) => string;
117
139
  }
118
- declare const SPARK_ATTRIBUTE_RENDERERS: InjectionToken<SparkAttributeRendererRegistration[]>;
140
+ export declare const SPARK_ATTRIBUTE_RENDERERS: InjectionToken<SparkAttributeRendererRegistration[]>;
119
141
  /**
120
142
  * Register custom attribute renderers globally.
121
143
  *
@@ -125,7 +147,21 @@ declare const SPARK_ATTRIBUTE_RENDERERS: InjectionToken<SparkAttributeRendererRe
125
147
  * { name: 'color-swatch', detailComponent: ColorDetailComponent, columnComponent: ColorColumnComponent },
126
148
  * ])
127
149
  */
128
- declare function provideSparkAttributeRenderers(renderers: SparkAttributeRendererRegistration[]): Provider;
129
-
130
- export { SPARK_ATTRIBUTE_RENDERERS, cellValue, provideSparkAttributeRenderers, rendererValue, withDeclaredInputs };
131
- export type { SparkAttributeColumnRenderer, SparkAttributeDetailRenderer, SparkAttributeEditRenderer, SparkAttributeRendererRegistration };
150
+ export declare function provideSparkAttributeRenderers(renderers: SparkAttributeRendererRegistration[]): Provider;
151
+ /** The row renderer of an AsDetail row type, resolved once per type (see `rowComponent`). */
152
+ export interface SparkResolvedRowRenderer {
153
+ component: Type<any>;
154
+ /** The row-type attributes carrying the renderer, in model order. */
155
+ attributes: EntityAttributeDefinition[];
156
+ /** `rendererOptions` of the first of them. */
157
+ options: Record<string, any> | undefined;
158
+ }
159
+ /** Whether `attribute` is drawn by a row renderer (and therefore not as a column). */
160
+ export declare function isRowRendered(attribute: EntityAttributeDefinition, registry: readonly SparkAttributeRendererRegistration[] | null | undefined): boolean;
161
+ /**
162
+ * The first row renderer the row type's visible attributes name, or null. One per row: a row type
163
+ * whose attributes name two different row renderers gets the first in model order.
164
+ */
165
+ export declare function resolveRowRenderer(rowType: EntityType | null | undefined, registry: readonly SparkAttributeRendererRegistration[] | null | undefined): SparkResolvedRowRenderer | null;
166
+ /** The input bag for a row renderer, filtered to what the component declares. */
167
+ export declare function rowRendererInputs(renderer: SparkResolvedRowRenderer, row: Record<string, any>, ownerId: string | undefined): Record<string, any>;
@@ -1,8 +1,7 @@
1
- import * as _angular_core from '@angular/core';
2
- import { Color } from '@mintplayer/ng-bootstrap';
3
- import { RetryActionService } from '@mintplayer/ng-spark/services';
4
- import { EntityType } from '@mintplayer/ng-spark/models';
5
-
1
+ import { Color } from "@mintplayer/ng-bootstrap";
2
+ import { RetryActionService } from "@mintplayer/ng-spark/services";
3
+ import { EntityType } from "@mintplayer/ng-spark/models";
4
+ import * as i0 from "@angular/core";
6
5
  /**
7
6
  * Renders a retry-action popup. Before PRD §3 this component rendered title / message /
8
7
  * option buttons only and silently forwarded the incoming <c>persistentObject</c> back to
@@ -12,32 +11,30 @@ import { EntityType } from '@mintplayer/ng-spark/models';
12
11
  * field, and the values the user fills in flow back to the server via
13
12
  * <c>RetryResult.PersistentObject</c>.
14
13
  */
15
- declare class SparkRetryActionModalComponent {
16
- protected readonly retryActionService: RetryActionService;
17
- private readonly sparkService;
18
- colors: typeof Color;
19
- isOpen: _angular_core.Signal<boolean>;
20
- /**
21
- * EntityType definition for the incoming PO — fetched lazily via SparkService so the
22
- * form knows which attributes are editable, their labels, rules, renderers, etc.
23
- * `null` when the payload has no persistentObject or its objectTypeId doesn't match
24
- * any registered entity type (renders the modal as a simple option picker).
25
- */
26
- entityType: _angular_core.WritableSignal<EntityType | null>;
27
- formData: _angular_core.WritableSignal<Record<string, any>>;
28
- private allEntityTypes;
29
- constructor();
30
- private seedForm;
31
- onOption(option: string): void;
32
- /**
33
- * Builds the PO the server sees under <c>Retry.Result.PersistentObject</c>. If the
34
- * form resolved an EntityType, rebuild from the schema + formData (identical to the
35
- * po-edit save path — AsDetail recursion included). Otherwise forward the incoming
36
- * PO unmodified so pre-§3 flows without editable attributes keep working.
37
- */
38
- private populatedPersistentObject;
39
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkRetryActionModalComponent, never>;
40
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SparkRetryActionModalComponent, "spark-retry-action-modal", never, {}, {}, never, never, true, never>;
41
- }
42
-
43
- export { SparkRetryActionModalComponent };
14
+ export declare class SparkRetryActionModalComponent {
15
+ protected readonly retryActionService: RetryActionService;
16
+ private readonly sparkService;
17
+ colors: typeof Color;
18
+ isOpen: import("@angular/core").Signal<boolean>;
19
+ /**
20
+ * EntityType definition for the incoming PO — fetched lazily via SparkService so the
21
+ * form knows which attributes are editable, their labels, rules, renderers, etc.
22
+ * `null` when the payload has no persistentObject or its objectTypeId doesn't match
23
+ * any registered entity type (renders the modal as a simple option picker).
24
+ */
25
+ entityType: import("@angular/core").WritableSignal<EntityType | null>;
26
+ formData: import("@angular/core").WritableSignal<Record<string, any>>;
27
+ private allEntityTypes;
28
+ constructor();
29
+ private seedForm;
30
+ onOption(option: string): void;
31
+ /**
32
+ * Builds the PO the server sees under <c>Retry.Result.PersistentObject</c>. If the
33
+ * form resolved an EntityType, rebuild from the schema + formData (identical to the
34
+ * po-edit save path — AsDetail recursion included). Otherwise forward the incoming
35
+ * PO unmodified so pre-§3 flows without editable attributes keep working.
36
+ */
37
+ private populatedPersistentObject;
38
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkRetryActionModalComponent, never>;
39
+ static ɵcmp: i0.ɵɵComponentDeclaration<SparkRetryActionModalComponent, "spark-retry-action-modal", never, {}, {}, never, never, true, never>;
40
+ }
@@ -1,12 +1,8 @@
1
- import { Route, Routes } from '@angular/router';
2
-
3
- interface SparkRouteConfig {
4
- queryList?: Route['loadComponent'];
5
- poCreate?: Route['loadComponent'];
6
- poEdit?: Route['loadComponent'];
7
- poDetail?: Route['loadComponent'];
1
+ import { Route, Routes } from "@angular/router";
2
+ export interface SparkRouteConfig {
3
+ queryList?: Route['loadComponent'];
4
+ poCreate?: Route['loadComponent'];
5
+ poEdit?: Route['loadComponent'];
6
+ poDetail?: Route['loadComponent'];
8
7
  }
9
- declare function sparkRoutes(config?: SparkRouteConfig): Routes;
10
-
11
- export { sparkRoutes };
12
- export type { SparkRouteConfig };
8
+ export declare function sparkRoutes(config?: SparkRouteConfig): Routes;