@mintplayer/ng-spark 22.31.0 → 22.33.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 (75) hide show
  1. package/README.md +101 -1
  2. package/fesm2022/mintplayer-ng-spark-attribute-description.mjs +3 -3
  3. package/fesm2022/mintplayer-ng-spark-auth-account.mjs +18 -18
  4. package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs +16 -8
  5. package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs.map +1 -1
  6. package/fesm2022/mintplayer-ng-spark-auth-confirm-email.mjs +3 -3
  7. package/fesm2022/mintplayer-ng-spark-auth-core.mjs +6 -6
  8. package/fesm2022/mintplayer-ng-spark-auth-external-login.mjs +3 -3
  9. package/fesm2022/mintplayer-ng-spark-auth-forgot-password.mjs +3 -3
  10. package/fesm2022/mintplayer-ng-spark-auth-login.mjs +3 -3
  11. package/fesm2022/mintplayer-ng-spark-auth-pipes.mjs +3 -3
  12. package/fesm2022/mintplayer-ng-spark-auth-register.mjs +3 -3
  13. package/fesm2022/mintplayer-ng-spark-auth-reset-password.mjs +3 -3
  14. package/fesm2022/mintplayer-ng-spark-auth-sign-in.mjs +3 -3
  15. package/fesm2022/mintplayer-ng-spark-auth-two-factor.mjs +3 -3
  16. package/fesm2022/mintplayer-ng-spark-client-operations.mjs +24 -24
  17. package/fesm2022/mintplayer-ng-spark-column-filter.mjs +3 -3
  18. package/fesm2022/mintplayer-ng-spark-contributions.mjs +9 -9
  19. package/fesm2022/mintplayer-ng-spark-grid.mjs +220 -49
  20. package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
  21. package/fesm2022/mintplayer-ng-spark-history.mjs +9 -9
  22. package/fesm2022/mintplayer-ng-spark-icon.mjs +3 -3
  23. package/fesm2022/mintplayer-ng-spark-identity-provider-connected-applications.mjs +3 -3
  24. package/fesm2022/mintplayer-ng-spark-identity-provider-core.mjs +9 -9
  25. package/fesm2022/mintplayer-ng-spark-identity-provider-developers.mjs +6 -6
  26. package/fesm2022/mintplayer-ng-spark-identity-provider-management.mjs +3 -3
  27. package/fesm2022/mintplayer-ng-spark-models.mjs +44 -1
  28. package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
  29. package/fesm2022/mintplayer-ng-spark-moderation.mjs +21 -21
  30. package/fesm2022/mintplayer-ng-spark-notifications.mjs +687 -0
  31. package/fesm2022/mintplayer-ng-spark-notifications.mjs.map +1 -0
  32. package/fesm2022/mintplayer-ng-spark-organizations-accept.mjs +179 -0
  33. package/fesm2022/mintplayer-ng-spark-organizations-accept.mjs.map +1 -0
  34. package/fesm2022/mintplayer-ng-spark-organizations.mjs +202 -0
  35. package/fesm2022/mintplayer-ng-spark-organizations.mjs.map +1 -0
  36. package/fesm2022/mintplayer-ng-spark-pipes.mjs +125 -85
  37. package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
  38. package/fesm2022/mintplayer-ng-spark-po-create.mjs +3 -3
  39. package/fesm2022/mintplayer-ng-spark-po-detail.mjs +90 -26
  40. package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
  41. package/fesm2022/mintplayer-ng-spark-po-edit.mjs +84 -12
  42. package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -1
  43. package/fesm2022/mintplayer-ng-spark-po-form.mjs +9 -9
  44. package/fesm2022/mintplayer-ng-spark-pwa.mjs +74 -6
  45. package/fesm2022/mintplayer-ng-spark-pwa.mjs.map +1 -1
  46. package/fesm2022/mintplayer-ng-spark-query-list.mjs +10 -109
  47. package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
  48. package/fesm2022/mintplayer-ng-spark-renderers.mjs +3 -3
  49. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +3 -3
  50. package/fesm2022/mintplayer-ng-spark-score-renderers.mjs +801 -0
  51. package/fesm2022/mintplayer-ng-spark-score-renderers.mjs.map +1 -0
  52. package/fesm2022/mintplayer-ng-spark-services.mjs +424 -72
  53. package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
  54. package/fesm2022/mintplayer-ng-spark-share-page.mjs +334 -0
  55. package/fesm2022/mintplayer-ng-spark-share-page.mjs.map +1 -0
  56. package/fesm2022/mintplayer-ng-spark-share.mjs +10 -0
  57. package/fesm2022/mintplayer-ng-spark-share.mjs.map +1 -0
  58. package/fesm2022/mintplayer-ng-spark-shell.mjs +38 -36
  59. package/fesm2022/mintplayer-ng-spark-shell.mjs.map +1 -1
  60. package/fesm2022/mintplayer-ng-spark-soft-delete.mjs +9 -9
  61. package/package.json +25 -1
  62. package/types/mintplayer-ng-spark-grid.d.ts +77 -26
  63. package/types/mintplayer-ng-spark-models.d.ts +150 -17
  64. package/types/mintplayer-ng-spark-notifications.d.ts +188 -0
  65. package/types/mintplayer-ng-spark-organizations-accept.d.ts +40 -0
  66. package/types/mintplayer-ng-spark-organizations.d.ts +72 -0
  67. package/types/mintplayer-ng-spark-pipes.d.ts +10 -0
  68. package/types/mintplayer-ng-spark-po-detail.d.ts +26 -0
  69. package/types/mintplayer-ng-spark-po-edit.d.ts +37 -0
  70. package/types/mintplayer-ng-spark-pwa.d.ts +48 -2
  71. package/types/mintplayer-ng-spark-query-list.d.ts +8 -23
  72. package/types/mintplayer-ng-spark-score-renderers.d.ts +340 -0
  73. package/types/mintplayer-ng-spark-services.d.ts +146 -6
  74. package/types/mintplayer-ng-spark-share-page.d.ts +67 -0
  75. package/types/mintplayer-ng-spark-share.d.ts +26 -0
