@firestitch/report 18.11.0 → 18.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/reports/components/component-grid/component-grid.component.d.ts +29 -0
- package/app/reports/components/component-grid/report-grid-formatter.d.ts +9 -0
- package/app/reports/data/report-grid-source.d.ts +22 -0
- package/app/reports/data/report.data.d.ts +3 -1
- package/app/reports/interfaces/report-chat-viewer-state.interface.d.ts +2 -0
- package/app/reports/interfaces/report-chat-viewer-tile.interface.d.ts +5 -0
- package/app/reports/interfaces/report-grid-config.interface.d.ts +5 -0
- package/app/reports/interfaces/report-grid-line.interface.d.ts +6 -0
- package/app/reports/interfaces/report-grid-params.interface.d.ts +7 -0
- package/app/reports/interfaces/report-grid-report.interface.d.ts +2 -0
- package/app/reports/interfaces/report-grid-session-layout.interface.d.ts +5 -0
- package/app/reports/interfaces/report.interface.d.ts +3 -2
- package/app/reports/report-chat-viewer-state.d.ts +4 -1
- package/app/reports/report-grid-layout.d.ts +4 -0
- package/app/reports/services/report-filter-state.service.d.ts +6 -0
- package/app/reports/views/report/fs-ai-report.component.d.ts +2 -0
- package/esm2022/app/reports/components/component-grid/component-grid.component.mjs +93 -0
- package/esm2022/app/reports/components/component-grid/report-grid-formatter.mjs +94 -0
- package/esm2022/app/reports/components/component-text/component-text.component.mjs +1 -1
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +21 -14
- package/esm2022/app/reports/data/report-grid-source.mjs +105 -0
- package/esm2022/app/reports/data/report.data.mjs +13 -2
- package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +1 -1
- package/esm2022/app/reports/interfaces/report-chat-viewer-tile.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-grid-config.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-grid-line.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-grid-params.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-grid-report.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-grid-session-layout.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
- package/esm2022/app/reports/report-chat-viewer-state.mjs +21 -6
- package/esm2022/app/reports/report-grid-layout.mjs +14 -0
- package/esm2022/app/reports/report-tile.mjs +5 -5
- package/esm2022/app/reports/services/report-filter-state.service.mjs +77 -11
- package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +36 -13
- package/fesm2022/{firestitch-report-echarts-DKXlgu1D.mjs → firestitch-report-echarts-CoaGXKET.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-DKXlgu1D.mjs.map → firestitch-report-echarts-CoaGXKET.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-Bnv62suw.mjs → firestitch-report-firestitch-report-CHPA7sla.mjs} +457 -52
- package/fesm2022/firestitch-report-firestitch-report-CHPA7sla.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +4 -2
- package/fesm2022/firestitch-report-firestitch-report-Bnv62suw.mjs.map +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { OnInit } from '@angular/core';
|
|
2
|
+
import { GridLayout } from '@firestitch/grid';
|
|
3
|
+
import { ReportGridSource } from '../../data/report-grid-source';
|
|
4
|
+
import { ReportGridParams } from '../../interfaces/report-grid-params.interface';
|
|
5
|
+
import { ReportComponent } from '../../interfaces/report.interface';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
export declare class ComponentGridComponent implements OnInit {
|
|
8
|
+
readonly reportId: import("@angular/core").InputSignal<number>;
|
|
9
|
+
readonly component: import("@angular/core").InputSignal<ReportComponent>;
|
|
10
|
+
readonly params: import("@angular/core").WritableSignal<ReportGridParams>;
|
|
11
|
+
readonly controls: import("@angular/core").Signal<import("@firestitch/grid").GridControls>;
|
|
12
|
+
readonly source: import("@angular/core").Signal<ReportGridSource>;
|
|
13
|
+
readonly layout: import("@angular/core").Signal<GridLayout>;
|
|
14
|
+
readonly noteData: import("@angular/core").Signal<import("../../interfaces/report-grid-report.interface").ReportGridReport>;
|
|
15
|
+
readonly formatter: import("@angular/core").Signal<import("@firestitch/grid").GridFormatter>;
|
|
16
|
+
private readonly _componentId;
|
|
17
|
+
private _reportData;
|
|
18
|
+
private _filterState;
|
|
19
|
+
private _destroyRef;
|
|
20
|
+
private _paramsVersion;
|
|
21
|
+
ngOnInit(): void;
|
|
22
|
+
setLayout(layout: GridLayout): void;
|
|
23
|
+
private _init;
|
|
24
|
+
private _settled$;
|
|
25
|
+
private _applyParams;
|
|
26
|
+
private _readParams;
|
|
27
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ComponentGridComponent, never>;
|
|
28
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ComponentGridComponent, "app-report-component-grid", never, { "reportId": { "alias": "reportId"; "required": true; "isSignal": true; }; "component": { "alias": "component"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GridFormatter } from '@firestitch/grid';
|
|
2
|
+
import { ReportGridReport } from '../../interfaces/report-grid-report.interface';
|
|
3
|
+
import { ReportFormatContext } from '../../interfaces/report.interface';
|
|
4
|
+
export interface ReportGridFormatContext {
|
|
5
|
+
format: ReportFormatContext;
|
|
6
|
+
timezone: string;
|
|
7
|
+
report: ReportGridReport | null;
|
|
8
|
+
}
|
|
9
|
+
export declare function reportGridFormatter(context: ReportGridFormatContext): GridFormatter;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { GridParams, GridRequest, GridResult, GridSource } from '@firestitch/grid';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { ReportGridReport } from '../interfaces/report-grid-report.interface';
|
|
4
|
+
import { ReportLocaleTag } from '../interfaces/report.interface';
|
|
5
|
+
import { ReportData } from './report.data';
|
|
6
|
+
export interface ReportGridSourceOptions {
|
|
7
|
+
isExport?: boolean;
|
|
8
|
+
locale?: () => ReportLocaleTag;
|
|
9
|
+
}
|
|
10
|
+
export declare class ReportGridSource implements GridSource {
|
|
11
|
+
private readonly _reportData;
|
|
12
|
+
private readonly _reportId;
|
|
13
|
+
private readonly _componentId;
|
|
14
|
+
readonly report: import("@angular/core").WritableSignal<ReportGridReport>;
|
|
15
|
+
private readonly _isExport;
|
|
16
|
+
private readonly _locale;
|
|
17
|
+
constructor(_reportData: ReportData, _reportId: number, _componentId: number, options?: ReportGridSourceOptions);
|
|
18
|
+
read(request: GridRequest, params: GridParams): Observable<GridResult>;
|
|
19
|
+
private _stream$;
|
|
20
|
+
private _part$;
|
|
21
|
+
private _described;
|
|
22
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { RequestConfig } from '@firestitch/api';
|
|
1
|
+
import { RequestConfig, StreamEvent } from '@firestitch/api';
|
|
2
|
+
import { GridRequest } from '@firestitch/grid';
|
|
2
3
|
import { Observable } from 'rxjs';
|
|
3
4
|
import { ReportExportLine } from '../interfaces/report-export-line.interface';
|
|
4
5
|
import { ReportFilterGroupChanges } from '../interfaces/report-filter-group-changes.interface';
|
|
@@ -54,6 +55,7 @@ export declare class ReportData<T = any> {
|
|
|
54
55
|
h: number;
|
|
55
56
|
}>)[], config?: RequestConfig): Observable<T>;
|
|
56
57
|
componentData(reportId: number, componentId: number, filters?: ResolvedFilterValue[], state?: ComponentDataState, isExport?: boolean, config?: RequestConfig): Observable<T>;
|
|
58
|
+
componentGrid(reportId: number, componentId: number, filters: ResolvedFilterValue[], state: ComponentDataState, grid: GridRequest, isExport?: boolean, config?: RequestConfig): Observable<StreamEvent>;
|
|
57
59
|
pageValues(reportId: number, pageId: number, filters?: ResolvedFilterValue[], isExport?: boolean, config?: RequestConfig, matchAnyGroupIds?: number[]): Observable<ReportPageValue[]>;
|
|
58
60
|
exportComponent(reportId: number, componentId: number, filters?: ResolvedFilterValue[], state?: ComponentDataState, title?: string, config?: RequestConfig): Observable<ComponentExportResponse>;
|
|
59
61
|
exportReport(reportId: number, filters?: ResolvedFilterValue[], pageId?: number | null, frequency?: ChartGranularity | null, filterLines?: ReportExportLine[], states?: Record<number, ComponentDataState>, titles?: Record<number, string>, config?: RequestConfig): Observable<T>;
|
|
@@ -3,6 +3,7 @@ import { ReportChatViewerDetail } from './report-chat-viewer-detail.interface';
|
|
|
3
3
|
import { ReportChatViewerDrill } from './report-chat-viewer-drill.interface';
|
|
4
4
|
import { ReportChatViewerFilter } from './report-chat-viewer-filter.interface';
|
|
5
5
|
import { ReportChatViewerSelection } from './report-chat-viewer-selection.interface';
|
|
6
|
+
import { ReportChatViewerTile } from './report-chat-viewer-tile.interface';
|
|
6
7
|
import { ReportFilterMatch } from './report-filter-match.type';
|
|
7
8
|
import { ChartGranularity } from './report.interface';
|
|
8
9
|
export interface ReportChatViewerState {
|
|
@@ -13,5 +14,6 @@ export interface ReportChatViewerState {
|
|
|
13
14
|
crossFilters?: ReportChatViewerCrossFilter[];
|
|
14
15
|
drills?: ReportChatViewerDrill[];
|
|
15
16
|
detail?: ReportChatViewerDetail | null;
|
|
17
|
+
tiles?: ReportChatViewerTile[];
|
|
16
18
|
selection?: ReportChatViewerSelection;
|
|
17
19
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { GridParams } from '@firestitch/grid';
|
|
2
|
+
import { ChartGranularity, ResolvedFilterValue } from './report.interface';
|
|
3
|
+
export interface ReportGridParams extends GridParams {
|
|
4
|
+
filters: ResolvedFilterValue[];
|
|
5
|
+
matchAnyGroupIds?: number[];
|
|
6
|
+
frequency?: ChartGranularity;
|
|
7
|
+
}
|
|
@@ -11,6 +11,7 @@ import { ReportValueFormula } from '../enums/report-value-formula.enum';
|
|
|
11
11
|
import { ComponentDataApplied } from './component-data-applied.interface';
|
|
12
12
|
import { ComponentDataDrill } from './component-data-drill.interface';
|
|
13
13
|
import { ReportDrillStep } from './report-drill-step.interface';
|
|
14
|
+
import { GridConfig } from './report-grid-config.interface';
|
|
14
15
|
import { ReportViewerFeature } from './report-viewer-feature.type';
|
|
15
16
|
export type ReportLocaleTag = string;
|
|
16
17
|
export type ReportCurrencyCode = string;
|
|
@@ -84,7 +85,7 @@ export interface ReportPage {
|
|
|
84
85
|
components: ReportComponent[];
|
|
85
86
|
values?: ReportComponent[];
|
|
86
87
|
}
|
|
87
|
-
export type ReportComponentType = 'chart' | 'list' | 'kpi' | 'text' | 'value';
|
|
88
|
+
export type ReportComponentType = 'chart' | 'list' | 'grid' | 'kpi' | 'text' | 'value';
|
|
88
89
|
export interface ReportComponent {
|
|
89
90
|
id: number;
|
|
90
91
|
type: ReportComponentType;
|
|
@@ -95,7 +96,7 @@ export interface ReportComponent {
|
|
|
95
96
|
h: number;
|
|
96
97
|
autoHeight: boolean;
|
|
97
98
|
sql: string | null;
|
|
98
|
-
config: ChartConfig & ListConfig & KpiConfig & TextConfig & ValueConfig & ComponentLayoutConfig & Record<string, unknown>;
|
|
99
|
+
config: ChartConfig & ListConfig & GridConfig & KpiConfig & TextConfig & ValueConfig & ComponentLayoutConfig & Record<string, unknown>;
|
|
99
100
|
filters: ReportFilter[];
|
|
100
101
|
}
|
|
101
102
|
export interface ReportComponentSql {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { GridLayout } from '@firestitch/grid';
|
|
1
2
|
import { ReportChatViewerDrill } from './interfaces/report-chat-viewer-drill.interface';
|
|
2
3
|
import { ReportChatViewerState } from './interfaces/report-chat-viewer-state.interface';
|
|
4
|
+
import { ReportChatViewerTile } from './interfaces/report-chat-viewer-tile.interface';
|
|
3
5
|
import { ReportStateSnapshot } from './interfaces/report-state-snapshot.interface';
|
|
4
|
-
import { ReportLocaleTag } from './interfaces/report.interface';
|
|
6
|
+
import { Report, ReportComponent, ReportLocaleTag } from './interfaces/report.interface';
|
|
5
7
|
export declare const CHAT_DRILLS_MAX = 10;
|
|
6
8
|
export declare const CHAT_LABEL_MAX = 100;
|
|
7
9
|
export declare function chatViewerMatch(snapshot: ReportStateSnapshot): Pick<ReportChatViewerState, 'match'>;
|
|
8
10
|
export declare function chatViewerDrills(snapshot: ReportStateSnapshot, locale: ReportLocaleTag): ReportChatViewerDrill[];
|
|
11
|
+
export declare function chatViewerTiles(report: Report | null, pageId: number | null, layoutOf: (component: ReportComponent) => GridLayout | null): ReportChatViewerTile[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GridLayout } from '@firestitch/grid';
|
|
1
2
|
import { Observable } from 'rxjs';
|
|
2
3
|
import { ReportChatViewerFilter } from '../interfaces/report-chat-viewer-filter.interface';
|
|
3
4
|
import { ReportDrillStep } from '../interfaces/report-drill-step.interface';
|
|
@@ -49,6 +50,7 @@ export declare class ReportFilterStateService {
|
|
|
49
50
|
private _match;
|
|
50
51
|
private _drills;
|
|
51
52
|
private _drillChanged$;
|
|
53
|
+
private _gridLayouts;
|
|
52
54
|
private _temporary;
|
|
53
55
|
init(report: Report): void;
|
|
54
56
|
value(groupId: number): FilterGroupValue | undefined;
|
|
@@ -82,6 +84,9 @@ export declare class ReportFilterStateService {
|
|
|
82
84
|
setDrill(componentId: number, path: readonly ReportDrillStep[]): void;
|
|
83
85
|
drillChanges(componentId: number): Observable<void>;
|
|
84
86
|
adoptDrill(componentId: number, path: readonly ReportDrillStep[]): boolean;
|
|
87
|
+
gridLayout(component: ReportComponent): GridLayout;
|
|
88
|
+
gridSessionLayout(component: ReportComponent): GridLayout | null;
|
|
89
|
+
setGridLayout(component: ReportComponent, layout: GridLayout): void;
|
|
85
90
|
snapshot(): ReportStateSnapshot;
|
|
86
91
|
authoredConfig(): ReportStateSnapshot;
|
|
87
92
|
resetToDefaults(): void;
|
|
@@ -107,6 +112,7 @@ export declare class ReportFilterStateService {
|
|
|
107
112
|
private _notifyReset;
|
|
108
113
|
private _tiles;
|
|
109
114
|
private _isChart;
|
|
115
|
+
private _pruneGridLayouts;
|
|
110
116
|
private _prunePageState;
|
|
111
117
|
private _resolveExcludeAndRange;
|
|
112
118
|
private _excludeOrRangeDefault;
|
|
@@ -24,6 +24,7 @@ export declare class FsAiReportComponent {
|
|
|
24
24
|
private _reportData;
|
|
25
25
|
private _reportAiChatData;
|
|
26
26
|
private _route;
|
|
27
|
+
private _router;
|
|
27
28
|
private _filterState;
|
|
28
29
|
private _filterOptions;
|
|
29
30
|
private _exportService;
|
|
@@ -51,6 +52,7 @@ export declare class FsAiReportComponent {
|
|
|
51
52
|
onResizeStart(event: PointerEvent): void;
|
|
52
53
|
private _chatViewerState;
|
|
53
54
|
private _resizeTo;
|
|
55
|
+
private _writePageToUrl;
|
|
54
56
|
private _pageIdFromUrl;
|
|
55
57
|
private _loadReport;
|
|
56
58
|
private _reportGroups;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, input, signal, } from '@angular/core';
|
|
2
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
3
|
+
import { FsGridComponent } from '@firestitch/grid';
|
|
4
|
+
import { filter, map, of, switchMap, tap, timer } from 'rxjs';
|
|
5
|
+
import { ReportData } from '../../data/report.data';
|
|
6
|
+
import { ReportGridSource } from '../../data/report-grid-source';
|
|
7
|
+
import { ReportFilterStateService } from '../../services/report-filter-state.service';
|
|
8
|
+
import { TILE_REFRESH_DEBOUNCE_MS } from '../../tile-loads';
|
|
9
|
+
import { ComponentNoteComponent } from '../component-note/component-note.component';
|
|
10
|
+
import { reportGridFormatter } from './report-grid-formatter';
|
|
11
|
+
import * as i0 from "@angular/core";
|
|
12
|
+
// A grid tile: fs-grid over the tile's rows, read through ReportGridSource.
|
|
13
|
+
//
|
|
14
|
+
// - The params (the report filters the tile resolves to and the 'any'
|
|
15
|
+
// groups) are seeded before the first render, so no read goes out without
|
|
16
|
+
// them. After that a change to one of the tile's filter groups settles for
|
|
17
|
+
// TILE_REFRESH_DEBOUNCE_MS, so a sweep of changes costs one read; one sent
|
|
18
|
+
// under an older state version is dropped.
|
|
19
|
+
// - The layout on screen is the state service's (gridLayout): the viewer's
|
|
20
|
+
// own while they changed it from the layout authored now, else the
|
|
21
|
+
// authored one. It outlives a page switch, and the chat reads it.
|
|
22
|
+
// - A state version move (Clear filters, a saved filter) skips the wait; the
|
|
23
|
+
// reset has put the authored layout back in the same tick, so it costs one
|
|
24
|
+
// read.
|
|
25
|
+
// - fs-grid compares the layout and params by value: a cloned value never
|
|
26
|
+
// reads again.
|
|
27
|
+
export class ComponentGridComponent {
|
|
28
|
+
reportId = input.required();
|
|
29
|
+
component = input.required();
|
|
30
|
+
params = signal(null);
|
|
31
|
+
controls = computed(() => this.component().config?.controls ?? {});
|
|
32
|
+
source = computed(() => new ReportGridSource(this._reportData, this.reportId(), this._componentId(), {
|
|
33
|
+
locale: () => this._filterState.formatContext().locale,
|
|
34
|
+
}));
|
|
35
|
+
layout = computed(() => this._filterState.gridLayout(this.component()));
|
|
36
|
+
noteData = computed(() => this.source().report());
|
|
37
|
+
formatter = computed(() => reportGridFormatter({
|
|
38
|
+
format: this._filterState.formatContext(),
|
|
39
|
+
timezone: this._filterState.timezone(),
|
|
40
|
+
report: this.source().report(),
|
|
41
|
+
}));
|
|
42
|
+
_componentId = computed(() => this.component().id);
|
|
43
|
+
_reportData = inject(ReportData);
|
|
44
|
+
_filterState = inject(ReportFilterStateService);
|
|
45
|
+
_destroyRef = inject(DestroyRef);
|
|
46
|
+
// The state version the params on screen were read under.
|
|
47
|
+
_paramsVersion = 0;
|
|
48
|
+
ngOnInit() {
|
|
49
|
+
this._init();
|
|
50
|
+
}
|
|
51
|
+
setLayout(layout) {
|
|
52
|
+
this._filterState.setGridLayout(this.component(), layout);
|
|
53
|
+
}
|
|
54
|
+
_init() {
|
|
55
|
+
this._paramsVersion = this._filterState.stateVersion();
|
|
56
|
+
this.params.set(this._readParams());
|
|
57
|
+
this._filterState.changesFor(this.component())
|
|
58
|
+
.pipe(switchMap(() => this._settled$()), tap(() => this._applyParams()), takeUntilDestroyed(this._destroyRef))
|
|
59
|
+
.subscribe();
|
|
60
|
+
}
|
|
61
|
+
// A change, once it has settled: at once when the state version moved,
|
|
62
|
+
// else after the debounce; dropped when the version moves while it waits,
|
|
63
|
+
// since that move brings its own change.
|
|
64
|
+
_settled$() {
|
|
65
|
+
const version = this._filterState.stateVersion();
|
|
66
|
+
const moved = version !== this._paramsVersion;
|
|
67
|
+
return (moved ? of(0) : timer(TILE_REFRESH_DEBOUNCE_MS))
|
|
68
|
+
.pipe(filter(() => this._filterState.stateVersion() === version), map(() => undefined));
|
|
69
|
+
}
|
|
70
|
+
_applyParams() {
|
|
71
|
+
this._paramsVersion = this._filterState.stateVersion();
|
|
72
|
+
this.params.set(this._readParams());
|
|
73
|
+
}
|
|
74
|
+
// The tile's report filters and 'any' groups as they stand.
|
|
75
|
+
_readParams() {
|
|
76
|
+
const component = this.component();
|
|
77
|
+
const matchAnyGroupIds = this._filterState.tileState(component).matchAnyGroupIds;
|
|
78
|
+
return {
|
|
79
|
+
filters: this._filterState.resolveForComponent(component),
|
|
80
|
+
...(matchAnyGroupIds?.length ? { matchAnyGroupIds } : {}),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
84
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ComponentGridComponent, isStandalone: true, selector: "app-report-component-grid", inputs: { reportId: { classPropertyName: "reportId", publicName: "reportId", isSignal: true, isRequired: true, transformFunction: null }, component: { classPropertyName: "component", publicName: "component", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<!-- The comparison and window note strip above the table, from the report\n line of the latest read; the windows' descriptions and notes go in each\n column's \"About this column\" instead. -->\n<div class=\"fs-column grid-pane\">\n <app-report-component-note\n [data]=\"noteData()\"\n [windowNotes]=\"false\">\n </app-report-component-note>\n <!-- The params are seeded before the first render, so the grid's first read\n carries the tile's report filters. -->\n @if (params(); as params) {\n <fs-grid\n class=\"fs-flex\"\n [source]=\"source()\"\n [layout]=\"layout()\"\n [params]=\"params\"\n [controls]=\"controls()\"\n [formatter]=\"formatter()\"\n (layoutChange)=\"setLayout($event)\">\n </fs-grid>\n }\n</div>\n", styles: [":host{display:block;height:100%}.grid-pane{height:100%;min-height:0}fs-grid{min-height:0}\n"], dependencies: [{ kind: "component", type: FsGridComponent, selector: "fs-grid", inputs: ["source", "layout", "controls", "params", "expansion", "panel", "editorOpen", "formatter", "clearedFilter"], outputs: ["layoutChange", "expansionChange", "panelChange", "editorOpenChange"] }, { kind: "component", type: ComponentNoteComponent, selector: "app-report-component-note", inputs: ["data", "windows", "windowDescriptions", "windowNotes"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
85
|
+
}
|
|
86
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentGridComponent, decorators: [{
|
|
87
|
+
type: Component,
|
|
88
|
+
args: [{ selector: 'app-report-component-grid', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
89
|
+
FsGridComponent,
|
|
90
|
+
ComponentNoteComponent,
|
|
91
|
+
], template: "<!-- The comparison and window note strip above the table, from the report\n line of the latest read; the windows' descriptions and notes go in each\n column's \"About this column\" instead. -->\n<div class=\"fs-column grid-pane\">\n <app-report-component-note\n [data]=\"noteData()\"\n [windowNotes]=\"false\">\n </app-report-component-note>\n <!-- The params are seeded before the first render, so the grid's first read\n carries the tile's report filters. -->\n @if (params(); as params) {\n <fs-grid\n class=\"fs-flex\"\n [source]=\"source()\"\n [layout]=\"layout()\"\n [params]=\"params\"\n [controls]=\"controls()\"\n [formatter]=\"formatter()\"\n (layoutChange)=\"setLayout($event)\">\n </fs-grid>\n }\n</div>\n", styles: [":host{display:block;height:100%}.grid-pane{height:100%;min-height:0}fs-grid{min-height:0}\n"] }]
|
|
92
|
+
}] });
|
|
93
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LWdyaWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvY29tcG9uZW50LWdyaWQvY29tcG9uZW50LWdyaWQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvY29tcG9uZW50LWdyaWQvY29tcG9uZW50LWdyaWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQVUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxHQUN4RixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVoRSxPQUFPLEVBQUUsZUFBZSxFQUFjLE1BQU0sa0JBQWtCLENBQUM7QUFFL0QsT0FBTyxFQUFjLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUdqRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUN0RixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUVwRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7QUFHOUQsNEVBQTRFO0FBQzVFLEVBQUU7QUFDRixzRUFBc0U7QUFDdEUsNEVBQTRFO0FBQzVFLDZFQUE2RTtBQUM3RSw2RUFBNkU7QUFDN0UsNkNBQTZDO0FBQzdDLDJFQUEyRTtBQUMzRSxxRUFBcUU7QUFDckUsb0VBQW9FO0FBQ3BFLDZFQUE2RTtBQUM3RSw2RUFBNkU7QUFDN0UsVUFBVTtBQUNWLDBFQUEwRTtBQUMxRSxpQkFBaUI7QUFZakIsTUFBTSxPQUFPLHNCQUFzQjtJQUVqQixRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBVSxDQUFDO0lBQ3BDLFNBQVMsR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFtQixDQUFDO0lBRTlDLE1BQU0sR0FBRyxNQUFNLENBQTBCLElBQUksQ0FBQyxDQUFDO0lBQy9DLFFBQVEsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLE1BQU0sRUFBRSxRQUFRLElBQUksRUFBRSxDQUFDLENBQUM7SUFDbkUsTUFBTSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBRTtRQUNuSCxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxNQUFNO0tBQ3ZELENBQUMsQ0FBQyxDQUFDO0lBRVksTUFBTSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXhFLFFBQVEsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDbEQsU0FBUyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztRQUM3RCxNQUFNLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUU7UUFDekMsUUFBUSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFO1FBQ3RDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxFQUFFO0tBQy9CLENBQUMsQ0FBQyxDQUFDO0lBRWEsWUFBWSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDNUQsV0FBVyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNqQyxZQUFZLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDaEQsV0FBVyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN6QywwREFBMEQ7SUFDbEQsY0FBYyxHQUFHLENBQUMsQ0FBQztJQUVwQixRQUFRO1FBQ2IsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2YsQ0FBQztJQUVNLFNBQVMsQ0FBQyxNQUFrQjtRQUNqQyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVPLEtBQUs7UUFDWCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdkQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFFcEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2FBQzNDLElBQUksQ0FDSCxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQ2pDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsRUFDOUIsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUNyQzthQUNBLFNBQVMsRUFBRSxDQUFDO0lBQ2pCLENBQUM7SUFFRCx1RUFBdUU7SUFDdkUsMEVBQTBFO0lBQzFFLHlDQUF5QztJQUNqQyxTQUFTO1FBQ2YsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNqRCxNQUFNLEtBQUssR0FBRyxPQUFPLEtBQUssSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUU5QyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO2FBQ3JELElBQUksQ0FDSCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsS0FBSyxPQUFPLENBQUMsRUFDMUQsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUNyQixDQUFDO0lBQ04sQ0FBQztJQUVPLFlBQVk7UUFDbEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3ZELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRCw0REFBNEQ7SUFDcEQsV0FBVztRQUNqQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDbkMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQztRQUVqRixPQUFPO1lBQ0wsT0FBTyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsbUJBQW1CLENBQUMsU0FBUyxDQUFDO1lBQ3pELEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQzFELENBQUM7SUFDSixDQUFDO3dHQTVFVSxzQkFBc0I7NEZBQXRCLHNCQUFzQixvV0M5Q25DLGt4QkFzQkEscUpEb0JJLGVBQWUsMlBBQ2Ysc0JBQXNCOzs0RkFHYixzQkFBc0I7a0JBWGxDLFNBQVM7K0JBQ0UsMkJBQTJCLG1CQUdwQix1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUDt3QkFDUCxlQUFlO3dCQUNmLHNCQUFzQjtxQkFDdkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBEZXN0cm95UmVmLCBPbkluaXQsIGNvbXB1dGVkLCBpbmplY3QsIGlucHV0LCBzaWduYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuXG5pbXBvcnQgeyBGc0dyaWRDb21wb25lbnQsIEdyaWRMYXlvdXQgfSBmcm9tICdAZmlyZXN0aXRjaC9ncmlkJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZmlsdGVyLCBtYXAsIG9mLCBzd2l0Y2hNYXAsIHRhcCwgdGltZXIgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHsgUmVwb3J0R3JpZFNvdXJjZSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LWdyaWQtc291cmNlJztcbmltcG9ydCB7IFJlcG9ydEdyaWRQYXJhbXMgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC1ncmlkLXBhcmFtcy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0Q29tcG9uZW50IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JlcG9ydC1maWx0ZXItc3RhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBUSUxFX1JFRlJFU0hfREVCT1VOQ0VfTVMgfSBmcm9tICcuLi8uLi90aWxlLWxvYWRzJztcbmltcG9ydCB7IENvbXBvbmVudE5vdGVDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnQtbm90ZS9jb21wb25lbnQtbm90ZS5jb21wb25lbnQnO1xuXG5pbXBvcnQgeyByZXBvcnRHcmlkRm9ybWF0dGVyIH0gZnJvbSAnLi9yZXBvcnQtZ3JpZC1mb3JtYXR0ZXInO1xuXG5cbi8vIEEgZ3JpZCB0aWxlOiBmcy1ncmlkIG92ZXIgdGhlIHRpbGUncyByb3dzLCByZWFkIHRocm91Z2ggUmVwb3J0R3JpZFNvdXJjZS5cbi8vXG4vLyAtIFRoZSBwYXJhbXMgKHRoZSByZXBvcnQgZmlsdGVycyB0aGUgdGlsZSByZXNvbHZlcyB0byBhbmQgdGhlICdhbnknXG4vLyAgIGdyb3VwcykgYXJlIHNlZWRlZCBiZWZvcmUgdGhlIGZpcnN0IHJlbmRlciwgc28gbm8gcmVhZCBnb2VzIG91dCB3aXRob3V0XG4vLyAgIHRoZW0uIEFmdGVyIHRoYXQgYSBjaGFuZ2UgdG8gb25lIG9mIHRoZSB0aWxlJ3MgZmlsdGVyIGdyb3VwcyBzZXR0bGVzIGZvclxuLy8gICBUSUxFX1JFRlJFU0hfREVCT1VOQ0VfTVMsIHNvIGEgc3dlZXAgb2YgY2hhbmdlcyBjb3N0cyBvbmUgcmVhZDsgb25lIHNlbnRcbi8vICAgdW5kZXIgYW4gb2xkZXIgc3RhdGUgdmVyc2lvbiBpcyBkcm9wcGVkLlxuLy8gLSBUaGUgbGF5b3V0IG9uIHNjcmVlbiBpcyB0aGUgc3RhdGUgc2VydmljZSdzIChncmlkTGF5b3V0KTogdGhlIHZpZXdlcidzXG4vLyAgIG93biB3aGlsZSB0aGV5IGNoYW5nZWQgaXQgZnJvbSB0aGUgbGF5b3V0IGF1dGhvcmVkIG5vdywgZWxzZSB0aGVcbi8vICAgYXV0aG9yZWQgb25lLiBJdCBvdXRsaXZlcyBhIHBhZ2Ugc3dpdGNoLCBhbmQgdGhlIGNoYXQgcmVhZHMgaXQuXG4vLyAtIEEgc3RhdGUgdmVyc2lvbiBtb3ZlIChDbGVhciBmaWx0ZXJzLCBhIHNhdmVkIGZpbHRlcikgc2tpcHMgdGhlIHdhaXQ7IHRoZVxuLy8gICByZXNldCBoYXMgcHV0IHRoZSBhdXRob3JlZCBsYXlvdXQgYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyBpdCBjb3N0cyBvbmVcbi8vICAgcmVhZC5cbi8vIC0gZnMtZ3JpZCBjb21wYXJlcyB0aGUgbGF5b3V0IGFuZCBwYXJhbXMgYnkgdmFsdWU6IGEgY2xvbmVkIHZhbHVlIG5ldmVyXG4vLyAgIHJlYWRzIGFnYWluLlxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXJlcG9ydC1jb21wb25lbnQtZ3JpZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9jb21wb25lbnQtZ3JpZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NvbXBvbmVudC1ncmlkLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgRnNHcmlkQ29tcG9uZW50LFxuICAgIENvbXBvbmVudE5vdGVDb21wb25lbnQsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIENvbXBvbmVudEdyaWRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIHB1YmxpYyByZWFkb25seSByZXBvcnRJZCA9IGlucHV0LnJlcXVpcmVkPG51bWJlcj4oKTtcbiAgcHVibGljIHJlYWRvbmx5IGNvbXBvbmVudCA9IGlucHV0LnJlcXVpcmVkPFJlcG9ydENvbXBvbmVudD4oKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgcGFyYW1zID0gc2lnbmFsPFJlcG9ydEdyaWRQYXJhbXMgfCBudWxsPihudWxsKTtcbiAgcHVibGljIHJlYWRvbmx5IGNvbnRyb2xzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb21wb25lbnQoKS5jb25maWc/LmNvbnRyb2xzID8/IHt9KTtcbiAgcHVibGljIHJlYWRvbmx5IHNvdXJjZSA9IGNvbXB1dGVkKCgpID0+IG5ldyBSZXBvcnRHcmlkU291cmNlKHRoaXMuX3JlcG9ydERhdGEsIHRoaXMucmVwb3J0SWQoKSwgdGhpcy5fY29tcG9uZW50SWQoKSwge1xuICAgIGxvY2FsZTogKCkgPT4gdGhpcy5fZmlsdGVyU3RhdGUuZm9ybWF0Q29udGV4dCgpLmxvY2FsZSxcbiAgfSkpO1xuXG4gIHB1YmxpYyByZWFkb25seSBsYXlvdXQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9maWx0ZXJTdGF0ZS5ncmlkTGF5b3V0KHRoaXMuY29tcG9uZW50KCkpKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgbm90ZURhdGEgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnNvdXJjZSgpLnJlcG9ydCgpKTtcbiAgcHVibGljIHJlYWRvbmx5IGZvcm1hdHRlciA9IGNvbXB1dGVkKCgpID0+IHJlcG9ydEdyaWRGb3JtYXR0ZXIoe1xuICAgIGZvcm1hdDogdGhpcy5fZmlsdGVyU3RhdGUuZm9ybWF0Q29udGV4dCgpLFxuICAgIHRpbWV6b25lOiB0aGlzLl9maWx0ZXJTdGF0ZS50aW1lem9uZSgpLFxuICAgIHJlcG9ydDogdGhpcy5zb3VyY2UoKS5yZXBvcnQoKSxcbiAgfSkpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2NvbXBvbmVudElkID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb21wb25lbnQoKS5pZCk7XG4gIHByaXZhdGUgX3JlcG9ydERhdGEgPSBpbmplY3QoUmVwb3J0RGF0YSk7XG4gIHByaXZhdGUgX2ZpbHRlclN0YXRlID0gaW5qZWN0KFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSk7XG4gIHByaXZhdGUgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gIC8vIFRoZSBzdGF0ZSB2ZXJzaW9uIHRoZSBwYXJhbXMgb24gc2NyZWVuIHdlcmUgcmVhZCB1bmRlci5cbiAgcHJpdmF0ZSBfcGFyYW1zVmVyc2lvbiA9IDA7XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuX2luaXQoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRMYXlvdXQobGF5b3V0OiBHcmlkTGF5b3V0KTogdm9pZCB7XG4gICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0R3JpZExheW91dCh0aGlzLmNvbXBvbmVudCgpLCBsYXlvdXQpO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLl9wYXJhbXNWZXJzaW9uID0gdGhpcy5fZmlsdGVyU3RhdGUuc3RhdGVWZXJzaW9uKCk7XG4gICAgdGhpcy5wYXJhbXMuc2V0KHRoaXMuX3JlYWRQYXJhbXMoKSk7XG5cbiAgICB0aGlzLl9maWx0ZXJTdGF0ZS5jaGFuZ2VzRm9yKHRoaXMuY29tcG9uZW50KCkpXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuX3NldHRsZWQkKCkpLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy5fYXBwbHlQYXJhbXMoKSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8vIEEgY2hhbmdlLCBvbmNlIGl0IGhhcyBzZXR0bGVkOiBhdCBvbmNlIHdoZW4gdGhlIHN0YXRlIHZlcnNpb24gbW92ZWQsXG4gIC8vIGVsc2UgYWZ0ZXIgdGhlIGRlYm91bmNlOyBkcm9wcGVkIHdoZW4gdGhlIHZlcnNpb24gbW92ZXMgd2hpbGUgaXQgd2FpdHMsXG4gIC8vIHNpbmNlIHRoYXQgbW92ZSBicmluZ3MgaXRzIG93biBjaGFuZ2UuXG4gIHByaXZhdGUgX3NldHRsZWQkKCk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLl9maWx0ZXJTdGF0ZS5zdGF0ZVZlcnNpb24oKTtcbiAgICBjb25zdCBtb3ZlZCA9IHZlcnNpb24gIT09IHRoaXMuX3BhcmFtc1ZlcnNpb247XG5cbiAgICByZXR1cm4gKG1vdmVkID8gb2YoMCkgOiB0aW1lcihUSUxFX1JFRlJFU0hfREVCT1VOQ0VfTVMpKVxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcigoKSA9PiB0aGlzLl9maWx0ZXJTdGF0ZS5zdGF0ZVZlcnNpb24oKSA9PT0gdmVyc2lvbiksXG4gICAgICAgIG1hcCgoKSA9PiB1bmRlZmluZWQpLFxuICAgICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX2FwcGx5UGFyYW1zKCk6IHZvaWQge1xuICAgIHRoaXMuX3BhcmFtc1ZlcnNpb24gPSB0aGlzLl9maWx0ZXJTdGF0ZS5zdGF0ZVZlcnNpb24oKTtcbiAgICB0aGlzLnBhcmFtcy5zZXQodGhpcy5fcmVhZFBhcmFtcygpKTtcbiAgfVxuXG4gIC8vIFRoZSB0aWxlJ3MgcmVwb3J0IGZpbHRlcnMgYW5kICdhbnknIGdyb3VwcyBhcyB0aGV5IHN0YW5kLlxuICBwcml2YXRlIF9yZWFkUGFyYW1zKCk6IFJlcG9ydEdyaWRQYXJhbXMge1xuICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50KCk7XG4gICAgY29uc3QgbWF0Y2hBbnlHcm91cElkcyA9IHRoaXMuX2ZpbHRlclN0YXRlLnRpbGVTdGF0ZShjb21wb25lbnQpLm1hdGNoQW55R3JvdXBJZHM7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZmlsdGVyczogdGhpcy5fZmlsdGVyU3RhdGUucmVzb2x2ZUZvckNvbXBvbmVudChjb21wb25lbnQpLFxuICAgICAgLi4uKG1hdGNoQW55R3JvdXBJZHM/Lmxlbmd0aCA/IHsgbWF0Y2hBbnlHcm91cElkcyB9IDoge30pLFxuICAgIH07XG4gIH1cblxufVxuIiwiPCEtLSBUaGUgY29tcGFyaXNvbiBhbmQgd2luZG93IG5vdGUgc3RyaXAgYWJvdmUgdGhlIHRhYmxlLCBmcm9tIHRoZSByZXBvcnRcbiAgICAgbGluZSBvZiB0aGUgbGF0ZXN0IHJlYWQ7IHRoZSB3aW5kb3dzJyBkZXNjcmlwdGlvbnMgYW5kIG5vdGVzIGdvIGluIGVhY2hcbiAgICAgY29sdW1uJ3MgXCJBYm91dCB0aGlzIGNvbHVtblwiIGluc3RlYWQuIC0tPlxuPGRpdiBjbGFzcz1cImZzLWNvbHVtbiBncmlkLXBhbmVcIj5cbiAgPGFwcC1yZXBvcnQtY29tcG9uZW50LW5vdGVcbiAgICBbZGF0YV09XCJub3RlRGF0YSgpXCJcbiAgICBbd2luZG93Tm90ZXNdPVwiZmFsc2VcIj5cbiAgPC9hcHAtcmVwb3J0LWNvbXBvbmVudC1ub3RlPlxuICA8IS0tIFRoZSBwYXJhbXMgYXJlIHNlZWRlZCBiZWZvcmUgdGhlIGZpcnN0IHJlbmRlciwgc28gdGhlIGdyaWQncyBmaXJzdCByZWFkXG4gICAgICAgY2FycmllcyB0aGUgdGlsZSdzIHJlcG9ydCBmaWx0ZXJzLiAtLT5cbiAgQGlmIChwYXJhbXMoKTsgYXMgcGFyYW1zKSB7XG4gICAgPGZzLWdyaWRcbiAgICAgIGNsYXNzPVwiZnMtZmxleFwiXG4gICAgICBbc291cmNlXT1cInNvdXJjZSgpXCJcbiAgICAgIFtsYXlvdXRdPVwibGF5b3V0KClcIlxuICAgICAgW3BhcmFtc109XCJwYXJhbXNcIlxuICAgICAgW2NvbnRyb2xzXT1cImNvbnRyb2xzKClcIlxuICAgICAgW2Zvcm1hdHRlcl09XCJmb3JtYXR0ZXIoKVwiXG4gICAgICAobGF5b3V0Q2hhbmdlKT1cInNldExheW91dCgkZXZlbnQpXCI+XG4gICAgPC9mcy1ncmlkPlxuICB9XG48L2Rpdj5cbiJdfQ==
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { GridFieldType, GridFormat, GridUnits, } from '@firestitch/grid';
|
|
2
|
+
import { ReportNumberUnits } from '../../enums/report-number-units.enum';
|
|
3
|
+
import { ReportValueFormat } from '../../enums/report-value-format.enum';
|
|
4
|
+
import { formatNumber, formatOutputValue, formatReportDate, numberFormat } from '../../format';
|
|
5
|
+
const VALUE_FORMATS = {
|
|
6
|
+
[GridFormat.Number]: ReportValueFormat.Number,
|
|
7
|
+
[GridFormat.Percent]: ReportValueFormat.Percent,
|
|
8
|
+
[GridFormat.Currency]: ReportValueFormat.Currency,
|
|
9
|
+
};
|
|
10
|
+
const NUMBER_UNITS = {
|
|
11
|
+
[GridUnits.None]: ReportNumberUnits.None,
|
|
12
|
+
[GridUnits.Thousands]: ReportNumberUnits.Thousands,
|
|
13
|
+
[GridUnits.Millions]: ReportNumberUnits.Millions,
|
|
14
|
+
[GridUnits.Auto]: ReportNumberUnits.Auto,
|
|
15
|
+
};
|
|
16
|
+
// What an abbreviated number's suffix multiplies it by, when a viewer types one.
|
|
17
|
+
const UNIT_SUFFIXES = { k: 1e3, m: 1e6 };
|
|
18
|
+
const YES = 'Yes';
|
|
19
|
+
const NO = 'No';
|
|
20
|
+
// A grid tile's formatter: every value written as the report writes it on
|
|
21
|
+
// a list today. An output number reads through formatOutputValue with what
|
|
22
|
+
// the report line says the output holds (a change is signed, a missing prior
|
|
23
|
+
// reads as the list's dash); a plain number through formatNumber; a date in
|
|
24
|
+
// the report's locale, an instant in its zone. The placement's format,
|
|
25
|
+
// precision and units win over the field's.
|
|
26
|
+
export function reportGridFormatter(context) {
|
|
27
|
+
return {
|
|
28
|
+
format: (value, field, placement) => formatGridValue(context, value, field, placement),
|
|
29
|
+
toNumber: (text, field, placement) => readGridNumber(context, text, field, placement),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function formatGridValue(context, value, field, placement) {
|
|
33
|
+
if (value === null || value === undefined || value === '') {
|
|
34
|
+
return '';
|
|
35
|
+
}
|
|
36
|
+
switch (field.type) {
|
|
37
|
+
case GridFieldType.Number:
|
|
38
|
+
return formatGridNumber(context, value, field, placement);
|
|
39
|
+
case GridFieldType.Date:
|
|
40
|
+
case GridFieldType.Datetime:
|
|
41
|
+
return formatReportDate(value, context.timezone, context.format.locale);
|
|
42
|
+
case GridFieldType.Boolean:
|
|
43
|
+
return value ? YES : NO;
|
|
44
|
+
default:
|
|
45
|
+
return optionLabel(value, field) ?? String(value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function formatGridNumber(context, value, field, placement) {
|
|
49
|
+
const spec = numberSpec(field, placement);
|
|
50
|
+
const output = isAggregate(placement) ? null : context.report?.outputs?.[field.name];
|
|
51
|
+
return output
|
|
52
|
+
? formatOutputValue(value, output, spec, context.format).text
|
|
53
|
+
: formatNumber(value, spec, context.format);
|
|
54
|
+
}
|
|
55
|
+
// The format, precision and units a number is written with: the placement's,
|
|
56
|
+
// else the field's.
|
|
57
|
+
function numberSpec(field, placement) {
|
|
58
|
+
const placed = placement;
|
|
59
|
+
const format = placed?.format ?? field.format;
|
|
60
|
+
const precision = placed?.precision ?? field.precision;
|
|
61
|
+
const units = placed?.units ?? field.units;
|
|
62
|
+
return {
|
|
63
|
+
...(format ? { format: VALUE_FORMATS[format] } : {}),
|
|
64
|
+
...(typeof precision === 'number' ? { precision } : {}),
|
|
65
|
+
...(units ? { units: NUMBER_UNITS[units] } : {}),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// A value placement is an aggregate of the field, not the output itself.
|
|
69
|
+
function isAggregate(placement) {
|
|
70
|
+
return !!placement?.aggregation;
|
|
71
|
+
}
|
|
72
|
+
function optionLabel(value, field) {
|
|
73
|
+
return field.options?.find((option) => option.key === value)?.label ?? null;
|
|
74
|
+
}
|
|
75
|
+
// A number a viewer typed, read in the report's locale: its grouping dropped,
|
|
76
|
+
// its decimal mark read, a K or M suffix multiplied out, and a percent of a
|
|
77
|
+
// ratio-percent report read back to its ratio. null when it is no number.
|
|
78
|
+
function readGridNumber(context, text, field, placement) {
|
|
79
|
+
const decimal = decimalMark(context.format.locale);
|
|
80
|
+
const trimmed = text.trim().toLowerCase();
|
|
81
|
+
const multiplier = UNIT_SUFFIXES[trimmed.slice(-1)] ?? 1;
|
|
82
|
+
const digits = trimmed
|
|
83
|
+
.split(decimal).map((part) => part.replace(/[^0-9-]/g, '')).join('.');
|
|
84
|
+
const number = digits && digits !== '-' && digits !== '.' ? Number(digits) * multiplier : NaN;
|
|
85
|
+
if (!Number.isFinite(number)) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
const isPercent = (placement?.format ?? field.format) === GridFormat.Percent;
|
|
89
|
+
return isPercent && context.format.ratioPercent ? number / 100 : number;
|
|
90
|
+
}
|
|
91
|
+
function decimalMark(locale) {
|
|
92
|
+
return numberFormat(locale, {}).formatToParts(1.5).find((part) => part.type === 'decimal')?.value ?? '.';
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWdyaWQtZm9ybWF0dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvY29tcG9uZW50LWdyaWQvcmVwb3J0LWdyaWQtZm9ybWF0dGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDa0IsYUFBYSxFQUFFLFVBQVUsRUFBNEIsU0FBUyxHQUN0RixNQUFNLGtCQUFrQixDQUFDO0FBRTFCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBZ0IvRixNQUFNLGFBQWEsR0FBb0Q7SUFDckUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsaUJBQWlCLENBQUMsTUFBTTtJQUM3QyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxPQUFPO0lBQy9DLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLFFBQVE7Q0FDbEQsQ0FBQztBQUVGLE1BQU0sWUFBWSxHQUFtRDtJQUNuRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO0lBQ3hDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLFNBQVM7SUFDbEQsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUUsaUJBQWlCLENBQUMsUUFBUTtJQUNoRCxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO0NBQ3pDLENBQUM7QUFFRixpRkFBaUY7QUFDakYsTUFBTSxhQUFhLEdBQXFDLEVBQUUsQ0FBQyxFQUFF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QUFDO0lBQ3pELE1BQU0sTUFBTSxHQUFHLE9BQU87U0FDbkIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEUsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLE1BQU0sS0FBSyxHQUFHLElBQUksTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBRTlGLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDN0IsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxTQUFTLEdBQUcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxVQUFVLENBQUMsT0FBTyxDQUFDO0lBRTdFLE9BQU8sU0FBUyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7QUFDMUUsQ0FBQztBQUVELFNBQVMsV0FBVyxDQUFDLE1BQWM7SUFDakMsT0FBTyxZQUFZLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLEVBQUUsS0FBSyxJQUFJLEdBQUcsQ0FBQztBQUMzRyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgR3JpZERldGFpbCwgR3JpZEZpZWxkLCBHcmlkRmllbGRUeXBlLCBHcmlkRm9ybWF0LCBHcmlkRm9ybWF0dGVyLCBHcmlkTGV2ZWwsIEdyaWRVbml0cywgR3JpZFZhbHVlLFxufSBmcm9tICdAZmlyZXN0aXRjaC9ncmlkJztcblxuaW1wb3J0IHsgUmVwb3J0TnVtYmVyVW5pdHMgfSBmcm9tICcuLi8uLi9lbnVtcy9yZXBvcnQtbnVtYmVyLXVuaXRzLmVudW0nO1xuaW1wb3J0IHsgUmVwb3J0VmFsdWVGb3JtYXQgfSBmcm9tICcuLi8uLi9lbnVtcy9yZXBvcnQtdmFsdWUtZm9ybWF0LmVudW0nO1xuaW1wb3J0IHsgZm9ybWF0TnVtYmVyLCBmb3JtYXRPdXRwdXRWYWx1ZSwgZm9ybWF0UmVwb3J0RGF0ZSwgbnVtYmVyRm9ybWF0IH0gZnJvbSAnLi4vLi4vZm9ybWF0JztcbmltcG9ydCB7IFJlcG9ydEdyaWRSZXBvcnQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC1ncmlkLXJlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTnVtYmVyRm9ybWF0U3BlYywgUmVwb3J0Rm9ybWF0Q29udGV4dCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5cblxudHlwZSBHcmlkUGxhY2VtZW50ID0gR3JpZFZhbHVlIHwgR3JpZERldGFpbCB8IEdyaWRMZXZlbDtcblxuLy8gV2hhdCBhIGdyaWQgdGlsZSBpcyB3cml0dGVuIHdpdGg6IHRoZSByZXBvcnQncyBsb2NhbGUsIGN1cnJlbmN5IGFuZFxuLy8gcGVyY2VudCBmb3JtLCB0aGUgem9uZSBpdHMgaW5zdGFudHMgcmVhZCBpbiwgYW5kIHRoZSByZXBvcnQgbGluZSBvZiBpdHNcbi8vIGxhdGVzdCByZWFkICh3aGF0IGVhY2ggb3V0cHV0IGZpZWxkIGhvbGRzKS5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0R3JpZEZvcm1hdENvbnRleHQge1xuICBmb3JtYXQ6IFJlcG9ydEZvcm1hdENvbnRleHQ7XG4gIHRpbWV6b25lOiBzdHJpbmc7XG4gIHJlcG9ydDogUmVwb3J0R3JpZFJlcG9ydCB8IG51bGw7XG59XG5cbmNvbnN0IFZBTFVFX0ZPUk1BVFM6IFJlYWRvbmx5PFJlY29yZDxHcmlkRm9ybWF0LCBSZXBvcnRWYWx1ZUZvcm1hdD4+ID0ge1xuICBbR3JpZEZvcm1hdC5OdW1iZXJdOiBSZXBvcnRWYWx1ZUZvcm1hdC5OdW1iZXIsXG4gIFtHcmlkRm9ybWF0LlBlcmNlbnRdOiBSZXBvcnRWYWx1ZUZvcm1hdC5QZXJjZW50LFxuICBbR3JpZEZvcm1hdC5DdXJyZW5jeV06IFJlcG9ydFZhbHVlRm9ybWF0LkN1cnJlbmN5LFxufTtcblxuY29uc3QgTlVNQkVSX1VOSVRTOiBSZWFkb25seTxSZWNvcmQ8R3JpZFVuaXRzLCBSZXBvcnROdW1iZXJVbml0cz4+ID0ge1xuICBbR3JpZFVuaXRzLk5vbmVdOiBSZXBvcnROdW1iZXJVbml0cy5Ob25lLFxuICBbR3JpZFVuaXRzLlRob3VzYW5kc106IFJlcG9ydE51bWJlclVuaXRzLlRob3VzYW5kcyxcbiAgW0dyaWRVbml0cy5NaWxsaW9uc106IFJlcG9ydE51bWJlclVuaXRzLk1pbGxpb25zLFxuICBbR3JpZFVuaXRzLkF1dG9dOiBSZXBvcnROdW1iZXJVbml0cy5BdXRvLFxufTtcblxuLy8gV2hhdCBhbiBhYmJyZXZpYXRlZCBudW1iZXIncyBzdWZmaXggbXVsdGlwbGllcyBpdCBieSwgd2hlbiBhIHZpZXdlciB0eXBlcyBvbmUuXG5jb25zdCBVTklUX1NVRkZJWEVTOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBudW1iZXI+PiA9IHsgazogMWUzLCBtOiAxZTYgfTtcblxuY29uc3QgWUVTID0gJ1llcyc7XG5jb25zdCBOTyA9ICdObyc7XG5cbi8vIEEgZ3JpZCB0aWxlJ3MgZm9ybWF0dGVyOiBldmVyeSB2YWx1ZSB3cml0dGVuIGFzIHRoZSByZXBvcnQgd3JpdGVzIGl0IG9uXG4vLyBhIGxpc3QgdG9kYXkuIEFuIG91dHB1dCBudW1iZXIgcmVhZHMgdGhyb3VnaCBmb3JtYXRPdXRwdXRWYWx1ZSB3aXRoIHdoYXRcbi8vIHRoZSByZXBvcnQgbGluZSBzYXlzIHRoZSBvdXRwdXQgaG9sZHMgKGEgY2hhbmdlIGlzIHNpZ25lZCwgYSBtaXNzaW5nIHByaW9yXG4vLyByZWFkcyBhcyB0aGUgbGlzdCdzIGRhc2gpOyBhIHBsYWluIG51bWJlciB0aHJvdWdoIGZvcm1hdE51bWJlcjsgYSBkYXRlIGluXG4vLyB0aGUgcmVwb3J0J3MgbG9jYWxlLCBhbiBpbnN0YW50IGluIGl0cyB6b25lLiBUaGUgcGxhY2VtZW50J3MgZm9ybWF0LFxuLy8gcHJlY2lzaW9uIGFuZCB1bml0cyB3aW4gb3ZlciB0aGUgZmllbGQncy5cbmV4cG9ydCBmdW5jdGlvbiByZXBvcnRHcmlkRm9ybWF0dGVyKGNvbnRleHQ6IFJlcG9ydEdyaWRGb3JtYXRDb250ZXh0KTogR3JpZEZvcm1hdHRlciB7XG4gIHJldHVybiB7XG4gICAgZm9ybWF0OiAodmFsdWUsIGZpZWxkLCBwbGFjZW1lbnQpID0+IGZvcm1hdEdyaWRWYWx1ZShjb250ZXh0LCB2YWx1ZSwgZmllbGQsIHBsYWNlbWVudCksXG4gICAgdG9OdW1iZXI6ICh0ZXh0LCBmaWVsZCwgcGxhY2VtZW50KSA9PiByZWFkR3JpZE51bWJlcihjb250ZXh0LCB0ZXh0LCBmaWVsZCwgcGxhY2VtZW50KSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0R3JpZFZhbHVlKFxuICBjb250ZXh0OiBSZXBvcnRHcmlkRm9ybWF0Q29udGV4dCxcbiAgdmFsdWU6IHVua25vd24sXG4gIGZpZWxkOiBHcmlkRmllbGQsXG4gIHBsYWNlbWVudD86IEdyaWRQbGFjZW1lbnQsXG4pOiBzdHJpbmcge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gJycpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBzd2l0Y2ggKGZpZWxkLnR5cGUpIHtcbiAgICBjYXNlIEdyaWRGaWVsZFR5cGUuTnVtYmVyOlxuICAgICAgcmV0dXJuIGZvcm1hdEdyaWROdW1iZXIoY29udGV4dCwgdmFsdWUsIGZpZWxkLCBwbGFjZW1lbnQpO1xuICAgIGNhc2UgR3JpZEZpZWxkVHlwZS5EYXRlOlxuICAgIGNhc2UgR3JpZEZpZWxkVHlwZS5EYXRldGltZTpcbiAgICAgIHJldHVybiBmb3JtYXRSZXBvcnREYXRlKHZhbHVlLCBjb250ZXh0LnRpbWV6b25lLCBjb250ZXh0LmZvcm1hdC5sb2NhbGUpO1xuICAgIGNhc2UgR3JpZEZpZWxkVHlwZS5Cb29sZWFuOlxuICAgICAgcmV0dXJuIHZhbHVlID8gWUVTIDogTk87XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBvcHRpb25MYWJlbCh2YWx1ZSwgZmllbGQpID8/IFN0cmluZyh2YWx1ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZm9ybWF0R3JpZE51bWJlcihcbiAgY29udGV4dDogUmVwb3J0R3JpZEZvcm1hdENvbnRleHQsXG4gIHZhbHVlOiB1bmtub3duLFxuICBmaWVsZDogR3JpZEZpZWxkLFxuICBwbGFjZW1lbnQ/OiBHcmlkUGxhY2VtZW50LFxuKTogc3RyaW5nIHtcbiAgY29uc3Qgc3BlYyA9IG51bWJlclNwZWMoZmllbGQsIHBsYWNlbWVudCk7XG4gIGNvbnN0IG91dHB1dCA9IGlzQWdncmVnYXRlKHBsYWNlbWVudCkgPyBudWxsIDogY29udGV4dC5yZXBvcnQ/Lm91dHB1dHM/LltmaWVsZC5uYW1lXTtcblxuICByZXR1cm4gb3V0cHV0XG4gICAgPyBmb3JtYXRPdXRwdXRWYWx1ZSh2YWx1ZSwgb3V0cHV0LCBzcGVjLCBjb250ZXh0LmZvcm1hdCkudGV4dFxuICAgIDogZm9ybWF0TnVtYmVyKHZhbHVlLCBzcGVjLCBjb250ZXh0LmZvcm1hdCk7XG59XG5cbi8vIFRoZSBmb3JtYXQsIHByZWNpc2lvbiBhbmQgdW5pdHMgYSBudW1iZXIgaXMgd3JpdHRlbiB3aXRoOiB0aGUgcGxhY2VtZW50J3MsXG4vLyBlbHNlIHRoZSBmaWVsZCdzLlxuZnVuY3Rpb24gbnVtYmVyU3BlYyhmaWVsZDogR3JpZEZpZWxkLCBwbGFjZW1lbnQ/OiBHcmlkUGxhY2VtZW50KTogTnVtYmVyRm9ybWF0U3BlYyB7XG4gIGNvbnN0IHBsYWNlZCA9IHBsYWNlbWVudCBhcyBHcmlkVmFsdWUgfCBHcmlkRGV0YWlsIHwgdW5kZWZpbmVkO1xuICBjb25zdCBmb3JtYXQgPSBwbGFjZWQ/LmZvcm1hdCA/PyBmaWVsZC5mb3JtYXQ7XG4gIGNvbnN0IHByZWNpc2lvbiA9IHBsYWNlZD8ucHJlY2lzaW9uID8/IGZpZWxkLnByZWNpc2lvbjtcbiAgY29uc3QgdW5pdHMgPSBwbGFjZWQ/LnVuaXRzID8/IGZpZWxkLnVuaXRzO1xuXG4gIHJldHVybiB7XG4gICAgLi4uKGZvcm1hdCA/IHsgZm9ybWF0OiBWQUxVRV9GT1JNQVRTW2Zvcm1hdF0gfSA6IHt9KSxcbiAgICAuLi4odHlwZW9mIHByZWNpc2lvbiA9PT0gJ251bWJlcicgPyB7IHByZWNpc2lvbiB9IDoge30pLFxuICAgIC4uLih1bml0cyA/IHsgdW5pdHM6IE5VTUJFUl9VTklUU1t1bml0c10gfSA6IHt9KSxcbiAgfTtcbn1cblxuLy8gQSB2YWx1ZSBwbGFjZW1lbnQgaXMgYW4gYWdncmVnYXRlIG9mIHRoZSBmaWVsZCwgbm90IHRoZSBvdXRwdXQgaXRzZWxmLlxuZnVuY3Rpb24gaXNBZ2dyZWdhdGUocGxhY2VtZW50PzogR3JpZFBsYWNlbWVudCk6IGJvb2xlYW4ge1xuICByZXR1cm4gISEocGxhY2VtZW50IGFzIEdyaWRWYWx1ZSB8IHVuZGVmaW5lZCk/LmFnZ3JlZ2F0aW9uO1xufVxuXG5mdW5jdGlvbiBvcHRpb25MYWJlbCh2YWx1ZTogdW5rbm93biwgZmllbGQ6IEdyaWRGaWVsZCk6IHN0cmluZyB8IG51bGwge1xuICByZXR1cm4gZmllbGQub3B0aW9ucz8uZmluZCgob3B0aW9uKSA9PiBvcHRpb24ua2V5ID09PSB2YWx1ZSk/LmxhYmVsID8/IG51bGw7XG59XG5cbi8vIEEgbnVtYmVyIGEgdmlld2VyIHR5cGVkLCByZWFkIGluIHRoZSByZXBvcnQncyBsb2NhbGU6IGl0cyBncm91cGluZyBkcm9wcGVkLFxuLy8gaXRzIGRlY2ltYWwgbWFyayByZWFkLCBhIEsgb3IgTSBzdWZmaXggbXVsdGlwbGllZCBvdXQsIGFuZCBhIHBlcmNlbnQgb2YgYVxuLy8gcmF0aW8tcGVyY2VudCByZXBvcnQgcmVhZCBiYWNrIHRvIGl0cyByYXRpby4gbnVsbCB3aGVuIGl0IGlzIG5vIG51bWJlci5cbmZ1bmN0aW9uIHJlYWRHcmlkTnVtYmVyKFxuICBjb250ZXh0OiBSZXBvcnRHcmlkRm9ybWF0Q29udGV4dCxcbiAgdGV4dDogc3RyaW5nLFxuICBmaWVsZDogR3JpZEZpZWxkLFxuICBwbGFjZW1lbnQ/OiBHcmlkVmFsdWUgfCBHcmlkRGV0YWlsLFxuKTogbnVtYmVyIHwgbnVsbCB7XG4gIGNvbnN0IGRlY2ltYWwgPSBkZWNpbWFsTWFyayhjb250ZXh0LmZvcm1hdC5sb2NhbGUpO1xuICBjb25zdCB0cmltbWVkID0gdGV4dC50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgY29uc3QgbXVsdGlwbGllciA9IFVOSVRfU1VGRklYRVNbdHJpbW1lZC5zbGljZSgtMSldID8/IDE7XG4gIGNvbnN0IGRpZ2l0cyA9IHRyaW1tZWRcbiAgICAuc3BsaXQoZGVjaW1hbCkubWFwKChwYXJ0KSA9PiBwYXJ0LnJlcGxhY2UoL1teMC05LV0vZywgJycpKS5qb2luKCcuJyk7XG4gIGNvbnN0IG51bWJlciA9IGRpZ2l0cyAmJiBkaWdpdHMgIT09ICctJyAmJiBkaWdpdHMgIT09ICcuJyA/IE51bWJlcihkaWdpdHMpICogbXVsdGlwbGllciA6IE5hTjtcblxuICBpZiAoIU51bWJlci5pc0Zpbml0ZShudW1iZXIpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBpc1BlcmNlbnQgPSAocGxhY2VtZW50Py5mb3JtYXQgPz8gZmllbGQuZm9ybWF0KSA9PT0gR3JpZEZvcm1hdC5QZXJjZW50O1xuXG4gIHJldHVybiBpc1BlcmNlbnQgJiYgY29udGV4dC5mb3JtYXQucmF0aW9QZXJjZW50ID8gbnVtYmVyIC8gMTAwIDogbnVtYmVyO1xufVxuXG5mdW5jdGlvbiBkZWNpbWFsTWFyayhsb2NhbGU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBudW1iZXJGb3JtYXQobG9jYWxlLCB7fSkuZm9ybWF0VG9QYXJ0cygxLjUpLmZpbmQoKHBhcnQpID0+IHBhcnQudHlwZSA9PT0gJ2RlY2ltYWwnKT8udmFsdWUgPz8gJy4nO1xufVxuIl19
|
|
@@ -365,7 +365,7 @@ export class ComponentTextComponent {
|
|
|
365
365
|
}
|
|
366
366
|
}
|
|
367
367
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
368
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ComponentTextComponent, isStandalone: true, selector: "app-report-component-text", inputs: { html: { classPropertyName: "html", publicName: "html", isSignal: true, isRequired: false, transformFunction: null }, tokens: { classPropertyName: "tokens", publicName: "tokens", isSignal: true, isRequired: true, transformFunction: null }, editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null }, shownElsewhere: { classPropertyName: "shownElsewhere", publicName: "shownElsewhere", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved", editEnded: "editEnded", valueSettings: "valueSettings" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "style.--text-size": "typeScale.body", "style.--text-h1-size": "typeScale.h1", "style.--text-h2-size": "typeScale.h2", "style.--text-h3-size": "typeScale.h3", "style.--text-color": "typeScale.color", "style.--text-table-border": "tableLook.border", "style.--text-table-padding": "tableLook.padding", "style.--text-table-margin": "tableLook.margin" } }, viewQueries: [{ propertyName: "_editor", first: true, predicate: FsHtmlEditorComponent, descendants: true, isSignal: true }, { propertyName: "_valuePopoverAnchor", first: true, predicate: ["valuePopoverAnchor"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "@if (editing()) {\n <!-- Floating fs-html-editor: no frame, Froala's inline toolbar pops up over\n the text. pointerdown stays here so a press in the text never starts a\n drag of the block or a pan of the canvas. -->\n <fs-html-editor\n class=\"text-content editing\"\n [config]=\"editorConfig\"\n [(ngModel)]=\"draft\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\">\n </fs-html-editor>\n\n <!-- One notice at a time: an edit stopped because it would have removed\n values, an edit that left values no text reads, or a refused command.\n mousedown keeps the editor's focus and selection, so Undo reaches it. -->\n @if (notice(); as current) {\n <div\n class=\"value-notice fs-row.gap-sm\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.preventDefault()\">\n @switch (current.kind) {\n @case ('blocked') {\n @if (current.block.removeSelection) {\n <span>\n This selection includes {{ current.block.count }} {{ current.block.count === 1 ? 'value' : 'values' }}.\n </span>\n <button\n mat-button\n color=\"primary\"\n type=\"button\"\n (click)=\"removeBlockedSelection()\">\n Remove text and {{ current.block.count === 1 ? 'value' : current.block.count + ' values' }}\n </button>\n } @else {\n <span>To take a value out, select it, then press Delete.</span>\n }\n }\n @case ('unused') {\n <span>{{ current.count }} {{ current.count === 1 ? 'value' : 'values' }} moved to Not used</span>\n <button\n mat-button\n color=\"primary\"\n type=\"button\"\n (click)=\"undoValuesUnused()\">\n Undo\n </button>\n }\n @case ('message') {\n <span>{{ current.text }}</span>\n }\n }\n <button\n mat-button\n type=\"button\"\n (click)=\"dismissNotice()\">\n Dismiss\n </button>\n </div>\n }\n} @else {\n <div\n class=\"text-content\"\n [innerHTML]=\"displayHtml()\">\n </div>\n}\n\n<!-- A clicked value chip's popover: an fs-popover on an invisible anchor laid\n over the chip (the chip itself belongs to the editor). Outside the editing\n block, so a popover still open when editing ends closes the usual way. -->\n<span\n #valuePopoverAnchor\n class=\"value-popover-anchor\"\n aria-hidden=\"true\"\n fsPopover\n trigger=\"click\"\n wrapperClass=\"value-popover-wrapper\"\n [template]=\"valuePopoverTemplate\"\n [indication]=\"false\"\n [maxWidth]=\"320\"\n [style.left.px]=\"valuePopover()?.left\"\n [style.top.px]=\"valuePopover()?.top\"\n [style.width.px]=\"valuePopover()?.width\"\n [style.height.px]=\"valuePopover()?.height\">\n</span>\n<ng-template\n #valuePopoverTemplate\n let-popover=\"popover\">\n <!-- What the value is, and its settings (where it can also be deleted); a\n chip naming no value on the page has no settings. -->\n <div class=\"value-popover fs-row\">\n <div class=\"fs-flex\">\n <div class=\"value-popover-name\">{{ valuePopoverValue()?.name ?? valuePopover()?.key }}</div>\n @if (!valuePopoverValue()) {\n <div class=\"small\">Not a value on this page</div>\n }\n </div>\n @if (valuePopoverValue()) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"value-popover-settings\"\n matTooltip=\"Settings\"\n (click)=\"openValueSettings(popover)\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:block;position:relative;width:100%;height:100%}.text-content{display:block;width:100%;height:100%;overflow:hidden;font-family:Arial,Helvetica,sans-serif;font-size:var(--text-size);line-height:1.25;color:var(--text-color);word-wrap:break-word;letter-spacing:normal;word-spacing:normal;font-weight:400;font-style:normal;text-transform:none;white-space:normal}.text-content ::ng-deep p,.text-content ::ng-deep h1,.text-content ::ng-deep h2,.text-content ::ng-deep h3,.text-content ::ng-deep ul,.text-content ::ng-deep ol{margin:0}.text-content ::ng-deep h1{font-size:var(--text-h1-size)}.text-content ::ng-deep h2{font-size:var(--text-h2-size)}.text-content ::ng-deep h3{font-size:var(--text-h3-size)}.text-content ::ng-deep h1,.text-content ::ng-deep h2,.text-content ::ng-deep h3{font-weight:700;line-height:1.2}.text-content ::ng-deep ul,.text-content ::ng-deep ol{padding-left:1.4em}.text-content ::ng-deep p:empty:before{content:\"\\200b\"}.text-content ::ng-deep a{color:inherit}.text-content ::ng-deep table{border-collapse:collapse;margin:var(--text-table-margin) 0}.text-content ::ng-deep th,.text-content ::ng-deep td{border:var(--text-table-border);padding:var(--text-table-padding);vertical-align:middle;text-align:left}.text-content ::ng-deep th{text-align:center;font-weight:700}.text-content.editing{overflow:auto;cursor:text}.text-content.editing ::ng-deep [data-embed-key],.text-content.editing ::ng-deep [data-embed-field]{padding:0 2px;border-radius:3px;background-color:#4e79a729;-webkit-user-select:all;user-select:all}.text-content.editing ::ng-deep [data-embed-key]{cursor:pointer}.text-content.editing ::ng-deep [data-embed-key]:hover{background-color:#4e79a747}.text-content.editing ::ng-deep [data-embed-missing]{background-color:#e1575924;outline:1px dashed rgba(225,87,89,.7)}.text-content.editing ::ng-deep th,.text-content.editing ::ng-deep tfoot td{background-color:transparent}.text-content.editing ::ng-deep .fr-table-selector{display:none}.text-content.editing ::ng-deep .fr-table-selection-hover{outline:none}.value-popover-anchor{position:absolute;pointer-events:none}::ng-deep .value-popover-wrapper .popover-content{padding:15px!important}.value-popover{gap:15px}.value-popover-name{font-weight:600}.value-popover-settings{--mdc-icon-button-state-layer-size: 24px;width:24px;height:24px;padding:0}.value-notice{position:absolute;top:100%;left:0;z-index:2;margin-top:4px;padding:2px 4px 2px 10px;border:1px solid #d9dee3;border-radius:4px;background:#fff;white-space:nowrap;font-family:Arial,Helvetica,sans-serif}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: FsHtmlEditorComponent, selector: "fs-html-editor", inputs: ["config", "disabled"] }, { kind: "directive", type: FsPopoverDirective, selector: "[fsPopover]", inputs: ["text", "template", "data", "leaveDelay", "showDelay", "maxWidth", "maxHeight", "wrapperClass", "autoShow", "autoClose", "loadingDiameter", "loading", "indication", "position", "theme", "size", "trigger", "enabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
368
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ComponentTextComponent, isStandalone: true, selector: "app-report-component-text", inputs: { html: { classPropertyName: "html", publicName: "html", isSignal: true, isRequired: false, transformFunction: null }, tokens: { classPropertyName: "tokens", publicName: "tokens", isSignal: true, isRequired: true, transformFunction: null }, editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null }, shownElsewhere: { classPropertyName: "shownElsewhere", publicName: "shownElsewhere", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved", editEnded: "editEnded", valueSettings: "valueSettings" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "style.--text-size": "typeScale.body", "style.--text-h1-size": "typeScale.h1", "style.--text-h2-size": "typeScale.h2", "style.--text-h3-size": "typeScale.h3", "style.--text-color": "typeScale.color", "style.--text-table-border": "tableLook.border", "style.--text-table-padding": "tableLook.padding", "style.--text-table-margin": "tableLook.margin" } }, viewQueries: [{ propertyName: "_editor", first: true, predicate: FsHtmlEditorComponent, descendants: true, isSignal: true }, { propertyName: "_valuePopoverAnchor", first: true, predicate: ["valuePopoverAnchor"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "@if (editing()) {\n <!-- Floating fs-html-editor: no frame, Froala's inline toolbar pops up over\n the text. pointerdown stays here so a press in the text never starts a\n drag of the block or a pan of the canvas. -->\n <fs-html-editor\n class=\"text-content editing\"\n [config]=\"editorConfig\"\n [(ngModel)]=\"draft\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\">\n </fs-html-editor>\n\n <!-- One notice at a time: an edit stopped because it would have removed\n values, an edit that left values no text reads, or a refused command.\n mousedown keeps the editor's focus and selection, so Undo reaches it. -->\n @if (notice(); as current) {\n <div\n class=\"value-notice fs-row.gap-sm\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.preventDefault()\">\n @switch (current.kind) {\n @case ('blocked') {\n @if (current.block.removeSelection) {\n <span>\n This selection includes {{ current.block.count }} {{ current.block.count === 1 ? 'value' : 'values' }}.\n </span>\n <button\n mat-button\n color=\"primary\"\n type=\"button\"\n (click)=\"removeBlockedSelection()\">\n Remove text and {{ current.block.count === 1 ? 'value' : current.block.count + ' values' }}\n </button>\n } @else {\n <span>To take a value out, select it, then press Delete.</span>\n }\n }\n @case ('unused') {\n <span>{{ current.count }} {{ current.count === 1 ? 'value' : 'values' }} moved to Not used</span>\n <button\n mat-button\n color=\"primary\"\n type=\"button\"\n (click)=\"undoValuesUnused()\">\n Undo\n </button>\n }\n @case ('message') {\n <span>{{ current.text }}</span>\n }\n }\n <button\n mat-button\n type=\"button\"\n (click)=\"dismissNotice()\">\n Dismiss\n </button>\n </div>\n }\n} @else {\n <div\n class=\"text-content\"\n [innerHTML]=\"displayHtml()\">\n </div>\n}\n\n<!-- A clicked value chip's popover: an fs-popover on an invisible anchor laid\n over the chip (the chip itself belongs to the editor). Outside the editing\n block, so a popover still open when editing ends closes the usual way. -->\n<span\n #valuePopoverAnchor\n class=\"value-popover-anchor\"\n aria-hidden=\"true\"\n fsPopover\n trigger=\"click\"\n wrapperClass=\"value-popover-wrapper\"\n [template]=\"valuePopoverTemplate\"\n [indication]=\"false\"\n [maxWidth]=\"320\"\n [style.left.px]=\"valuePopover()?.left\"\n [style.top.px]=\"valuePopover()?.top\"\n [style.width.px]=\"valuePopover()?.width\"\n [style.height.px]=\"valuePopover()?.height\">\n</span>\n<ng-template\n #valuePopoverTemplate\n let-popover=\"popover\">\n <!-- What the value is, and its settings (where it can also be deleted); a\n chip naming no value on the page has no settings. -->\n <div class=\"value-popover fs-row\">\n <div class=\"fs-flex\">\n <div class=\"value-popover-name\">{{ valuePopoverValue()?.name ?? valuePopover()?.key }}</div>\n @if (!valuePopoverValue()) {\n <div class=\"small\">Not a value on this page</div>\n }\n </div>\n @if (valuePopoverValue()) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"value-popover-settings\"\n matTooltip=\"Settings\"\n (click)=\"openValueSettings(popover)\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:block;position:relative;width:100%;height:100%}.text-content{display:block;width:100%;height:100%;overflow:hidden;font-family:Arial,Helvetica,sans-serif;font-size:var(--text-size);line-height:1.25;color:var(--text-color);word-wrap:break-word;letter-spacing:normal;word-spacing:normal;font-weight:400;font-style:normal;text-transform:none;white-space:normal}.text-content ::ng-deep p,.text-content ::ng-deep h1,.text-content ::ng-deep h2,.text-content ::ng-deep h3,.text-content ::ng-deep ul,.text-content ::ng-deep ol{margin:0}.text-content ::ng-deep h1{font-size:var(--text-h1-size)}.text-content ::ng-deep h2{font-size:var(--text-h2-size)}.text-content ::ng-deep h3{font-size:var(--text-h3-size)}.text-content ::ng-deep h1,.text-content ::ng-deep h2,.text-content ::ng-deep h3{font-weight:700;line-height:1.2}.text-content ::ng-deep ul,.text-content ::ng-deep ol{padding-left:1.4em}.text-content ::ng-deep p:empty:before{content:\"\\200b\"}.text-content ::ng-deep a{color:inherit}.text-content ::ng-deep table{border-collapse:collapse;margin:var(--text-table-margin) 0}.text-content ::ng-deep th,.text-content ::ng-deep td{border:var(--text-table-border);padding:var(--text-table-padding);vertical-align:middle;text-align:left}.text-content ::ng-deep th{text-align:center;font-weight:700}.text-content.editing{overflow:auto;cursor:text}.text-content.editing ::ng-deep [data-embed-key],.text-content.editing ::ng-deep [data-embed-field]{padding:0 2px;border-radius:3px;background-color:#4e79a729;-webkit-user-select:all;user-select:all}.text-content.editing ::ng-deep [data-embed-key]{cursor:pointer}.text-content.editing ::ng-deep [data-embed-key]:hover{background-color:#4e79a747}.text-content.editing ::ng-deep [data-embed-missing]{background-color:#e1575924;outline:1px dashed rgba(225,87,89,.7)}.text-content.editing ::ng-deep th,.text-content.editing ::ng-deep tfoot td{background-color:transparent}.text-content.editing ::ng-deep .fr-table-selector{display:none}.text-content.editing ::ng-deep .fr-table-selection-hover{outline:none}.value-popover-anchor{position:absolute;pointer-events:none}::ng-deep .value-popover-wrapper .popover-content{padding:15px!important}.value-popover{gap:15px}.value-popover-name{font-weight:600}.value-popover-settings{--mdc-icon-button-state-layer-size: 24px;width:24px;height:24px;padding:0}.value-notice{position:absolute;top:100%;left:0;z-index:2;margin-top:4px;padding:2px 4px 2px 10px;border:1px solid #d9dee3;border-radius:4px;background:#fff;white-space:nowrap;font-family:Arial,Helvetica,sans-serif}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: FsHtmlEditorComponent, selector: "fs-html-editor", inputs: ["config", "disabled"] }, { kind: "directive", type: FsPopoverDirective, selector: "[fsPopover]", inputs: ["text", "template", "data", "leaveDelay", "showDelay", "maxWidth", "maxHeight", "wrapperClass", "autoShow", "autoClose", "loadingDiameter", "loading", "indication", "position", "theme", "size", "trigger", "enabled", "panel"], outputs: ["closed"], exportAs: ["fsPopover"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
369
369
|
}
|
|
370
370
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentTextComponent, decorators: [{
|
|
371
371
|
type: Component,
|