@meshmakers/octo-meshboard 3.5.490 → 3.5.510

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.
@@ -1,14 +1,14 @@
1
1
  import { ProcessWidgetSpecificConfig } from '@meshmakers/octo-process-diagrams';
2
2
  import * as _angular_core from '@angular/core';
3
3
  import { Signal, AfterViewInit, OnChanges, EventEmitter, SimpleChanges, Type, OnDestroy, OnInit, EnvironmentProviders, InjectionToken, Provider } from '@angular/core';
4
- import { ControlValueAccessor } from '@angular/forms';
5
- import * as i1 from '@meshmakers/shared-ui';
6
- import { EntitySelectDialogDataSource, ColumnDefinition, DialogFetchOptions, DialogFetchResult, EntitySelectInputComponent, TimeRange, FetchDataOptions, FetchResultTyped, TableColumn as TableColumn$1, ListViewMessages, HasUnsavedChanges, TimeRangePickerLabels, TimeRangeSelection as TimeRangeSelection$1 } from '@meshmakers/shared-ui';
7
4
  import { Observable, Subject } from 'rxjs';
8
- import { EntitySelectDataSource, EntitySelectResult } from '@meshmakers/shared-services';
9
5
  import * as Types from '@meshmakers/octo-services';
10
- import { CkTypeSelectorItem, RuntimeEntityItem, RuntimeEntitySelectDataSource, RuntimeEntityDialogDataSource, SortDto, FieldFilterDto, QueryModeDto, ResolveSeriesQueryInputDto, CkRollupFunctionDto, SeriesResolutionSignalDto, AttributeItem, TenantIdProvider, TenantFeaturesStatus, HealthCheck } from '@meshmakers/octo-services';
6
+ import { SortDto, FieldFilterDto, QueryModeDto, ResolveSeriesQueryInputDto, CkRollupFunctionDto, SeriesResolutionSignalDto, CkTypeSelectorItem, RuntimeEntityItem, RuntimeEntitySelectDataSource, RuntimeEntityDialogDataSource, AttributeItem, TenantIdProvider, TenantFeaturesStatus, HealthCheck } from '@meshmakers/octo-services';
11
7
  export { RuntimeEntityDialogDataSource, RuntimeEntityItem, RuntimeEntitySelectDataSource, TENANT_ID_PROVIDER, TenantIdProvider } from '@meshmakers/octo-services';
8
+ import { ControlValueAccessor } from '@angular/forms';
9
+ import * as i1 from '@meshmakers/shared-ui';
10
+ import { EntitySelectDialogDataSource, ColumnDefinition, DialogFetchOptions, DialogFetchResult, EntitySelectInputComponent, TimeRange, FetchDataOptions, FetchResultTyped, TableColumn as TableColumn$1, ListViewMessages, EntitySelectInputMessages, HasUnsavedChanges, TimeRangePickerLabels, TimeRangeSelection as TimeRangeSelection$1 } from '@meshmakers/shared-ui';
11
+ import { EntitySelectDataSource, EntitySelectResult } from '@meshmakers/shared-services';
12
12
  import * as Apollo from 'apollo-angular';
13
13
  import { CkTypeSelectorInputComponent, AttributeValueTypeDto, FieldFilterItem, FilterVariable, PropertyGridItem, PropertyGridConfig, OctoGraphQlDataSource, FieldFilterEditorComponent } from '@meshmakers/octo-ui';
14
14
  import * as _meshmakers_octo_meshboard from '@meshmakers/octo-meshboard';
