@mintplayer/ng-spark 22.29.0 → 22.30.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 (29) hide show
  1. package/README.md +1 -1
  2. package/fesm2022/mintplayer-ng-spark-client-operations.mjs +76 -2
  3. package/fesm2022/mintplayer-ng-spark-client-operations.mjs.map +1 -1
  4. package/fesm2022/mintplayer-ng-spark-grid.mjs +22 -9
  5. package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
  6. package/fesm2022/mintplayer-ng-spark-models.mjs +2 -1
  7. package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
  8. package/fesm2022/mintplayer-ng-spark-po-detail.mjs +13 -3
  9. package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
  10. package/fesm2022/mintplayer-ng-spark-po-form.mjs +6 -3
  11. package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -1
  12. package/fesm2022/mintplayer-ng-spark-query-list.mjs +5 -2
  13. package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
  14. package/fesm2022/mintplayer-ng-spark-renderers.mjs +109 -4
  15. package/fesm2022/mintplayer-ng-spark-renderers.mjs.map +1 -1
  16. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +36 -6
  17. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs.map +1 -1
  18. package/fesm2022/mintplayer-ng-spark-services.mjs +37 -5
  19. package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
  20. package/package.json +3 -3
  21. package/types/mintplayer-ng-spark-client-operations.d.ts +70 -0
  22. package/types/mintplayer-ng-spark-grid.d.ts +19 -1
  23. package/types/mintplayer-ng-spark-models.d.ts +28 -0
  24. package/types/mintplayer-ng-spark-po-detail.d.ts +8 -0
  25. package/types/mintplayer-ng-spark-po-form.d.ts +2 -0
  26. package/types/mintplayer-ng-spark-query-list.d.ts +2 -0
  27. package/types/mintplayer-ng-spark-renderers.d.ts +47 -0
  28. package/types/mintplayer-ng-spark-retry-action-modal.d.ts +1 -0
  29. package/types/mintplayer-ng-spark-services.d.ts +27 -1