@@ -0,0 +1,72 @@
1
+ import { CanActivateFn } from "@angular/router";
2
+ import { SparkAuthRouteEntry } from "@mintplayer/ng-spark/auth/models";
3
+ import { SparkAuthRoutesFeature } from "@mintplayer/ng-spark/auth/routes";
4
+ import * as i0 from "@angular/core";
5
+ import { OnInit } from "@angular/core";
6
+ /**
7
+ * The organizations package's one SPA page (`docs/seo_analyzer_PRD.md` X11): the target of a mailed
8
+ * invitation or join request, `organizations/accept/:token?id=<invitationId>`, as a `sparkAuthRoutes()`
9
+ * feature:
10
+ *
11
+ * ```ts
12
+ * sparkAuthRoutes(withExternalLogin(), withAccount(), withOrganizationRoutes())
13
+ * ```
14
+ *
15
+ * The page needs a signed-in user: the guard (default `[sparkAuthGuard]`) sends everyone else to the
16
+ * sign-in page and back. Organizations, members and invitations themselves are the generic `po/:type`
17
+ * and `query/:id` screens. Moving the page means setting `Spark:Organizations:AcceptPath` to match, so
18
+ * the mailed links follow.
19
+ */
20
+ export declare function withOrganizationRoutes(options?: {
21
+ canActivate?: CanActivateFn[];
22
+ accept?: SparkAuthRouteEntry;
23
+ }): SparkAuthRoutesFeature;
24
+ /** One organization the switcher offers (`GET /spark/organizations/current`). */
25
+ export interface SparkOrganizationChoice {
26
+ id: string;
27
+ name: string;
28
+ isPersonal: boolean;
29
+ }
30
+ /** What `/spark/organizations/current` answers: the chosen organization (`null`: all of them) and the caller's organizations. */
31
+ export interface SparkCurrentOrganization {
32
+ current: string | null;
33
+ organizations: SparkOrganizationChoice[];
34
+ }
35
+ /** English fallbacks of the switcher's texts (`organizations.spa.*` in the organizations package's translations). */
36
+ export declare const SPARK_ORGANIZATION_SWITCHER_TEXTS: Record<string, string>;
37
+ /**
38
+ * The organization switcher for an app's top bar (`docs/seo_analyzer_PRD.md` Q-M11a): "All organizations" or one
39
+ * of the caller's organizations. The server keeps the choice (a cookie it checks against the caller's memberships
40
+ * on every request), lists of organization-owned rows show only the chosen organization's, and a new row whose
41
+ * form names no organization lands in it. A detail page, a sub-query and the organization list are not narrowed.
42
+ *
43
+ * ```html
44
+ * @if (auth.isAuthenticated()) { <spark-organization-switcher /> }
45
+ * ```
46
+ *
47
+ * Renders nothing for a user in one organization (or none), so it can sit in the top bar unconditionally. A
48
+ * choice reloads the page (`reloadOnChange`), so every grid, live list and cached page reads the new scope.
49
+ */
50
+ export declare class SparkOrganizationSwitcherComponent implements OnInit {
51
+ private readonly http;
52
+ private readonly language;
53
+ private readonly document;
54
+ /** Reload the page after a choice, so every list reads the new scope. Default true. */
55
+ readonly reloadOnChange: import("@angular/core").InputSignal<boolean>;
56
+ readonly state: import("@angular/core").WritableSignal<SparkCurrentOrganization | null>;
57
+ readonly busy: import("@angular/core").WritableSignal<boolean>;
58
+ ngOnInit(): Promise<void>;
59
+ protected t(key: string): string;
60
+ protected label(organization: SparkOrganizationChoice): string;
61
+ /** Reloads the page; a seam for tests. */
62
+ protected reload(): void;
63
+ choose(organizationId: string | null): Promise<void>;
64
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkOrganizationSwitcherComponent, never>;
65
+ static ɵcmp: i0.ɵɵComponentDeclaration<SparkOrganizationSwitcherComponent, "spark-organization-switcher", never, {
66
+ "reloadOnChange": {
67
+ "alias": "reloadOnChange";
68
+ "required": false;
69
+ "isSignal": true;
70
+ };
71
+ }, {}, never, never, true, never>;
72
+ }
@@ -46,6 +46,16 @@ export declare class AttributeValuePipe implements PipeTransform {
46
46
  static ɵfac: i0.ɵɵFactoryDeclaration<AttributeValuePipe, never>;
47
47
  static ɵpipe: i0.ɵɵPipeDeclaration<AttributeValuePipe, "attributeValue", true>;
48
48
  }