@@ -281,7 +281,7 @@ interface PersistentQueryDataSource extends WidgetDataSource {
281
281
  /**
282
282
  * Asset-scope binding: the `id` of an entity selector whose selection scopes
283
283
  * this widget's stream-data query. The selector resolves its picked entity to
284
- * a set of source rtIds (via its `childScope` one-hop, or the picked entity
284
+ * a set of source rtIds (via its `childScope` hop or path, or the picked entity
285
285
  * itself when no childScope is configured); those rtIds are passed as the
286
286
  * query's `streamDataArgs.rtIds`, replacing the persisted RtIds at execution
287
287
  * time. Absent ⇒ the query runs with its persisted scope. Ignored for runtime
@@ -577,9 +577,29 @@ interface TableColumnStatusIconMapping {
577
577
  tooltip: string;
578
578
  color?: string;
579
579
  }
580
+ /**
581
+ * Display label of one raw cell value of a table column (AB#7655), e.g. `{ label: 'L2' }` for `2`.
582
+ */
583
+ interface TableColumnValueLabel {
584
+ /**
585
+ * Text shown instead of the raw value: one string for every language, or a text per culture
586
+ * code (`{ "de-AT": "gut", "en-GB": "good" }`) that follows the host language
587
+ * (`MESHBOARD_LANGUAGE`; exact culture, then language part). Without a match the raw value shows.
588
+ */
589
+ label: string | Record<string, string>;
590
+ /** Optional CSS text colour (e.g. `var(--kendo-color-success)`); without it the theme text colour applies. */
591
+ color?: string;
592
+ }
580
593
  interface TableColumn {
581
594
  field: string;
595
+ /** Header text; the fallback when `titles` has no text for the host language. */
582
596
  title: string;
597
+ /**
598
+ * Header text per culture code (AB#7655), e.g. `{ "de-AT": "Datenqualität", "en-GB": "Data quality" }`.
599
+ * Picked for the host language (`MESHBOARD_LANGUAGE` / `provideMeshBoard({ language })`): exact
600
+ * culture, then a key equal to the language part (`de`), then `title`. No host language = `title`.
601
+ */
602
+ titles?: Record<string, string>;
583
603
  width?: number;
584
604
  dataType?: string;
585
605
  /**
@@ -589,6 +609,15 @@ interface TableColumn {
589
609
  */
590
610
  format?: string;
591
611
  statusMapping?: Record<string, TableColumnStatusIconMapping>;
612
+ /**
613
+ * Labels for raw cell values (AB#7655), keyed by the value as string (`"1"`, `"2"`, `"3"`); a
614
+ * number `2` and a string `"2"` both match `"2"`. The cell shows the label as plain text (with the
615
+ * optional colour); a value without a label keeps the column's `dataType` / `format` rendering,
616
+ * `null` / missing is an empty cell. When no label applies for the current language the column
617
+ * renders as without `valueLabels`. Wins over `MESHBOARD_LABEL_RESOLVER`. Not supported together
618
+ * with `statusMapping` (the labels are shown, a console warning is logged).
619
+ */
620
+ valueLabels?: Record<string, TableColumnValueLabel>;
592
621
  }
593
622
  /**
594
623
  * Gauge types available
@@ -1374,21 +1403,44 @@ interface EntitySelectorAttributeMapping {
1374
1403
  attributeValueType?: string;
1375
1404
  }
1376
1405
  /**
1377
- * One-hop association traversal that turns a selected entity into the set of
1378
- * source rtIds a stream-data widget should be scoped to.
1406
+ * One association hop of a multi-hop child scope (AB#7723): from the entities
1407
+ * reached so far (the picked entity for the first hop) over `roleId` in
1408
+ * `direction` to the entities of `targetCkTypeId`.
1409
+ */
1410
+ interface EntitySelectorScopeHop {
1411
+ /** Association role of this hop (e.g. "System/ParentChild"). */
1412
+ roleId: string;
1413
+ /** Traversal direction; defaults to `'in'` (see {@link EntitySelectorChildScope.direction}). */
1414
+ direction?: 'in' | 'out';
1415
+ /** CK type of the entities this hop reaches; the source type of the next hop. */
1416
+ targetCkTypeId: string;
1417
+ }
1418
+ /**
1419
+ * Association traversal that turns a selected entity into the set of source
1420
+ * rtIds a stream-data widget should be scoped to.
1379
1421
  *
1380
1422
  * Use case: the user picks a `MeteringPoint`, but the stream-data archive is
1381
1423
  * keyed by its child `EnergyMeasurement` rtIds. The childScope describes that
1382
- * single hop (target type + association role + direction); the selected
1383
- * entity's children of `targetCkTypeId` reached via `roleId` become the scope
1384
- * rtIds. When a selector has no childScope, the picked entity's own rtId is the
1385
- * scope (direct keying).
1424
+ * hop (target type + association role + direction); the selected entity's
1425
+ * children of `targetCkTypeId` reached via `roleId` become the scope rtIds.
1426
+ * When a selector has no childScope, the picked entity's own rtId is the scope
1427
+ * (direct keying).
1428
+ *
1429
+ * Two forms (AB#7723):
1430
+ * - **One hop** — the top-level `targetCkTypeId` / `roleId` / `direction`. This
1431
+ * is the original form; the editor keeps writing one-hop scopes this way, so
1432
+ * older library versions keep reading them.
1433
+ * - **Path** — `path`, an ordered list of 2 to {@link MAX_SCOPE_HOPS} hops
1434
+ * (A → B → C). The source type of hop n is the target type of hop n-1; the
1435
+ * scope is the distinct rtIds reached by the last hop. When `path` is present
1436
+ * (non-empty) it wins and the top-level fields are ignored; the editor then
1437
+ * omits them.
1386
1438
  */
1387
1439
  interface EntitySelectorChildScope {
1388
- /** CK type of the child entities that key the stream-data archive (e.g. EnergyMeasurement). */
1389
- targetCkTypeId: string;
1390
- /** Association role linking the selected entity to the children (e.g. "System/ParentChild"). */
1391
- roleId: string;
1440
+ /** CK type of the child entities that key the stream-data archive (e.g. EnergyMeasurement). One-hop form. */
1441
+ targetCkTypeId?: string;
1442
+ /** Association role linking the selected entity to the children (e.g. "System/ParentChild"). One-hop form. */
1443
+ roleId?: string;
1392
1444
  /**
1393
1445
  * Traversal direction from the selected (parent) entity to its children.
1394
1446
  * For `System/ParentChild` the child owns the association to its parent, so
@@ -1396,7 +1448,15 @@ interface EntitySelectorChildScope {
1396
1448
  * `'out'` only for custom roles modelled parent → child.
1397
1449
  */
1398
1450
  direction?: 'in' | 'out';
1451
+ /**
1452
+ * Ordered multi-hop path (AB#7723). Wins over the top-level fields when
1453
+ * non-empty. At most {@link MAX_SCOPE_HOPS} hops; a longer path, or a hop
1454
+ * without role or target type, makes the scope fail (no data plus notice).
1455
+ */
1456
+ path?: EntitySelectorScopeHop[];
1399
1457
  }
1458
+ /** Maximum number of hops of a child-scope path, enforced by editor and runtime (AB#7723). */
1459
+ declare const MAX_SCOPE_HOPS = 5;
1400
1460
  /**
1401
1461
  * Configuration for a single entity selector in the MeshBoard toolbar.
1402
1462
  * Each selector is bound to a CK type and populates variables from the selected entity.
@@ -1415,11 +1475,38 @@ interface EntitySelectorConfig {
1415
1475
  /** Optional pre-selected entity rtId */
1416
1476
  defaultRtId?: string;
1417
1477
  /**
1418
- * Optional one-hop traversal that resolves the picked entity to the child
1419
- * source rtIds a stream-data widget scopes by. Absent ⇒ the picked entity's
1478
+ * Optional traversal (one hop, or a multi-hop `path` — AB#7723) that resolves
1479
+ * the picked entity to the source rtIds a stream-data widget scopes by. Absent ⇒ the picked entity's
1420
1480
  * own rtId is the scope. See {@link EntitySelectorChildScope}.
1421
1481
  */
1422
1482
  childScope?: EntitySelectorChildScope;
1483
+ /**
1484
+ * Optional id of the selector this one follows (AB#7722). A follower has no
1485
+ * picker of its own and is never written to or read from the URL: it takes
1486
+ * the leader's current pick as its picked entity (its `ckTypeId` is the
1487
+ * leader's) and resolves its own `childScope` and `attributeMappings` from it.
1488
+ * Its `defaultRtId` is used only while the leader has no pick. One level only:
1489
+ * a leader cannot itself be a follower. An unknown or chained leader is
1490
+ * treated as "leader has no pick" (plus a console warning).
1491
+ * See `utils/entity-selector-follow.ts`.
1492
+ */
1493
+ followsSelectorId?: string;
1494
+ /**
1495
+ * Optional picker filter (AB#7724): attribute filter rows on `ckTypeId`,
1496
+ * combined with AND, the same type and variable substitution as widget
1497
+ * filters (`MeshBoardVariableService.convertToFieldFilterDto`). The toolbar
1498
+ * dropdown, its search dialog and the editor's default-entity picker send
1499
+ * the rows as GraphQL `fieldFilter` (server side); the picker's text search
1500
+ * is one more AND row. Absent or empty ⇒ the picker lists every entity of
1501
+ * `ckTypeId`, as before.
1502
+ *
1503
+ * The filter affects the listing only: a `defaultRtId` or a URL pick that
1504
+ * does not match is still applied (the editor warns about a non-matching
1505
+ * `defaultRtId`). Followers have no picker; the editor writes no filter for
1506
+ * them and a follower's filter is ignored at runtime.
1507
+ * See `utils/entity-selector-filter.ts`.
1508
+ */
1509
+ filters?: WidgetFilterConfig[];
1423
1510
  /** Current selection (transient, not persisted) */
1424
1511
  selectedRtId?: string;
1425
1512
  /** Display name of the currently selected entity */
@@ -1760,6 +1847,315 @@ declare function isMeshBoardChrome(value: unknown): value is MeshBoardChrome;
1760
1847
  */
1761
1848
  declare function resolveMeshBoardChrome(inputChrome: unknown, routeDataChrome: unknown): MeshBoardChrome;
1762
1849
 
1850
+ /**
1851
+ * Result of resolution-aware series routing (AB#4290). The caller runs the existing
1852
+ * stream-data downsampling query against {@link archiveRtId} with `limit = points`
1853
+ * and the column aggregation set to {@link reducingFunction}. `signal` is a truthful
1854
+ * outcome the widget can surface (e.g. a "resolution-limited" hint).
1855
+ *
1856
+ * The coverage signal (AB#5157) rides the same fields: `signal` is `CoverageLimited` when the
1857
+ * resolver's coverage filter skipped a finer rung because it holds no measured data over the
1858
+ * requested window, `actualPoints` / `diagnostic` carry the deliverable count and the rung that
1859
+ * was excluded, and {@link finerRungAvailableFrom} says from when that finer rung could serve.
1860
+ */
1861
+ interface SeriesResolutionResult {
1862
+ archiveRtId: string;
1863
+ effectiveBucketMs: number;
1864
+ points: number;
1865
+ reducingFunction: CkRollupFunctionDto;
1866
+ signal: SeriesResolutionSignalDto;
1867
+ actualPoints: number | null;
1868
+ diagnostic: string | null;
1869
+ /**
1870
+ * Earliest instant from which the coverage-excluded finer rung would be usable (AB#5157).
1871
+ * Set only on `CoverageLimited`, null otherwise. Passed through as the wire delivers it —
1872
+ * a `DateTime` scalar arrives as an ISO string unless a scalar parser turns it into a `Date` —
1873
+ * so read it through `toInstant` / `formatInstant` rather than assuming either shape.
1874
+ * Optional so that code constructing a result (mocks, adapters) written before AB#5157 keeps
1875
+ * compiling; a missing value means the same as `null`.
1876
+ */
1877
+ finerRungAvailableFrom?: Date | string | null;
1878
+ }
1879
+ /**
1880
+ * Time-range and downsampling arguments for stream-data persistent queries.
1881
+ * Mirrors the GraphQL input `StreamDataArguments` so widgets can build it
1882
+ * without importing generated DTO types directly.
1883
+ *
1884
+ * Backend semantics (verified against StreamDataQueryDtoType.cs and
1885
+ * StreamDataVariantExecutor.cs; `queryMode` override added in AB#4233):
1886
+ * - `from` / `to` / `limit` override the persisted query's intrinsic values
1887
+ * when set (`execOverride?.From ?? simple.From` pattern in the resolver).
1888
+ * - `interval` is currently ignored by every variant; the downsampling path
1889
+ * derives `(to - from) / limit` itself.
1890
+ * - `queryMode: DOWNSAMPLING` on a `SimpleSdQuery` (persisted) or the transient
1891
+ * `simple` sub-connection now drives the downsampling execution path: with a
1892
+ * full from/to/limit contract the backend reduces to `limit` buckets per series
1893
+ * (per-type reducers + group-by source rtId). Without all three it falls back
1894
+ * to raw rows. For the other variants the execution shape still comes from the
1895
+ * CK subtype / sub-connection; `queryMode` is a no-op there.
1896
+ */
1897
+ interface StreamDataExecutionArgs {
1898
+ from?: Date | null;
1899
+ to?: Date | null;
1900
+ interval?: number | null;
1901
+ limit?: number | null;
1902
+ /**
1903
+ * `DOWNSAMPLING` switches a SimpleSdQuery / transient `simple` query to the
1904
+ * downsampling path (with from/to/limit); a no-op for the other variants.
1905
+ * Defaults to `Default` (raw rows).
1906
+ */
1907
+ queryMode?: QueryModeDto;
1908
+ /**
1909
+ * Source runtime ids to scope the query to. When set, replaces the persisted
1910
+ * RtIds on the query at execution time — used to scope a stream-data widget to
1911
+ * the entities resolved from a selected asset (e.g. the EnergyMeasurement rtIds
1912
+ * under a picked MeteringPoint). An empty array is treated as "no scope".
1913
+ */
1914
+ rtIds?: string[] | null;
1915
+ }
1916
+ interface QueryExecutionOptions {
1917
+ /** Page size — passed to the GraphQL `first` variable. */
1918
+ first?: number | null;
1919
+ /** Cursor — passed to the GraphQL `after` variable. */
1920
+ after?: string | null;
1921
+ /** Optional column / row sort definitions. */
1922
+ sortOrder?: SortDto[] | null;
1923
+ /** Field filters applied to the query rows. */
1924
+ fieldFilter?: FieldFilterDto[] | null;
1925
+ /** Stream-data-only: time-range, interval, limit, queryMode. Ignored for runtime queries. */
1926
+ streamDataArgs?: StreamDataExecutionArgs | null;
1927
+ /**
1928
+ * Entity-selector scope (AB#7725): the source rtIds a widget bound to an entity
1929
+ * selector is restricted to. Applied on the server for both families:
1930
+ * - runtime queries (SimpleRtQuery, AggregationRtQuery, GroupingAggregationRtQuery):
1931
+ * adds the field filter `rtId IN (scopeRtIds)`, AND-combined with
1932
+ * {@link fieldFilter} and the persisted query's own filters — a grouping or
1933
+ * aggregation query aggregates over the scoped entities only;
1934
+ * - stream-data queries: sent as `arg.rtIds` unless `streamDataArgs.rtIds` is set.
1935
+ *
1936
+ * `null`/`undefined` or an empty array means "no scope" (the query runs as saved).
1937
+ * An empty scope must never reach the executor: callers skip the query instead
1938
+ * (`StreamDataScope.kind === 'empty'`, AB#7721).
1939
+ */
1940
+ scopeRtIds?: string[] | null;
1941
+ /** Force a network round-trip instead of using the Apollo cache. */
1942
+ forceRefresh?: boolean;
1943
+ }
1944
+ interface QueryColumnInfo {
1945
+ attributePath: string;
1946
+ attributeValueType?: string | null;
1947
+ aggregationType?: string | null;
1948
+ }
1949
+ interface QueryCell {
1950
+ attributePath: string;
1951
+ value: unknown;
1952
+ }
1953
+ /**
1954
+ * Unified result-row shape across runtime and stream-data queries.
1955
+ * `__typename` lets callers distinguish row kinds when needed
1956
+ * (`RtSimpleQueryRow`, `RtAggregationQueryRow`, `RtGroupingAggregationQueryRow`,
1957
+ * `StreamDataQueryRow`).
1958
+ *
1959
+ * Stream-data rows surface `timestamp`, `rtWellKnownName`,
1960
+ * `rtCreationDateTime`, and `rtChangedDateTime` directly on the row — useful
1961
+ * for time-series x-axes. Runtime rows leave those fields undefined.
1962
+ */
1963
+ interface QueryResultRow {
1964
+ __typename?: string;
1965
+ rtId?: string | null;
1966
+ ckTypeId?: string | null;
1967
+ timestamp?: Date | null;
1968
+ rtWellKnownName?: string | null;
1969
+ rtCreationDateTime?: Date | null;
1970
+ rtChangedDateTime?: Date | null;
1971
+ cells: QueryCell[];
1972
+ }
1973
+ interface QueryExecutionResult {
1974
+ family: QueryFamily;
1975
+ queryRtId?: string | null;
1976
+ associatedCkTypeId?: string | null;
1977
+ columns: QueryColumnInfo[];
1978
+ rows: QueryResultRow[];
1979
+ totalCount: number;
1980
+ hasNextPage: boolean;
1981
+ endCursor?: string | null;
1982
+ }
1983
+ /**
1984
+ * Executes persistent queries by rtId and returns a unified result shape
1985
+ * regardless of whether the underlying query is runtime-data or stream-data.
1986
+ *
1987
+ * Widgets consume `QueryExecutionResult` and stay agnostic about which family
1988
+ * the saved query belongs to — switching a widget's data source between
1989
+ * runtime and stream-data is purely a configuration change.
1990
+ */
1991
+ declare class QueryExecutorService {
1992
+ private readonly runtimeGql;
1993
+ private readonly streamDataGql;
1994
+ private readonly persistentQueriesGql;
1995
+ private readonly resolveSeriesGql;
1996
+ private readonly queryArchiveGql;
1997
+ private readonly downsampleGql;
1998
+ private readonly entitiesGql;
1999
+ private readonly secretSafeNames;
2000
+ /**
2001
+ * Cache of resolved query families, keyed by query rtId. Filled lazily for
2002
+ * legacy widget configs that pre-date the `queryFamily` field — saves a
2003
+ * round-trip on every refresh.
2004
+ */
2005
+ private readonly familyCache;
2006
+ execute(family: QueryFamily | undefined, queryRtId: string, options?: QueryExecutionOptions): Observable<QueryExecutionResult>;
2007
+ /**
2008
+ * Resolves the family of a persistent query by rtId. Falls back to
2009
+ * `'runtime'` when the query type cannot be classified — this matches the
2010
+ * pre-Phase-1 behavior.
2011
+ */
2012
+ resolveFamily(queryRtId: string): Promise<QueryFamily>;
2013
+ executeRuntime(queryRtId: string, options?: QueryExecutionOptions): Observable<QueryExecutionResult>;
2014
+ executeStreamData(queryRtId: string, options?: QueryExecutionOptions): Observable<QueryExecutionResult>;
2015
+ /**
2016
+ * Resolution-aware series routing (AB#4290): asks the backend which archive/rollup to
2017
+ * query for a base archive family, time window and target point count — so a widget can
2018
+ * render ~`targetPoints` points without knowing which physical archive holds the data at a
2019
+ * usable grain. The caller then runs {@link executeStreamData} (downsampling) against the
2020
+ * returned `archiveRtId` with `limit = points`. Returns null when StreamData is not enabled.
2021
+ */
2022
+ resolveSeriesQuery(input: ResolveSeriesQueryInputDto): Promise<SeriesResolutionResult | null>;
2023
+ /**
2024
+ * Resolution-aware routing (AB#4290): reads a persisted stream-data query's base archive rtId
2025
+ * and target CK type WITHOUT executing the query (the `rows` sub-connection is not selected), so
2026
+ * a widget can feed the archive to {@link resolveSeriesQuery} and use the CK type to resolve
2027
+ * per-series labels. Also reads the query's persisted RtIds pin
2028
+ * (`System/StreamDataQuery.RtIds`) from the runtime entity — the transient downsampling path
2029
+ * bypasses the persisted query execution, so widgets must re-apply the pin themselves
2030
+ * (AB#4818). `rtIds` is null when the query has no pin (or is not a SimpleSdQuery).
2031
+ * Returns null when the query is missing or has no archive.
2032
+ */
2033
+ fetchQueryArchive(queryRtId: string): Promise<{
2034
+ archiveRtId: string;
2035
+ ckTypeId: string | null;
2036
+ rtIds: string[] | null;
2037
+ } | null>;
2038
+ /**
2039
+ * Resolution-aware routing (AB#4290): runs the AB#4233 downsampling query against an explicit
2040
+ * archive rtId (the rollup/base chosen by {@link resolveSeriesQuery}), reducing `sourcePath`
2041
+ * with `aggregation` to at most `limit` buckets. The transient downsampling groups by bin
2042
+ * (not by source rtId), so callers that need per-series lines scope `rtIds` to one source
2043
+ * entity per call. Returns the unified rows; each row's single value cell carries the reduced
2044
+ * value under its wire column name (e.g. `amountvalue_sum`) alongside the bin `timestamp`.
2045
+ */
2046
+ downsampleByArchive(params: {
2047
+ archiveRtId: string;
2048
+ from: Date;
2049
+ to: Date;
2050
+ limit: number;
2051
+ sourcePath: string;
2052
+ aggregation: string;
2053
+ rtIds?: string[] | null;
2054
+ fieldFilter?: FieldFilterDto[] | null;
2055
+ }): Promise<QueryResultRow[]>;
2056
+ /**
2057
+ * Best-effort per-series labels for resolution-aware fan-out (AB#4290): reads each source
2058
+ * entity's attribute matching `labelField` (canonical, case/underscore-insensitive so an archive
2059
+ * column name maps to its CK attribute). Entities that fail to load or lack the attribute are
2060
+ * simply omitted; the caller falls back to the rtId. Returns a `rtId → label` map.
2061
+ */
2062
+ fetchSeriesLabels(ckTypeId: string, rtIds: string[], labelField: string): Promise<Map<string, string>>;
2063
+ /**
2064
+ * The non-secret attribute names of `ckTypeId` whose canonical form matches `wanted`
2065
+ * (SECRET-safe explicit list, AB#5542). Empty when nothing matches — the caller then falls back
2066
+ * as for a missing attribute.
2067
+ */
2068
+ private matchingAttributeNames;
2069
+ /** Cap on the source-entity population read for group-aggregation (AB#4714). A truncated read is
2070
+ * logged, never silent. */
2071
+ private static readonly ENTITY_GROUP_FETCH_CAP;
2072
+ /**
2073
+ * Group-aggregation source resolution (AB#4714): fetches the source entities of `ckTypeId` in a
2074
+ * single bulk read and buckets their rtIds by the value of `groupField` (canonical match — case
2075
+ * and non-alphanumerics are ignored, so an archive column name maps to its CK attribute). Returns
2076
+ * `groupValue → rtIds`. Optionally restricted to `restrictRtIds` (an entity-selector scope) —
2077
+ * entities outside that set are dropped. Entities whose group attribute is missing/null are
2078
+ * omitted (they cannot be attributed to a line). The population is bounded to
2079
+ * {@link ENTITY_GROUP_FETCH_CAP}; a truncated read is logged (never silently capped).
2080
+ */
2081
+ fetchEntityGroups(ckTypeId: string, groupField: string, restrictRtIds?: string[]): Promise<Map<string, string[]>>;
2082
+ /**
2083
+ * Runtime entity-selector scope (AB#7725): appends `rtId IN (scopeRtIds)` to the
2084
+ * caller's field filters. The backend AND-combines all runtime field filters with
2085
+ * the persisted query's filters before the database query, so simple rows as well
2086
+ * as aggregation / grouping results cover the scoped entities only. Returns the
2087
+ * caller's filters unchanged (or `undefined`) when there is no scope.
2088
+ */
2089
+ static withRtIdScope(fieldFilter: FieldFilterDto[] | null | undefined, scopeRtIds: string[] | null | undefined): FieldFilterDto[] | undefined;
2090
+ /** Stream-data entity-selector scope: `scopeRtIds` fill `rtIds` unless the caller set them. */
2091
+ private static withStreamDataScope;
2092
+ private buildStreamDataArg;
2093
+ private mapColumns;
2094
+ private mapRuntimeRows;
2095
+ private mapStreamDataRows;
2096
+ private mapCells;
2097
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<QueryExecutorService, never>;
2098
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<QueryExecutorService>;
2099
+ }
2100
+
2101
+ /**
2102
+ * Resolution state of one entity selector's stream-data scope (AB#7721). Kept
2103
+ * transiently by `MeshBoardStateService`, written by the view while a pick is
2104
+ * resolved to its source rtIds.
2105
+ *
2106
+ * - `pending`: the pick is being resolved (childScope traversal, one hop or a path).
2107
+ * - `resolved`: the pick resolved to `rtIds` — possibly none.
2108
+ * - `failed`: the resolution threw (e.g. the association fetch failed).
2109
+ *
2110
+ * A selector without an entry has no active pick: bound widgets keep the
2111
+ * query's persisted scope.
2112
+ */
2113
+ type EntitySelectorScopeState = {
2114
+ status: 'pending';
2115
+ } | {
2116
+ status: 'resolved';
2117
+ rtIds: string[];
2118
+ } | {
2119
+ status: 'failed';
2120
+ };
2121
+ /**
2122
+ * What a widget bound to an entity selector does with its persistent query —
2123
+ * stream data (AB#7721) and runtime queries (AB#7725). Returned by
2124
+ * `MeshBoardStateService.resolveEntitySelectorScope`.
2125
+ *
2126
+ * - `unscoped`: no binding or no active pick — query with the persisted scope
2127
+ * (unchanged behaviour).
2128
+ * - `pending`: the scope is still resolving — show the loading state and send
2129
+ * NO query; the view triggers a refresh once the scope is known.
2130
+ * - `scoped`: query restricted to `rtIds` on the server — stream data via
2131
+ * `streamDataArgs.rtIds`, runtime queries (simple, aggregation, grouping) via
2132
+ * the field filter `rtId IN (rtIds)` (`QueryExecutionOptions.scopeRtIds`).
2133
+ * - `empty`: the pick has nothing in scope (`noTargets`) or the lookup failed
2134
+ * (`failed`) — show the no-data state and send NO query. Never fall back to
2135
+ * the persisted scope: that would show rows of other entities.
2136
+ * `invalidTimeRange` (AB#7582): the embedding host set a `timeRange` that is
2137
+ * unparseable or empty (`from >= to`) — every stream-data query bound to the
2138
+ * time filter is skipped, whatever its selector binding; a widget with
2139
+ * `ignoreTimeFilter` is not affected.
2140
+ */
2141
+ type StreamDataScope = {
2142
+ kind: 'unscoped';
2143
+ } | {
2144
+ kind: 'pending';
2145
+ } | {
2146
+ kind: 'scoped';
2147
+ rtIds: string[];
2148
+ } | {
2149
+ kind: 'empty';
2150
+ reason: 'noTargets' | 'failed' | 'invalidTimeRange';
2151
+ };
2152
+ /**
2153
+ * The result a widget renders instead of executing its query when its scope is
2154
+ * `empty` (AB#7721). Shape-compatible with a real empty response, so each
2155
+ * widget's existing no-data rendering applies unchanged.
2156
+ */
2157
+ declare function emptyQueryExecutionResult(family: QueryFamily | undefined): QueryExecutionResult;
2158
+
1763
2159
  type GetSystemPersistentQueriesQueryVariablesDto = Types.Exact<{
1764
2160
  after?: Types.InputMaybe<Types.Scalars['String']['input']>;
1765
2161
  first?: Types.InputMaybe<Types.Scalars['Int']['input']>;
@@ -2136,6 +2532,20 @@ declare class MeshBoardPersistenceService {
2136
2532
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<MeshBoardPersistenceService>;
2137
2533
  }
2138
2534
 
2535
+ /**
2536
+ * The period an embedding host sets on the board (AB#7582): two exact instants
2537
+ * (half-open `[from, to)`), or `invalid` (with the reason) when the host passed an
2538
+ * unparseable or empty range. Produced by `parseHostTimeRange`, held transiently by
2539
+ * {@link MeshBoardStateService.setHostTimeRange}.
2540
+ */
2541
+ type HostTimeRangeState = {
2542
+ status: 'valid';
2543
+ from: Date;
2544
+ to: Date;
2545
+ } | {
2546
+ status: 'invalid';
2547
+ reason: string;
2548
+ };
2139
2549
  /**
2140
2550
  * Service that manages MeshBoard state and persistence.
2141
2551
  * Coordinates loading, saving, and switching between MeshBoards.
@@ -2154,12 +2564,20 @@ declare class MeshBoardStateService {
2154
2564
  private readonly _isModelAvailable;
2155
2565
  private readonly _variableResolutionErrors;
2156
2566
  /**
2157
- * Transient cache of the source rtIds resolved from each entity selector's
2158
- * current selection (keyed by selector id). Populated by the view component
2159
- * when a selection resolves (one-hop childScope traversal, or the picked
2160
- * entity's own rtId). Not persisted — derived fresh from each selection.
2567
+ * Transient scope state of each entity selector's current selection (keyed
2568
+ * by selector id): `pending` while the view resolves the pick, `resolved`
2569
+ * with the source rtIds (childScope hop or path, or the picked entity's
2570
+ * own rtId; possibly none), or `failed`. No entry = no active pick. Not
2571
+ * persisted — derived fresh from each selection, cleared on board switch
2572
+ * (AB#7721).
2161
2573
  */
2162
- private readonly _entitySelectorRtIds;
2574
+ private readonly _entitySelectorScopes;
2575
+ /**
2576
+ * Period set by the page that embeds the board (`MeshBoardViewComponent.timeRange`, AB#7582):
2577
+ * exact instants, or `invalid` when the host passed an unusable range. `null` = the board's own
2578
+ * selection applies. Transient — never persisted, never written into the board config.
2579
+ */
2580
+ private readonly _hostTimeRange;
2163
2581
  /**
2164
2582
  * Transient variables published by widgets (KPI output variables, AB#5364).
2165
2583
  * Kept apart from `_meshBoardConfig` so publishing triggers no persistence and
@@ -2411,6 +2829,11 @@ declare class MeshBoardStateService {
2411
2829
  * Boundaries are resolved on the board's {@link timeZoneMode} basis (local by
2412
2830
  * default, or UTC), the same basis widgets format their datetime display on —
2413
2831
  * so the selected range and the displayed timestamps stay consistent.
2832
+ *
2833
+ * While an embedding host has set a period ({@link setHostTimeRange}, AB#7582)
2834
+ * and the board's time filter is enabled, the host's instants are returned
2835
+ * unchanged (no day snapping, no zone conversion) and the stored selection is
2836
+ * ignored; an invalid host period resolves to `null`.
2414
2837
  */
2415
2838
  resolveCurrentTimeRange(): TimeRange | null;
2416
2839
  /**
@@ -2441,25 +2864,104 @@ declare class MeshBoardStateService {
2441
2864
  * for (AB#5157 review). `undefined` now only means the browser named no zone at all.
2442
2865
  */
2443
2866
  resolveStreamDataTimeZone(): string | undefined;
2867
+ /**
2868
+ * Marks an entity selector's scope as being resolved (AB#7721). Bound
2869
+ * stream-data widgets show their loading state and send no query until the
2870
+ * scope is resolved, failed or cleared — so they never flash rows of the
2871
+ * query's persisted (unscoped) scope while a pick is resolving.
2872
+ */
2873
+ setEntitySelectorScopePending(selectorId: string): void;
2444
2874
  /**
2445
2875
  * Stores the source rtIds resolved from an entity selector's current
2446
2876
  * selection. Called by the view component after a selection resolves (the
2447
- * one-hop childScope traversal, or the picked entity's own rtId when the
2448
- * selector has no childScope). Transient — not persisted.
2877
+ * childScope traversal (one hop or a path), or the picked entity's own rtId when the
2878
+ * selector has no childScope). An empty array is a resolved EMPTY scope:
2879
+ * bound widgets show no data and send no query (AB#7721). Transient — not
2880
+ * persisted.
2449
2881
  */
2450
2882
  setEntitySelectorRtIds(selectorId: string, rtIds: string[]): void;
2451
2883
  /**
2452
- * Clears the cached source rtIds for an entity selector (e.g. when its
2453
- * selection is cleared).
2884
+ * Marks an entity selector's scope resolution as failed (e.g. the association
2885
+ * fetch threw). Bound widgets treat it like an empty scope — no data, no
2886
+ * query — and the view tells the user the scope could not be resolved
2887
+ * (AB#7721).
2888
+ */
2889
+ setEntitySelectorScopeFailed(selectorId: string): void;
2890
+ /**
2891
+ * Clears the scope state for an entity selector (its selection was cleared).
2892
+ * Bound widgets then query with the persisted scope again.
2454
2893
  */
2455
2894
  clearEntitySelectorRtIds(selectorId: string): void;
2895
+ /** The raw scope state of a selector, or `undefined` when it has no active pick. */
2896
+ getEntitySelectorScopeState(selectorId: string): EntitySelectorScopeState | undefined;
2456
2897
  /**
2457
- * Resolves the stream-data `rtIds` scope for a persistent-query widget bound
2458
- * to an entity selector. Returns the source rtIds cached from the selector's
2459
- * current selection, or `undefined` when the selector id is absent, unknown,
2460
- * or has no active selection (so the query keeps its persisted scope).
2898
+ * Ids of the selectors whose scope resolution failed (for the view's
2899
+ * "could not resolve the scope" notice, AB#7721).
2900
+ */
2901
+ readonly failedEntitySelectorScopeIds: _angular_core.Signal<string[]>;
2902
+ /**
2903
+ * Decides how a widget runs its persistent query — the entry point every
2904
+ * built-in widget calls with its binding, query family and time-filter opt-out:
2905
+ *
2906
+ * 1. Host gate (AB#7582): while the embedding host's period is invalid, every
2907
+ * stream-data query bound to the time filter is `empty` (`invalidTimeRange`),
2908
+ * whatever its selector binding; pass the widget's `ignoreTimeFilter` so an
2909
+ * opted-out widget, whose data does not depend on the period, keeps querying.
2910
+ * Runtime queries have no time window and are not gated. A legacy config
2911
+ * without `queryFamily` is treated as stream data here.
2912
+ * 2. Entity-selector scope ({@link resolveEntitySelectorScope}, AB#7721) — since
2913
+ * AB#7725 for runtime queries too: `unscoped` / `pending` / `scoped` / `empty`.
2914
+ */
2915
+ resolveStreamDataScope(entitySelectorId?: string, family?: QueryFamily, ignoreTimeFilter?: boolean): StreamDataScope;
2916
+ /**
2917
+ * The entity-selector part of {@link resolveStreamDataScope}, without the host
2918
+ * gate — stream data (AB#7721) and runtime queries alike (AB#7725):
2919
+ *
2920
+ * - `unscoped` — no binding, or no active pick: keep the query as saved.
2921
+ * - `pending` — the pick is still resolving: show loading, send no query.
2922
+ * - `scoped` — query restricted to the resolved rtIds: stream data via
2923
+ * `streamDataArgs.rtIds`, runtime queries via the `rtId IN` field filter
2924
+ * (`QueryExecutionOptions.scopeRtIds`).
2925
+ * - `empty` — the pick has nothing in scope or the lookup failed: show the
2926
+ * no-data state and send no query. Never fall back to the persisted scope.
2927
+ */
2928
+ resolveEntitySelectorScope(entitySelectorId?: string): StreamDataScope;
2929
+ /**
2930
+ * Resolves the stream-data `rtIds` for a persistent-query widget bound to an
2931
+ * entity selector: the resolved source rtIds when the scope is `scoped`,
2932
+ * otherwise `undefined`.
2933
+ *
2934
+ * `undefined` does NOT mean "query with the persisted scope" for a pending or
2935
+ * empty scope — callers must check {@link resolveStreamDataScope} first and
2936
+ * skip the query for `pending` / `empty` (AB#7721).
2461
2937
  */
2462
2938
  resolveStreamDataRtIds(entitySelectorId?: string): string[] | undefined;
2939
+ private setEntitySelectorScope;
2940
+ /**
2941
+ * Sets (or with `null` clears) the period of the page embedding the board
2942
+ * (AB#7582). Called by `MeshBoardViewComponent` for its `timeRange` input; a
2943
+ * host normally sets the input instead of calling this. Transient: not
2944
+ * persisted, not written into the board config, so it never causes unsaved
2945
+ * changes. Only takes effect while the board's time filter is enabled.
2946
+ */
2947
+ setHostTimeRange(state: HostTimeRangeState | null, owner?: object): void;
2948
+ /**
2949
+ * Clears the host period only if `owner` set it (AB#7582). The service is
2950
+ * root-provided, so a view that is destroyed (or drops its `timeRange`) must not
2951
+ * clear a period another view set in the meantime.
2952
+ */
2953
+ clearHostTimeRange(owner: object): void;
2954
+ /** The view (or other caller) that set the current host period, if it said so. */
2955
+ private hostTimeRangeOwner;
2956
+ /** The period set by the embedding host, or `null` when the board's own selection applies. */
2957
+ readonly hostTimeRange: _angular_core.Signal<HostTimeRangeState | null>;
2958
+ /**
2959
+ * True when an invalid host period blocks a stream-data query that is bound to
2960
+ * the time filter (AB#7582): the period is invalid, the board's time filter is
2961
+ * enabled and the caller did not opt out with `ignoreTimeFilter`. Such a query
2962
+ * must not be sent — without a window it would read the whole archive.
2963
+ */
2964
+ isStreamDataBlockedByHostTimeRange(ignoreTimeFilter?: boolean): boolean;
2463
2965
  /**
2464
2966
  * Updates the time filter configuration.
2465
2967
  */
@@ -2561,12 +3063,17 @@ interface RepeaterDataItem {
2561
3063
  /** All attributes as a Map for easy access */
2562
3064
  attributes: Map<string, unknown>;
2563
3065
  }
3066
+ /** Source rtIds per request of one batched association hop (AB#7723). */
3067
+ declare const ASSOCIATION_HOP_SOURCE_BATCH = 100;
3068
+ /** Targets read per source entity in one association hop (AB#7723). */
3069
+ declare const ASSOCIATION_HOP_TARGETS_PER_SOURCE = 1000;
2564
3070
  declare class MeshBoardDataService {
2565
3071
  private readonly getDashboardEntityGQL;
2566
3072
  private readonly getCkModelsWithStateGQL;
2567
3073
  private readonly getEntitiesByCkTypeGQL;
2568
3074
  private readonly queryExecutor;
2569
3075
  private readonly getAssociationTargetsGQL;
3076
+ private readonly getAssociationTargetRtIdsGQL;
2570
3077
  private readonly secretSafeNames;
2571
3078
  private readonly getCkTypeAttributesGQL;
2572
3079
  private readonly apollo;
@@ -2649,6 +3156,20 @@ declare class MeshBoardDataService {
2649
3156
  * Uses the associations.targets() GraphQL endpoint.
2650
3157
  */
2651
3158
  fetchAssociationTargets(sourceRtId: string, sourceCkTypeId: string, targetCkTypeId: string, roleId: string, direction: 'in' | 'out', attributeNames?: string[], first?: number): Observable<TargetEntityWithAttributes[]>;
3159
+ /**
3160
+ * One association hop for MANY source entities (AB#7723, multi-hop child
3161
+ * scope): the rtIds of the `targetCkTypeId` entities reached from each of
3162
+ * `sourceRtIds` (all of `sourceCkTypeId`) over `roleId` in `direction`.
3163
+ *
3164
+ * Query cost: the sources go out in batches of
3165
+ * {@link ASSOCIATION_HOP_SOURCE_BATCH} rtIds per request (`runtimeEntities(rtIds:)`
3166
+ * with the association targets nested), the batches of one hop in parallel —
3167
+ * never one request per entity. Only rtIds are selected. Per source at most
3168
+ * {@link ASSOCIATION_HOP_TARGETS_PER_SOURCE} targets are read; a truncated
3169
+ * source is logged as a warning. Duplicates are not removed here.
3170
+ * Errors propagate (the caller turns them into a failed scope).
3171
+ */
3172
+ fetchAssociationTargetRtIds(sourceRtIds: readonly string[], sourceCkTypeId: string, targetCkTypeId: string, roleId: string, direction: 'in' | 'out'): Observable<string[]>;
2652
3173
  /**
2653
3174
  * Fetches CK type attribute definitions (name + type) for config dialog.
2654
3175
  */
@@ -3000,301 +3521,74 @@ declare class EditModeStateService {
3000
3521
  getSnapshot<T>(): T | null;
3001
3522
  /**
3002
3523
  * Updates the snapshot with new data while staying in edit mode.
3003
- * Useful when you want to update the "base" state during editing.
3004
- */
3005
- updateSnapshot<T>(data: T): void;
3006
- /**
3007
- * Resets all state (useful for cleanup).
3008
- */
3009
- reset(): void;
3010
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<EditModeStateService, never>;
3011
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<EditModeStateService>;
3012
- }
3013
-
3014
- interface GridCell {
3015
- col: number;
3016
- row: number;
3017
- }
3018
- interface GridPosition {
3019
- col: number;
3020
- row: number;
3021
- }
3022
- /**
3023
- * Service for MeshBoard grid layout calculations and collision detection.
3024
- * Handles widget positioning, overlap detection, and finding available positions.
3025
- */
3026
- declare class MeshBoardGridService {
3027
- /**
3028
- * Returns all grid cells occupied by a widget at the given position/size.
3029
- */
3030
- getCells(col: number, row: number, colSpan: number, rowSpan: number): GridCell[];
3031
- /**
3032
- * Checks if placing a widget at the given position/size would overlap with any other widget.
3033
- * Uses the model (not DOM) for accurate, predictable collision detection.
3034
- */
3035
- wouldCauseOverlap(widgets: AnyWidgetConfig[], widgetId: string, col: number, row: number, colSpan: number, rowSpan: number): boolean;
3036
- /**
3037
- * Checks if a widget would extend beyond the grid boundaries.
3038
- */
3039
- isOutOfBounds(col: number, colSpan: number, maxColumns: number): boolean;
3040
- /**
3041
- * Finds an available position for a widget of the given size.
3042
- */
3043
- findAvailablePosition(widgets: AnyWidgetConfig[], colSpan: number, rowSpan: number, maxColumns: number): GridPosition;
3044
- /**
3045
- * Resolves overlapping widgets by moving them to non-overlapping positions.
3046
- * Modifies the widgets array in place.
3047
- * Returns the list of widgets that were moved.
3048
- */
3049
- resolveOverlaps(widgets: AnyWidgetConfig[], maxColumns: number): AnyWidgetConfig[];
3050
- /**
3051
- * Gets all widgets that would be outside the grid if columns were reduced.
3052
- */
3053
- getWidgetsOutOfBounds(widgets: AnyWidgetConfig[], newColumns: number): AnyWidgetConfig[];
3054
- /**
3055
- * Calculates the maximum row used by any widget.
3056
- */
3057
- getMaxRow(widgets: AnyWidgetConfig[]): number;
3058
- /**
3059
- * Creates a set of all occupied cell keys from the widgets.
3060
- */
3061
- private getOccupiedCells;
3062
- /**
3063
- * Finds an available position using a pre-computed set of occupied cells.
3064
- */
3065
- private findAvailablePositionWithOccupied;
3066
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<MeshBoardGridService, never>;
3067
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<MeshBoardGridService>;
3068
- }
3069
- /** @deprecated Use MeshBoardGridService instead */
3070
- declare const DashboardGridService: typeof MeshBoardGridService;
3071
-
3072
- /**
3073
- * Result of resolution-aware series routing (AB#4290). The caller runs the existing
3074
- * stream-data downsampling query against {@link archiveRtId} with `limit = points`
3075
- * and the column aggregation set to {@link reducingFunction}. `signal` is a truthful
3076
- * outcome the widget can surface (e.g. a "resolution-limited" hint).
3077
- *
3078
- * The coverage signal (AB#5157) rides the same fields: `signal` is `CoverageLimited` when the
3079
- * resolver's coverage filter skipped a finer rung because it holds no measured data over the
3080
- * requested window, `actualPoints` / `diagnostic` carry the deliverable count and the rung that
3081
- * was excluded, and {@link finerRungAvailableFrom} says from when that finer rung could serve.
3082
- */
3083
- interface SeriesResolutionResult {
3084
- archiveRtId: string;
3085
- effectiveBucketMs: number;
3086
- points: number;
3087
- reducingFunction: CkRollupFunctionDto;
3088
- signal: SeriesResolutionSignalDto;
3089
- actualPoints: number | null;
3090
- diagnostic: string | null;
3091
- /**
3092
- * Earliest instant from which the coverage-excluded finer rung would be usable (AB#5157).
3093
- * Set only on `CoverageLimited`, null otherwise. Passed through as the wire delivers it —
3094
- * a `DateTime` scalar arrives as an ISO string unless a scalar parser turns it into a `Date` —
3095
- * so read it through `toInstant` / `formatInstant` rather than assuming either shape.
3096
- * Optional so that code constructing a result (mocks, adapters) written before AB#5157 keeps
3097
- * compiling; a missing value means the same as `null`.
3098
- */
3099
- finerRungAvailableFrom?: Date | string | null;
3100
- }
3101
- /**
3102
- * Time-range and downsampling arguments for stream-data persistent queries.
3103
- * Mirrors the GraphQL input `StreamDataArguments` so widgets can build it
3104
- * without importing generated DTO types directly.
3105
- *
3106
- * Backend semantics (verified against StreamDataQueryDtoType.cs and
3107
- * StreamDataVariantExecutor.cs; `queryMode` override added in AB#4233):
3108
- * - `from` / `to` / `limit` override the persisted query's intrinsic values
3109
- * when set (`execOverride?.From ?? simple.From` pattern in the resolver).
3110
- * - `interval` is currently ignored by every variant; the downsampling path
3111
- * derives `(to - from) / limit` itself.
3112
- * - `queryMode: DOWNSAMPLING` on a `SimpleSdQuery` (persisted) or the transient
3113
- * `simple` sub-connection now drives the downsampling execution path: with a
3114
- * full from/to/limit contract the backend reduces to `limit` buckets per series
3115
- * (per-type reducers + group-by source rtId). Without all three it falls back
3116
- * to raw rows. For the other variants the execution shape still comes from the
3117
- * CK subtype / sub-connection; `queryMode` is a no-op there.
3118
- */
3119
- interface StreamDataExecutionArgs {
3120
- from?: Date | null;
3121
- to?: Date | null;
3122
- interval?: number | null;
3123
- limit?: number | null;
3124
- /**
3125
- * `DOWNSAMPLING` switches a SimpleSdQuery / transient `simple` query to the
3126
- * downsampling path (with from/to/limit); a no-op for the other variants.
3127
- * Defaults to `Default` (raw rows).
3128
- */
3129
- queryMode?: QueryModeDto;
3130
- /**
3131
- * Source runtime ids to scope the query to. When set, replaces the persisted
3132
- * RtIds on the query at execution time — used to scope a stream-data widget to
3133
- * the entities resolved from a selected asset (e.g. the EnergyMeasurement rtIds
3134
- * under a picked MeteringPoint). An empty array is treated as "no scope".
3135
- */
3136
- rtIds?: string[] | null;
3137
- }
3138
- interface QueryExecutionOptions {
3139
- /** Page size — passed to the GraphQL `first` variable. */
3140
- first?: number | null;
3141
- /** Cursor — passed to the GraphQL `after` variable. */
3142
- after?: string | null;
3143
- /** Optional column / row sort definitions. */
3144
- sortOrder?: SortDto[] | null;
3145
- /** Field filters applied to the query rows. */
3146
- fieldFilter?: FieldFilterDto[] | null;
3147
- /** Stream-data-only: time-range, interval, limit, queryMode. Ignored for runtime queries. */
3148
- streamDataArgs?: StreamDataExecutionArgs | null;
3149
- /** Force a network round-trip instead of using the Apollo cache. */
3150
- forceRefresh?: boolean;
3151
- }
3152
- interface QueryColumnInfo {
3153
- attributePath: string;
3154
- attributeValueType?: string | null;
3155
- aggregationType?: string | null;
3156
- }
3157
- interface QueryCell {
3158
- attributePath: string;
3159
- value: unknown;
3160
- }
3161
- /**
3162
- * Unified result-row shape across runtime and stream-data queries.
3163
- * `__typename` lets callers distinguish row kinds when needed
3164
- * (`RtSimpleQueryRow`, `RtAggregationQueryRow`, `RtGroupingAggregationQueryRow`,
3165
- * `StreamDataQueryRow`).
3166
- *
3167
- * Stream-data rows surface `timestamp`, `rtWellKnownName`,
3168
- * `rtCreationDateTime`, and `rtChangedDateTime` directly on the row — useful
3169
- * for time-series x-axes. Runtime rows leave those fields undefined.
3170
- */
3171
- interface QueryResultRow {
3172
- __typename?: string;
3173
- rtId?: string | null;
3174
- ckTypeId?: string | null;
3175
- timestamp?: Date | null;
3176
- rtWellKnownName?: string | null;
3177
- rtCreationDateTime?: Date | null;
3178
- rtChangedDateTime?: Date | null;
3179
- cells: QueryCell[];
3524
+ * Useful when you want to update the "base" state during editing.
3525
+ */
3526
+ updateSnapshot<T>(data: T): void;
3527
+ /**
3528
+ * Resets all state (useful for cleanup).
3529
+ */
3530
+ reset(): void;
3531
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EditModeStateService, never>;
3532
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<EditModeStateService>;
3180
3533
  }
3181
- interface QueryExecutionResult {
3182
- family: QueryFamily;
3183
- queryRtId?: string | null;
3184
- associatedCkTypeId?: string | null;
3185
- columns: QueryColumnInfo[];
3186
- rows: QueryResultRow[];
3187
- totalCount: number;
3188
- hasNextPage: boolean;
3189
- endCursor?: string | null;
3534
+
3535
+ interface GridCell {
3536
+ col: number;
3537
+ row: number;
3538
+ }
3539
+ interface GridPosition {
3540
+ col: number;
3541
+ row: number;
3190
3542
  }
3191
3543
  /**
3192
- * Executes persistent queries by rtId and returns a unified result shape
3193
- * regardless of whether the underlying query is runtime-data or stream-data.
3194
- *
3195
- * Widgets consume `QueryExecutionResult` and stay agnostic about which family
3196
- * the saved query belongs to — switching a widget's data source between
3197
- * runtime and stream-data is purely a configuration change.
3544
+ * Service for MeshBoard grid layout calculations and collision detection.
3545
+ * Handles widget positioning, overlap detection, and finding available positions.
3198
3546
  */
3199
- declare class QueryExecutorService {
3200
- private readonly runtimeGql;
3201
- private readonly streamDataGql;
3202
- private readonly persistentQueriesGql;
3203
- private readonly resolveSeriesGql;
3204
- private readonly queryArchiveGql;
3205
- private readonly downsampleGql;
3206
- private readonly entitiesGql;
3207
- private readonly secretSafeNames;
3547
+ declare class MeshBoardGridService {
3208
3548
  /**
3209
- * Cache of resolved query families, keyed by query rtId. Filled lazily for
3210
- * legacy widget configs that pre-date the `queryFamily` field — saves a
3211
- * round-trip on every refresh.
3549
+ * Returns all grid cells occupied by a widget at the given position/size.
3212
3550
  */
3213
- private readonly familyCache;
3214
- execute(family: QueryFamily | undefined, queryRtId: string, options?: QueryExecutionOptions): Observable<QueryExecutionResult>;
3551
+ getCells(col: number, row: number, colSpan: number, rowSpan: number): GridCell[];
3215
3552
  /**
3216
- * Resolves the family of a persistent query by rtId. Falls back to
3217
- * `'runtime'` when the query type cannot be classified — this matches the
3218
- * pre-Phase-1 behavior.
3553
+ * Checks if placing a widget at the given position/size would overlap with any other widget.
3554
+ * Uses the model (not DOM) for accurate, predictable collision detection.
3219
3555
  */
3220
- resolveFamily(queryRtId: string): Promise<QueryFamily>;
3221
- executeRuntime(queryRtId: string, options?: QueryExecutionOptions): Observable<QueryExecutionResult>;
3222
- executeStreamData(queryRtId: string, options?: QueryExecutionOptions): Observable<QueryExecutionResult>;
3556
+ wouldCauseOverlap(widgets: AnyWidgetConfig[], widgetId: string, col: number, row: number, colSpan: number, rowSpan: number): boolean;
3223
3557
  /**
3224
- * Resolution-aware series routing (AB#4290): asks the backend which archive/rollup to
3225
- * query for a base archive family, time window and target point count — so a widget can
3226
- * render ~`targetPoints` points without knowing which physical archive holds the data at a
3227
- * usable grain. The caller then runs {@link executeStreamData} (downsampling) against the
3228
- * returned `archiveRtId` with `limit = points`. Returns null when StreamData is not enabled.
3558
+ * Checks if a widget would extend beyond the grid boundaries.
3229
3559
  */
3230
- resolveSeriesQuery(input: ResolveSeriesQueryInputDto): Promise<SeriesResolutionResult | null>;
3560
+ isOutOfBounds(col: number, colSpan: number, maxColumns: number): boolean;
3231
3561
  /**
3232
- * Resolution-aware routing (AB#4290): reads a persisted stream-data query's base archive rtId
3233
- * and target CK type WITHOUT executing the query (the `rows` sub-connection is not selected), so
3234
- * a widget can feed the archive to {@link resolveSeriesQuery} and use the CK type to resolve
3235
- * per-series labels. Also reads the query's persisted RtIds pin
3236
- * (`System/StreamDataQuery.RtIds`) from the runtime entity — the transient downsampling path
3237
- * bypasses the persisted query execution, so widgets must re-apply the pin themselves
3238
- * (AB#4818). `rtIds` is null when the query has no pin (or is not a SimpleSdQuery).
3239
- * Returns null when the query is missing or has no archive.
3562
+ * Finds an available position for a widget of the given size.
3240
3563
  */
3241
- fetchQueryArchive(queryRtId: string): Promise<{
3242
- archiveRtId: string;
3243
- ckTypeId: string | null;
3244
- rtIds: string[] | null;
3245
- } | null>;
3564
+ findAvailablePosition(widgets: AnyWidgetConfig[], colSpan: number, rowSpan: number, maxColumns: number): GridPosition;
3246
3565
  /**
3247
- * Resolution-aware routing (AB#4290): runs the AB#4233 downsampling query against an explicit
3248
- * archive rtId (the rollup/base chosen by {@link resolveSeriesQuery}), reducing `sourcePath`
3249
- * with `aggregation` to at most `limit` buckets. The transient downsampling groups by bin
3250
- * (not by source rtId), so callers that need per-series lines scope `rtIds` to one source
3251
- * entity per call. Returns the unified rows; each row's single value cell carries the reduced
3252
- * value under its wire column name (e.g. `amountvalue_sum`) alongside the bin `timestamp`.
3566
+ * Resolves overlapping widgets by moving them to non-overlapping positions.
3567
+ * Modifies the widgets array in place.
3568
+ * Returns the list of widgets that were moved.
3253
3569
  */
3254
- downsampleByArchive(params: {
3255
- archiveRtId: string;
3256
- from: Date;
3257
- to: Date;
3258
- limit: number;
3259
- sourcePath: string;
3260
- aggregation: string;
3261
- rtIds?: string[] | null;
3262
- fieldFilter?: FieldFilterDto[] | null;
3263
- }): Promise<QueryResultRow[]>;
3570
+ resolveOverlaps(widgets: AnyWidgetConfig[], maxColumns: number): AnyWidgetConfig[];
3264
3571
  /**
3265
- * Best-effort per-series labels for resolution-aware fan-out (AB#4290): reads each source
3266
- * entity's attribute matching `labelField` (canonical, case/underscore-insensitive so an archive
3267
- * column name maps to its CK attribute). Entities that fail to load or lack the attribute are
3268
- * simply omitted; the caller falls back to the rtId. Returns a `rtId → label` map.
3572
+ * Gets all widgets that would be outside the grid if columns were reduced.
3269
3573
  */
3270
- fetchSeriesLabels(ckTypeId: string, rtIds: string[], labelField: string): Promise<Map<string, string>>;
3574
+ getWidgetsOutOfBounds(widgets: AnyWidgetConfig[], newColumns: number): AnyWidgetConfig[];
3271
3575
  /**
3272
- * The non-secret attribute names of `ckTypeId` whose canonical form matches `wanted`
3273
- * (SECRET-safe explicit list, AB#5542). Empty when nothing matches — the caller then falls back
3274
- * as for a missing attribute.
3576
+ * Calculates the maximum row used by any widget.
3275
3577
  */
3276
- private matchingAttributeNames;
3277
- /** Cap on the source-entity population read for group-aggregation (AB#4714). A truncated read is
3278
- * logged, never silent. */
3279
- private static readonly ENTITY_GROUP_FETCH_CAP;
3578
+ getMaxRow(widgets: AnyWidgetConfig[]): number;
3280
3579
  /**
3281
- * Group-aggregation source resolution (AB#4714): fetches the source entities of `ckTypeId` in a
3282
- * single bulk read and buckets their rtIds by the value of `groupField` (canonical match — case
3283
- * and non-alphanumerics are ignored, so an archive column name maps to its CK attribute). Returns
3284
- * `groupValue → rtIds`. Optionally restricted to `restrictRtIds` (an entity-selector scope) —
3285
- * entities outside that set are dropped. Entities whose group attribute is missing/null are
3286
- * omitted (they cannot be attributed to a line). The population is bounded to
3287
- * {@link ENTITY_GROUP_FETCH_CAP}; a truncated read is logged (never silently capped).
3580
+ * Creates a set of all occupied cell keys from the widgets.
3288
3581
  */
3289
- fetchEntityGroups(ckTypeId: string, groupField: string, restrictRtIds?: string[]): Promise<Map<string, string[]>>;
3290
- private buildStreamDataArg;
3291
- private mapColumns;
3292
- private mapRuntimeRows;
3293
- private mapStreamDataRows;
3294
- private mapCells;
3295
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<QueryExecutorService, never>;
3296
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<QueryExecutorService>;
3582
+ private getOccupiedCells;
3583
+ /**
3584
+ * Finds an available position using a pre-computed set of occupied cells.
3585
+ */
3586
+ private findAvailablePositionWithOccupied;
3587
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MeshBoardGridService, never>;
3588
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<MeshBoardGridService>;
3297
3589
  }
3590
+ /** @deprecated Use MeshBoardGridService instead */
3591
+ declare const DashboardGridService: typeof MeshBoardGridService;
3298
3592
 
3299
3593
  /**
3300
3594
  * Manages a `setInterval` lifecycle for MeshBoard auto-refresh.
@@ -4026,17 +4320,34 @@ declare class TableWidgetComponent implements DashboardWidget<TableWidgetConfig,
4026
4320
  dataSource?: TableWidgetDataSourceDirective;
4027
4321
  private readonly stateService;
4028
4322
  /** Host texts (`MESHBOARD_MESSAGES`, AB#5622): list texts (empty state, pager, toolbar) and the placeholder. */
4029
- protected readonly texts: _angular_core.Signal<_meshmakers_octo_meshboard.MeshBoardMessages & Required<Omit<_meshmakers_octo_meshboard.MeshBoardMessages, "tableList">>>;
4323
+ protected readonly texts: Signal<_meshmakers_octo_meshboard.MeshBoardMessages & Required<Omit<_meshmakers_octo_meshboard.MeshBoardMessages, "tableList">>>;
4030
4324
  /** Host translation of enum cell values (`MESHBOARD_LABEL_RESOLVER`, AB#5622); absent = raw text. */
4031
4325
  private readonly labelResolver;
4032
4326
  /** CK value type per derived column field (persistent queries), for the label resolver. */
4033
4327
  private readonly _queryColumnValueTypes;
4328
+ /** Host UI language (`MESHBOARD_LANGUAGE`, AB#7655) for column `titles` / `valueLabels`; `null` = `title` / raw texts. */
4329
+ private readonly language;
4330
+ /**
4331
+ * Problems already warned about (`<widget id or instance>|<field>|<problem hash>`), so a bad config
4332
+ * logs once, not on every language change, while a new problem after a config edit is reported again.
4333
+ */
4334
+ private readonly warnedColumns;
4335
+ /** Fallback warning key of a widget without an id. */
4336
+ private readonly instanceKey;
4337
+ /** App locale for the `number` / `date` rendering of unlabelled values in value-label columns. */
4338
+ private readonly locale;
4339
+ /**
4340
+ * Bumped on every `config` change: `config` is a plain `@Input`, so the computeds that read it
4341
+ * depend on this signal to pick up a new config on the same widget instance (AB#7655).
4342
+ */
4343
+ private readonly _configVersion;
4344
+ constructor();
4034
4345
  private readonly _isLoading;
4035
4346
  private readonly _data;
4036
4347
  private readonly _error;
4037
- readonly isLoading: _angular_core.Signal<boolean>;
4038
- readonly data: _angular_core.Signal<Record<string, unknown>[]>;
4039
- readonly error: _angular_core.Signal<string | null>;
4348
+ readonly isLoading: Signal<boolean>;
4349
+ readonly data: Signal<Record<string, unknown>[]>;
4350
+ readonly error: Signal<string | null>;
4040
4351
  /** Signal to track query columns from data source (for persistent queries) */
4041
4352
  private readonly _queryColumnsForView;
4042
4353
  /**
@@ -4048,7 +4359,7 @@ declare class TableWidgetComponent implements DashboardWidget<TableWidgetConfig,
4048
4359
  * Converts TableWidgetConfig columns to ListViewComponent TableColumn format.
4049
4360
  * For persistent queries, uses dynamically derived columns from the query response.
4050
4361
  */
4051
- readonly listViewColumns: _angular_core.Signal<TableColumn$1[]>;
4362
+ readonly listViewColumns: Signal<TableColumn$1[]>;
4052
4363
  /**
4053
4364
  * Checks if the widget has a valid configuration.
4054
4365
  * Supports both runtimeEntity and persistentQuery data sources.
@@ -4059,7 +4370,15 @@ declare class TableWidgetComponent implements DashboardWidget<TableWidgetConfig,
4059
4370
  * For persistent queries, columns are derived from the query response.
4060
4371
  * Returns true once columns are available.
4061
4372
  */
4062
- readonly columnsReady: _angular_core.Signal<boolean>;
4373
+ readonly columnsReady: Signal<boolean>;
4374
+ /**
4375
+ * Logs one console warning per widget, column and set of problems for ignored `titles` /
4376
+ * `valueLabels` entries (unknown culture keys, malformed titles or value labels, `valueLabels`
4377
+ * together with `statusMapping`, AB#7655). The table still renders. The key carries a hash of the
4378
+ * problem list, so a different problem after a config edit is reported again; widgets without an
4379
+ * id use a per-instance key.
4380
+ */
4381
+ private warnOnce;
4063
4382
  private formatColumnTitle;
4064
4383
  ngOnChanges(changes: SimpleChanges): void;
4065
4384
  refresh(): void;
@@ -4103,6 +4422,10 @@ declare class TableConfigDialogComponent implements OnInit {
4103
4422
  private readonly getCkTypeAvailableQueryColumnsGQL;
4104
4423
  private readonly stateService;
4105
4424
  private readonly windowRef;
4425
+ private readonly getRuntimeQueryColumnsGQL;
4426
+ private readonly queryExecutor;
4427
+ /** Fields the saved query returns now, loaded once per query rtId (AB#7655, kept explicit columns). */
4428
+ private queryFieldsLoad?;
4106
4429
  ckTypeSelectorInput?: CkTypeSelectorInputComponent;
4107
4430
  filterEditor?: FieldFilterEditorComponent;
4108
4431
  querySelector?: QuerySelectorComponent;
@@ -4160,7 +4483,13 @@ declare class TableConfigDialogComponent implements OnInit {
4160
4483
  onFiltersChange(filters: FieldFilterItem[]): void;
4161
4484
  getColumnsSummary(): string;
4162
4485
  getSortingSummary(): string;
4163
- onSave(): void;
4486
+ /**
4487
+ * The fields a persistent query returns now (`null` when unknown or the lookup failed). Runtime
4488
+ * queries use the metadata-only column resolver; stream-data queries execute with `first: 1`
4489
+ * (no column-introspection endpoint), like the chart dialogs.
4490
+ */
4491
+ private loadQueryFields;
4492
+ onSave(): Promise<void>;
4164
4493
  private formatColumnTitle;
4165
4494
  onCancel(): void;
4166
4495
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TableConfigDialogComponent, never>;
@@ -5393,6 +5722,7 @@ declare class StatsGridWidgetComponent implements OnInit, OnChanges {
5393
5722
  */
5394
5723
  private resolveStatValue;
5395
5724
  private loadPersistentQueryValue;
5725
+ private scopeOf;
5396
5726
  private buildStreamDataArgs;
5397
5727
  private convertFiltersToDto;
5398
5728
  private getColorClass;
@@ -5985,6 +6315,7 @@ declare class SummaryCardWidgetComponent implements DashboardWidget<SummaryCardW
5985
6315
  private loadData;
5986
6316
  private fetchTileValue;
5987
6317
  private fetchPersistentQueryValue;
6318
+ private scopeOf;
5988
6319
  private buildStreamDataArgs;
5989
6320
  private convertFiltersToDto;
5990
6321
  private fetchEntityAttributes;
@@ -6278,6 +6609,12 @@ interface MeshBoardMessages {
6278
6609
  tableList?: Partial<ListViewMessages>;
6279
6610
  /** Placeholder of a table widget without data source / columns. Default: "Table not configured" */
6280
6611
  tableNotConfigured?: string;
6612
+ /**
6613
+ * Board notice when an entity selector's stream-data scope could not be resolved (AB#7721);
6614
+ * `{label}` is replaced by the selector label. Default:
6615
+ * 'Could not resolve the scope of "{label}" - widgets bound to it show no data.'
6616
+ */
6617
+ scopeResolutionFailed?: string;
6281
6618
  }
6282
6619
  /** Default texts of {@link MeshBoardMessages} (the list texts default inside `mm-list-view`). */
6283
6620
  declare const DEFAULT_MESHBOARD_MESSAGES: Required<Omit<MeshBoardMessages, 'tableList'>>;
@@ -6299,6 +6636,36 @@ declare const MESHBOARD_MESSAGES: InjectionToken<MeshBoardMessagesSource>;
6299
6636
  /** The resolved MeshBoard texts: defaults with the host layer on top (missing / null members keep the default). */
6300
6637
  declare function resolveMeshBoardMessages(messages: MeshBoardMessages | null | undefined): MeshBoardMessages & typeof DEFAULT_MESHBOARD_MESSAGES;
6301
6638
 
6639
+ /**
6640
+ * What a host provides on {@link MESHBOARD_LANGUAGE} (AB#7655): the current UI language as a culture
6641
+ * code (`de-AT`, `en-GB`, `de`), fixed or as a signal for apps that switch the language at runtime
6642
+ * (the widgets follow it without reloading data). `null` / `undefined` / `''` = no language.
6643
+ */
6644
+ type MeshBoardLanguageSource = string | Signal<string | null | undefined>;
6645
+ /**
6646
+ * Optional: the host's current UI language. MeshBoard does not derive it from `LOCALE_ID` (that is
6647
+ * static in many apps); a host that wants per-language texts in board configurations (table column
6648
+ * `titles`, `valueLabels`) hands its language over once, via `provideMeshBoard({ language })`,
6649
+ * `provideMeshBoardLanguage(language)` or this token directly. Not provided = the configured default
6650
+ * texts (e.g. the column `title`).
6651
+ *
6652
+ * ```ts
6653
+ * providers: [provideMeshBoard({ language: languageService.currentLanguage })] // Signal<string>
6654
+ * ```
6655
+ */
6656
+ declare const MESHBOARD_LANGUAGE: InjectionToken<MeshBoardLanguageSource>;
6657
+ /**
6658
+ * Picks the text for `language` from a per-language map (AB#7655). Lookup order:
6659
+ * 1. the exact culture or language (`de-AT`, `de`; case-insensitive);
6660
+ * 2. a culture (`de-AT`) without an exact key: a key equal to its language part (`de`). A culture
6661
+ * never picks a sibling culture (`de-DE` does not take `de-AT`);
6662
+ * 3. a bare language (`de`) without an exact key: the first authored key of that language
6663
+ * (`de-AT` in `{ 'en-GB': …, 'de-AT': …, 'de-DE': … }`), in the map's key order.
6664
+ * Returns `undefined` when there is no language, no map or no match, so the caller applies its own
6665
+ * fallback (e.g. the column `title`).
6666
+ */
6667
+ declare function pickLocalizedText(texts: Readonly<Record<string, string>> | null | undefined, language: string | null | undefined): string | undefined;
6668
+
6302
6669
  declare function registerDefaultWidgets(registry: WidgetRegistryService): void;
6303
6670
  /**
6304
6671
  * Provides the widget registry with all built-in widgets registered.
@@ -6332,6 +6699,13 @@ interface MeshBoardOptions {
6332
6699
  * table widget's list texts. Fixed object or signal. Absent = English.
6333
6700
  */
6334
6701
  messages?: MeshBoardMessagesSource;
6702
+ /**
6703
+ * The host's current UI language (AB#7655), provided as `MESHBOARD_LANGUAGE`: a culture code
6704
+ * (`de-AT`) or a signal of it for apps that switch the language at runtime. Board configurations
6705
+ * use it to pick per-language texts (table column `titles`, `valueLabels`). Absent = the default
6706
+ * texts (column `title`); MeshBoard never falls back to `LOCALE_ID`.
6707
+ */
6708
+ language?: MeshBoardLanguageSource;
6335
6709
  }
6336
6710
  /**
6337
6711
  * Injection token for MeshBoard options
@@ -6366,6 +6740,11 @@ declare function provideMeshBoard(options?: MeshBoardOptions): EnvironmentProvid
6366
6740
  * without `provideMeshBoard()` — for apps that register the widgets lazily.
6367
6741
  */
6368
6742
  declare function provideMeshBoardMessages(messages: MeshBoardMessagesSource): EnvironmentProviders;
6743
+ /**
6744
+ * Provides the host's UI language (`MESHBOARD_LANGUAGE`, AB#7655) without `provideMeshBoard()` —
6745
+ * for apps that register the widgets lazily. A string or a signal (the widgets follow it).
6746
+ */
6747
+ declare function provideMeshBoardLanguage(language: MeshBoardLanguageSource): EnvironmentProviders;
6369
6748
  /**
6370
6749
  * Provider function for registering custom widgets.
6371
6750
  * Use this to add your own widget types to MeshBoard.
@@ -6446,9 +6825,17 @@ declare class EntitySelectorEditorComponent {
6446
6825
  private readonly attributeSelectorService;
6447
6826
  private readonly variableService;
6448
6827
  private readonly getEntitiesByCkTypeGQL;
6828
+ private readonly confirmationService;
6829
+ private readonly cdr;
6830
+ private readonly destroyRef;
6449
6831
  entitySelectors: EntitySelectorConfig[];
6450
6832
  /** Existing variable names from other sources (static variables, other selectors) for duplicate detection */
6451
6833
  existingVariableNames: string[];
6834
+ /**
6835
+ * The board's static variables (AB#7724): offered in the picker filter and
6836
+ * substituted when the editor lists default entities and checks the default.
6837
+ */
6838
+ variables: MeshBoardVariable[];
6452
6839
  entitySelectorsChange: EventEmitter<EntitySelectorConfig[]>;
6453
6840
  /** Emits true when entering edit mode, false when leaving — allows parent to hide its own buttons */
6454
6841
  editingStateChange: EventEmitter<boolean>;
@@ -6464,12 +6851,19 @@ declare class EntitySelectorEditorComponent {
6464
6851
  protected editMappings: EntitySelectorAttributeMapping[];
6465
6852
  protected editShowInToolbar: boolean;
6466
6853
  protected editDefaultRtId: string;
6467
- protected editChildScopeTargetCkTypeId: string;
6468
- protected editChildScopeTargetCkTypeItem: CkTypeSelectorItem | null;
6469
- protected editChildScopeRoleId: string;
6470
- protected editChildScopeDirection: 'in' | 'out';
6854
+ protected editScopeHops: EntitySelectorScopeHop[];
6855
+ protected editFollowsSelectorId: string;
6856
+ /** Why choosing the leader changed the form (CK type fixed, mappings/default cleared). */
6857
+ protected followNotice: string;
6858
+ protected editFilters: FieldFilterItem[];
6859
+ /** Filter rows a follower carries from hand-editing; ignored and dropped on save. */
6860
+ protected followerFilterCount: number;
6861
+ /** Result of the server check whether the default entity matches the filter. */
6862
+ protected defaultFilterCheck: DefaultFilterCheck;
6863
+ private readonly defaultCheckRequests;
6471
6864
  protected defaultEntityDataSource: RuntimeEntitySelectDataSource | null;
6472
6865
  protected defaultEntityDialogDataSource: RuntimeEntityDialogDataSource | null;
6866
+ constructor();
6473
6867
  /**
6474
6868
  * Starts adding a new entity selector.
6475
6869
  */
@@ -6481,7 +6875,29 @@ declare class EntitySelectorEditorComponent {
6481
6875
  /**
6482
6876
  * Removes an entity selector at the given index.
6483
6877
  */
6484
- removeSelector(index: number): void;
6878
+ removeSelector(index: number): Promise<void>;
6879
+ /** Selectors the edited selector may follow (non-followers, never itself). */
6880
+ get leaderOptions(): EntitySelectorConfig[];
6881
+ /** Selectors that follow the edited selector (it then cannot follow one itself). */
6882
+ get followedBy(): EntitySelectorConfig[];
6883
+ /** True when the stored leader is not among the selectable leaders (deleted or a follower). */
6884
+ get isLeaderUnavailable(): boolean;
6885
+ /** "A, B and C" of the selectors following the edited one. */
6886
+ get followedByLabels(): string;
6887
+ /** Validation message of the "Follows" choice, or '' when it is valid. */
6888
+ get followError(): string;
6889
+ /** True while the edited selector follows another one. */
6890
+ get isFollower(): boolean;
6891
+ /**
6892
+ * Handles a change of the "Follows" choice. Choosing a leader fixes the CK type
6893
+ * to the leader's (clearing default entity and mappings with a notice when the
6894
+ * type changes) and hides the toolbar option; back to none makes the CK type
6895
+ * editable again with "Show in Toolbar" unchecked.
6896
+ */
6897
+ onFollowsChanged(leaderId: string): void;
6898
+ /** True when the selector names a leader that does not exist or is itself a follower. */
6899
+ isOrphanFollower(selector: EntitySelectorConfig): boolean;
6900
+ private applyLeaderCkType;
6485
6901
  /**
6486
6902
  * Handles CK type selection in the editor form.
6487
6903
  */
@@ -6494,14 +6910,10 @@ declare class EntitySelectorEditorComponent {
6494
6910
  * Opens the attribute selector dialog to pick attributes for variable mappings.
6495
6911
  */
6496
6912
  selectAttributes(): Promise<void>;
6497
- /**
6498
- * Handles child-scope target CK type selection.
6499
- */
6500
- onChildScopeCkTypeSelected(ckType: CkTypeSelectorItem): void;
6501
- /**
6502
- * Handles child-scope target CK type cleared.
6503
- */
6504
- onChildScopeCkTypeCleared(): void;
6913
+ /** Takes the hop list of the child-scope editor (AB#7723). */
6914
+ onScopeHopsChanged(hops: EntitySelectorScopeHop[]): void;
6915
+ /** Validation message of the hop list, or '' when it can be saved. */
6916
+ get scopeHopsError(): string;
6505
6917
  /**
6506
6918
  * Handles default entity selection from the entity picker.
6507
6919
  */
@@ -6510,6 +6922,20 @@ declare class EntitySelectorEditorComponent {
6510
6922
  * Handles default entity cleared.
6511
6923
  */
6512
6924
  onDefaultEntityCleared(): void;
6925
+ /** Takes the rows of the picker filter editor (AB#7724). */
6926
+ onFiltersChange(filters: FieldFilterItem[]): void;
6927
+ /**
6928
+ * Variables offered in filter values: the board's static variables and the
6929
+ * variables other selectors map. The edited selector's own mappings are
6930
+ * left out — they are filled from its own pick.
6931
+ */
6932
+ get filterVariables(): FilterVariable[];
6933
+ /** "2 filters" chip of a selector in the list, or '' without filter. */
6934
+ getFilterSummary(selector: EntitySelectorConfig): string;
6935
+ /** "$a, $b" of the variables the default-entity check cannot substitute. */
6936
+ get uncheckedVariablesText(): string;
6937
+ /** Label of the leader the edited follower takes its pick from. */
6938
+ get leaderLabel(): string;
6513
6939
  /**
6514
6940
  * Saves the current entity selector being edited.
6515
6941
  */
@@ -6549,9 +6975,143 @@ declare class EntitySelectorEditorComponent {
6549
6975
  getVariableNameError(mapping: EntitySelectorAttributeMapping): string;
6550
6976
  private generateSelectorId;
6551
6977
  private updateDefaultEntityDataSources;
6978
+ private toFilterConfigs;
6979
+ /**
6980
+ * The filter rows that apply in the editor, with the board's static
6981
+ * variables substituted. Rows whose value still names a variable without a
6982
+ * value (e.g. one a selector pick fills at view time) are left out and
6983
+ * reported in `unresolved`; the editor cannot know their value.
6984
+ */
6985
+ private resolvedEditorFilters;
6986
+ /** Queues the (debounced) check whether the default entity matches the filter. */
6987
+ private requestDefaultCheck;
6988
+ /** Asks the server whether the entity is among the filtered ones (rtId + filter, first 1). */
6989
+ private checkDefaultEntity;
6552
6990
  private emitChange;
6553
6991
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EntitySelectorEditorComponent, never>;
6554
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EntitySelectorEditorComponent, "mm-entity-selector-editor", never, { "entitySelectors": { "alias": "entitySelectors"; "required": false; }; "existingVariableNames": { "alias": "existingVariableNames"; "required": false; }; }, { "entitySelectorsChange": "entitySelectorsChange"; "editingStateChange": "editingStateChange"; }, never, never, true, never>;
6992
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EntitySelectorEditorComponent, "mm-entity-selector-editor", never, { "entitySelectors": { "alias": "entitySelectors"; "required": false; }; "existingVariableNames": { "alias": "existingVariableNames"; "required": false; }; "variables": { "alias": "variables"; "required": false; }; }, { "entitySelectorsChange": "entitySelectorsChange"; "editingStateChange": "editingStateChange"; }, never, never, true, never>;
6993
+ }
6994
+ /**
6995
+ * Outcome of the default-entity filter check (AB#7724). Never blocks saving:
6996
+ * `mismatch` warns, `error` says the check failed, `unchecked` names the
6997
+ * variables the editor cannot substitute.
6998
+ */
6999
+ type DefaultFilterCheck = {
7000
+ state: 'none';
7001
+ } | {
7002
+ state: 'match';
7003
+ } | {
7004
+ state: 'mismatch';
7005
+ } | {
7006
+ state: 'error';
7007
+ } | {
7008
+ state: 'unchecked';
7009
+ variables: string[];
7010
+ };
7011
+
7012
+ /** One association of a CK type as the "Association" dropdown offers it. */
7013
+ interface ScopeAssociationOption {
7014
+ /** `<direction>|<roleId>|<baseTargetCkTypeId>`, or {@link OTHER_ASSOCIATION}. */
7015
+ key: string;
7016
+ roleId: string;
7017
+ direction: 'in' | 'out';
7018
+ /** Target type of the association in the CK metadata (base type for the target-type picker). */
7019
+ baseTargetCkTypeId: string;
7020
+ label: string;
7021
+ }
7022
+ /** Editor row of one hop. */
7023
+ interface HopRow {
7024
+ roleId: string;
7025
+ direction: 'in' | 'out';
7026
+ targetCkTypeId: string;
7027
+ targetItem: CkTypeSelectorItem | null;
7028
+ /** Key of the chosen association, or {@link OTHER_ASSOCIATION} for free text. */
7029
+ associationKey: string;
7030
+ }
7031
+ /**
7032
+ * Hop list of an entity selector's child scope (AB#7723; wireframe agreed by
7033
+ * Freya, AB#7723 comment 6625315). Each hop picks an association of its source
7034
+ * type from the CK metadata (role + direction + base target in one entry, or
7035
+ * "Other role…" for free text) and a target type restricted to types derived
7036
+ * from the association's target. The source type of hop 1 is the selector's
7037
+ * CK type, of every later hop the previous hop's target type. Hops can be
7038
+ * added (at most {@link MAX_SCOPE_HOPS}), removed and moved up/down.
7039
+ *
7040
+ * Two-way bindable; emits the hops as configured (validation is the host's,
7041
+ * see `scopeHopsValidationError`):
7042
+ * ```html
7043
+ * <mm-entity-selector-scope-path-editor
7044
+ * [sourceCkTypeId]="ckTypeId"
7045
+ * [(hops)]="hops">
7046
+ * </mm-entity-selector-scope-path-editor>
7047
+ * ```
7048
+ */
7049
+ declare class EntitySelectorScopePathEditorComponent {
7050
+ private readonly rolesGQL;
7051
+ private readonly cdr;
7052
+ hopsChange: EventEmitter<EntitySelectorScopeHop[]>;
7053
+ private hopCards?;
7054
+ protected rows: HopRow[];
7055
+ protected readonly plusIcon: _progress_kendo_svg_icons.SVGIcon;
7056
+ protected readonly arrowUpIcon: _progress_kendo_svg_icons.SVGIcon;
7057
+ protected readonly arrowDownIcon: _progress_kendo_svg_icons.SVGIcon;
7058
+ protected readonly trashIcon: _progress_kendo_svg_icons.SVGIcon;
7059
+ private _sourceCkTypeId;
7060
+ private lastEmitted;
7061
+ private readonly associations;
7062
+ /** CK type of the picked entity — the source type of hop 1. */
7063
+ set sourceCkTypeId(value: string | null | undefined);
7064
+ get sourceCkTypeId(): string;
7065
+ /** The configured hops (one-hop form = one hop). */
7066
+ set hops(value: EntitySelectorScopeHop[] | null | undefined);
7067
+ /** Maximum hop count (getter: relative imports must not initialise fields, see CLAUDE.md). */
7068
+ get maxHops(): number;
7069
+ get canAddHop(): boolean;
7070
+ /** "Test/Site → Test/System → Test/Device". */
7071
+ get pathLabel(): string;
7072
+ /** True when the association metadata of any shown source type could not be loaded. */
7073
+ get metadataFailed(): boolean;
7074
+ /** Source type of hop `index`. */
7075
+ sourceTypeOf(index: number): string;
7076
+ /** Dropdown entries of hop `index`: the source type's associations plus "Other role…". */
7077
+ associationOptions(index: number): ScopeAssociationOption[];
7078
+ /** True when hop `index` offers the association dropdown (metadata loaded with ≥1 association). */
7079
+ hasAssociationList(index: number): boolean;
7080
+ /** True when hop `index` shows the free-text role and direction fields. */
7081
+ isFreeText(index: number): boolean;
7082
+ /** Base type the target-type picker of hop `index` is restricted to (undefined = any type). */
7083
+ baseTargetOf(index: number): string | undefined;
7084
+ /**
7085
+ * Warning of hop `index` when its role is not an association of its (new)
7086
+ * source type — after a reorder, a removal or a changed earlier target. The
7087
+ * values are kept; it does not block saving.
7088
+ */
7089
+ associationWarning(index: number): string;
7090
+ /** Validation message of hop `index`: an incomplete hop blocks saving (see `scopeHopsValidationError`). */
7091
+ hopError(index: number): string;
7092
+ isRoleInvalid(index: number): boolean;
7093
+ isTargetInvalid(index: number): boolean;
7094
+ addHop(): void;
7095
+ removeHop(index: number): void;
7096
+ moveHop(index: number, delta: -1 | 1): void;
7097
+ onAssociationChanged(index: number, key: string): void;
7098
+ onRoleChanged(index: number, roleId: string): void;
7099
+ onDirectionChanged(index: number, direction: 'in' | 'out'): void;
7100
+ onTargetSelected(index: number, ckType: CkTypeSelectorItem): void;
7101
+ onTargetCleared(index: number): void;
7102
+ private emit;
7103
+ private loadOf;
7104
+ /**
7105
+ * Matches every hop's role/direction to an entry of its source type's
7106
+ * associations (loading missing metadata); a hop whose association is not
7107
+ * listed switches to "Other role…" with its values kept.
7108
+ */
7109
+ private syncAssociationKeys;
7110
+ private loadAssociations;
7111
+ /** Keeps the keyboard focus on a moved hop (wireframe change 4). */
7112
+ private focusHop;
7113
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EntitySelectorScopePathEditorComponent, never>;
7114
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EntitySelectorScopePathEditorComponent, "mm-entity-selector-scope-path-editor", never, { "sourceCkTypeId": { "alias": "sourceCkTypeId"; "required": false; }; "hops": { "alias": "hops"; "required": false; }; }, { "hopsChange": "hopsChange"; }, never, never, true, never>;
6555
7115
  }
6556
7116
 
6557
7117
  /**
@@ -6569,18 +7129,34 @@ interface EntitySelectorClearEvent {
6569
7129
  }
6570
7130
  /**
6571
7131
  * Toolbar component that renders entity select inputs for each configured entity selector.
6572
- * Creates data sources per CK type and emits selection/clear events.
7132
+ * Creates data sources per CK type and picker filter (AB#7724) and emits selection/clear events.
6573
7133
  */
6574
7134
  declare class EntitySelectorToolbarComponent implements OnChanges {
6575
7135
  private readonly getEntitiesByCkTypeGQL;
7136
+ private readonly variableService;
6576
7137
  entitySelectors: EntitySelectorConfig[];
7138
+ /**
7139
+ * Board variables substituted into the selectors' picker filters (AB#7724),
7140
+ * the same substitution widget filters get.
7141
+ */
7142
+ variables: MeshBoardVariable[];
6577
7143
  entitySelected: EventEmitter<EntitySelectorEvent>;
6578
7144
  entityCleared: EventEmitter<EntitySelectorClearEvent>;
6579
7145
  private dataSourceCache;
6580
7146
  private dialogDataSourceCache;
6581
7147
  protected selectorDataSources: Map<string, RuntimeEntitySelectDataSource>;
6582
7148
  protected selectorDialogDataSources: Map<string, RuntimeEntityDialogDataSource>;
7149
+ protected selectorMessages: Map<string, Partial<EntitySelectInputMessages>>;
6583
7150
  ngOnChanges(changes: SimpleChanges): void;
7151
+ /** Texts of the selector's picker: a filtered picker explains its empty list (AB#7724). */
7152
+ getMessages(selector: EntitySelectorConfig): Partial<EntitySelectInputMessages>;
7153
+ /** Title of the selector's search dialog; marks a filtered picker (AB#7724). */
7154
+ getDialogTitle(selector: EntitySelectorConfig): string;
7155
+ /**
7156
+ * True when the selector renders a picker. Hidden selectors and followers
7157
+ * (AB#7722) never do; a follower's pick is derived from its leader.
7158
+ */
7159
+ showsInToolbar(selector: EntitySelectorConfig): boolean;
6584
7160
  /**
6585
7161
  * Returns the data source for a selector.
6586
7162
  */
@@ -6598,11 +7174,17 @@ declare class EntitySelectorToolbarComponent implements OnChanges {
6598
7174
  */
6599
7175
  onEntityCleared(selectorId: string): void;
6600
7176
  /**
6601
- * Creates or retrieves cached data sources for each selector.
7177
+ * Creates or retrieves cached data sources for each selector. Selectors of
7178
+ * the same CK type and the same resolved filter share their data sources; a
7179
+ * selector without filter uses the plain query, exactly as before AB#7724.
7180
+ * Entries no selector uses any more (e.g. after a filter variable changed)
7181
+ * are dropped, so the caches never outgrow the current selectors.
6602
7182
  */
6603
7183
  private updateDataSources;
7184
+ /** Number of cached data source pairs (for tests). */
7185
+ get cachedDataSourceCount(): number;
6604
7186
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EntitySelectorToolbarComponent, never>;
6605
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EntitySelectorToolbarComponent, "mm-entity-selector-toolbar", never, { "entitySelectors": { "alias": "entitySelectors"; "required": false; }; }, { "entitySelected": "entitySelected"; "entityCleared": "entityCleared"; }, never, never, true, never>;
7187
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EntitySelectorToolbarComponent, "mm-entity-selector-toolbar", never, { "entitySelectors": { "alias": "entitySelectors"; "required": false; }; "variables": { "alias": "variables"; "required": false; }; }, { "entitySelected": "entitySelected"; "entityCleared": "entityCleared"; }, never, never, true, never>;
6606
7188
  }
6607
7189
 
6608
7190
  /**
@@ -6626,6 +7208,28 @@ interface WidgetPlacement {
6626
7208
  rowSpan: number;
6627
7209
  }
6628
7210
 
7211
+ /**
7212
+ * The period a host page sets on an embedded MeshBoard (`mm-meshboard-view [timeRange]`, AB#7582):
7213
+ * two exact instants, half-open `[from, to)`. A string must be an RFC 3339 date-time with an
7214
+ * explicit offset - see {@link parseHostTimeRange}.
7215
+ */
7216
+ interface MeshBoardHostTimeRange {
7217
+ from: Date | string;
7218
+ to: Date | string;
7219
+ }
7220
+ /**
7221
+ * Who controls the board's period: `board` (default) shows the board's own time-range picker;
7222
+ * `host` hides the picker and its reset button because the host page owns the period.
7223
+ */
7224
+ type MeshBoardTimeFilterControl = 'board' | 'host';
7225
+ /**
7226
+ * Parses the host's `timeRange` input. `undefined`/`null` = the host sets no period.
7227
+ * Never snaps or converts: the instants are taken as given. `Date` objects are accepted as they
7228
+ * are; strings must be RFC 3339 with an offset, e.g. `2026-03-28T05:00:00Z` or
7229
+ * `2026-03-28T06:00:00+01:00` (see {@link RFC3339}).
7230
+ */
7231
+ declare function parseHostTimeRange(value: MeshBoardHostTimeRange | null | undefined): HostTimeRangeState | undefined;
7232
+
6629
7233
  interface WidgetPositionUpdate {
6630
7234
  id: string;
6631
7235
  title: string;
@@ -6734,6 +7338,41 @@ declare class MeshBoardViewComponent implements OnInit, OnDestroy, HasUnsavedCha
6734
7338
  readonly chrome: _angular_core.InputSignal<MeshBoardChrome | undefined>;
6735
7339
  private readonly routeChrome;
6736
7340
  protected readonly effectiveChrome: _angular_core.Signal<MeshBoardChrome>;
7341
+ /**
7342
+ * The period set by the host page (AB#7582): two exact instants, half-open `[from, to)`, as
7343
+ * `Date` objects or ISO 8601 strings with a zone designator. While set (and the board's time
7344
+ * filter is enabled) the view publishes exactly these instants as `$timeRangeFrom` /
7345
+ * `$timeRangeTo` and as the stream-data window - no day snapping, no zone conversion - and
7346
+ * ignores the `tf_*` query parameters and the stored/default selection. It writes no `tf_*`
7347
+ * parameters and causes no unsaved changes. A change reloads the widgets once; `undefined`
7348
+ * returns the board to its own selection. Day rules (e.g. a 06:00 gas day) belong to the host.
7349
+ * An invalid range (unparseable, or `from >= to`) sends no stream-data query and logs one
7350
+ * console error. A board with the time filter disabled ignores the input.
7351
+ */
7352
+ readonly timeRange: _angular_core.InputSignal<MeshBoardHostTimeRange | undefined>;
7353
+ /**
7354
+ * Who controls the period: `board` (default, unchanged behaviour) shows the board's time-range
7355
+ * picker; `host` hides the picker and its reset button - entity selectors and actions stay.
7356
+ * While `timeRange` is set the picker is hidden and its events are ignored either way.
7357
+ */
7358
+ readonly timeFilterControl: _angular_core.InputSignal<MeshBoardTimeFilterControl>;
7359
+ /** The parsed `timeRange` input; `undefined` = the host sets no period. */
7360
+ protected readonly parsedHostTimeRange: _angular_core.Signal<HostTimeRangeState | undefined>;
7361
+ /** True while the host owns the period (a valid or an invalid `timeRange` is set). */
7362
+ protected readonly isHostTimeRangeActive: _angular_core.Signal<boolean>;
7363
+ /** Whether the board's own time-range picker (and its reset button) is rendered. */
7364
+ protected readonly showTimeRangePicker: _angular_core.Signal<boolean>;
7365
+ /** The host range last applied to the state service (to reload only on a real change). */
7366
+ private appliedHostTimeRange;
7367
+ /** The invalid host range already reported, so a board switch does not log it again. */
7368
+ private reportedInvalidHostTimeRange;
7369
+ /**
7370
+ * Set once the host has owned the period: the `tf_*` parameters of the URL this view was opened
7371
+ * with are stale from then on and are not applied again when `timeRange` goes back to undefined.
7372
+ */
7373
+ private hostHasOwnedPeriod;
7374
+ /** Set in ngOnDestroy; the async initial load stops touching shared state after it (AB#7582). */
7375
+ private destroyed;
6737
7376
  protected readonly meshBoardPageLink: _angular_core.Signal<string>;
6738
7377
  protected readonly hasWidgets: _angular_core.Signal<boolean>;
6739
7378
  /** Widgets shown: outside edit mode those that reported "nothing for this viewer" are collapsed (AB#5558). */
@@ -6756,6 +7395,8 @@ declare class MeshBoardViewComponent implements OnInit, OnDestroy, HasUnsavedCha
6756
7395
  private readonly _urlTimeSelection;
6757
7396
  protected readonly initialTimeSelection: _angular_core.Signal<TimeRangeSelection$1 | undefined>;
6758
7397
  protected readonly entitySelectorsConfig: _angular_core.Signal<EntitySelectorConfig[]>;
7398
+ /** Board variables substituted into the selectors' picker filters (AB#7724). */
7399
+ protected readonly boardVariables: _angular_core.Signal<_meshmakers_octo_meshboard.MeshBoardVariable[]>;
6759
7400
  protected readonly hasEntitySelectors: _angular_core.Signal<boolean>;
6760
7401
  protected readonly unselectedToolbarSelectors: _angular_core.Signal<EntitySelectorConfig[]>;
6761
7402
  /**
@@ -6778,7 +7419,12 @@ declare class MeshBoardViewComponent implements OnInit, OnDestroy, HasUnsavedCha
6778
7419
  * fail with a NavigationError (AB#4457).
6779
7420
  */
6780
7421
  private updateUrlWithRtId;
6781
- /** The active time-filter selection to mirror into the URL, or null when the filter is off. */
7422
+ /**
7423
+ * The active time-filter selection to mirror into the URL, or null when the filter is off or
7424
+ * the host owns the period or controls the filter (AB#7582: the view then writes no tf_*
7425
+ * parameters; with `timeFilterControl='host'` and no `timeRange` the board selection still
7426
+ * applies, but the URL is the host's).
7427
+ */
6782
7428
  private activeTimeFilterSelection;
6783
7429
  ngOnInit(): Promise<void>;
6784
7430
  /**
@@ -6802,8 +7448,22 @@ declare class MeshBoardViewComponent implements OnInit, OnDestroy, HasUnsavedCha
6802
7448
  /**
6803
7449
  * Initializes time filter variables based on URL query params or stored selection.
6804
7450
  * URL params take precedence over stored selection to support page reload.
7451
+ * A period set by the host (`timeRange`, AB#7582) takes precedence over both.
6805
7452
  */
6806
7453
  private initializeTimeFilterVariables;
7454
+ /**
7455
+ * Hands the host period to the state service and publishes `$timeRangeFrom` / `$timeRangeTo`
7456
+ * as exactly its instants (AB#7582). Returns true while the host owns the period, so the
7457
+ * caller skips the board's own selection. With the time filter disabled the period is only
7458
+ * stored (the state service ignores it then) and nothing is logged.
7459
+ */
7460
+ private applyHostTimeRange;
7461
+ /**
7462
+ * Applies a change of the `timeRange` input after the initial load (AB#7582): the host period,
7463
+ * or the board's own selection again when the input went back to `undefined`. Reloads the
7464
+ * widgets once; an equal period (same instants) changes nothing.
7465
+ */
7466
+ private onHostTimeRangeChanged;
6807
7467
  /**
6808
7468
  * Recomputes the active time-filter range from the current selection on the
6809
7469
  * board's (possibly just-changed) timezone mode and republishes the
@@ -6869,8 +7529,35 @@ declare class MeshBoardViewComponent implements OnInit, OnDestroy, HasUnsavedCha
6869
7529
  * Programmatically clears an entity selector value from outside the component.
6870
7530
  */
6871
7531
  clearEntitySelector(selectorId: string): void;
7532
+ /**
7533
+ * Clears one selector's pick, variables and scope state. Without a pick bound
7534
+ * widgets fall back to the persisted scope (AB#7721).
7535
+ */
7536
+ private clearSelectorPick;
7537
+ /**
7538
+ * The leader `leaderId` has no pick any more: each of its followers resolves
7539
+ * its own `defaultRtId`, or — without one — has no pick and no scope
7540
+ * (AB#7722). Followers with a default are marked pending synchronously.
7541
+ * Returns a promise for the default resolutions, or `null` when there are none.
7542
+ */
7543
+ private resetFollowersOf;
6872
7544
  /** Resolution errors for runtime entity variables */
6873
7545
  readonly variableResolutionErrors: _angular_core.Signal<_meshmakers_octo_meshboard.VariableResolutionError[]>;
7546
+ private readonly messages;
7547
+ /**
7548
+ * One notice per entity selector whose stream-data scope could not be
7549
+ * resolved (AB#7721), so "nothing in scope" (empty widgets, no notice) and
7550
+ * "lookup failed" (empty widgets plus this notice) are distinguishable.
7551
+ */
7552
+ protected readonly scopeResolutionErrors: _angular_core.Signal<{
7553
+ selectorId: string;
7554
+ message: string;
7555
+ }[]>;
7556
+ /**
7557
+ * Per-selector sequence number of the latest scope resolution, so a slower
7558
+ * resolution of an earlier pick never overwrites the scope of a newer pick.
7559
+ */
7560
+ private readonly scopeRequestSeq;
6874
7561
  /**
6875
7562
  * Handles time range change from the time range picker.
6876
7563
  * No-op: refresh is triggered by onTimeSelectionChange to ensure variables are updated first.
@@ -6992,19 +7679,63 @@ declare class MeshBoardViewComponent implements OnInit, OnDestroy, HasUnsavedCha
6992
7679
  */
6993
7680
  private initializeEntitySelectors;
6994
7681
  /**
6995
- * Resolves variables for an entity selector by fetching entity attributes.
7682
+ * The initial pick of each entity selector. Priority: route data > URL
7683
+ * params > defaultRtId. Selectors without a pick are left out.
7684
+ *
7685
+ * Followers (AB#7722) never read route data or the URL: a follower takes its
7686
+ * leader's initial pick (`viaLeader: true`, resolved together with the
7687
+ * leader) and falls back to its own `defaultRtId` only when the leader has
7688
+ * none. An unknown or chained leader counts as "leader has no pick"; with
7689
+ * `warn` set this logs a console warning.
7690
+ */
7691
+ private initialEntitySelectorPicks;
7692
+ /**
7693
+ * Marks the scope of every selector that has an initial pick as pending
7694
+ * (AB#7721). Called synchronously right after a board is loaded, before
7695
+ * change detection renders its widgets, so a bound stream-data widget starts
7696
+ * in its loading state instead of querying the persisted (unscoped) scope.
7697
+ * Selectors without a pick stay without scope state (persisted scope).
7698
+ */
7699
+ private primeEntitySelectorScopes;
7700
+ /**
7701
+ * Resolves variables for an entity selector by fetching entity attributes,
7702
+ * then its stream-data scope.
7703
+ *
7704
+ * A leader's pick is also the pick of all its followers (AB#7722): they are
7705
+ * marked pending together with the leader, the picked entity is fetched
7706
+ * once, and each follower gets its own variables (its attribute mappings,
7707
+ * `<id>_rtId`, `<id>_rtCkTypeId`), its own scope (its `childScope`) and the
7708
+ * leader's selection. Returns the picked entity's display name.
6996
7709
  */
6997
7710
  private resolveEntitySelectorVariables;
7711
+ /**
7712
+ * The variables one selector derives from the picked entity: its attribute
7713
+ * mappings plus the auto-exposed `<id>_rtId` and `<id>_rtCkTypeId`.
7714
+ */
7715
+ private selectorVariables;
6998
7716
  /**
6999
7717
  * Resolves the set of source rtIds that a stream-data widget bound to this
7000
7718
  * selector should be scoped to, and caches them on the state service.
7001
7719
  *
7002
- * When the selector defines a {@link EntitySelectorChildScope}, the picked
7003
- * entity's children of `targetCkTypeId` reached via `roleId`/`direction`
7004
- * become the scope (e.g. MeteringPoint → its EnergyMeasurement rtIds). With
7005
- * no childScope, the picked entity's own rtId is the scope (direct keying).
7720
+ * - No {@link EntitySelectorChildScope}: the picked entity's own rtId is the
7721
+ * scope (direct keying).
7722
+ * - One-hop form (top-level fields): the picked entity's targets of
7723
+ * `targetCkTypeId` reached via `roleId`/`direction` (e.g. MeteringPoint →
7724
+ * its EnergyMeasurement rtIds) — exactly as before AB#7723.
7725
+ * - `path` (AB#7723): hop by hop, each hop one batched request over all
7726
+ * entities the previous hop reached; the scope is the distinct rtIds of the
7727
+ * last hop. An empty hop ends the resolution with an empty scope; a failed
7728
+ * hop, or an invalid path (more than 5 hops, a hop without role or target
7729
+ * type), is a failed scope (AB#7721).
7006
7730
  */
7007
7731
  private resolveEntitySelectorScopeRtIds;
7732
+ /**
7733
+ * Starts the scope resolution of a new pick: marks the scope pending and
7734
+ * returns the sequence number that identifies this resolution (AB#7721).
7735
+ */
7736
+ private beginScopeResolution;
7737
+ /** Marks the scope failed — unless a newer pick has started resolving meanwhile. */
7738
+ private failScopeResolution;
7008
7739
  /**
7009
7740
  * Writes entity selector selections to URL query parameters.
7010
7741
  * Format: es_<selectorId>=<rtId>
@@ -7026,7 +7757,7 @@ declare class MeshBoardViewComponent implements OnInit, OnDestroy, HasUnsavedCha
7026
7757
  */
7027
7758
  saveChanges(): Promise<boolean>;
7028
7759
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<MeshBoardViewComponent, never>;
7029
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<MeshBoardViewComponent, "mm-meshboard-view", never, { "headerMode": { "alias": "headerMode"; "required": false; "isSignal": true; }; "chrome": { "alias": "chrome"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.UnsavedChangesDirective; inputs: {}; outputs: {}; }]>;
7760
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MeshBoardViewComponent, "mm-meshboard-view", never, { "headerMode": { "alias": "headerMode"; "required": false; "isSignal": true; }; "chrome": { "alias": "chrome"; "required": false; "isSignal": true; }; "timeRange": { "alias": "timeRange"; "required": false; "isSignal": true; }; "timeFilterControl": { "alias": "timeFilterControl"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.UnsavedChangesDirective; inputs: {}; outputs: {}; }]>;
7030
7761
  }
7031
7762
 
7032
7763
  /**
@@ -8888,5 +9619,5 @@ declare function pipelineExecutionInputs(children: (unknown | null)[] | null | u
8888
9619
  */
8889
9620
  declare function countPipelineExecutions(pipelines: PipelineExecutionInput[], now?: number): PipelineExecutionCounts;
8890
9621
 
8891
- export { ADAPTER_OFFLINE_GRACE_MS, ATTENTION_SEVERITY_ORDER, AdaptersAttentionProvider, AddWidgetDialogComponent, AiInsightsConfigDialogComponent, AiInsightsService, AiInsightsWidgetComponent, AlertBannerConfigDialogComponent, AlertBannerWidgetComponent, AlertListConfigDialogComponent, AlertListWidgetComponent, AssociationsConfigDialogComponent, AttentionListConfigDialogComponent, AttentionListWidgetComponent, AutoRefreshTimerService, BUILT_IN_ATTENTION_PROVIDERS, BarChartConfigDialogComponent, BarChartWidgetComponent, BlueprintUpdatesAttentionProvider, COCKPIT_ADAPTER_LIMIT, COCKPIT_ATTENTION_PROVIDERS, COCKPIT_BLUEPRINT_CATALOG_LIMIT, COCKPIT_CHILD_TENANT_IDS, COCKPIT_DATA_FLOW_LIMIT, COCKPIT_EXPLAIN_HANDLER, COCKPIT_FAILED_EXECUTIONS_OPTIONS, COCKPIT_KPI_GATES, COCKPIT_KPI_SLOW_LOADING_MS, COCKPIT_LINK_RESOLVER, COCKPIT_RECENT_ITEMS, COCKPIT_ROLES, COCKPIT_SERVICE_NAMES, COCKPIT_VERSION_SOURCE, COCKPIT_VIEWER_ACCESS, COCKPIT_WIDGET_MESSAGES, COCKPIT_WIDGET_TYPES, CkModelsResolveFailedAttentionProvider, CockpitAdapterStatesService, CockpitAttentionService, CockpitBlueprintStatusService, CockpitChildTenantsService, CockpitCkModelStatesService, CockpitContextService, CockpitDataFlowExecutionsService, CockpitKpiConfigDialogComponent, CockpitKpiService, CockpitKpiWidgetComponent, CockpitServiceHealthService, DAY_MS, DEFAULT_ATTENTION_MAX_ITEMS, DEFAULT_COCKPIT_WIDGET_MESSAGES, DEFAULT_FAILED_EXECUTIONS_OPTIONS, DEFAULT_MESHBOARD_MESSAGES, DEFAULT_RECENT_ITEMS_MAX, DEFAULT_TIME_ZONE_MODE, DashboardDataService, DashboardGridService, EditModeStateService, EditWidgetDialogComponent, EntityAssociationsWidgetComponent, EntityCardConfigDialogComponent, EntityCardWidgetComponent, EntityDetailDialogComponent, EntitySelectorEditorComponent, EntitySelectorToolbarComponent, FALLBACK_SERIES_COLORS, FailedExecutionsAttentionProvider, FeaturesNotInstalledAttentionProvider, GaugeConfigDialogComponent, GaugeWidgetComponent, HISTOGRAM_HOURS, HOUR_MS, HeatmapConfigDialogComponent, HeatmapWidgetComponent, KPI_ERROR_TEXT, KpiConfigDialogComponent, KpiWidgetComponent, LazyMarkdownComponent, LineChartConfigDialogComponent, LineChartWidgetComponent, MAX_RECENT_ITEMS, MESHBOARD_CHROME_ROUTE_DATA, MESHBOARD_DESCRIPTION_MARKER, MESHBOARD_EDIT_QUERY_PARAM, MESHBOARD_HEADER_MODE_ROUTE_DATA, MESHBOARD_LABEL_RESOLVER, MESHBOARD_MESSAGES, MESHBOARD_OPTIONS, MESHBOARD_TENANT_ID_PROVIDER, MarkdownConfigDialogComponent, MarkdownWidgetComponent, MeshBoardDataService, MeshBoardGridService, MeshBoardManagerDialogComponent, MeshBoardPersistenceService, MeshBoardSettingsDialogComponent, MeshBoardSettingsResult, MeshBoardStateService, MeshBoardViewComponent, NOT_AVAILABLE_TEXT, PieChartConfigDialogComponent, PieChartWidgetComponent, QueryExecutorService, QuerySelectorComponent, RecentItemsConfigDialogComponent, RecentItemsWidgetComponent, RuntimeEntitySelectorComponent, SERVICE_MANAGED_BLUEPRINT_PREFIX, STATE_STATUS_BY_KEY, ServiceHealthConfigDialogComponent, ServiceHealthWidgetComponent, ServicesHealthAttentionProvider, StatsGridConfigDialogComponent, StatsGridWidgetComponent, StatusIndicatorConfigDialogComponent, StatusIndicatorWidgetComponent, StatusListConfigDialogComponent, StatusListWidgetComponent, SummaryCardConfigDialogComponent, SummaryCardWidgetComponent, TableConfigDialogComponent, TableWidgetComponent, TableWidgetDataSourceDirective, UnregisteredPoolsAttentionProvider, WidgetFactoryService, WidgetGroupComponent, WidgetGroupConfigDialogComponent, WidgetNotConfiguredComponent, WidgetRegistryService, adapterKpi, adaptersInError, adaptersOffline, blueprintUpdatesKpi, buildHourlyHistogram, categoryStatus, chartSeriesColors, ckModelKpi, classifyQuery, compareBlueprintVersions, compareMeshBoardNavigation, countFlowExecutions, countLabel, countPipelineExecutions, enabledButNotInstalled, executionKpi, failedExecutionsSeverity, formatCockpitMessage, formatCount, humanizeCategory, isAdapterAtRest, isAdapterExpectedToRun, isAdapterOnline, isCockpitWidgetType, isMeshBoardChrome, isMeshBoardHeaderMode, isServiceConfigured, joinEncodedDescription, kpiKindOf, latestStatisticsUpdate, legacyCockpitLinkTarget, loadNgxMarkdown, nameList, newMeshBoardConfig, normalizeNavigation, observeThemeChanges, pipelineExecutionInputs, plural, provideCockpitWidgetHost, provideCockpitWidgets, provideDefaultWidgets, provideMeshBoard, provideMeshBoardMessages, provideProcessWidget, provideWidgetRegistrations, queryFamily, readMeshBoardNavigation, recentRelativeTime, registerCockpitWidgets, registerDefaultWidgets, registerProcessWidget, resolveChartColor, resolveCockpitWidgetMessages, resolveMeshBoardChrome, resolveMeshBoardHeaderMode, resolveMeshBoardLabel, resolveMeshBoardMessages, selectProviders, serviceStateText, servicesHealthKpi, sortAttentionFindings, sparklineGeometry, splitBlueprintId, splitEncodedDescription, statusColor, summarizeAdapterOnline, tenantCountKpi, toBlueprintStatus, toServiceHealthStatus, truncationNote, versionKpi, withMeshBoardNavigation };
8892
- export type { AdapterOnlineFields, AdapterOnlineSummary, AdapterStatusWidgetConfig, AggregationDataSource, AggregationQuery, AggregationType, AiInsightsConfigResult, AiInsightsWidgetConfig, AlertBannerConfigResult, AlertBannerWidgetConfig, AlertListConfigResult, AlertListWidgetConfig, AnyWidgetConfig, AssociationsConfigResult, AttentionContext, AttentionFinding, AttentionLink, AttentionListConfigResult, AttentionListWidgetConfig, AttentionProvider, AttentionProviderInfo, AttentionSeverity, AttentionState, BarChartColorThreshold, BarChartConfigResult, BarChartSeries, BarChartType, BarChartWidgetConfig, BaseWidgetConfig, BlueprintUpdatesWidgetConfig, CategoryStatus, CategoryValueItem, ChartReferenceLine, CkModelStateWidgetConfig, CkQueryResult, CkQueryTarget, CkTypeAttributeInfo, CockpitAdapterState, CockpitAdapterStates, CockpitBlueprintStatus, CockpitBlueprintUpdate, CockpitChildTenants, CockpitCkModelCounts, CockpitDataFlowExecutions, CockpitDataFlowRow, CockpitExecutionCounts, CockpitExplainHandler, CockpitExplainTarget, CockpitKpi, CockpitKpiConfigResult, CockpitKpiKind, CockpitKpiResult, CockpitKpiStatus, CockpitKpiWidgetConfig, CockpitKpiWidgetOptions, CockpitLinkQueryParams, CockpitLinkResolver, CockpitLinkTarget, CockpitRecentItem, CockpitRecentItemKind, CockpitRecentItemsSource, CockpitResolvedLink, CockpitRouteLinkTarget, CockpitServiceHealth, CockpitServiceHealthStatus, CockpitServiceKey, CockpitVersionEntry, CockpitVersionSource, CockpitViewerAccess, CockpitWidgetHost, CockpitWidgetMessages, CockpitWidgetMessagesSource, CockpitWidgetType, ConfigDialogResult, ConfigResultApplier, ConstructionKitQueryDataSource, DashboardConfig, DashboardWidget, DataSource, DataSourceType, DiagramPropertyMapping, EncodedDescription, EntityAssociation, EntityAttribute, EntityCardConfigResult, EntityCardWidgetConfig, EntityListWidget, EntitySelectorAttributeMapping, EntitySelectorChildScope, EntitySelectorClearEvent, EntitySelectorConfig, EntitySelectorEvent, EntityWidget, EntityWithAssociationsWidgetConfig, FailedExecutionsAttentionOptions, GaugeConfigResult, GaugeRange, GaugeType, GaugeWidgetConfig, GridCell, GridPosition, GroupChildWidgetType, GroupedDataItem, HeatmapAggregation, HeatmapColorMode, HeatmapColorScheme, HeatmapConfigResult, HeatmapWidgetConfig, HourlyExecutionBucket, HourlyHistogramOptions, KpiConfigResult, KpiDataSourceType, KpiQueryMode, KpiValueMode, KpiWidgetConfig, LatestExecutionInput, LineChartConfigResult, LineChartType, LineChartWidgetConfig, MarkdownConfigResult, MarkdownTextAlign, MarkdownWidgetConfig, MeshBoardChrome, MeshBoardConfig, MeshBoardHeaderMode, MeshBoardLabelKind, MeshBoardLabelRequest, MeshBoardLabelResolver, MeshBoardMessages, MeshBoardMessagesSource, MeshBoardNavigationConfig, MeshBoardOptions, MeshBoardTimeFilterConfig, MeshBoardTimeZoneMode, MeshBoardVariable, MeshBoardVariableSource, MeshBoardVariableType, ParentAssociationMode, PersistedDashboard, PersistedMeshBoard, PersistedWidget, PersistedWidgetData, PersistentQueryCellMode, PersistentQueryCellSource, PersistentQueryDataSource, PersistentQueryItem, PieChartConfigResult, PieChartLabelPosition, PieChartType, PieChartWidgetConfig, PipelineExecutionCounts, PipelineExecutionInput, PipelineExecutionsWidgetConfig, PipelineStatisticsInput, ProcessWidgetConfig, Quarter, QueryCell, QueryClassification, QueryColumn, QueryColumnInfo, QueryColumnItem, QueryExecutionOptions, QueryExecutionResult, QueryFamily, QueryKind, QueryResultRow, RawHourBucket, RecentItemsConfigResult, RecentItemsWidgetConfig, RelativeTimeUnit, RepeaterDataItem, RepeaterQueryDataSource, RuntimeEntityData, RuntimeEntityDataSource, RuntimeEntitySelectorValue, SeriesAggregationFunction, SeriesResolutionResult, ServiceCallDataSource, ServiceCallType, ServiceHealthConfigResult, ServiceHealthWidgetConfig, ServicesHealthWidgetConfig, SparklineGeometry, StatColor, StatItem, StaticDataSource, StatsGridConfigResult, StatsGridWidgetConfig, StatusIndicatorConfigResult, StatusIndicatorWidgetConfig, StatusListConfigResult, StatusListWidgetConfig, StreamDataExecutionArgs, SummaryCardConfigResult, SummaryCardTile, SummaryCardWidgetConfig, TableColumn, TableColumnStatusIconMapping, TableConfigResult, TableFilterConfig, TableSortConfig, TableWidgetConfig, TargetEntityWithAttributes, TenantCountWidgetConfig, TimeRangePickerConfig, TimeRangeSelection, TimeRangeType, UpdateDashboardResult, VariableResolutionError, VersionInfoWidgetConfig, WidgetConfig, WidgetConfigDialog, WidgetConfigDialogSize, WidgetConfigResult, WidgetCreationOptions, WidgetDataSource, WidgetFilterConfig, WidgetGroupAttributeMappings, WidgetGroupChildTemplate, WidgetGroupConfig, WidgetGroupConfigResult, WidgetGroupLayout, WidgetPersistenceData, WidgetPositionUpdate, WidgetRegistration, WidgetType, WidgetZone };
9622
+ export { ADAPTER_OFFLINE_GRACE_MS, ASSOCIATION_HOP_SOURCE_BATCH, ASSOCIATION_HOP_TARGETS_PER_SOURCE, ATTENTION_SEVERITY_ORDER, AdaptersAttentionProvider, AddWidgetDialogComponent, AiInsightsConfigDialogComponent, AiInsightsService, AiInsightsWidgetComponent, AlertBannerConfigDialogComponent, AlertBannerWidgetComponent, AlertListConfigDialogComponent, AlertListWidgetComponent, AssociationsConfigDialogComponent, AttentionListConfigDialogComponent, AttentionListWidgetComponent, AutoRefreshTimerService, BUILT_IN_ATTENTION_PROVIDERS, BarChartConfigDialogComponent, BarChartWidgetComponent, BlueprintUpdatesAttentionProvider, COCKPIT_ADAPTER_LIMIT, COCKPIT_ATTENTION_PROVIDERS, COCKPIT_BLUEPRINT_CATALOG_LIMIT, COCKPIT_CHILD_TENANT_IDS, COCKPIT_DATA_FLOW_LIMIT, COCKPIT_EXPLAIN_HANDLER, COCKPIT_FAILED_EXECUTIONS_OPTIONS, COCKPIT_KPI_GATES, COCKPIT_KPI_SLOW_LOADING_MS, COCKPIT_LINK_RESOLVER, COCKPIT_RECENT_ITEMS, COCKPIT_ROLES, COCKPIT_SERVICE_NAMES, COCKPIT_VERSION_SOURCE, COCKPIT_VIEWER_ACCESS, COCKPIT_WIDGET_MESSAGES, COCKPIT_WIDGET_TYPES, CkModelsResolveFailedAttentionProvider, CockpitAdapterStatesService, CockpitAttentionService, CockpitBlueprintStatusService, CockpitChildTenantsService, CockpitCkModelStatesService, CockpitContextService, CockpitDataFlowExecutionsService, CockpitKpiConfigDialogComponent, CockpitKpiService, CockpitKpiWidgetComponent, CockpitServiceHealthService, DAY_MS, DEFAULT_ATTENTION_MAX_ITEMS, DEFAULT_COCKPIT_WIDGET_MESSAGES, DEFAULT_FAILED_EXECUTIONS_OPTIONS, DEFAULT_MESHBOARD_MESSAGES, DEFAULT_RECENT_ITEMS_MAX, DEFAULT_TIME_ZONE_MODE, DashboardDataService, DashboardGridService, EditModeStateService, EditWidgetDialogComponent, EntityAssociationsWidgetComponent, EntityCardConfigDialogComponent, EntityCardWidgetComponent, EntityDetailDialogComponent, EntitySelectorEditorComponent, EntitySelectorScopePathEditorComponent, EntitySelectorToolbarComponent, FALLBACK_SERIES_COLORS, FailedExecutionsAttentionProvider, FeaturesNotInstalledAttentionProvider, GaugeConfigDialogComponent, GaugeWidgetComponent, HISTOGRAM_HOURS, HOUR_MS, HeatmapConfigDialogComponent, HeatmapWidgetComponent, KPI_ERROR_TEXT, KpiConfigDialogComponent, KpiWidgetComponent, LazyMarkdownComponent, LineChartConfigDialogComponent, LineChartWidgetComponent, MAX_RECENT_ITEMS, MAX_SCOPE_HOPS, MESHBOARD_CHROME_ROUTE_DATA, MESHBOARD_DESCRIPTION_MARKER, MESHBOARD_EDIT_QUERY_PARAM, MESHBOARD_HEADER_MODE_ROUTE_DATA, MESHBOARD_LABEL_RESOLVER, MESHBOARD_LANGUAGE, MESHBOARD_MESSAGES, MESHBOARD_OPTIONS, MESHBOARD_TENANT_ID_PROVIDER, MarkdownConfigDialogComponent, MarkdownWidgetComponent, MeshBoardDataService, MeshBoardGridService, MeshBoardManagerDialogComponent, MeshBoardPersistenceService, MeshBoardSettingsDialogComponent, MeshBoardSettingsResult, MeshBoardStateService, MeshBoardViewComponent, NOT_AVAILABLE_TEXT, PieChartConfigDialogComponent, PieChartWidgetComponent, QueryExecutorService, QuerySelectorComponent, RecentItemsConfigDialogComponent, RecentItemsWidgetComponent, RuntimeEntitySelectorComponent, SERVICE_MANAGED_BLUEPRINT_PREFIX, STATE_STATUS_BY_KEY, ServiceHealthConfigDialogComponent, ServiceHealthWidgetComponent, ServicesHealthAttentionProvider, StatsGridConfigDialogComponent, StatsGridWidgetComponent, StatusIndicatorConfigDialogComponent, StatusIndicatorWidgetComponent, StatusListConfigDialogComponent, StatusListWidgetComponent, SummaryCardConfigDialogComponent, SummaryCardWidgetComponent, TableConfigDialogComponent, TableWidgetComponent, TableWidgetDataSourceDirective, UnregisteredPoolsAttentionProvider, WidgetFactoryService, WidgetGroupComponent, WidgetGroupConfigDialogComponent, WidgetNotConfiguredComponent, WidgetRegistryService, adapterKpi, adaptersInError, adaptersOffline, blueprintUpdatesKpi, buildHourlyHistogram, categoryStatus, chartSeriesColors, ckModelKpi, classifyQuery, compareBlueprintVersions, compareMeshBoardNavigation, countFlowExecutions, countLabel, countPipelineExecutions, emptyQueryExecutionResult, enabledButNotInstalled, executionKpi, failedExecutionsSeverity, formatCockpitMessage, formatCount, humanizeCategory, isAdapterAtRest, isAdapterExpectedToRun, isAdapterOnline, isCockpitWidgetType, isMeshBoardChrome, isMeshBoardHeaderMode, isServiceConfigured, joinEncodedDescription, kpiKindOf, latestStatisticsUpdate, legacyCockpitLinkTarget, loadNgxMarkdown, nameList, newMeshBoardConfig, normalizeNavigation, observeThemeChanges, parseHostTimeRange, pickLocalizedText, pipelineExecutionInputs, plural, provideCockpitWidgetHost, provideCockpitWidgets, provideDefaultWidgets, provideMeshBoard, provideMeshBoardLanguage, provideMeshBoardMessages, provideProcessWidget, provideWidgetRegistrations, queryFamily, readMeshBoardNavigation, recentRelativeTime, registerCockpitWidgets, registerDefaultWidgets, registerProcessWidget, resolveChartColor, resolveCockpitWidgetMessages, resolveMeshBoardChrome, resolveMeshBoardHeaderMode, resolveMeshBoardLabel, resolveMeshBoardMessages, selectProviders, serviceStateText, servicesHealthKpi, sortAttentionFindings, sparklineGeometry, splitBlueprintId, splitEncodedDescription, statusColor, summarizeAdapterOnline, tenantCountKpi, toBlueprintStatus, toServiceHealthStatus, truncationNote, versionKpi, withMeshBoardNavigation };
9623
+ export type { AdapterOnlineFields, AdapterOnlineSummary, AdapterStatusWidgetConfig, AggregationDataSource, AggregationQuery, AggregationType, AiInsightsConfigResult, AiInsightsWidgetConfig, AlertBannerConfigResult, AlertBannerWidgetConfig, AlertListConfigResult, AlertListWidgetConfig, AnyWidgetConfig, AssociationsConfigResult, AttentionContext, AttentionFinding, AttentionLink, AttentionListConfigResult, AttentionListWidgetConfig, AttentionProvider, AttentionProviderInfo, AttentionSeverity, AttentionState, BarChartColorThreshold, BarChartConfigResult, BarChartSeries, BarChartType, BarChartWidgetConfig, BaseWidgetConfig, BlueprintUpdatesWidgetConfig, CategoryStatus, CategoryValueItem, ChartReferenceLine, CkModelStateWidgetConfig, CkQueryResult, CkQueryTarget, CkTypeAttributeInfo, CockpitAdapterState, CockpitAdapterStates, CockpitBlueprintStatus, CockpitBlueprintUpdate, CockpitChildTenants, CockpitCkModelCounts, CockpitDataFlowExecutions, CockpitDataFlowRow, CockpitExecutionCounts, CockpitExplainHandler, CockpitExplainTarget, CockpitKpi, CockpitKpiConfigResult, CockpitKpiKind, CockpitKpiResult, CockpitKpiStatus, CockpitKpiWidgetConfig, CockpitKpiWidgetOptions, CockpitLinkQueryParams, CockpitLinkResolver, CockpitLinkTarget, CockpitRecentItem, CockpitRecentItemKind, CockpitRecentItemsSource, CockpitResolvedLink, CockpitRouteLinkTarget, CockpitServiceHealth, CockpitServiceHealthStatus, CockpitServiceKey, CockpitVersionEntry, CockpitVersionSource, CockpitViewerAccess, CockpitWidgetHost, CockpitWidgetMessages, CockpitWidgetMessagesSource, CockpitWidgetType, ConfigDialogResult, ConfigResultApplier, ConstructionKitQueryDataSource, DashboardConfig, DashboardWidget, DataSource, DataSourceType, DiagramPropertyMapping, EncodedDescription, EntityAssociation, EntityAttribute, EntityCardConfigResult, EntityCardWidgetConfig, EntityListWidget, EntitySelectorAttributeMapping, EntitySelectorChildScope, EntitySelectorClearEvent, EntitySelectorConfig, EntitySelectorEvent, EntitySelectorScopeHop, EntitySelectorScopeState, EntityWidget, EntityWithAssociationsWidgetConfig, FailedExecutionsAttentionOptions, GaugeConfigResult, GaugeRange, GaugeType, GaugeWidgetConfig, GridCell, GridPosition, GroupChildWidgetType, GroupedDataItem, HeatmapAggregation, HeatmapColorMode, HeatmapColorScheme, HeatmapConfigResult, HeatmapWidgetConfig, HostTimeRangeState, HourlyExecutionBucket, HourlyHistogramOptions, KpiConfigResult, KpiDataSourceType, KpiQueryMode, KpiValueMode, KpiWidgetConfig, LatestExecutionInput, LineChartConfigResult, LineChartType, LineChartWidgetConfig, MarkdownConfigResult, MarkdownTextAlign, MarkdownWidgetConfig, MeshBoardChrome, MeshBoardConfig, MeshBoardHeaderMode, MeshBoardHostTimeRange, MeshBoardLabelKind, MeshBoardLabelRequest, MeshBoardLabelResolver, MeshBoardLanguageSource, MeshBoardMessages, MeshBoardMessagesSource, MeshBoardNavigationConfig, MeshBoardOptions, MeshBoardTimeFilterConfig, MeshBoardTimeFilterControl, MeshBoardTimeZoneMode, MeshBoardVariable, MeshBoardVariableSource, MeshBoardVariableType, ParentAssociationMode, PersistedDashboard, PersistedMeshBoard, PersistedWidget, PersistedWidgetData, PersistentQueryCellMode, PersistentQueryCellSource, PersistentQueryDataSource, PersistentQueryItem, PieChartConfigResult, PieChartLabelPosition, PieChartType, PieChartWidgetConfig, PipelineExecutionCounts, PipelineExecutionInput, PipelineExecutionsWidgetConfig, PipelineStatisticsInput, ProcessWidgetConfig, Quarter, QueryCell, QueryClassification, QueryColumn, QueryColumnInfo, QueryColumnItem, QueryExecutionOptions, QueryExecutionResult, QueryFamily, QueryKind, QueryResultRow, RawHourBucket, RecentItemsConfigResult, RecentItemsWidgetConfig, RelativeTimeUnit, RepeaterDataItem, RepeaterQueryDataSource, RuntimeEntityData, RuntimeEntityDataSource, RuntimeEntitySelectorValue, SeriesAggregationFunction, SeriesResolutionResult, ServiceCallDataSource, ServiceCallType, ServiceHealthConfigResult, ServiceHealthWidgetConfig, ServicesHealthWidgetConfig, SparklineGeometry, StatColor, StatItem, StaticDataSource, StatsGridConfigResult, StatsGridWidgetConfig, StatusIndicatorConfigResult, StatusIndicatorWidgetConfig, StatusListConfigResult, StatusListWidgetConfig, StreamDataExecutionArgs, StreamDataScope, SummaryCardConfigResult, SummaryCardTile, SummaryCardWidgetConfig, TableColumn, TableColumnStatusIconMapping, TableColumnValueLabel, TableConfigResult, TableFilterConfig, TableSortConfig, TableWidgetConfig, TargetEntityWithAttributes, TenantCountWidgetConfig, TimeRangePickerConfig, TimeRangeSelection, TimeRangeType, UpdateDashboardResult, VariableResolutionError, VersionInfoWidgetConfig, WidgetConfig, WidgetConfigDialog, WidgetConfigDialogSize, WidgetConfigResult, WidgetCreationOptions, WidgetDataSource, WidgetFilterConfig, WidgetGroupAttributeMappings, WidgetGroupChildTemplate, WidgetGroupConfig, WidgetGroupConfigResult, WidgetGroupLayout, WidgetPersistenceData, WidgetPositionUpdate, WidgetRegistration, WidgetType, WidgetZone };