@firestitch/report 18.21.1 → 18.21.3
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 +2 -1
- package/app/reports/services/report-filter-state.service.d.ts +1 -1
- package/esm2022/app/reports/components/component-grid/component-grid.component.mjs +30 -17
- package/esm2022/app/reports/components/component-grid/report-grid-formatter.mjs +23 -6
- package/esm2022/app/reports/components/component-list/component-list.component.mjs +5 -4
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +16 -14
- package/esm2022/app/reports/services/report-filter-state.service.mjs +13 -9
- package/fesm2022/{firestitch-report-echarts-D1UDj4L9.mjs → firestitch-report-echarts-CUVOSBvJ.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-D1UDj4L9.mjs.map → firestitch-report-echarts-CUVOSBvJ.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-cys9XusN.mjs → firestitch-report-firestitch-report-CfvBTMrG.mjs} +86 -49
- package/fesm2022/{firestitch-report-firestitch-report-cys9XusN.mjs.map → firestitch-report-firestitch-report-CfvBTMrG.mjs.map} +1 -1
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +1 -1
package/fesm2022/{firestitch-report-echarts-D1UDj4L9.mjs → firestitch-report-echarts-CUVOSBvJ.mjs}
RENAMED
|
@@ -4,7 +4,7 @@ import * as echarts from 'echarts/core';
|
|
|
4
4
|
export { echarts as default };
|
|
5
5
|
import { LabelLayout } from 'echarts/features';
|
|
6
6
|
import { CanvasRenderer } from 'echarts/renderers';
|
|
7
|
-
import { R as REPORT_CHART_COLORS_CSS, a as REPORT_CHART_FONT_FAMILY, b as REPORT_AXIS_LABEL_FONT_SIZE } from './firestitch-report-firestitch-report-
|
|
7
|
+
import { R as REPORT_CHART_COLORS_CSS, a as REPORT_CHART_FONT_FAMILY, b as REPORT_AXIS_LABEL_FONT_SIZE } from './firestitch-report-firestitch-report-CfvBTMrG.mjs';
|
|
8
8
|
|
|
9
9
|
// Tree-shaken ECharts build for the reports renderer: only the chart types and
|
|
10
10
|
// components the option-builder emits are registered, keeping the lazy chunk
|
|
@@ -63,4 +63,4 @@ echarts.registerTheme('report', {
|
|
|
63
63
|
axisLabel: { color: '#52606d', fontSize: REPORT_AXIS_LABEL_FONT_SIZE },
|
|
64
64
|
},
|
|
65
65
|
});
|
|
66
|
-
//# sourceMappingURL=firestitch-report-echarts-
|
|
66
|
+
//# sourceMappingURL=firestitch-report-echarts-CUVOSBvJ.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firestitch-report-echarts-
|
|
1
|
+
{"version":3,"file":"firestitch-report-echarts-CUVOSBvJ.mjs","sources":["../../src/app/reports/theme/echarts.ts"],"sourcesContent":["// Tree-shaken ECharts build for the reports renderer: only the chart types and\n// components the option-builder emits are registered, keeping the lazy chunk\n// lean. Loaded on demand by ngx-echarts via provideEchartsCore — see\n// REPORT_ECHARTS_PROVIDERS in reports-echarts.provider.ts.\n//\n// The canvas renderer (not SVG) is deliberate: chart.getDataURL() needs it for\n// the high-res images the PPT/PDF exports will use.\n\nimport { BarChart, LineChart, PieChart } from 'echarts/charts';\nimport {\n DatasetComponent,\n GridComponent,\n LegendComponent,\n MarkAreaComponent,\n MarkLineComponent,\n TooltipComponent,\n} from 'echarts/components';\nimport * as echarts from 'echarts/core';\nimport { LabelLayout } from 'echarts/features';\nimport { CanvasRenderer } from 'echarts/renderers';\n\nimport { REPORT_CHART_COLORS_CSS } from './palette';\nimport { REPORT_AXIS_LABEL_FONT_SIZE, REPORT_CHART_FONT_FAMILY } from './typography';\n\necharts.use([\n BarChart,\n LineChart,\n PieChart,\n GridComponent,\n TooltipComponent,\n LegendComponent,\n DatasetComponent,\n // Reference lines and statistic lines (markLine), reference bands\n // (markArea), and the overlap hiding of 'auto' data labels (LabelLayout).\n MarkLineComponent,\n MarkAreaComponent,\n LabelLayout,\n CanvasRenderer,\n]);\n\n// The house theme — the single place report chart \"standards\" live (palette,\n// typography, tooltip styling). Polished defaults now; refined in the polish\n// phase.\necharts.registerTheme('report', {\n color: REPORT_CHART_COLORS_CSS,\n textStyle: {\n fontFamily: REPORT_CHART_FONT_FAMILY,\n },\n title: {\n textStyle: { color: '#1f2933', fontSize: 14, fontWeight: 600 },\n },\n legend: {\n textStyle: { color: '#52606d', fontSize: 11 },\n },\n tooltip: {\n backgroundColor: 'rgba(31, 41, 51, 0.92)',\n borderWidth: 0,\n textStyle: { color: '#fff', fontSize: 12 },\n },\n categoryAxis: {\n axisLine: { lineStyle: { color: '#cbd2d9' } },\n axisTick: { show: false },\n axisLabel: { color: '#52606d', fontSize: REPORT_AXIS_LABEL_FONT_SIZE },\n splitLine: { show: false },\n },\n valueAxis: {\n axisLine: { show: false },\n axisLabel: { color: '#52606d', fontSize: REPORT_AXIS_LABEL_FONT_SIZE },\n splitLine: { lineStyle: { color: '#e4e7eb' } },\n },\n timeAxis: {\n axisLine: { lineStyle: { color: '#cbd2d9' } },\n axisLabel: { color: '#52606d', fontSize: REPORT_AXIS_LABEL_FONT_SIZE },\n },\n});\n\nexport default echarts;\n"],"names":[],"mappings":";;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAkBA,OAAO,CAAC,GAAG,CAAC;IACV,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,gBAAgB;;;IAGhB,iBAAiB;IACjB,iBAAiB;IACjB,WAAW;IACX,cAAc;AACf,CAAA,CAAC,CAAC;AAEH;AACA;AACA;AACA,OAAO,CAAC,aAAa,CAAC,QAAQ,EAAE;AAC9B,IAAA,KAAK,EAAE,uBAAuB;AAC9B,IAAA,SAAS,EAAE;AACT,QAAA,UAAU,EAAE,wBAAwB;AACrC,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE;AAC/D,KAAA;AACD,IAAA,MAAM,EAAE;QACN,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE;AAC9C,KAAA;AACD,IAAA,OAAO,EAAE;AACP,QAAA,eAAe,EAAE,wBAAwB;AACzC,QAAA,WAAW,EAAE,CAAC;QACd,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE;AAC3C,KAAA;AACD,IAAA,YAAY,EAAE;QACZ,QAAQ,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;AAC7C,QAAA,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;QACzB,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,2BAA2B,EAAE;AACtE,QAAA,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;AAC3B,KAAA;AACD,IAAA,SAAS,EAAE;AACT,QAAA,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;QACzB,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,2BAA2B,EAAE;QACtE,SAAS,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;AAC/C,KAAA;AACD,IAAA,QAAQ,EAAE;QACR,QAAQ,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;QAC7C,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,2BAA2B,EAAE;AACvE,KAAA;AACF,CAAA,CAAC"}
|
|
@@ -7955,19 +7955,23 @@ class ReportFilterStateService {
|
|
|
7955
7955
|
this._stateChanged$.next();
|
|
7956
7956
|
}
|
|
7957
7957
|
// Notifications relevant to ONE component: any change to a group one of its
|
|
7958
|
-
// filters belongs to (or a full re-init).
|
|
7958
|
+
// filters belongs to (or a full re-init). The component is read on each
|
|
7959
|
+
// event, never captured at subscribe: a tile keeps its subscription across
|
|
7960
|
+
// report loads, so a filter added to it while the report is open (the MCP,
|
|
7961
|
+
// a chat edit, the settings dialog) reaches it on the first change of its
|
|
7962
|
+
// group.
|
|
7959
7963
|
changesFor(component) {
|
|
7960
|
-
const groupIds = new Set((component.filters ?? []).map((filter) => filter.filterGroupId));
|
|
7961
7964
|
return this._changed$.asObservable()
|
|
7962
|
-
.pipe(filter((groupId) => groupId === null
|
|
7965
|
+
.pipe(filter((groupId) => groupId === null
|
|
7966
|
+
|| (component().filters ?? []).some((filter) => filter.filterGroupId === groupId)));
|
|
7963
7967
|
}
|
|
7964
7968
|
// Notifications relevant to ANY of a set of components that comes and goes
|
|
7965
7969
|
// (a page's values): a change to a group one of their filters belongs to.
|
|
7966
|
-
//
|
|
7967
|
-
//
|
|
7968
|
-
//
|
|
7969
|
-
//
|
|
7970
|
-
//
|
|
7970
|
+
// Like changesFor, the set is read on each event, so one subscription
|
|
7971
|
+
// follows the set as the report reloads. Unlike it, a full re-init (null)
|
|
7972
|
+
// is not passed on: init() runs on a report (re)load, and a caller of this
|
|
7973
|
+
// checks on that reload itself whether the filter values its components
|
|
7974
|
+
// are read with moved.
|
|
7971
7975
|
changesForAny(components) {
|
|
7972
7976
|
return this._changed$.asObservable()
|
|
7973
7977
|
.pipe(filter((groupId) => groupId !== null
|
|
@@ -9958,6 +9962,18 @@ const NUMBER_UNITS = {
|
|
|
9958
9962
|
};
|
|
9959
9963
|
// What an abbreviated number's suffix multiplies it by, when a viewer types one.
|
|
9960
9964
|
const UNIT_SUFFIXES = { k: 1e3, m: 1e6 };
|
|
9965
|
+
// A column written in thousands or millions is typed in them: the grid's
|
|
9966
|
+
// filter shows its K or M beside the inputs, so 12 there means 12,000. A K or
|
|
9967
|
+
// M typed after the digits wins, so 12K is still 12,000.
|
|
9968
|
+
const TYPED_UNITS = {
|
|
9969
|
+
[GridUnits.Thousands]: 1e3,
|
|
9970
|
+
[GridUnits.Millions]: 1e6,
|
|
9971
|
+
};
|
|
9972
|
+
// The significant digits a scaled typed number keeps, as fs-grid's own reader
|
|
9973
|
+
// keeps them: scaling leaves binary noise behind (12.3% reads
|
|
9974
|
+
// 0.12300000000000001, 1.005K 1004.9999999999999), which would move a range's
|
|
9975
|
+
// end past the very value it names.
|
|
9976
|
+
const TYPED_DIGITS = 15;
|
|
9961
9977
|
const YES = 'Yes';
|
|
9962
9978
|
const NO = 'No';
|
|
9963
9979
|
// A grid tile's formatter: every value written as the report writes it on
|
|
@@ -10035,20 +10051,25 @@ function optionLabel(value, field) {
|
|
|
10035
10051
|
return field.options?.find((option) => option.key === value)?.label ?? null;
|
|
10036
10052
|
}
|
|
10037
10053
|
// A number a viewer typed, read in the report's locale: its grouping dropped,
|
|
10038
|
-
// its decimal mark read, a K or M suffix multiplied out
|
|
10039
|
-
//
|
|
10054
|
+
// its decimal mark read, a K or M suffix multiplied out (else the column's own
|
|
10055
|
+
// thousands or millions), and a percent of a ratio-percent report read back to
|
|
10056
|
+
// its ratio. The placement's units and format win over the field's, as they do
|
|
10057
|
+
// where the number is written (numberSpec). null when it is no number.
|
|
10040
10058
|
function readGridNumber(context, text, field, placement) {
|
|
10041
10059
|
const decimal = decimalMark(context.format.locale);
|
|
10042
10060
|
const trimmed = text.trim().toLowerCase();
|
|
10043
|
-
const multiplier = UNIT_SUFFIXES[trimmed.slice(-1)]
|
|
10061
|
+
const multiplier = UNIT_SUFFIXES[trimmed.slice(-1)]
|
|
10062
|
+
?? TYPED_UNITS[placement?.units ?? field.units ?? GridUnits.None]
|
|
10063
|
+
?? 1;
|
|
10044
10064
|
const digits = trimmed
|
|
10045
10065
|
.split(decimal).map((part) => part.replace(/[^0-9-]/g, '')).join('.');
|
|
10046
10066
|
const number = digits && digits !== '-' && digits !== '.' ? Number(digits) * multiplier : NaN;
|
|
10047
10067
|
if (!Number.isFinite(number)) {
|
|
10048
10068
|
return null;
|
|
10049
10069
|
}
|
|
10050
|
-
const
|
|
10051
|
-
|
|
10070
|
+
const isRatio = (placement?.format ?? field.format) === GridFormat.Percent && context.format.ratioPercent;
|
|
10071
|
+
const value = isRatio ? number / 100 : number;
|
|
10072
|
+
return multiplier === 1 && !isRatio ? value : Number(value.toPrecision(TYPED_DIGITS));
|
|
10052
10073
|
}
|
|
10053
10074
|
function decimalMark(locale) {
|
|
10054
10075
|
return numberFormat(locale, {}).formatToParts(1.5).find((part) => part.type === 'decimal')?.value ?? '.';
|
|
@@ -10065,9 +10086,14 @@ function decimalMark(locale) {
|
|
|
10065
10086
|
// re-init the filter state) reads the table again at once, even when its
|
|
10066
10087
|
// filters did not move: the rows behind it, or its own query, may have.
|
|
10067
10088
|
// The load is counted into the params (reportLoads), since fs-grid reads
|
|
10068
|
-
// only when they move. The
|
|
10069
|
-
//
|
|
10070
|
-
//
|
|
10089
|
+
// only when they move. The params are derived from the tile as it is
|
|
10090
|
+
// drawn (params), so the read of a load carries the filters the load
|
|
10091
|
+
// brought, a filter added since the report opened included, and lands in
|
|
10092
|
+
// the same tick as the reloaded tile: a load that also moves the authored
|
|
10093
|
+
// layout costs one read.
|
|
10094
|
+
// - Which filter groups and whether the group-by reach the tile is read
|
|
10095
|
+
// from the tile as it stands at each change, never as it was drawn: a
|
|
10096
|
+
// filter added while the report is open reads on its first pick.
|
|
10071
10097
|
// - The layout on screen is the state service's (gridLayout): the viewer's
|
|
10072
10098
|
// own while they changed it from the layout authored now, else the
|
|
10073
10099
|
// authored one. It outlives a page switch, and the chat reads it. So do
|
|
@@ -10091,7 +10117,16 @@ function decimalMark(locale) {
|
|
|
10091
10117
|
class ComponentGridComponent {
|
|
10092
10118
|
reportId = input.required();
|
|
10093
10119
|
component = input.required();
|
|
10094
|
-
params
|
|
10120
|
+
// What fs-grid reads with: the tile's params (_readParams) for the
|
|
10121
|
+
// component drawn now, read again at each settled change (_paramsRead).
|
|
10122
|
+
// A load re-inits the filter state a tick before the tile gets the
|
|
10123
|
+
// component it brought, so deriving them here is what puts a filter added
|
|
10124
|
+
// by that load into its read.
|
|
10125
|
+
params = computed(() => {
|
|
10126
|
+
const component = this.component();
|
|
10127
|
+
this._paramsRead();
|
|
10128
|
+
return untracked(() => this._readParams(component));
|
|
10129
|
+
});
|
|
10095
10130
|
controls = computed(() => this.component().config?.controls ?? {});
|
|
10096
10131
|
source = computed(() => new ReportGridSource(this._reportData, this.reportId(), this._componentId(), {
|
|
10097
10132
|
locale: () => this._filterState.formatContext().locale,
|
|
@@ -10118,6 +10153,8 @@ class ComponentGridComponent {
|
|
|
10118
10153
|
_paramsVersion = 0;
|
|
10119
10154
|
// The report loads seen since the tile was drawn (ReportGridParams).
|
|
10120
10155
|
_reportLoads = 0;
|
|
10156
|
+
// Moves each time a settled change has the params read again.
|
|
10157
|
+
_paramsRead = signal(0);
|
|
10121
10158
|
ngOnInit() {
|
|
10122
10159
|
this.expansion.set(this._filterState.gridExpansion(this.component()));
|
|
10123
10160
|
this._init();
|
|
@@ -10131,16 +10168,14 @@ class ComponentGridComponent {
|
|
|
10131
10168
|
}
|
|
10132
10169
|
_init() {
|
|
10133
10170
|
this._paramsVersion = this._filterState.stateVersion();
|
|
10134
|
-
this.params.set(this._readParams());
|
|
10135
10171
|
// A null group is a full re-init: a report load, or a reset.
|
|
10136
|
-
this._filterState.changesFor(this.component
|
|
10172
|
+
this._filterState.changesFor(this.component)
|
|
10137
10173
|
.pipe(switchMap$1((groupId) => this._settled$(groupId === null)), tap$1((isLoad) => this._applyParams(isLoad)), takeUntilDestroyed(this._destroyRef))
|
|
10138
10174
|
.subscribe();
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
}
|
|
10175
|
+
// A load can make the table follow the group-by, or stop.
|
|
10176
|
+
this._filterState.frequencyChanges()
|
|
10177
|
+
.pipe(filter$1(() => followsGroupBy(this.component())), tap$1(() => this._applyParams()), takeUntilDestroyed(this._destroyRef))
|
|
10178
|
+
.subscribe();
|
|
10144
10179
|
}
|
|
10145
10180
|
// Once the tile's first read is in, its notes prune the viewer's layout
|
|
10146
10181
|
// (prunedGridLayout). A tile showing its authored layout has nothing to
|
|
@@ -10181,12 +10216,11 @@ class ComponentGridComponent {
|
|
|
10181
10216
|
this._reportLoads++;
|
|
10182
10217
|
}
|
|
10183
10218
|
this._paramsVersion = this._filterState.stateVersion();
|
|
10184
|
-
this.
|
|
10219
|
+
this._paramsRead.update((count) => count + 1);
|
|
10185
10220
|
}
|
|
10186
10221
|
// The tile's report filters, 'any' groups and group-by grain as they stand
|
|
10187
10222
|
// (tileState()), and the report loads it has seen.
|
|
10188
|
-
_readParams() {
|
|
10189
|
-
const component = this.component();
|
|
10223
|
+
_readParams(component) {
|
|
10190
10224
|
const { matchAnyGroupIds, frequency } = this._filterState.tileState(component);
|
|
10191
10225
|
return {
|
|
10192
10226
|
filters: this._filterState.resolveForComponent(component),
|
|
@@ -10196,7 +10230,7 @@ class ComponentGridComponent {
|
|
|
10196
10230
|
};
|
|
10197
10231
|
}
|
|
10198
10232
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10199
|
-
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
|
|
10233
|
+
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 read from the tile drawn (params), from its first\n render on, so every read carries the tile's report filters. -->\n <fs-grid\n class=\"fs-flex\"\n [source]=\"source()\"\n [layout]=\"layout()\"\n [expansion]=\"expansion()\"\n [clearedFilter]=\"clearedFilter()\"\n (expansionChange)=\"setExpansion($event)\"\n [params]=\"params()\"\n [controls]=\"controls()\"\n [formatter]=\"formatter()\"\n (layoutChange)=\"setLayout($event)\">\n <ng-template fsGridCell let-value let-field=\"field\" let-record=\"record\" let-text=\"text\">\n @if (value | fsReportGridCell: field : record : text : noteData() : formatContext(); as shown) {\n <!-- A cell that says why (a missing or zero prior) opens it on a\n click; no cell carries a native tooltip. -->\n @if (shown.title) {\n <span\n class=\"explained\"\n fsPopover\n trigger=\"click\"\n [template]=\"explanation\"\n [indication]=\"false\"\n [maxWidth]=\"320\">\n {{ shown.text }}\n </span>\n <ng-template #explanation>{{ shown.title }}</ng-template>\n } @else {\n <span>{{ shown.text }}</span>\n }\n }\n </ng-template>\n </fs-grid>\n</div>\n", styles: [":host{display:block;height:100%}.grid-pane{height:100%;min-height:0}fs-grid{min-height:0}.explained{cursor:pointer;text-decoration:underline dotted;text-underline-offset:2px}\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: "directive", type: FsGridCellDirective, selector: "[fsGridCell]" }, { 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"] }, { kind: "component", type: ComponentNoteComponent, selector: "app-report-component-note", inputs: ["data", "windows", "windowDescriptions", "windowNotes"] }, { kind: "pipe", type: ReportGridCellPipe, name: "fsReportGridCell" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10200
10234
|
}
|
|
10201
10235
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentGridComponent, decorators: [{
|
|
10202
10236
|
type: Component,
|
|
@@ -10206,7 +10240,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
10206
10240
|
FsPopoverDirective,
|
|
10207
10241
|
ComponentNoteComponent,
|
|
10208
10242
|
ReportGridCellPipe,
|
|
10209
|
-
], 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
|
|
10243
|
+
], 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 read from the tile drawn (params), from its first\n render on, so every read carries the tile's report filters. -->\n <fs-grid\n class=\"fs-flex\"\n [source]=\"source()\"\n [layout]=\"layout()\"\n [expansion]=\"expansion()\"\n [clearedFilter]=\"clearedFilter()\"\n (expansionChange)=\"setExpansion($event)\"\n [params]=\"params()\"\n [controls]=\"controls()\"\n [formatter]=\"formatter()\"\n (layoutChange)=\"setLayout($event)\">\n <ng-template fsGridCell let-value let-field=\"field\" let-record=\"record\" let-text=\"text\">\n @if (value | fsReportGridCell: field : record : text : noteData() : formatContext(); as shown) {\n <!-- A cell that says why (a missing or zero prior) opens it on a\n click; no cell carries a native tooltip. -->\n @if (shown.title) {\n <span\n class=\"explained\"\n fsPopover\n trigger=\"click\"\n [template]=\"explanation\"\n [indication]=\"false\"\n [maxWidth]=\"320\">\n {{ shown.text }}\n </span>\n <ng-template #explanation>{{ shown.title }}</ng-template>\n } @else {\n <span>{{ shown.text }}</span>\n }\n }\n </ng-template>\n </fs-grid>\n</div>\n", styles: [":host{display:block;height:100%}.grid-pane{height:100%;min-height:0}fs-grid{min-height:0}.explained{cursor:pointer;text-decoration:underline dotted;text-underline-offset:2px}\n"] }]
|
|
10210
10244
|
}] });
|
|
10211
10245
|
|
|
10212
10246
|
// A KPI's trend over its last periods: a line that stretches to the card's
|
|
@@ -10469,9 +10503,10 @@ class ComponentListComponent {
|
|
|
10469
10503
|
this._initListConfig(config);
|
|
10470
10504
|
this._observePinOffsets();
|
|
10471
10505
|
// A change to any group this list's filters belong to (from the report bar
|
|
10472
|
-
// or the component header strip) re-runs the list
|
|
10473
|
-
// So does a change of the text in its search
|
|
10474
|
-
|
|
10506
|
+
// or the component header strip) re-runs the list, a filter added since
|
|
10507
|
+
// the list was drawn included. So does a change of the text in its search
|
|
10508
|
+
// box (in the component header).
|
|
10509
|
+
merge(this._filterState.changesFor(this.component), this._filterState.listSearchChanges(component.id))
|
|
10475
10510
|
.pipe(tap$1(() => this.listComponent()?.reload()), takeUntilDestroyed(this._destroyRef))
|
|
10476
10511
|
.subscribe();
|
|
10477
10512
|
}
|
|
@@ -11922,19 +11957,21 @@ class ReportComponentComponent {
|
|
|
11922
11957
|
tileLoads(this._refresh$, () => this._load(), () => this._filterState.stateVersion())
|
|
11923
11958
|
.pipe(tap$1((result) => this._loaded(result)), takeUntilDestroyed(this._destroyRef))
|
|
11924
11959
|
.subscribe();
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
|
|
11960
|
+
// A change to one of the tile's filter groups, read from the tile as
|
|
11961
|
+
// it stands, so a filter a report load added reads on its first pick.
|
|
11962
|
+
this._filterState.changesFor(() => this.component)
|
|
11963
|
+
.pipe(tap$1(() => this._refresh$.next()), takeUntilDestroyed(this._destroyRef))
|
|
11964
|
+
.subscribe();
|
|
11928
11965
|
// A group-by change re-buckets every tile that follows it; it isn't
|
|
11929
|
-
// scoped to a filter group, so it rides its own stream.
|
|
11930
|
-
|
|
11931
|
-
|
|
11932
|
-
|
|
11933
|
-
|
|
11934
|
-
|
|
11935
|
-
|
|
11936
|
-
|
|
11937
|
-
|
|
11966
|
+
// scoped to a filter group, so it rides its own stream. Whether the
|
|
11967
|
+
// tile follows it is read at each change: a load can make it follow
|
|
11968
|
+
// (a chart moved onto a time axis) or stop.
|
|
11969
|
+
this._filterState.frequencyChanges()
|
|
11970
|
+
.pipe(filter$1(() => followsGroupBy(this.component)), tap$1(() => {
|
|
11971
|
+
this._grainMoved = true;
|
|
11972
|
+
this._refresh$.next();
|
|
11973
|
+
}), takeUntilDestroyed(this._destroyRef))
|
|
11974
|
+
.subscribe();
|
|
11938
11975
|
// A drill moves this chart alone.
|
|
11939
11976
|
this._filterState.drillChanges(this.component.id)
|
|
11940
11977
|
.pipe(takeUntilDestroyed(this._destroyRef))
|
|
@@ -12351,7 +12388,7 @@ class ReportComponentComponent {
|
|
|
12351
12388
|
// A change to one group the header shows with another value (another bar
|
|
12352
12389
|
// set it) builds it again too.
|
|
12353
12390
|
_rebuildHeaderOnNewState() {
|
|
12354
|
-
this._filterState.changesFor(this.component)
|
|
12391
|
+
this._filterState.changesFor(() => this.component)
|
|
12355
12392
|
.pipe(filter$1((groupId) => (groupId === null
|
|
12356
12393
|
? this._filterState.stateVersion() !== this._headerVersion()
|
|
12357
12394
|
: this._showsOtherValue(groupId))), tap$1(() => this._buildFilterConfig()), takeUntilDestroyed(this._destroyRef))
|
|
@@ -15819,7 +15856,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
15819
15856
|
// in the report's format context, as on screen.
|
|
15820
15857
|
async function renderChartImage(component, data, width, height, context, pixelRatio = 3) {
|
|
15821
15858
|
// The same tree-shaken echarts build + 'report' theme the live canvas uses.
|
|
15822
|
-
const echarts = (await import('./firestitch-report-echarts-
|
|
15859
|
+
const echarts = (await import('./firestitch-report-echarts-CUVOSBvJ.mjs')).default;
|
|
15823
15860
|
const host = document.createElement('div');
|
|
15824
15861
|
host.style.width = `${width}px`;
|
|
15825
15862
|
host.style.height = `${height}px`;
|
|
@@ -19512,7 +19549,7 @@ class FsAiReportComponent {
|
|
|
19512
19549
|
ReportAiChatData,
|
|
19513
19550
|
{ provide: FsAiChatData, useExisting: ReportAiChatData },
|
|
19514
19551
|
// Tree-shaken ECharts core + the 'report' house theme, loaded lazily.
|
|
19515
|
-
provideEchartsCore({ echarts: () => import('./firestitch-report-echarts-
|
|
19552
|
+
provideEchartsCore({ echarts: () => import('./firestitch-report-echarts-CUVOSBvJ.mjs').then((module) => module.default) }),
|
|
19516
19553
|
// The bar's date pickers start their weeks on Monday and list the built-in
|
|
19517
19554
|
// presets; a preset only sets the days.
|
|
19518
19555
|
provideReportDatePicker(),
|
|
@@ -19536,7 +19573,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
19536
19573
|
ReportAiChatData,
|
|
19537
19574
|
{ provide: FsAiChatData, useExisting: ReportAiChatData },
|
|
19538
19575
|
// Tree-shaken ECharts core + the 'report' house theme, loaded lazily.
|
|
19539
|
-
provideEchartsCore({ echarts: () => import('./firestitch-report-echarts-
|
|
19576
|
+
provideEchartsCore({ echarts: () => import('./firestitch-report-echarts-CUVOSBvJ.mjs').then((module) => module.default) }),
|
|
19540
19577
|
// The bar's date pickers start their weeks on Monday and list the built-in
|
|
19541
19578
|
// presets; a preset only sets the days.
|
|
19542
19579
|
provideReportDatePicker(),
|
|
@@ -19629,4 +19666,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
19629
19666
|
*/
|
|
19630
19667
|
|
|
19631
19668
|
export { FsAiReportsComponent as F, GRANULARITY_OPTIONS as G, REPORT_CHART_COLORS_CSS as R, REPORT_CHART_FONT_FAMILY as a, REPORT_AXIS_LABEL_FONT_SIZE as b, FsAiReportComponent as c, ReportData as d, ReportService as e, ReportFilterStateService as f, ReportNodeType as g, ReportState as h, ReportValueFormat as i, ReportValueFormula as j, ReportListColumnFormat as k, ReportNumberUnits as l, ReportChartDataLabels as m, ReportChartColor as n, ReportChartLineStyle as o, ReportChartMarkStat as p, ReportChartDateLabel as q, ReportChartSpanThrough as r, ReportChangePolarity as s };
|
|
19632
|
-
//# sourceMappingURL=firestitch-report-firestitch-report-
|
|
19669
|
+
//# sourceMappingURL=firestitch-report-firestitch-report-CfvBTMrG.mjs.map
|