49
+ /**
50
+ * A displayed value, or `-` when there is none: `null`, `undefined` or an empty (or blank) string. Unlike
51
+ * `value || '-'` it keeps the falsy values that are data: the number `0` (a page at depth 0, a count of 0) and `false`.
52
+ */
53
+ export declare function sparkOrDash(value: unknown): unknown;
54
+ export declare class OrDashPipe implements PipeTransform {
55
+ transform(value: unknown): unknown;
56
+ static ɵfac: i0.ɵɵFactoryDeclaration<OrDashPipe, never>;
57
+ static ɵpipe: i0.ɵɵPipeDeclaration<OrDashPipe, "orDash", true>;
58
+ }
49
59
  export declare class RawAttributeValuePipe implements PipeTransform {
50
60
  transform(attrName: string, item: PersistentObject | null): any;
51
61
  static ɵfac: i0.ɵɵFactoryDeclaration<RawAttributeValuePipe, never>;
@@ -12,6 +12,7 @@ export declare class SparkPoDetailComponent {
12
12
  private readonly returnNavigation;
13
13
  private readonly queryRefresh;
14
14
  private readonly attributeRefresh;
15
+ private readonly live;
15
16
  protected readonly lang: SparkLanguageService;
16
17
  private readonly clientMethods;
17
18
  protected readonly rendererRegistry: import("@mintplayer/ng-spark/renderers").SparkAttributeRendererRegistration[];
@@ -45,12 +46,17 @@ export declare class SparkPoDetailComponent {
45
46
  queryActionsTemplate: import("@angular/core").InputSignal<TemplateRef<any> | null>;
46
47
  edited: import("@angular/core").OutputEmitterRef<void>;
47
48
  deleted: import("@angular/core").OutputEmitterRef<void>;
49
+ /** After an action succeeded; `result` is what it handed to `CustomActionArgs.SetResult` (a download url, a new id). */
48
50
  customActionExecuted: import("@angular/core").OutputEmitterRef<{
49
51
  action: CustomActionDefinition;
50
52
  item: PersistentObject;
53
+ result?: unknown;
51
54
  }>;
52
55
  colors: typeof Color;
56
+ /** The page could not be loaded: shown instead of the page. */
53
57
  errorMessage: import("@angular/core").WritableSignal<string | null>;
58
+ /** A custom action failed or was refused: shown above the page, which stays (it used to replace the page). */
59
+ actionError: import("@angular/core").WritableSignal<string | null>;
54
60
  entityType: import("@angular/core").WritableSignal<EntityType | null>;
55
61
  /** The sub-queries rendered as cards below the form, in object form (#460, D17). */
56
62
  protected readonly subQueries: import("@angular/core").Signal<import("@mintplayer/ng-spark/models").SparkSubQuery[]>;
@@ -96,6 +102,21 @@ export declare class SparkPoDetailComponent {
96
102
  */
97
103
  visibleCustomActions: import("@angular/core").Signal<CustomActionDefinition[]>;
98
104
  constructor();
105
+ /** The live subscription of the object on screen, while its type is live; keyed so a reload keeps it. */
106
+ private liveSubscription;
107
+ private liveKey;
108
+ /** The catalogue and rights of the last load, so a pushed object re-derives its Edit/Delete/actions. */
109
+ private loadedActions;
110
+ /**
111
+ * Follows the object when its type is live: every push replaces the shown object and re-derives Edit,
112
+ * Delete and the custom actions from its own `can`/`disabledActions`, as a load does. `gone` (deleted, or
113
+ * no longer readable — one answer) shows the unavailable state. A subscription `error` stops following
114
+ * and keeps the loaded object: the page still shows what the HTTP load returned.
115
+ */
116
+ private follow;
117
+ private stopFollowing;
118
+ /** The translation, or `fallback` while the key has none (`t` echoes a missing key). */
119
+ private translateOr;
99
120
  /**
100
121
  * Applies patched attribute values in place, without a re-fetch.
101
122
  *
@@ -109,6 +130,11 @@ export declare class SparkPoDetailComponent {
109
130
  private loadItem;
110
131
  /** (Re)loads the object, its type, rights and actions. Also what add-ons call via `context.reload()`. */
111
132
  load(): Promise<void>;
133
+ /**
134
+ * Edit, Delete and the custom actions for `item`, from the last load's catalogue and rights: on a load,
135
+ * and again on every live push, since `can` and `disabledActions` travel with the object.
136
+ */
137
+ private deriveActions;
112
138
  /**
113
139
  * Drawn from the loaded object's own `showedOn`, falling back to the model's (#264, G-Q3): an action sets
114
140
  * it per object in `OnLoadAsync` — a stolen car's police report number is shown, the model says `None`.
@@ -133,6 +133,7 @@ export declare class SparkPoEditComponent {
133
133
  private readonly route;
134
134
  private readonly router;
135
135
  private readonly sparkService;
136
+ private readonly live;
136
137
  private readonly language;
137
138
  /** `SparkConfig.conflictDialog.showChangedBy`: whether the conflict notice may name a user at all. */
138
139
  private readonly showChangedBy;
@@ -186,6 +187,36 @@ export declare class SparkPoEditComponent {
186
187
  private readonly form;
187
188
  private readonly locale;
188
189
  constructor();
190
+ private liveSubscription;
191
+ /** The newest version pushed while this form is open; considered whenever the form can take it. */
192
+ private latestPushed;
193
+ /**
194
+ * A newer version someone else saved while the user has unsaved edits: the form is left alone and a
195
+ * banner offers to review it. Null when there is none (or it has been adopted or reviewed).
196
+ */
197
+ readonly liveTheirs: import("@angular/core").WritableSignal<PersistentObject | null>;
198
+ protected readonly liveChangedText: import("@angular/core").Signal<string>;
199
+ protected readonly liveReviewText: import("@angular/core").Signal<string>;
200
+ /**
201
+ * Watches the object while the form is open, when its type is live. A newer version (another etag) is
202
+ * adopted silently while the form is untouched — base and form replaced, so the next save posts the new
203
+ * etag — and only offered (banner, then the three-way merge) once the user has edited. `gone` reads as a
204
+ * 409 `deleted`. The 409 on save stays the server-side guarantee; this only brings it forward.
205
+ */
206
+ private follow;
207
+ private stopFollowing;
208
+ /** Adopts the latest pushed version when the form is clean, or offers it when the form is dirty. */
209
+ private considerLivePush;
210
+ /** Whether the form holds edits: it differs from the object it was built from. */
211
+ isDirty(): boolean;
212
+ /**
213
+ * The banner's Review: the existing three-way merge of the loaded base, the user's edits and the pushed
214
+ * version. Nothing conflicts → applied, and their etag adopted; conflicts → the conflict dialog. Nothing
215
+ * is saved either way.
216
+ */
217
+ reviewLiveChange(): void;
218
+ /** The translation, or `fallback` while the key has none (`t` echoes a missing key). */
219
+ private translateOr;
189
220
  private onParamsChange;
190
221
  initFormData(): void;
191
222
  /**
@@ -239,6 +270,12 @@ export declare class SparkPoEditComponent {
239
270
  * reviews and saves, and the server's validation and business rules run again on the result.
240
271
  */
241
272
  private resolveConcurrencyConflict;
273
+ /**
274
+ * Merges this form onto `theirs`, three-way against the object as loaded: disjoint edits are applied
275
+ * and their etag adopted (with a notice); true conflicts open the dialog. Shared by the 409 path and
276
+ * the live banner's Review.
277
+ */
278
+ private mergeWith;
242
279
  /**
243
280
  * Reference labels for the dialog, by id. The form keeps only ids; the labels are on the two reads
244
281
  * (theirs first: it is the fresher) and, for a reference the user just picked, in the candidate
@@ -1,6 +1,7 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { EnvironmentProviders, InjectionToken } from "@angular/core";
3
3
  import { SwRegistrationOptions } from "@angular/service-worker";
4
+ import { Location } from "@angular/common";
4
5
  export interface SparkServiceWorkerOptions {
5
6
  /** Whether the worker registers. Default: `!isDevMode()`, so only production builds register it. */
6
7
  enabled?: boolean;
@@ -11,7 +12,8 @@ export interface SparkServiceWorkerOptions {
11
12
  }
12
13
  /**
13
14
  * Registers Angular's service worker with Spark's update policy (#464, Q1b); see
14
- * {@link SparkServiceWorkerUpdates} for what happens when a new version is deployed.
15
+ * {@link SparkServiceWorkerUpdates} for what happens when a new version is deployed, and
16
+ * {@link SparkNotificationClicks} for a push notification clicked while the application is open.
15
17
  *
16
18
  * The application also needs an `ngsw-config.json` with Spark's navigation exclusions and
17
19
  * `serviceWorker` in its production build configuration; see `docs/guide-pwa.md`.
@@ -86,4 +88,48 @@ export declare class SparkServiceWorkerUpdates {
86
88
  private writeReloadedFor;
87
89
  static ɵfac: i0.ɵɵFactoryDeclaration<SparkServiceWorkerUpdates, never>;
88
90
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
89
- }
91
+ }
92
+ /**
93
+ * Notification clicks while the application is open (`docs/seo_analyzer_PRD.md` X10, D30): a click on
94
+ * a push whose `notification.data.url` is on this origin becomes an in-app router navigation, so the
95
+ * page keeps its state instead of loading again.
96
+ *
97
+ * What it does NOT do, because Angular's service worker (ngsw) already does it: show the push, and
98
+ * open the page when the application is closed. The server sends Angular's payload,
99
+ * `{ notification: { title, body, tag, data: { url, notificationId, onActionClick: { default: {
100
+ * operation, url } } } } }`, and ngsw performs `onActionClick.default` itself on the click, then
101
+ * broadcasts the click to the open pages, which is what {@link SwPush.notificationClicks} reports here.
102
+ *
103
+ * ⚠️ The operation decides whether this handler matters. ngsw runs it BEFORE the broadcast:
104
+ * `navigateLastFocusedOrOpen` makes the focused page load the URL in full, so this handler then
105
+ * finds the router already there and does nothing; `focusLastFocusedOrOpen` focuses the open page
106
+ * without loading it (and opens the URL when no page is open), leaving the navigation to this handler.
107
+ *
108
+ * Active only in a browser with the service worker enabled; started by `provideSparkServiceWorker()`.
109
+ */
110
+ export declare class SparkNotificationClicks {
111
+ private readonly swPush;
112
+ private readonly router;
113
+ private readonly location;
114
+ private readonly document;
115
+ private readonly platformId;
116
+ private readonly destroyRef;
117
+ private started;
118
+ /** Starts listening. Idempotent; called by the app initializer `provideSparkServiceWorker()` adds. */
119
+ start(): void;
120
+ private navigate;
121
+ /** A full page load (overridden in specs: jsdom cannot navigate). */
122
+ protected assign(href: string): void;
123
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkNotificationClicks, never>;
124
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
125
+ }
126
+ /**
127
+ * The router URL for `url` when it points into this application, else `null`.
128
+ *
129
+ * `url` may be app-relative (`/runs/42`) or absolute. It is resolved against the document's base URI;
130
+ * only an `http(s)` URL on the page's own origin is in-app, and its path loses the `<base href>`
131
+ * (through `Location.normalize`) because the router works below it. Everything else (another origin,
132
+ * `javascript:`, `mailto:`, an unparseable value) is `null`, so a caller never hands data-borne URLs
133
+ * to the router or to `location.assign` unchecked.
134
+ */
135
+ export declare function sparkInAppUrl(url: string | null | undefined, document: Document, location: Location | null): string | null;
@@ -3,7 +3,7 @@ import { TemplateRef } from "@angular/core";
3
3
  import { Color } from "@mintplayer/ng-bootstrap";
4
4
  import { SparkLanguageService } from "@mintplayer/ng-spark/services";
5
5
  import { SparkQueryToolbarAction } from "@mintplayer/ng-spark/grid";
6
- import { CustomActionDefinition, QueryColumn, QueryColumnFilter, QueryResultItem, SparkDeletedFilter, SparkSelectionModeSetting } from "@mintplayer/ng-spark/models";
6
+ import { CustomActionDefinition, QueryColumnFilter, QueryResultItem, SparkDeletedFilter, SparkSelectionModeSetting } from "@mintplayer/ng-spark/models";
7
7
  import { SparkQueryListContext } from "@mintplayer/ng-spark/panels";
8
8
  /**
9
9
  * The routed query page: chrome around one {@link SparkQueryGridComponent}.
@@ -14,9 +14,11 @@ import { SparkQueryListContext } from "@mintplayer/ng-spark/panels";
14
14
  * routes — `query/:queryId`, and `po/:type`, which resolves an entity type to a query. That
15
15
  * second one is type-to-query resolution, not query rendering, and is why this component still
16
16
  * exists rather than the router pointing at the grid.
17
- * - **Streaming.** The websocket lives here so it stays out of every PO detail page's bundle;
18
- * the snapshot is filtered and sorted client-side and handed to the grid as `[data]`.
19
- * - The action bar, the caption, the LIVE badge, the search box and the New button.
17
+ * - The action bar, the caption, the LIVE badge (the grid's `isLive()`), the search box and the
18
+ * New button.
19
+ *
20
+ * Live updates are the grid's (X4): a live query is followed by `spark-query-grid` itself, with
21
+ * server-side paging, sort and search, so every embedded grid follows it too — not only this page.
20
22
  *
21
23
  * The grid itself — columns, cells, paging, the row link, selection, custom-action execution —
22
24
  * is the shared component. This page previously wrote out `<bs-datatable>` twice, once per
@@ -26,8 +28,6 @@ export declare class SparkQueryListComponent {
26
28
  private readonly route;
27
29
  private readonly router;
28
30
  private readonly sparkService;
29
- private readonly streamingService;
30
- private readonly destroyRef;
31
31
  protected readonly lang: SparkLanguageService;
32
32
  extraActionsTemplate: import("@angular/core").InputSignal<TemplateRef<void> | null>;
33
33
  showCustomActions: import("@angular/core").InputSignal<boolean>;
@@ -65,6 +65,8 @@ export declare class SparkQueryListComponent {
65
65
  protected readonly resultCount: import("@angular/core").Signal<number | null>;
66
66
  protected readonly isVirtualScrolling: import("@angular/core").Signal<boolean>;
67
67
  protected readonly gridError: import("@angular/core").Signal<string | null>;
68
+ /** Whether the grid follows the query over `/spark/live` right now: the LIVE badge. */
69
+ protected readonly isLive: import("@angular/core").Signal<boolean>;
68
70
  protected readonly permissions: import("@angular/core").Signal<import("@mintplayer/ng-spark/models").EntityPermissions | null>;
69
71
  /** Add-on buttons for the action bar (#460, `SPARK_QUERY_LIST_ACTIONS`), e.g. the Deleted toggle. */
70
72
  protected readonly listActions: import("@mintplayer/ng-spark/panels").SparkQueryListAction[];
@@ -89,19 +91,6 @@ export declare class SparkQueryListComponent {
89
91
  protected toolbarActionUnavailableReason(action: SparkQueryToolbarAction): string | null;
90
92
  protected runToolbarAction(action: SparkQueryToolbarAction): void;
91
93
  protected isActionEnabled(action: CustomActionDefinition): boolean;
92
- isStreaming: import("@angular/core").WritableSignal<boolean>;
93
- private streamingSub;
94
- /** Columns as sent with the stream's snapshot; empty until it arrives. */
95
- protected readonly streamColumns: import("@angular/core").WritableSignal<QueryColumn[]>;
96
- private readonly allItems;
97
- private readonly streamItems;
98
- /**
99
- * Rows handed to the grid, or `null` to let it fetch for itself.
100
- *
101
- * Null for a normal query — an empty array would read as "here are no rows" and suppress the
102
- * fetch entirely.
103
- */
104
- protected readonly gridData: import("@angular/core").Signal<QueryResultItem[] | null>;
105
94
  constructor();
106
95
  /**
107
96
  * The parent the URL scopes the query to (`?parentId=…&parentType=…`), sent exactly as a sub-query
@@ -138,10 +127,6 @@ export declare class SparkQueryListComponent {
138
127
  protected onCustomAction(action: CustomActionDefinition): Promise<void>;
139
128
  protected onCreate(): void;
140
129
  protected clearSearch(): void;
141
- private connectStreaming;
142
- private disconnectStreaming;
143
- private handleStreamingMessage;
144
- private applyFilter;
145
130
  static ɵfac: i0.ɵɵFactoryDeclaration<SparkQueryListComponent, never>;
146
131
  static ɵcmp: i0.ɵɵComponentDeclaration<SparkQueryListComponent, "spark-query-list", never, {
147
132
  "extraActionsTemplate": {