Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/packages/firebird-ng/display/src/lib/services/painter-config.service.ts is written in an unsupported language. File is not indexed.

0001 import { Injectable, inject } from '@angular/core';
0002 import {
0003   EventPiece,
0004   PainterConfigView,
0005   PiecePainterConstructor,
0006   painterIdOf,
0007   painterMetaOf,
0008 } from '@dexvis/firebird-core';
0009 import { ConfigProperty, ConfigService } from '@dexvis/app-features';
0010 
0011 /**
0012  * Binds painter metadata to the config system.
0013  *
0014  * Two kinds of keys, both under normal config precedence (defaults < server
0015  * < localStorage < URL < runtime), so a yaml file, a deep link, and the
0016  * painter panel all reach the same knobs:
0017  *
0018  * - `painters.byPiece.<pieceName>` — WHICH painter draws the piece, holding
0019  *   a painter id from the registered candidates (default: first registered).
0020  * - `painters.byPiece.<pieceName>.<knob>` — the selected painter's knobs,
0021  *   declared from the painter's `static meta.configs`.
0022  *
0023  * Painter instances read the knobs through a `PainterConfigView` — a plain
0024  * object over the declared properties, so painter code stays worker-safe
0025  * (`@dexvis/firebird-core` never sees DI).
0026  */
0027 @Injectable({
0028   providedIn: 'root',
0029 })
0030 export class PainterConfigService {
0031   private config = inject(ConfigService);
0032 
0033   selectionKey(pieceName: string): string {
0034     return `painters.byPiece.${pieceName}`;
0035   }
0036 
0037   knobKey(pieceName: string, knob: string): string {
0038     return `painters.byPiece.${pieceName}.${knob}`;
0039   }
0040 
0041   visibilityKey(pieceName: string): string {
0042     return this.knobKey(pieceName, 'visible');
0043   }
0044 
0045   /**
0046    * Declares (or returns) the piece visibility property. 'visible' is a
0047    * RESERVED knob name (`RESERVED_PAINTER_KNOB_KEYS` in
0048    * `@dexvis/firebird-core`; painter registration rejects a painter that
0049    * declares it): it lives under the painter knob namespace so the normal
0050    * config precedence applies (a pack ships a piece hidden via
0051    * `withConfigDefaults`, a deep link or the panel overrides), but it is
0052    * applied to the painter's root node by EventDisplayService, not read by
0053    * painter code.
0054    */
0055   visibilityProperty(pieceName: string): ConfigProperty<boolean> {
0056     return this.config.declare<boolean>({
0057       key: this.visibilityKey(pieceName),
0058       default: true,
0059       label: 'Visible',
0060     });
0061   }
0062 
0063   /**
0064    * Declares (or returns) the painter-selection property of a piece.
0065    * The default is the first registered painter's id.
0066    */
0067   selectionProperty(pieceName: string, candidates: readonly PiecePainterConstructor[]): ConfigProperty<string> {
0068     return this.config.declare<string>({
0069       key: this.selectionKey(pieceName),
0070       default: candidates.length > 0 ? painterIdOf(candidates[0]) : '',
0071       label: `Painter`,
0072       options: candidates.map(painterIdOf),
0073     });
0074   }
0075 
0076   /** Resolves a selection property value to one of the candidate classes. */
0077   resolveSelection(
0078     pieceName: string,
0079     candidates: readonly PiecePainterConstructor[],
0080   ): PiecePainterConstructor | undefined {
0081     if (candidates.length === 0) return undefined;
0082     const selectedId = this.selectionProperty(pieceName, candidates).value;
0083     return candidates.find(candidate => painterIdOf(candidate) === selectedId) ?? candidates[0];
0084   }
0085 
0086   /** The declared knob properties of a painter applied to a piece. */
0087   knobProperties(piece: EventPiece, painterClass: PiecePainterConstructor): Map<string, ConfigProperty<unknown>> {
0088     const properties = new Map<string, ConfigProperty<unknown>>();
0089     const meta = painterMetaOf(painterClass);
0090     for (const descriptor of meta?.configs ?? []) {
0091       properties.set(descriptor.key, this.config.declare<unknown>({
0092         key: this.knobKey(piece.name, descriptor.key),
0093         default: descriptor.default,
0094         label: descriptor.label ?? descriptor.key,
0095         options: descriptor.options,
0096         min: descriptor.min,
0097         max: descriptor.max,
0098       }));
0099     }
0100     return properties;
0101   }
0102 
0103   /**
0104    * The resolved config view a painter instance reads its knobs through.
0105    * Undefined when the painter declares no knobs (defaults view applies).
0106    */
0107   buildConfigView(piece: EventPiece, painterClass: PiecePainterConstructor): PainterConfigView | undefined {
0108     const properties = this.knobProperties(piece, painterClass);
0109     if (properties.size === 0) return undefined;
0110     return {
0111       value: <T>(key: string): T => properties.get(key)?.value as T,
0112       signal: <T>(key: string) => properties.get(key)!.valueSignal as import('@angular/core').Signal<T>,
0113     };
0114   }
0115 }