@@ -252,6 +252,7 @@ export declare class SparkQueryGridComponent {
252
252
  /** Add-on row-menu entries (`SPARK_QUERY_ROW_ACTIONS`), e.g. Contributions' revert. */
253
253
  private readonly addonRowActions;
254
254
  readonly lang: SparkLanguageService;
255
+ private readonly clientMethods;
255
256
  /** Query alias or id. */
256
257
  queryId: import("@angular/core").InputSignal<string>;
257
258
  /**
@@ -549,6 +550,13 @@ export declare class SparkQueryGridComponent {
549
550
  * Every column that ships is drawn (#264): there is no shipped-but-hidden column.
550
551
  */
551
552
  allColumns: import("@angular/core").Signal<QueryColumn[]>;
553
+ /** The internal name of the per-row ⋮ menu's column; never shown or announced (its `label` is "Actions"). */
554
+ readonly rowActionsColumn = "__sparkRowActions";
555
+ /**
556
+ * The datatable's `[labels]`: the resize handle and its options dialog, translated. The column
557
+ * each string names comes from `bsDatatableColumnLabel` in the template. See `sparkDatatableLabels`.
558
+ */
559
+ datatableLabels: import("@angular/core").Signal<import("@mintplayer/ng-spark/services").SparkDatatableLabels>;
552
560
  /**
553
561
  * True when rows do not come from this component's own fetch.
554
562
  *
@@ -559,8 +567,16 @@ export declare class SparkQueryGridComponent {
559
567
  * before the host had anything to bind.
560
568
  */
561
569
  hasExternalData: import("@angular/core").Signal<boolean>;
562
- /** Whether an action's selection rule is satisfied right now. The server checks it again. */
570
+ /**
571
+ * Whether an action can run right now: its selection rule is satisfied, and the client method it
572
+ * requires (`requiresClient`) is registered and supported here. The server checks the rule again.
573
+ */
563
574
  isActionEnabled(action: CustomActionDefinition): boolean;
575
+ /**
576
+ * Why an action is disabled regardless of the selection, translated, for its tooltip: its required
577
+ * client method is missing or unsupported in this browser (Q9). Null when nothing stands in the way.
578
+ */
579
+ actionUnavailableReason(action: CustomActionDefinition): string | null;
564
580
  constructor();
565
581
  /**
566
582
  * Re-run the query, keeping the current page, sort and scroll position.
@@ -872,6 +888,8 @@ export declare class SparkQueryCardComponent {
872
888
  protected readonly toolbarActions: import("@angular/core").Signal<SparkQueryToolbarAction[]>;
873
889
  protected actionClass(action: SparkQueryToolbarAction): string;
874
890
  protected isEnabled(action: SparkQueryToolbarAction): boolean;
891
+ /** The tooltip of an action disabled for want of its client method (`requiresClient`); null otherwise. */
892
+ protected unavailableReason(action: SparkQueryToolbarAction): string | null;
875
893
  protected run(action: SparkQueryToolbarAction): void;
876
894
  protected readonly selection: import("@angular/core").Signal<QueryResultItem[]>;
877
895
  static ɵfac: i0.ɵɵFactoryDeclaration<SparkQueryCardComponent, never>;
@@ -169,6 +169,12 @@ export interface CustomActionDefinition {
169
169
  * `/po/new`, the edit page and `/po/delete-many`, never `/actions/execute`. Absent for a custom action.
170
170
  */
171
171
  isDefault?: boolean;
172
+ /**
173
+ * The client method the action needs in the browser (`provideSparkClientMethods`), e.g.
174
+ * `'webauthn.create'`. When it is not registered, or its `supported()` says no, the action is shown
175
+ * disabled with the reason as its tooltip. Advisory: the server still handles a cancelled step.
176
+ */
177
+ requiresClient?: string;
172
178
  }
173
179
  /**
174
180
  * Whether a grid lets the user tick rows — what `<bs-datatable>` renders. There is no single
@@ -665,19 +671,41 @@ export interface LookupReferenceValue {
665
671
  isActive: boolean;
666
672
  extra?: Record<string, unknown>;
667
673
  }
674
+ /**
675
+ * The option a cancelled retry step answers with (`RetryResult.CancelOption` on the server): the
676
+ * modal's own Cancel button or its dismissal on a `cancellable` prompt, and a client method that did
677
+ * not answer. An identifier, never a label: the button shows `common.cancel` in the user's language.
678
+ */
679
+ export declare const SPARK_RETRY_CANCEL = "Cancel";
668
680
  export interface RetryActionPayload {
669
681
  type: 'retry-action';
670
682
  step: number;
671
683
  title: string;
672
684
  message?: string;
685
+ /** The action's own options, shown as given. Never `'Cancel'`: see {@link cancellable}. */
673
686
  options: string[];
674
687
  defaultOption?: string;
675
688
  persistentObject?: PersistentObject;
689
+ /**
690
+ * Whether the modal adds its own Cancel button, labelled `common.cancel`, which, like closing the
691
+ * modal, answers {@link SPARK_RETRY_CANCEL}. Without it a closed modal abandons the request.
692
+ */
693
+ cancellable?: boolean;
694
+ /**
695
+ * Set when the server asks for a client method (`IRetryAccessor.Invoke`) instead of a choice: the
696
+ * name a method was registered under with `provideSparkClientMethods`. No modal is shown then.
697
+ */
698
+ clientMethod?: string;
699
+ /** The client method's argument, as the server serialized it. */
700
+ arguments?: unknown;
676
701
  }
677
702
  export interface RetryActionResult {
678
703
  step: number;
704
+ /** The option chosen. For a client-method step `'OK'` when it answered, `'Cancel'` otherwise. */
679
705
  option: string;
680
706
  persistentObject?: PersistentObject;
707
+ /** What the client method resolved with; absent for an ordinary prompt and for a cancelled step. */
708
+ value?: unknown;
681
709
  }
682
710
  export interface EntityPermissions {
683
711
  /**
@@ -13,6 +13,7 @@ export declare class SparkPoDetailComponent {
13
13
  private readonly queryRefresh;
14
14
  private readonly attributeRefresh;
15
15
  protected readonly lang: SparkLanguageService;
16
+ private readonly clientMethods;
16
17
  protected readonly rendererRegistry: import("@mintplayer/ng-spark/renderers").SparkAttributeRendererRegistration[];
17
18
  /**
18
19
  * Add-on panels and action-bar buttons (#460, `SPARK_DETAIL_PANELS` / `SPARK_DETAIL_ACTIONS`).
@@ -118,6 +119,8 @@ export declare class SparkPoDetailComponent {
118
119
  resolvedTabs: import("@angular/core").Signal<AttributeTab[]>;
119
120
  groupsForTab(tab: AttributeTab): AttributeGroup[];
120
121
  attrsForGroup(group: AttributeGroup): EntityAttributeDefinition[];
122
+ /** Whether the attribute's renderer asks for the whole row, without a label (`fullWidth`). */
123
+ isFullWidthRenderer(attr: EntityAttributeDefinition): boolean;
121
124
  getDetailRendererComponent(attr: EntityAttributeDefinition): Type<any> | null;
122
125
  /** Inputs of an AsDetail row renderer (`rowComponent`): the row and the object that owns it. */
123
126
  getRowRendererInputs(renderer: SparkResolvedRowRenderer, row: Record<string, any>, item: PersistentObject): Record<string, any>;
@@ -146,6 +149,11 @@ export declare class SparkPoDetailComponent {
146
149
  * a slow action and a broken one became indistinguishable.
147
150
  */
148
151
  runningAction: import("@angular/core").WritableSignal<string | null>;
152
+ /**
153
+ * Why an action cannot run in this browser, translated, for its tooltip: the client method it
154
+ * requires (`requiresClient`) is not registered or not supported here (Q9). Null otherwise.
155
+ */
156
+ protected customActionUnavailableReason(action: CustomActionDefinition): string | null;
149
157
  onCustomAction(action: CustomActionDefinition): Promise<void>;
150
158
  onEdit(): void;
151
159
  onDelete(): Promise<void>;
@@ -516,6 +516,8 @@ export declare class SparkReferencePickerComponent {
516
516
  searchTerm: string;
517
517
  /** The picker lists query rows, so its columns are the query's: `showedOn` includes Query (#264; not None). */
518
518
  visibleAttributes: import("@angular/core").Signal<import("@mintplayer/ng-spark/models").EntityAttributeDefinition[]>;
519
+ /** The resize handle and its options dialog, translated; columns are named by `bsDatatableColumnLabel`. */
520
+ datatableLabels: import("@angular/core").Signal<import("@mintplayer/ng-spark/services").SparkDatatableLabels>;
519
521
  rows: import("@angular/core").Signal<QueryResultItem[]>;
520
522
  displayValue: import("@angular/core").Signal<string>;
521
523
  open(): Promise<void>;
@@ -85,6 +85,8 @@ export declare class SparkQueryListComponent {
85
85
  protected readonly toolbarActions: import("@angular/core").Signal<SparkQueryToolbarAction[]>;
86
86
  protected toolbarActionClass(action: SparkQueryToolbarAction): string;
87
87
  protected isToolbarActionEnabled(action: SparkQueryToolbarAction): boolean;
88
+ /** The tooltip of an action disabled for want of its client method (`requiresClient`); null otherwise. */
89
+ protected toolbarActionUnavailableReason(action: SparkQueryToolbarAction): string | null;
88
90
  protected runToolbarAction(action: SparkQueryToolbarAction): void;
89
91
  protected isActionEnabled(action: CustomActionDefinition): boolean;
90
92
  isStreaming: import("@angular/core").WritableSignal<boolean>;
@@ -1,3 +1,4 @@
1
+ import * as i0 from "@angular/core";
1
2
  import { InjectionToken, InputSignal, Provider, Type } from "@angular/core";
2
3
  import { EntityAttributeDefinition, EntityType, PersistentObject, PersistentObjectAttribute, QueryResultItem, QueryResultItemValue, SparkCellColumn } from "@mintplayer/ng-spark/models";
3
4
  /**
@@ -136,7 +137,17 @@ export interface SparkAttributeRendererRegistration {
136
137
  * give it, which is the whole reason the renderer itself cannot be used here.
137
138
  */
138
139
  filterLabel?: (value: unknown) => string;
140
+ /**
141
+ * The detail page draws the renderer across the whole row, with no label: for text blocks such
142
+ * as the core `paragraph` renderer, which are body text rather than a labelled value.
143
+ */
144
+ fullWidth?: boolean;
139
145
  }
146
+ /**
147
+ * The renderers ng-spark ships itself, available in every app without registration. An app's own
148
+ * registration of the same name wins (it comes first in the list).
149
+ */
150
+ export declare const sparkCoreRenderers: readonly SparkAttributeRendererRegistration[];
140
151
  export declare const SPARK_ATTRIBUTE_RENDERERS: InjectionToken<SparkAttributeRendererRegistration[]>;
141
152
  /**
142
153
  * Register custom attribute renderers globally.
@@ -148,6 +159,42 @@ export declare const SPARK_ATTRIBUTE_RENDERERS: InjectionToken<SparkAttributeRen
148
159
  * ])
149
160
  */
150
161
  export declare function provideSparkAttributeRenderers(renderers: SparkAttributeRendererRegistration[]): Provider;
162
+ /**
163
+ * The core `paragraph` renderer (generic passkeys page, D5): a read-only string shown as body text,
164
+ * full width and without a label — an explanatory text block on a persistent object, filled from
165
+ * translations by the actions class. Pair it with `showedOn: PersistentObject` so it never becomes a
166
+ * grid column.
167
+ *
168
+ * **Escaped by default.** The value is interpolated, so markup in it is shown as text. A blank line
169
+ * starts a new paragraph and a single newline is a line break.
170
+ *
171
+ * `"rendererOptions": { "sanitize": false }` renders the value as HTML instead, through Angular's
172
+ * `[innerHTML]`, whose sanitizer still strips scripts, event handlers and `javascript:` URLs. There is
173
+ * deliberately no `bypassSecurityTrustHtml` anywhere on this path: the opt-out is "allow markup",
174
+ * never "allow script".
175
+ */
176
+ export declare class SparkParagraphRendererComponent implements SparkAttributeDetailRenderer {
177
+ readonly value: import("@angular/core").InputSignal<any>;
178
+ readonly options: import("@angular/core").InputSignal<Record<string, any> | undefined>;
179
+ protected readonly text: import("@angular/core").Signal<string>;
180
+ /** Only an explicit `false` opts out of escaping; anything else, absent included, escapes. */
181
+ protected readonly asHtml: import("@angular/core").Signal<boolean>;
182
+ /** Paragraphs split on blank lines, each a list of its lines. */
183
+ protected readonly paragraphs: import("@angular/core").Signal<string[][]>;
184
+ static ɵfac: i0.ɵɵFactoryDeclaration<SparkParagraphRendererComponent, never>;
185
+ static ɵcmp: i0.ɵɵComponentDeclaration<SparkParagraphRendererComponent, "spark-paragraph-renderer", never, {
186
+ "value": {
187
+ "alias": "value";
188
+ "required": false;
189
+ "isSignal": true;
190
+ };
191
+ "options": {
192
+ "alias": "options";
193
+ "required": false;
194
+ "isSignal": true;
195
+ };
196
+ }, {}, never, never, true, never>;
197
+ }
151
198
  /** The row renderer of an AsDetail row type, resolved once per type (see `rowComponent`). */
152
199
  export interface SparkResolvedRowRenderer {
153
200
  component: Type<any>;
@@ -15,6 +15,7 @@ export declare class SparkRetryActionModalComponent {
15
15
  protected readonly retryActionService: RetryActionService;
16
16
  private readonly sparkService;
17
17
  colors: typeof Color;
18
+ protected readonly cancel = "Cancel";
18
19
  isOpen: import("@angular/core").Signal<boolean>;
19
20
  /**
20
21
  * EntityType definition for the incoming PO — fetched lazily via SparkService so the
@@ -102,6 +102,7 @@ export declare class SparkService {
102
102
  */
103
103
  private static readonly MAX_RETRY_DEPTH;
104
104
  private readonly dispatcher;
105
+ private readonly clientMethods;
105
106
  getEntityTypes(): Promise<EntityType[]>;
106
107
  /**
107
108
  * One entity type, shaped by the caller's attribute rights. `purpose` narrows it for one form (#264, G1/G2):
@@ -492,4 +493,29 @@ export declare class SparkReturnNavigationService {
492
493
  listRouteFor(entityTypeName: string): Promise<unknown[] | null>;
493
494
  static ɵfac: i0.ɵɵFactoryDeclaration<SparkReturnNavigationService, never>;
494
495
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
495
- }
496
+ }
497
+ /** The `<bs-datatable>` strings Spark translates: the column-resize handle and its options dialog. */
498
+ export interface SparkDatatableLabels {
499
+ resizeColumn: (column: string) => string;
500
+ resizeColumnHint: string;
501
+ resizeColumnOptions: (column: string) => string;
502
+ narrowerColumn: (column: string) => string;
503
+ widerColumn: (column: string) => string;
504
+ columnWidth: (px: number) => string;
505
+ fitColumn: string;
506
+ resetColumn: string;
507
+ }
508
+ /**
509
+ * The `[labels]` a Spark `<bs-datatable>` passes so the column-resize handle, its keymap
510
+ * announcement and its resize options dialog (ng-bootstrap 22.22.0 / web-components 2.19.0) speak
511
+ * the viewer's language.
512
+ *
513
+ * The `column` these formatters receive is the column's label: every Spark grid binds
514
+ * `bsDatatableColumnLabel` to the header's translated text (and the row-actions column to
515
+ * "Actions"), so the datatable no longer falls back to the internal name. The keys omitted here
516
+ * keep the web component's English defaults.
517
+ *
518
+ * Every translation is read EAGERLY, so a `computed` that calls this tracks the language and the
519
+ * translation map, and hands the datatable a new object — which re-renders it — when either changes.
520
+ */
521
+ export declare function sparkDatatableLabels(lang: SparkLanguageService): SparkDatatableLabels;