@mintplayer/ng-spark 22.5.0 → 22.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/mintplayer-ng-spark-client-operations.mjs +12 -12
- package/fesm2022/mintplayer-ng-spark-grid.mjs +151 -70
- package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-icon.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-models.mjs +77 -7
- package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-pipes.mjs +167 -74
- package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-create.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs +5 -5
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-edit.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-po-form.mjs +20 -22
- package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-query-list.mjs +23 -9
- package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-renderers.mjs +14 -1
- package/fesm2022/mintplayer-ng-spark-renderers.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-services.mjs +107 -20
- package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-shell.mjs +416 -0
- package/fesm2022/mintplayer-ng-spark-shell.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark.mjs +17 -1
- package/fesm2022/mintplayer-ng-spark.mjs.map +1 -1
- package/package.json +5 -1
- package/types/mintplayer-ng-spark-grid.d.ts +75 -33
- package/types/mintplayer-ng-spark-models.d.ts +144 -7
- package/types/mintplayer-ng-spark-pipes.d.ts +42 -6
- package/types/mintplayer-ng-spark-po-detail.d.ts +2 -2
- package/types/mintplayer-ng-spark-po-form.d.ts +7 -7
- package/types/mintplayer-ng-spark-query-list.d.ts +11 -4
- package/types/mintplayer-ng-spark-renderers.d.ts +29 -11
- package/types/mintplayer-ng-spark-services.d.ts +71 -2
- package/types/mintplayer-ng-spark-shell.d.ts +272 -0
- package/types/mintplayer-ng-spark.d.ts +17 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _mintplayer_ng_spark_models from '@mintplayer/ng-spark/models';
|
|
2
|
-
import {
|
|
2
|
+
import { QueryResultItem, CustomActionDefinition, QueryColumn } from '@mintplayer/ng-spark/models';
|
|
3
3
|
import * as _angular_core from '@angular/core';
|
|
4
4
|
import { TemplateRef } from '@angular/core';
|
|
5
5
|
import { Color } from '@mintplayer/ng-bootstrap';
|
|
@@ -31,7 +31,12 @@ declare class SparkQueryListComponent {
|
|
|
31
31
|
protected readonly lang: SparkLanguageService;
|
|
32
32
|
extraActionsTemplate: _angular_core.InputSignal<TemplateRef<void> | null>;
|
|
33
33
|
showCustomActions: _angular_core.InputSignal<boolean>;
|
|
34
|
-
|
|
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>;
|
|
35
40
|
createClicked: _angular_core.OutputEmitterRef<void>;
|
|
36
41
|
customActionExecuted: _angular_core.OutputEmitterRef<{
|
|
37
42
|
action: CustomActionDefinition;
|
|
@@ -59,6 +64,8 @@ declare class SparkQueryListComponent {
|
|
|
59
64
|
protected isActionEnabled(action: CustomActionDefinition): boolean;
|
|
60
65
|
isStreaming: _angular_core.WritableSignal<boolean>;
|
|
61
66
|
private streamingSub;
|
|
67
|
+
/** Columns as sent with the stream's snapshot; empty until it arrives. */
|
|
68
|
+
protected readonly streamColumns: _angular_core.WritableSignal<QueryColumn[]>;
|
|
62
69
|
private readonly allItems;
|
|
63
70
|
private readonly streamItems;
|
|
64
71
|
/**
|
|
@@ -67,7 +74,7 @@ declare class SparkQueryListComponent {
|
|
|
67
74
|
* Null for a normal query — an empty array would read as "here are no rows" and suppress the
|
|
68
75
|
* fetch entirely.
|
|
69
76
|
*/
|
|
70
|
-
protected readonly gridData: _angular_core.Signal<
|
|
77
|
+
protected readonly gridData: _angular_core.Signal<QueryResultItem[] | null>;
|
|
71
78
|
constructor();
|
|
72
79
|
private onParamsChange;
|
|
73
80
|
/**
|
|
@@ -84,7 +91,7 @@ declare class SparkQueryListComponent {
|
|
|
84
91
|
private handleStreamingMessage;
|
|
85
92
|
private applyFilter;
|
|
86
93
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkQueryListComponent, never>;
|
|
87
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SparkQueryListComponent, "spark-query-list", never, { "extraActionsTemplate": { "alias": "extraActionsTemplate"; "required": false; "isSignal": true; }; "showCustomActions": { "alias": "showCustomActions"; "required": false; "isSignal": true; }; }, { "rowClicked": "rowClicked"; "createClicked": "createClicked"; "customActionExecuted": "customActionExecuted"; }, never, never, true, never>;
|
|
94
|
+
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>;
|
|
88
95
|
}
|
|
89
96
|
|
|
90
97
|
export { SparkQueryListComponent };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Type, InputSignal, InjectionToken, Provider } from '@angular/core';
|
|
2
|
-
import { PersistentObjectAttribute, EntityAttributeDefinition, PersistentObject } from '@mintplayer/ng-spark/models';
|
|
2
|
+
import { QueryResultItemValue, PersistentObjectAttribute, SparkCellColumn, QueryResultItem, EntityAttributeDefinition, PersistentObject } from '@mintplayer/ng-spark/models';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Drops entries the component doesn't declare, so every contract member is
|
|
@@ -10,8 +10,19 @@ declare function withDeclaredInputs(component: Type<any>, inputs: Record<string,
|
|
|
10
10
|
* The renderer-facing value of an attribute: the flat value, or for AsDetail
|
|
11
11
|
* attributes (whose flat value the server nulls on purpose) the nested
|
|
12
12
|
* PersistentObject (single) / PersistentObject[] (array).
|
|
13
|
+
*
|
|
14
|
+
* Used by the detail and edit paths, which still work in attributes.
|
|
13
15
|
*/
|
|
14
16
|
declare function rendererValue(attr: PersistentObjectAttribute | undefined): any;
|
|
17
|
+
/**
|
|
18
|
+
* The renderer-facing value of a query-result cell.
|
|
19
|
+
*
|
|
20
|
+
* A grid row carries no nested objects to fall back to — a projection is flat by construction —
|
|
21
|
+
* so this is deliberately not the same function as {@link rendererValue}. Keeping them separate
|
|
22
|
+
* is what stops a renderer silently receiving `undefined` because it was written against the
|
|
23
|
+
* attribute shape.
|
|
24
|
+
*/
|
|
25
|
+
declare function cellValue(value: QueryResultItemValue | undefined): any;
|
|
15
26
|
|
|
16
27
|
/**
|
|
17
28
|
* Contract for detail-page renderers (spark-po-detail).
|
|
@@ -38,21 +49,28 @@ interface SparkAttributeDetailRenderer {
|
|
|
38
49
|
*/
|
|
39
50
|
interface SparkAttributeColumnRenderer {
|
|
40
51
|
/**
|
|
41
|
-
* The
|
|
42
|
-
* PersistentObject
|
|
43
|
-
* sub-query grids, and the flattened value in AsDetail sub-table cells.
|
|
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.
|
|
44
54
|
*/
|
|
45
55
|
value?: InputSignal<any>;
|
|
46
|
-
/**
|
|
47
|
-
|
|
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>;
|
|
48
66
|
/** Renderer-specific options from rendererOptions */
|
|
49
67
|
options?: InputSignal<Record<string, any> | undefined>;
|
|
50
68
|
/**
|
|
51
|
-
* The row this cell belongs to: a
|
|
52
|
-
*
|
|
53
|
-
*
|
|
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.
|
|
54
72
|
*/
|
|
55
|
-
item?: InputSignal<
|
|
73
|
+
item?: InputSignal<QueryResultItem | Record<string, any> | undefined>;
|
|
56
74
|
}
|
|
57
75
|
/**
|
|
58
76
|
* Contract for edit-form renderers (spark-po-form on create/edit pages).
|
|
@@ -94,5 +112,5 @@ declare const SPARK_ATTRIBUTE_RENDERERS: InjectionToken<SparkAttributeRendererRe
|
|
|
94
112
|
*/
|
|
95
113
|
declare function provideSparkAttributeRenderers(renderers: SparkAttributeRendererRegistration[]): Provider;
|
|
96
114
|
|
|
97
|
-
export { SPARK_ATTRIBUTE_RENDERERS, provideSparkAttributeRenderers, rendererValue, withDeclaredInputs };
|
|
115
|
+
export { SPARK_ATTRIBUTE_RENDERERS, cellValue, provideSparkAttributeRenderers, rendererValue, withDeclaredInputs };
|
|
98
116
|
export type { SparkAttributeColumnRenderer, SparkAttributeDetailRenderer, SparkAttributeEditRenderer, SparkAttributeRendererRegistration };
|
|
@@ -83,7 +83,20 @@ declare class SparkService {
|
|
|
83
83
|
refresh(type: string, data: Partial<PersistentObject>, triggeredBy: string): Promise<PersistentObject>;
|
|
84
84
|
delete(type: string, id: string): Promise<void>;
|
|
85
85
|
getCustomActions(objectTypeId: string): Promise<CustomActionDefinition[]>;
|
|
86
|
-
|
|
86
|
+
/**
|
|
87
|
+
* @param parent The object of THIS type the action is operating on — the detail-page invocation.
|
|
88
|
+
* @param selectedItemIds Row ids from a query. Ids, never row objects: a row is a projection.
|
|
89
|
+
* @param queryParent When invoked from a sub-query, the object whose detail page it was rendered
|
|
90
|
+
* on — a DIFFERENT type (the cars listed on a company's page are Cars, the page is a Company).
|
|
91
|
+
* Sent as id + type, exactly as the query endpoint names it, and resolved server-side under its
|
|
92
|
+
* own type with its own Read gate.
|
|
93
|
+
* @param queryId The query the selection came from, so the server can re-run it narrowed to those
|
|
94
|
+
* ids and hand the action the rows the grid actually had -- index-computed columns included.
|
|
95
|
+
*/
|
|
96
|
+
executeCustomAction(objectTypeId: string, actionName: string, parent?: PersistentObject, selectedItemIds?: string[], queryParent?: {
|
|
97
|
+
id: string;
|
|
98
|
+
type: string;
|
|
99
|
+
}, queryId?: string): Promise<void>;
|
|
87
100
|
getLookupReferences(): Promise<LookupReferenceListItem[]>;
|
|
88
101
|
getLookupReference(name: string): Promise<LookupReference>;
|
|
89
102
|
addLookupReferenceValue(name: string, value: LookupReferenceValue): Promise<LookupReferenceValue>;
|
|
@@ -133,4 +146,60 @@ declare class SparkIconRegistry {
|
|
|
133
146
|
static ɵprov: i0.ɵɵInjectableDeclaration<SparkIconRegistry>;
|
|
134
147
|
}
|
|
135
148
|
|
|
136
|
-
|
|
149
|
+
/**
|
|
150
|
+
* A query's custom actions, reachable **without the grid that usually renders them**.
|
|
151
|
+
*
|
|
152
|
+
* ## Why this exists
|
|
153
|
+
*
|
|
154
|
+
* A query's actions were only ever obtainable by rendering `<spark-query-grid>`, which loads the
|
|
155
|
+
* query, resolves its entity type, fetches the actions and filters them to the ones marked for a
|
|
156
|
+
* query surface — all privately. A page that wanted the same buttons somewhere else (a toolbar
|
|
157
|
+
* above the card, the shell's topbar) had three bad options: duplicate the four-step resolution
|
|
158
|
+
* and let it drift, reach into the grid's internals, or put the button in the wrong place.
|
|
159
|
+
*
|
|
160
|
+
* This exposes the resolution itself. The grid keeps rendering the default placement; a host that
|
|
161
|
+
* wants a different one asks here and renders its own control.
|
|
162
|
+
*
|
|
163
|
+
* ## What it does not do
|
|
164
|
+
*
|
|
165
|
+
* It does not authorize. `/spark/actions/{type}` returns only the actions this caller may see —
|
|
166
|
+
* the server filters against `security.json`, and executing re-checks — so nothing here is a gate,
|
|
167
|
+
* and a host must not treat "the list came back empty" as anything other than a display fact.
|
|
168
|
+
*
|
|
169
|
+
* It also does not cache. Actions depend on the caller, and a memo keyed by type id would survive
|
|
170
|
+
* a sign-out.
|
|
171
|
+
*/
|
|
172
|
+
declare class SparkQueryActionsService {
|
|
173
|
+
private readonly sparkService;
|
|
174
|
+
/**
|
|
175
|
+
* The custom actions of the query named by id or alias, already filtered to those that belong on
|
|
176
|
+
* a query surface.
|
|
177
|
+
*
|
|
178
|
+
* Returns an empty list — rather than throwing — when the query resolves to no entity type,
|
|
179
|
+
* because a caller rendering a toolbar wants "no buttons", not a broken page.
|
|
180
|
+
*/
|
|
181
|
+
actionsFor(queryIdOrAlias: string): Promise<CustomActionDefinition[]>;
|
|
182
|
+
/**
|
|
183
|
+
* Runs one of those actions. `selectedItemIds` are row ids, exactly as the grid posts them —
|
|
184
|
+
* the server re-materializes each one through the same load path a detail page uses, so an id
|
|
185
|
+
* from anywhere is treated as caller input rather than as a verified row.
|
|
186
|
+
*/
|
|
187
|
+
execute(queryIdOrAlias: string, actionName: string, options?: {
|
|
188
|
+
parent?: PersistentObject;
|
|
189
|
+
selectedItemIds?: string[];
|
|
190
|
+
/** For a sub-query: the object whose detail page it was rendered on. See SparkService. */
|
|
191
|
+
queryParent?: {
|
|
192
|
+
id: string;
|
|
193
|
+
type: string;
|
|
194
|
+
};
|
|
195
|
+
}): Promise<void>;
|
|
196
|
+
/**
|
|
197
|
+
* The query and the entity type its rows are mapped against — the two-step resolution both
|
|
198
|
+
* methods need, kept in one place so they cannot disagree about which type an action runs on.
|
|
199
|
+
*/
|
|
200
|
+
private contextFor;
|
|
201
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkQueryActionsService, never>;
|
|
202
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<SparkQueryActionsService>;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export { RetryActionService, SparkIconRegistry, SparkLanguageService, SparkQueryActionsService, SparkService, SparkStreamingService };
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { TemplateRef } from '@angular/core';
|
|
3
|
+
import { BsShellState } from '@mintplayer/ng-bootstrap/shell';
|
|
4
|
+
import { Breakpoint } from '@mintplayer/ng-bootstrap';
|
|
5
|
+
import { ShellStateChangeEventDetail } from '@mintplayer/web-components/shell';
|
|
6
|
+
import { ProgramUnitGroup } from '@mintplayer/ng-spark/models';
|
|
7
|
+
import { SparkLanguageService } from '@mintplayer/ng-spark/services';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Region slots for `<spark-shell>`.
|
|
11
|
+
*
|
|
12
|
+
* Each directive marks a template that REPLACES one region of the shell chrome (or fills an
|
|
13
|
+
* empty one). An omitted slot is not an empty slot: the shell renders its default — the toggler,
|
|
14
|
+
* the language selector, the title heading — so a host that supplies nothing still gets a
|
|
15
|
+
* complete working shell, and a host that supplies one slot leaves the rest alone.
|
|
16
|
+
*
|
|
17
|
+
* The menu itself is deliberately NOT a slot. Navigation is sourced entirely from
|
|
18
|
+
* `programUnits.json` through the rights-filtered `/spark/program-units` endpoint and re-fetched
|
|
19
|
+
* on sign-in/out; a host that finds itself writing unit anchors in a slot should be adding units
|
|
20
|
+
* to `programUnits.json` instead. Slots exist for the content AROUND the menu: an auth bar, a
|
|
21
|
+
* user chip, branding, a one-off extra link, an alert strip above the routed content.
|
|
22
|
+
*
|
|
23
|
+
* Naming follows the house convention (prefix, component, slot — see `*sparkQueryIcon` in
|
|
24
|
+
* `@mintplayer/ng-spark/grid`): `sparkShell` + region. Every slot also exists as a `TemplateRef`
|
|
25
|
+
* input on `SparkShellComponent` for hosts that cannot use content projection.
|
|
26
|
+
*
|
|
27
|
+
* ```html
|
|
28
|
+
* <spark-shell title="My App">
|
|
29
|
+
* <spark-auth-bar *sparkShellTopbarEnd />
|
|
30
|
+
* <div *sparkShellSidebarTop>
|
|
31
|
+
* <a routerLink="/github-projects" class="nav-link">GitHub projects</a>
|
|
32
|
+
* </div>
|
|
33
|
+
* <router-outlet />
|
|
34
|
+
* </spark-shell>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
/** Topbar, leading edge. Default: a `bs-navbar-toggler` mirroring the shell's open state. */
|
|
38
|
+
declare class SparkShellTopbarStartDirective {
|
|
39
|
+
readonly templateRef: TemplateRef<unknown>;
|
|
40
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkShellTopbarStartDirective, never>;
|
|
41
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SparkShellTopbarStartDirective, "[sparkShellTopbarStart]", never, {}, {}, never, never, true, never>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Topbar, trailing edge. Default: the language selector (which hides itself when the app has
|
|
45
|
+
* one language). This is where an auth bar goes — the shell cannot ship one itself, since
|
|
46
|
+
* `@mintplayer/ng-spark` does not (and must not) depend on `@mintplayer/ng-spark-auth`.
|
|
47
|
+
*/
|
|
48
|
+
declare class SparkShellTopbarEndDirective {
|
|
49
|
+
readonly templateRef: TemplateRef<unknown>;
|
|
50
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkShellTopbarEndDirective, never>;
|
|
51
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SparkShellTopbarEndDirective, "[sparkShellTopbarEnd]", never, {}, {}, never, never, true, never>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Topbar, trailing edge, **beside** the default chrome rather than instead of it — rendered before
|
|
55
|
+
* the language selector, which stays.
|
|
56
|
+
*
|
|
57
|
+
* ## Why this is not just `*sparkShellTopbarEnd`
|
|
58
|
+
*
|
|
59
|
+
* That slot REPLACES the region, which is right for an auth bar (a host taking over the trailing
|
|
60
|
+
* edge wholesale) and wrong for a page-level action button. A host that only wanted to add a
|
|
61
|
+
* button had to re-render the language selector itself to keep it — which means importing it,
|
|
62
|
+
* knowing it hides itself in a single-language app, and keeping that copy in step with the shell.
|
|
63
|
+
* Every host that did this got it slightly differently.
|
|
64
|
+
*
|
|
65
|
+
* Pairs with `SparkQueryActionsService`: that service resolves a query's custom actions without the
|
|
66
|
+
* grid, and this is where a page-level one goes.
|
|
67
|
+
*
|
|
68
|
+
* ```html
|
|
69
|
+
* <button *sparkShellTopbarActions class="btn btn-primary" (click)="publish()">Publish</button>
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* Supplying both slots is allowed and does what it says: `topbarEnd` replaces the default chrome,
|
|
73
|
+
* and these actions still render ahead of whatever it put there.
|
|
74
|
+
*/
|
|
75
|
+
declare class SparkShellTopbarActionsDirective {
|
|
76
|
+
readonly templateRef: TemplateRef<unknown>;
|
|
77
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkShellTopbarActionsDirective, never>;
|
|
78
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SparkShellTopbarActionsDirective, "[sparkShellTopbarActions]", never, {}, {}, never, never, true, never>;
|
|
79
|
+
}
|
|
80
|
+
/** Sidebar, above everything. Default: `<h5>{{ title }}</h5>`. */
|
|
81
|
+
declare class SparkShellSidebarHeaderDirective {
|
|
82
|
+
readonly templateRef: TemplateRef<unknown>;
|
|
83
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkShellSidebarHeaderDirective, never>;
|
|
84
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SparkShellSidebarHeaderDirective, "[sparkShellSidebarHeader]", never, {}, {}, never, never, true, never>;
|
|
85
|
+
}
|
|
86
|
+
/** Sidebar, between the header and the program-units menu. No default. */
|
|
87
|
+
declare class SparkShellSidebarTopDirective {
|
|
88
|
+
readonly templateRef: TemplateRef<unknown>;
|
|
89
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkShellSidebarTopDirective, never>;
|
|
90
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SparkShellSidebarTopDirective, "[sparkShellSidebarTop]", never, {}, {}, never, never, true, never>;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* An extra accordion tab in the sidebar menu, rendered after the generated program-unit groups
|
|
94
|
+
* and sharing their single-open behavior.
|
|
95
|
+
*
|
|
96
|
+
* A tab is contributed as DATA (header + body template), not as markup, and that is load-bearing:
|
|
97
|
+
* `bs-accordion` discovers its tabs with an Angular content query, which matches by declaration
|
|
98
|
+
* view, so a `<bs-accordion-tab>` written in a host's template and inserted into the library's
|
|
99
|
+
* accordion is never registered — it would land at index -1, get no hoisted header and no slot.
|
|
100
|
+
* Declaring a second `<bs-accordion>` instead is what puts the tab in its own exclusivity group:
|
|
101
|
+
* `mp-accordion` enforces single-open per element, over children it owns and over
|
|
102
|
+
* `<details name>`, whose grouping cannot cross a shadow root. So the tab element must be created
|
|
103
|
+
* by the menu itself, from what this directive carries.
|
|
104
|
+
*
|
|
105
|
+
* ```html
|
|
106
|
+
* <ng-container *sparkShellTab="'Component demos'; icon: 'palette'">
|
|
107
|
+
* <a routerLink="/query-slots" routerLinkActive="active" class="nav-link">Query card slots</a>
|
|
108
|
+
* </ng-container>
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* Navigation still belongs in `programUnits.json` — this is for pages the model cannot describe
|
|
112
|
+
* (client-side demos, external tools). For sidebar content that is NOT an accordion tab, use
|
|
113
|
+
* `*sparkShellSidebarTop` or `*sparkShellSidebarFooter`.
|
|
114
|
+
*/
|
|
115
|
+
declare class SparkShellTabDirective {
|
|
116
|
+
readonly templateRef: TemplateRef<unknown>;
|
|
117
|
+
/** The tab's header label. */
|
|
118
|
+
readonly header: _angular_core.InputSignal<string>;
|
|
119
|
+
/** Bootstrap icon name for the header, as in `programUnits.json`. Defaults to a folder. */
|
|
120
|
+
readonly icon: _angular_core.InputSignal<string | undefined>;
|
|
121
|
+
/** Replaces the icon+label header entirely, for a header that needs its own markup. */
|
|
122
|
+
readonly headerTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
|
|
123
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkShellTabDirective, never>;
|
|
124
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SparkShellTabDirective, "[sparkShellTab]", never, { "header": { "alias": "sparkShellTab"; "required": true; "isSignal": true; }; "icon": { "alias": "sparkShellTabIcon"; "required": false; "isSignal": true; }; "headerTemplate": { "alias": "sparkShellTabHeader"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* A sidebar accordion tab in the shape the menu renders it. Hosts normally contribute tabs with
|
|
128
|
+
* `*sparkShellTab`; this is the same thing as data, for a host that computes its tabs.
|
|
129
|
+
*/
|
|
130
|
+
interface SparkSidebarTab {
|
|
131
|
+
readonly header: string;
|
|
132
|
+
readonly icon?: string;
|
|
133
|
+
readonly headerTemplate?: TemplateRef<unknown> | null;
|
|
134
|
+
readonly content: TemplateRef<unknown>;
|
|
135
|
+
}
|
|
136
|
+
/** Sidebar, at the very bottom. No default. */
|
|
137
|
+
declare class SparkShellSidebarFooterDirective {
|
|
138
|
+
readonly templateRef: TemplateRef<unknown>;
|
|
139
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkShellSidebarFooterDirective, never>;
|
|
140
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SparkShellSidebarFooterDirective, "[sparkShellSidebarFooter]", never, {}, {}, never, never, true, never>;
|
|
141
|
+
}
|
|
142
|
+
/** Main region, above the projected content (the host's `<router-outlet>`). No default. */
|
|
143
|
+
declare class SparkShellMainHeaderDirective {
|
|
144
|
+
readonly templateRef: TemplateRef<unknown>;
|
|
145
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkShellMainHeaderDirective, never>;
|
|
146
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SparkShellMainHeaderDirective, "[sparkShellMainHeader]", never, {}, {}, never, never, true, never>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* The application frame: topbar + sidebar + main, wrapping ng-bootstrap's `bs-shell` (whose
|
|
151
|
+
* `mp-shell` web component owns ALL responsive behavior — breakpoints, the overlay drawer,
|
|
152
|
+
* dismiss-on-navigate — in CSS; nothing here re-derives a pixel width). The sidebar renders the
|
|
153
|
+
* server-driven program-units menu; the host projects its `<router-outlet>` as the default
|
|
154
|
+
* content and customizes the chrome through the `*sparkShell*` slots (see `spark-shell-slots.ts`
|
|
155
|
+
* for the doctrine: an omitted slot renders its default, and the menu itself is never a slot).
|
|
156
|
+
*
|
|
157
|
+
* ```html
|
|
158
|
+
* <spark-shell title="My App">
|
|
159
|
+
* <spark-auth-bar *sparkShellTopbarEnd />
|
|
160
|
+
* <router-outlet />
|
|
161
|
+
* </spark-shell>
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* The one piece of state the shell keeps is the toggler↔drawer mirror: the built-in hamburger is
|
|
165
|
+
* hidden (`::part(hamburger)`) in favor of a `bs-navbar-toggler` in the topbar, so the shell
|
|
166
|
+
* listens to `statechange` to keep the toggler's icon truthful in `auto` mode and only forces
|
|
167
|
+
* `show`/`hide` on explicit toggles.
|
|
168
|
+
*
|
|
169
|
+
* Theming: the chrome colors are CSS custom properties with the classic dark-sidebar defaults —
|
|
170
|
+
* `--spark-shell-topbar-bg`, `--spark-shell-sidebar-bg`, `--spark-shell-main-bg` — overridable on
|
|
171
|
+
* the `<spark-shell>` element. `sidebarTheme` flips the sidebar's `data-bs-theme` (which is what
|
|
172
|
+
* recolors the accordion internals across the shadow boundary) together with its default palette.
|
|
173
|
+
*/
|
|
174
|
+
declare class SparkShellComponent {
|
|
175
|
+
/** The sidebar heading. Ignored when a `*sparkShellSidebarHeader` slot is supplied. */
|
|
176
|
+
readonly title: _angular_core.InputSignal<string>;
|
|
177
|
+
/** Forwarded to `bs-shell`: below it the sidebar is an overlay drawer. */
|
|
178
|
+
readonly breakpoint: _angular_core.InputSignal<Breakpoint>;
|
|
179
|
+
/**
|
|
180
|
+
* `data-bs-theme` for the sidebar — what flips the accordion's shadow-DOM internals between
|
|
181
|
+
* palettes — plus the matching default background. `null` sets no theme (inherit the page's).
|
|
182
|
+
*/
|
|
183
|
+
readonly sidebarTheme: _angular_core.InputSignal<"dark" | "light" | null>;
|
|
184
|
+
/** Forwarded to the menu: any changed value re-fetches the program units. */
|
|
185
|
+
readonly reloadToken: _angular_core.InputSignal<unknown>;
|
|
186
|
+
/** Extra sidebar tabs as data, for hosts that compute them; `*sparkShellTab` is the usual way. */
|
|
187
|
+
readonly sidebarTabs: _angular_core.InputSignal<readonly SparkSidebarTab[]>;
|
|
188
|
+
readonly topbarStartTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
|
|
189
|
+
readonly topbarEndTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
|
|
190
|
+
readonly topbarActionsTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
|
|
191
|
+
readonly sidebarHeaderTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
|
|
192
|
+
readonly sidebarTopTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
|
|
193
|
+
readonly sidebarFooterTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
|
|
194
|
+
readonly mainHeaderTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
|
|
195
|
+
private readonly topbarStartSlot;
|
|
196
|
+
private readonly topbarEndSlot;
|
|
197
|
+
private readonly topbarActionsSlot;
|
|
198
|
+
private readonly sidebarHeaderSlot;
|
|
199
|
+
private readonly sidebarTopSlot;
|
|
200
|
+
private readonly sidebarFooterSlot;
|
|
201
|
+
private readonly mainHeaderSlot;
|
|
202
|
+
protected readonly topbarStartTpl: _angular_core.Signal<TemplateRef<unknown> | null>;
|
|
203
|
+
protected readonly topbarEndTpl: _angular_core.Signal<TemplateRef<unknown> | null>;
|
|
204
|
+
protected readonly topbarActionsTpl: _angular_core.Signal<TemplateRef<unknown> | null>;
|
|
205
|
+
protected readonly sidebarHeaderTpl: _angular_core.Signal<TemplateRef<unknown> | null>;
|
|
206
|
+
protected readonly sidebarTopTpl: _angular_core.Signal<TemplateRef<unknown> | null>;
|
|
207
|
+
protected readonly sidebarFooterTpl: _angular_core.Signal<TemplateRef<unknown> | null>;
|
|
208
|
+
protected readonly mainHeaderTpl: _angular_core.Signal<TemplateRef<unknown> | null>;
|
|
209
|
+
/**
|
|
210
|
+
* Extra accordion tabs, forwarded to the menu so IT creates the `<bs-accordion-tab>` elements —
|
|
211
|
+
* the only way they share the generated groups' single-open behavior (see
|
|
212
|
+
* `SparkShellTabDirective`). Data-supplied tabs come first, then projected ones in declaration
|
|
213
|
+
* order.
|
|
214
|
+
*/
|
|
215
|
+
private readonly tabSlots;
|
|
216
|
+
protected readonly tabs: _angular_core.Signal<readonly SparkSidebarTab[]>;
|
|
217
|
+
protected readonly shellState: _angular_core.WritableSignal<BsShellState>;
|
|
218
|
+
protected readonly isSidebarVisible: _angular_core.WritableSignal<boolean>;
|
|
219
|
+
protected toggleSidebar(open: boolean): void;
|
|
220
|
+
protected onShellToggle(detail: ShellStateChangeEventDetail): void;
|
|
221
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkShellComponent, never>;
|
|
222
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SparkShellComponent, "spark-shell", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "breakpoint": { "alias": "breakpoint"; "required": false; "isSignal": true; }; "sidebarTheme": { "alias": "sidebarTheme"; "required": false; "isSignal": true; }; "reloadToken": { "alias": "reloadToken"; "required": false; "isSignal": true; }; "sidebarTabs": { "alias": "sidebarTabs"; "required": false; "isSignal": true; }; "topbarStartTemplate": { "alias": "topbarStartTemplate"; "required": false; "isSignal": true; }; "topbarEndTemplate": { "alias": "topbarEndTemplate"; "required": false; "isSignal": true; }; "topbarActionsTemplate": { "alias": "topbarActionsTemplate"; "required": false; "isSignal": true; }; "sidebarHeaderTemplate": { "alias": "sidebarHeaderTemplate"; "required": false; "isSignal": true; }; "sidebarTopTemplate": { "alias": "sidebarTopTemplate"; "required": false; "isSignal": true; }; "sidebarFooterTemplate": { "alias": "sidebarFooterTemplate"; "required": false; "isSignal": true; }; "mainHeaderTemplate": { "alias": "mainHeaderTemplate"; "required": false; "isSignal": true; }; }, {}, ["topbarStartSlot", "topbarEndSlot", "topbarActionsSlot", "sidebarHeaderSlot", "sidebarTopSlot", "sidebarFooterSlot", "mainHeaderSlot", "tabSlots"], ["*"], true, never>;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* The server-driven navigation menu: an accordion of program-unit groups fetched from
|
|
227
|
+
* `GET /spark/program-units`, which the server has already filtered to what the caller's rights
|
|
228
|
+
* allow. Hosts write ZERO router links for navigation — every group, unit, icon, label and link
|
|
229
|
+
* comes from `programUnits.json`; content around the menu belongs in `<spark-shell>`'s slots,
|
|
230
|
+
* and a host tempted to hand-write a unit anchor should add a unit to `programUnits.json`
|
|
231
|
+
* instead.
|
|
232
|
+
*
|
|
233
|
+
* Because the response is caller-scoped it must be re-fetched when the caller changes: the
|
|
234
|
+
* component tracks the optional `SPARK_AUTH_STATE` signal (supplied by ng-spark-auth's
|
|
235
|
+
* `provideSparkAuth()`, or by the app's own auth stack) and reloads on every change. Without a
|
|
236
|
+
* provider it fetches once. `reloadToken` is the manual escape hatch (any changed value triggers
|
|
237
|
+
* a reload), and `reload()` the imperative one.
|
|
238
|
+
*
|
|
239
|
+
* Usually rendered by `<spark-shell>`; exported standalone for hosts that own their own layout.
|
|
240
|
+
*/
|
|
241
|
+
declare class SparkProgramUnitsComponent {
|
|
242
|
+
private readonly sparkService;
|
|
243
|
+
private readonly authState;
|
|
244
|
+
/** Any changed value triggers a reload — for apps whose auth state isn't a provided signal. */
|
|
245
|
+
readonly reloadToken: _angular_core.InputSignal<unknown>;
|
|
246
|
+
/**
|
|
247
|
+
* Extra tabs to render after the generated groups, normally forwarded by `<spark-shell>` from
|
|
248
|
+
* its `*sparkShellTab` directives. They must be rendered by THIS template — see
|
|
249
|
+
* `SparkShellTabDirective` for why a host-declared `<bs-accordion-tab>` cannot work.
|
|
250
|
+
*/
|
|
251
|
+
readonly extraTabs: _angular_core.InputSignal<readonly SparkSidebarTab[]>;
|
|
252
|
+
protected readonly groups: _angular_core.WritableSignal<ProgramUnitGroup[]>;
|
|
253
|
+
constructor();
|
|
254
|
+
/** Re-fetches the menu. The response is already rights-filtered per caller. */
|
|
255
|
+
reload(): Promise<void>;
|
|
256
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkProgramUnitsComponent, never>;
|
|
257
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SparkProgramUnitsComponent, "spark-program-units", never, { "reloadToken": { "alias": "reloadToken"; "required": false; "isSignal": true; }; "extraTabs": { "alias": "extraTabs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* The culture switcher: a `bs-select` over `SparkLanguageService`'s languages, persisting the
|
|
262
|
+
* choice. Renders nothing when the app declares one language (or none), so hosts can include it
|
|
263
|
+
* unconditionally — `<spark-shell>`'s topbar does exactly that as its trailing default.
|
|
264
|
+
*/
|
|
265
|
+
declare class SparkLanguageSelectorComponent {
|
|
266
|
+
protected readonly lang: SparkLanguageService;
|
|
267
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkLanguageSelectorComponent, never>;
|
|
268
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SparkLanguageSelectorComponent, "spark-language-selector", never, {}, {}, never, never, true, never>;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export { SparkLanguageSelectorComponent, SparkProgramUnitsComponent, SparkShellComponent, SparkShellMainHeaderDirective, SparkShellSidebarFooterDirective, SparkShellSidebarHeaderDirective, SparkShellSidebarTopDirective, SparkShellTabDirective, SparkShellTopbarActionsDirective, SparkShellTopbarEndDirective, SparkShellTopbarStartDirective };
|
|
272
|
+
export type { SparkSidebarTab };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InjectionToken, Provider } from '@angular/core';
|
|
1
|
+
import { InjectionToken, Signal, Provider } from '@angular/core';
|
|
2
2
|
|
|
3
3
|
interface SparkConfig {
|
|
4
4
|
baseUrl: string;
|
|
@@ -6,7 +6,22 @@ interface SparkConfig {
|
|
|
6
6
|
declare const SPARK_CONFIG: InjectionToken<SparkConfig>;
|
|
7
7
|
declare const defaultSparkConfig: SparkConfig;
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* A signal that changes whenever the authenticated user changes — the bridge that lets ng-spark
|
|
11
|
+
* components react to sign-in/out without a dependency on `@mintplayer/ng-spark-auth` (no
|
|
12
|
+
* dependency exists between the two packages, in either direction, on purpose).
|
|
13
|
+
*
|
|
14
|
+
* `@mintplayer/ng-spark-auth`'s `provideSparkAuth()` supplies it from `SparkAuthService.user`;
|
|
15
|
+
* an app with its own auth stack provides any signal that changes on sign-in/out. Consumers
|
|
16
|
+
* inject it `{ optional: true }` — absent, auth-sensitive data (the program-units menu) is
|
|
17
|
+
* fetched once and never re-fetched.
|
|
18
|
+
*
|
|
19
|
+
* The signal's VALUE is deliberately opaque (`unknown`): consumers only track it for change,
|
|
20
|
+
* never read it — what "the user" looks like belongs to the auth package.
|
|
21
|
+
*/
|
|
22
|
+
declare const SPARK_AUTH_STATE: InjectionToken<Signal<unknown>>;
|
|
23
|
+
|
|
9
24
|
declare function provideSpark(config?: Partial<SparkConfig>): Provider[];
|
|
10
25
|
|
|
11
|
-
export { SPARK_CONFIG, defaultSparkConfig, provideSpark };
|
|
26
|
+
export { SPARK_AUTH_STATE, SPARK_CONFIG, defaultSparkConfig, provideSpark };
|
|
12
27
|
export type { SparkConfig };
|