@ryuzaki13/react-foundation-lib 2.20.0 → 2.21.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/README.md +2 -0
- package/dist/analytical-table/aggregation.d.ts +4 -0
- package/dist/analytical-table/aggregation.d.ts.map +1 -0
- package/dist/analytical-table/buildAnalyticalTableModel.d.ts +4 -0
- package/dist/analytical-table/buildAnalyticalTableModel.d.ts.map +1 -0
- package/dist/analytical-table/calculationTypes.d.ts +11 -0
- package/dist/analytical-table/calculationTypes.d.ts.map +1 -0
- package/dist/analytical-table/calculations.d.ts +6 -0
- package/dist/analytical-table/calculations.d.ts.map +1 -0
- package/dist/analytical-table/columnTypes.d.ts +30 -0
- package/dist/analytical-table/columnTypes.d.ts.map +1 -0
- package/dist/analytical-table/dataTypes.d.ts +14 -0
- package/dist/analytical-table/dataTypes.d.ts.map +1 -0
- package/dist/analytical-table/dateColumnTypes.d.ts +31 -0
- package/dist/analytical-table/dateColumnTypes.d.ts.map +1 -0
- package/dist/analytical-table/dateColumns.d.ts +11 -0
- package/dist/analytical-table/dateColumns.d.ts.map +1 -0
- package/dist/analytical-table/expansion.d.ts +4 -0
- package/dist/analytical-table/expansion.d.ts.map +1 -0
- package/dist/analytical-table/exportProjection.d.ts +4 -0
- package/dist/analytical-table/exportProjection.d.ts.map +1 -0
- package/dist/analytical-table/exportTypes.d.ts +31 -0
- package/dist/analytical-table/exportTypes.d.ts.map +1 -0
- package/dist/analytical-table/filtering.d.ts +4 -0
- package/dist/analytical-table/filtering.d.ts.map +1 -0
- package/dist/analytical-table/index.d.ts +8 -0
- package/dist/analytical-table/index.d.ts.map +1 -0
- package/dist/analytical-table/index.js +364 -0
- package/dist/analytical-table/index.js.map +1 -0
- package/dist/analytical-table/indexAnalyticalRows.d.ts +4 -0
- package/dist/analytical-table/indexAnalyticalRows.d.ts.map +1 -0
- package/dist/analytical-table/modelTypes.d.ts +43 -0
- package/dist/analytical-table/modelTypes.d.ts.map +1 -0
- package/dist/analytical-table/types.d.ts +8 -0
- package/dist/analytical-table/types.d.ts.map +1 -0
- package/dist/analytical-table/valueComparison.d.ts +5 -0
- package/dist/analytical-table/valueComparison.d.ts.map +1 -0
- package/dist/analytical-table/viewTypes.d.ts +24 -0
- package/dist/analytical-table/viewTypes.d.ts.map +1 -0
- package/dist/chunks/{formatters-hHUJpZqD.js → formatters-CEltML3y.js} +224 -224
- package/dist/chunks/{formatters-hHUJpZqD.js.map → formatters-CEltML3y.js.map} +1 -1
- package/dist/chunks/{validate-DnkaY38p.js → validate-M2zPiLXn.js} +24 -24
- package/dist/chunks/{validate-DnkaY38p.js.map → validate-M2zPiLXn.js.map} +1 -1
- package/dist/error-report/index.js +20 -20
- package/dist/excel/index.js +36 -36
- package/dist/excel/index.js.map +1 -1
- package/dist/formatters/index.js +2 -2
- package/dist/hooks/useFloatingListbox.d.ts +1 -1
- package/dist/odata-service/formatters.d.ts +2 -2
- package/package.json +5 -1
- package/src/analytical-table/README.mdx +169 -0
package/README.md
CHANGED
|
@@ -86,6 +86,7 @@ npm run pack:dry-run
|
|
|
86
86
|
| Группировка, дедупликация, порядок и нормализация массивов | [`array`](./src/array/index.ts), подробный README: [`array/README.mdx`](./src/array/README.mdx) |
|
|
87
87
|
| OData metadata, values, path, filters, sorts, code/text collections и store | [`odata-service`](./src/odata-service/index.ts), подробный README: [`odata-service/README.mdx`](./src/odata-service/README.mdx), тесты в [`odata-service`](./src/odata-service) |
|
|
88
88
|
| TanStack Table helpers | [`table`](./src/table/index.ts), единый подробный справочник: [`table/README.mdx`](./src/table/README.mdx), тесты в [`table`](./src/table) |
|
|
89
|
+
| Аналитическая таблица полного снимка | [`analytical-table`](./src/analytical-table/index.ts), [руководство](./src/analytical-table/README.mdx) |
|
|
89
90
|
| Tree table преобразования | [`tree-table`](./src/tree-table/index.ts), документация в общем справочнике [`table/README.mdx`](./src/table/README.mdx), тесты в [`tree-table`](./src/tree-table) |
|
|
90
91
|
| Excel export | [`excel`](./src/excel/index.ts), подробный README: [`excel/README.mdx`](./src/excel/README.mdx), тесты: [`excel.test.ts`](./src/excel/excel.test.ts), [`tableExport.test.ts`](./src/excel/tableExport.test.ts) |
|
|
91
92
|
| FileReader, изображения, base64 Blob | [`file`](./src/file/index.ts), [`binary`](./src/binary/index.ts) |
|
|
@@ -140,6 +141,7 @@ npm run pack:dry-run
|
|
|
140
141
|
| `/string-comparison` | [`string-comparison/README.mdx`](./src/string-comparison/README.mdx) |
|
|
141
142
|
| `/table` | [`table/README.mdx`](./src/table/README.mdx) |
|
|
142
143
|
| `/three-scene` | [`three-scene/README.mdx`](./src/three-scene/README.mdx) |
|
|
144
|
+
| `/analytical-table` | [`analytical-table/README.mdx`](./src/analytical-table/README.mdx) |
|
|
143
145
|
| `/tree-table` | Раздел tree-table в [`table/README.mdx`](./src/table/README.mdx) |
|
|
144
146
|
| `/types` | [`types/README.mdx`](./src/types/README.mdx) |
|
|
145
147
|
| `/utils` | [`utils/README.mdx`](./src/utils/README.mdx) |
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type AnalyticalAggregation } from "./types";
|
|
2
|
+
/** null/пустые/нечисловые значения не превращаются в ноль; count считает непустые факты. */
|
|
3
|
+
export declare function aggregateAnalyticalValues(values: readonly unknown[], aggregation: AnalyticalAggregation): number | null;
|
|
4
|
+
//# sourceMappingURL=aggregation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregation.d.ts","sourceRoot":"","sources":["../../src/analytical-table/aggregation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD,4FAA4F;AAC5F,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,EAAE,WAAW,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAyBvH"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type AnalyticalTableModel, type BuildAnalyticalTableModelOptions } from "./types";
|
|
2
|
+
/** Чистая модель полного снимка: не владеет транспортом, кэшем, DOM и жизненным циклом Query. */
|
|
3
|
+
export declare function buildAnalyticalTableModel<T>(options: BuildAnalyticalTableModelOptions<T>): AnalyticalTableModel<T>;
|
|
4
|
+
//# sourceMappingURL=buildAnalyticalTableModel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildAnalyticalTableModel.d.ts","sourceRoot":"","sources":["../../src/analytical-table/buildAnalyticalTableModel.ts"],"names":[],"mappings":"AASA,OAAO,EAGN,KAAK,oBAAoB,EAEzB,KAAK,gCAAgC,EACrC,MAAM,SAAS,CAAC;AAYjB,iGAAiG;AACjG,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,OAAO,EAAE,gCAAgC,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAmIlH"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type AnalyticalValues } from "./dataTypes";
|
|
2
|
+
export type AnalyticalCalculationStep = Readonly<{
|
|
3
|
+
columnId: string;
|
|
4
|
+
dependencies: readonly string[];
|
|
5
|
+
compute: (values: AnalyticalValues) => unknown;
|
|
6
|
+
}>;
|
|
7
|
+
export type AnalyticalCalculationPlan = Readonly<{
|
|
8
|
+
steps: readonly AnalyticalCalculationStep[];
|
|
9
|
+
requiredColumnIds: readonly string[];
|
|
10
|
+
}>;
|
|
11
|
+
//# sourceMappingURL=calculationTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calculationTypes.d.ts","sourceRoot":"","sources":["../../src/analytical-table/calculationTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,OAAO,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC;CAC/C,CAAC,CAAC;AAEH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAChD,KAAK,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC5C,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,CAAC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type AnalyticalCalculationPlan, type AnalyticalColumn, type AnalyticalValues } from "./types";
|
|
2
|
+
/** Проверяет граф зависимостей до расчёта строк и компилирует каждую формулу один раз. */
|
|
3
|
+
export declare function createAnalyticalCalculationPlan<T>(columns: readonly AnalyticalColumn<T>[], requiredColumnIds?: readonly string[]): AnalyticalCalculationPlan;
|
|
4
|
+
/** Возвращает отдельный набор значений; исходный DTO и значения Query не мутируются. */
|
|
5
|
+
export declare function calculateAnalyticalValues(values: AnalyticalValues, plan: AnalyticalCalculationPlan): AnalyticalValues;
|
|
6
|
+
//# sourceMappingURL=calculations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calculations.d.ts","sourceRoot":"","sources":["../../src/analytical-table/calculations.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,yBAAyB,EAAkC,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEvI,0FAA0F;AAC1F,wBAAgB,+BAA+B,CAAC,CAAC,EAChD,OAAO,EAAE,SAAS,gBAAgB,CAAC,CAAC,CAAC,EAAE,EACvC,iBAAiB,GAAE,SAAS,MAAM,EAAuC,GACvE,yBAAyB,CAsC3B;AAED,wFAAwF;AACxF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,yBAAyB,GAAG,gBAAgB,CAIrH"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type AnalyticalDataRow, type AnalyticalValues } from "./dataTypes";
|
|
2
|
+
import { type AnalyticalFilter } from "./viewTypes";
|
|
3
|
+
export type AnalyticalAggregation = "sum" | "min" | "max" | "avg" | "count";
|
|
4
|
+
export type AnalyticalAggregateContext<TOriginal = unknown> = Readonly<{
|
|
5
|
+
scope: "group" | "grand";
|
|
6
|
+
/** Только исходные строки выбранной зернистости, без синтетических групп. */
|
|
7
|
+
rows: readonly AnalyticalDataRow<TOriginal>[];
|
|
8
|
+
groupingPath: AnalyticalValues;
|
|
9
|
+
}>;
|
|
10
|
+
export type AnalyticalFormula = Readonly<{
|
|
11
|
+
formulaId: string;
|
|
12
|
+
dependencies: readonly string[];
|
|
13
|
+
}>;
|
|
14
|
+
export type AnalyticalCalculation = Readonly<{
|
|
15
|
+
dependencies: readonly string[];
|
|
16
|
+
compute: (values: AnalyticalValues) => unknown;
|
|
17
|
+
}>;
|
|
18
|
+
export type AnalyticalColumn<TOriginal = unknown> = Readonly<{
|
|
19
|
+
id: string;
|
|
20
|
+
label?: string;
|
|
21
|
+
kind?: "dimension" | "measure";
|
|
22
|
+
valueType?: "string" | "number" | "boolean" | "date";
|
|
23
|
+
compare?: (left: unknown, right: unknown) => number;
|
|
24
|
+
filter?: (value: unknown, filter: AnalyticalFilter, row: AnalyticalDataRow<TOriginal>) => boolean;
|
|
25
|
+
aggregate?: AnalyticalAggregation | ((context: AnalyticalAggregateContext<TOriginal>) => unknown);
|
|
26
|
+
/** Исполнение использует реестр /formulas; зависимости определяют порядок расчёта. */
|
|
27
|
+
formula?: AnalyticalFormula;
|
|
28
|
+
calculate?: AnalyticalCalculation;
|
|
29
|
+
}>;
|
|
30
|
+
//# sourceMappingURL=columnTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columnTypes.d.ts","sourceRoot":"","sources":["../../src/analytical-table/columnTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;AAE5E,MAAM,MAAM,0BAA0B,CAAC,SAAS,GAAG,OAAO,IAAI,QAAQ,CAAC;IACtE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,6EAA6E;IAC7E,IAAI,EAAE,SAAS,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;IAC9C,YAAY,EAAE,gBAAgB,CAAC;CAC/B,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AAEjG,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAAE,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAA;CAAE,CAAC,CAAC;AAElI,MAAM,MAAM,gBAAgB,CAAC,SAAS,GAAG,OAAO,IAAI,QAAQ,CAAC;IAC5D,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACrD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;IACpD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,iBAAiB,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC;IAClG,SAAS,CAAC,EAAE,qBAAqB,GAAG,CAAC,CAAC,OAAO,EAAE,0BAA0B,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,CAAC;IAClG,sFAAsF;IACtF,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,SAAS,CAAC,EAAE,qBAAqB,CAAC;CAClC,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Значения таблицы отделены от исходного DTO: runtime не изменяет снимок Query. */
|
|
2
|
+
export type AnalyticalValues = Readonly<Record<string, unknown>>;
|
|
3
|
+
export type AnalyticalDataRow<TOriginal = unknown> = Readonly<{
|
|
4
|
+
id: string;
|
|
5
|
+
parentId?: string | null;
|
|
6
|
+
kind?: string;
|
|
7
|
+
original?: TOriginal;
|
|
8
|
+
values: AnalyticalValues;
|
|
9
|
+
}>;
|
|
10
|
+
/** Готовый полный снимок. Его загрузкой и отменой владеет транспорт потребителя. */
|
|
11
|
+
export type AnalyticalSnapshot<TOriginal = unknown> = Readonly<{
|
|
12
|
+
rows: readonly AnalyticalDataRow<TOriginal>[];
|
|
13
|
+
}>;
|
|
14
|
+
//# sourceMappingURL=dataTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataTypes.d.ts","sourceRoot":"","sources":["../../src/analytical-table/dataTypes.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEjE,MAAM,MAAM,iBAAiB,CAAC,SAAS,GAAG,OAAO,IAAI,QAAQ,CAAC;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;CACzB,CAAC,CAAC;AAEH,oFAAoF;AACpF,MAAM,MAAM,kBAAkB,CAAC,SAAS,GAAG,OAAO,IAAI,QAAQ,CAAC;IAC9D,IAAI,EAAE,SAAS,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;CAC9C,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type AnalyticalAggregation } from "./columnTypes";
|
|
2
|
+
import { type AnalyticalDataRow, type AnalyticalValues } from "./dataTypes";
|
|
3
|
+
/** Dynamic facts уже входят в снимок: проектирование не выполняет запросов. */
|
|
4
|
+
export type AnalyticalDateColumnsOptions = Readonly<{
|
|
5
|
+
id: string;
|
|
6
|
+
from: string;
|
|
7
|
+
to: string;
|
|
8
|
+
granularity: "day" | "week" | "month" | "quarter" | "year";
|
|
9
|
+
identityColumnIds: readonly string[];
|
|
10
|
+
/** Поле факта должно содержать только YYYY-MM-DD; Date/timestamp отклоняются. */
|
|
11
|
+
dateColumnId: string;
|
|
12
|
+
measureColumnId: string;
|
|
13
|
+
aggregation: AnalyticalAggregation;
|
|
14
|
+
maxColumns?: number;
|
|
15
|
+
}>;
|
|
16
|
+
export type AnalyticalDateColumn = Readonly<{
|
|
17
|
+
id: string;
|
|
18
|
+
label: string;
|
|
19
|
+
from: string;
|
|
20
|
+
to: string;
|
|
21
|
+
}>;
|
|
22
|
+
export type AnalyticalDateColumnsPlan = Readonly<{
|
|
23
|
+
options: AnalyticalDateColumnsOptions;
|
|
24
|
+
columns: readonly AnalyticalDateColumn[];
|
|
25
|
+
}>;
|
|
26
|
+
export type ProjectAnalyticalDateFactsOptions<TOriginal = unknown> = Readonly<{
|
|
27
|
+
rows: readonly AnalyticalDataRow<TOriginal>[];
|
|
28
|
+
facts: readonly AnalyticalValues[];
|
|
29
|
+
plan: AnalyticalDateColumnsPlan;
|
|
30
|
+
}>;
|
|
31
|
+
//# sourceMappingURL=dateColumnTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dateColumnTypes.d.ts","sourceRoot":"","sources":["../../src/analytical-table/dateColumnTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE5E,+EAA+E;AAC/E,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAC3D,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,iFAAiF;IACjF,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,qBAAqB,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACX,CAAC,CAAC;AAEH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAChD,OAAO,EAAE,4BAA4B,CAAC;IACtC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACzC,CAAC,CAAC;AAEH,MAAM,MAAM,iCAAiC,CAAC,SAAS,GAAG,OAAO,IAAI,QAAQ,CAAC;IAC7E,IAAI,EAAE,SAAS,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;IAC9C,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnC,IAAI,EAAE,yBAAyB,CAAC;CAChC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type AnalyticalDataRow, type AnalyticalDateColumnsOptions, type AnalyticalDateColumnsPlan, type AnalyticalValues, type ProjectAnalyticalDateFactsOptions } from "./types";
|
|
2
|
+
/** Строит ограниченный календарный план; ISO-моменты времени сюда не передаются. */
|
|
3
|
+
export declare function createAnalyticalDateColumnsPlan(options: AnalyticalDateColumnsOptions): AnalyticalDateColumnsPlan;
|
|
4
|
+
/** Сопоставляет отдельные facts составному ключу строки; порядок и количество base rows неизменны. */
|
|
5
|
+
export declare function projectAnalyticalDateFacts<T>(args: ProjectAnalyticalDateFactsOptions<T>): readonly AnalyticalDataRow<T>[];
|
|
6
|
+
/**
|
|
7
|
+
* Общие итоги считаются по исходным facts с полным ключом: среднее от средних не подменяет взвешенный результат.
|
|
8
|
+
* Отбор допустимых непустых identities по области доступа и фильтрам выполняет вызывающий адаптер.
|
|
9
|
+
*/
|
|
10
|
+
export declare function aggregateAnalyticalDateFacts(facts: readonly AnalyticalValues[], plan: AnalyticalDateColumnsPlan): AnalyticalValues;
|
|
11
|
+
//# sourceMappingURL=dateColumns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dateColumns.d.ts","sourceRoot":"","sources":["../../src/analytical-table/dateColumns.ts"],"names":[],"mappings":"AAeA,OAAO,EACN,KAAK,iBAAiB,EAEtB,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,iCAAiC,EACtC,MAAM,SAAS,CAAC;AA+CjB,oFAAoF;AACpF,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,4BAA4B,GAAG,yBAAyB,CAuBhH;AAYD,sGAAsG;AACtG,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,IAAI,EAAE,iCAAiC,CAAC,CAAC,CAAC,GAAG,SAAS,iBAAiB,CAAC,CAAC,CAAC,EAAE,CA0BzH;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,SAAS,gBAAgB,EAAE,EAAE,IAAI,EAAE,yBAAyB,GAAG,gBAAgB,CAelI"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type AnalyticalTableModel } from "./types";
|
|
2
|
+
/** Раскрытие не меняет группировки, формулы и итоги; UI мемоизирует базовую модель отдельно. */
|
|
3
|
+
export declare function projectAnalyticalTableExpansion<T>(model: AnalyticalTableModel<T>, expandedRowIds: readonly string[] | "all"): AnalyticalTableModel<T>;
|
|
4
|
+
//# sourceMappingURL=expansion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expansion.d.ts","sourceRoot":"","sources":["../../src/analytical-table/expansion.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE7E,gGAAgG;AAChG,wBAAgB,+BAA+B,CAAC,CAAC,EAChD,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,EAC9B,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,GACvC,oBAAoB,CAAC,CAAC,CAAC,CAUzB"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type AnalyticalExportProjection, type ProjectAnalyticalTableExportOptions } from "./types";
|
|
2
|
+
/** Проекция для /excel или /table-document; сам runtime не скачивает файлы и не читает DOM. */
|
|
3
|
+
export declare function projectAnalyticalTableExport<T>(args: ProjectAnalyticalTableExportOptions<T>): AnalyticalExportProjection;
|
|
4
|
+
//# sourceMappingURL=exportProjection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exportProjection.d.ts","sourceRoot":"","sources":["../../src/analytical-table/exportProjection.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,0BAA0B,EAAE,KAAK,mCAAmC,EAAE,MAAM,SAAS,CAAC;AAEjI,+FAA+F;AAC/F,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,IAAI,EAAE,mCAAmC,CAAC,CAAC,CAAC,GAAG,0BAA0B,CAwBxH"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type AnalyticalModelRow, type AnalyticalTableModel } from "./modelTypes";
|
|
2
|
+
export type AnalyticalExportColumn<TOriginal = unknown> = Readonly<{
|
|
3
|
+
id: string;
|
|
4
|
+
label?: string;
|
|
5
|
+
format?: (value: unknown, row: AnalyticalModelRow<TOriginal>) => unknown;
|
|
6
|
+
/** Общий итог не является строкой исходного дерева и не имеет original/children. */
|
|
7
|
+
formatTotal?: (value: unknown) => unknown;
|
|
8
|
+
}>;
|
|
9
|
+
export type AnalyticalExportHeader = Readonly<{
|
|
10
|
+
id: string;
|
|
11
|
+
label: string;
|
|
12
|
+
}>;
|
|
13
|
+
export type AnalyticalExportRow = Readonly<{
|
|
14
|
+
id: string;
|
|
15
|
+
level: number;
|
|
16
|
+
kind: "data" | "group" | "grand";
|
|
17
|
+
values: readonly unknown[];
|
|
18
|
+
}>;
|
|
19
|
+
export type AnalyticalExportProjection = Readonly<{
|
|
20
|
+
columns: readonly AnalyticalExportHeader[];
|
|
21
|
+
rows: readonly AnalyticalExportRow[];
|
|
22
|
+
}>;
|
|
23
|
+
export type ProjectAnalyticalTableExportOptions<TOriginal = unknown> = Readonly<{
|
|
24
|
+
model: AnalyticalTableModel<TOriginal>;
|
|
25
|
+
columns?: readonly AnalyticalExportColumn<TOriginal>[];
|
|
26
|
+
scope?: "all" | "visible" | "selected";
|
|
27
|
+
selectedRowIds?: readonly string[];
|
|
28
|
+
includeGroups?: boolean;
|
|
29
|
+
includeGrandTotals?: boolean;
|
|
30
|
+
}>;
|
|
31
|
+
//# sourceMappingURL=exportTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exportTypes.d.ts","sourceRoot":"","sources":["../../src/analytical-table/exportTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAElF,MAAM,MAAM,sBAAsB,CAAC,SAAS,GAAG,OAAO,IAAI,QAAQ,CAAC;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC;IACzE,oFAAoF;IACpF,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;CAC1C,CAAC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE7E,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,CAAC,CAAC;AAExI,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IACjD,OAAO,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC3C,IAAI,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,MAAM,mCAAmC,CAAC,SAAS,GAAG,OAAO,IAAI,QAAQ,CAAC;IAC/E,KAAK,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;IACvC,OAAO,CAAC,EAAE,SAAS,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAAC;IACvD,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,UAAU,CAAC;IACvC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type AnalyticalColumn, type AnalyticalDataRow, type AnalyticalFilter } from "./types";
|
|
2
|
+
/** Операции фильтра относятся к данным, поэтому одинаково работают при SSR и в браузере. */
|
|
3
|
+
export declare function matchesAnalyticalFilter<T>(row: AnalyticalDataRow<T>, filter: AnalyticalFilter, column?: AnalyticalColumn<T>): boolean;
|
|
4
|
+
//# sourceMappingURL=filtering.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filtering.d.ts","sourceRoot":"","sources":["../../src/analytical-table/filtering.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG/F,4FAA4F;AAC5F,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,OAAO,CAgCrI"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { aggregateAnalyticalValues } from "./aggregation";
|
|
2
|
+
export { buildAnalyticalTableModel } from "./buildAnalyticalTableModel";
|
|
3
|
+
export { calculateAnalyticalValues, createAnalyticalCalculationPlan } from "./calculations";
|
|
4
|
+
export { aggregateAnalyticalDateFacts, createAnalyticalDateColumnsPlan, projectAnalyticalDateFacts } from "./dateColumns";
|
|
5
|
+
export { projectAnalyticalTableExpansion } from "./expansion";
|
|
6
|
+
export { projectAnalyticalTableExport } from "./exportProjection";
|
|
7
|
+
export type * from "./types";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytical-table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,yBAAyB,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AAC5F,OAAO,EAAE,4BAA4B,EAAE,+BAA+B,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAC1H,OAAO,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAClE,mBAAmB,SAAS,CAAC"}
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { Dt as e, Et as t, Mt as n, Nt as r, Ot as i, Pt as a, jt as o, kt as s } from "../chunks/formatters-CEltML3y.js";
|
|
2
|
+
import { a as c, y as l } from "../chunks/array-D-_yMMUK.js";
|
|
3
|
+
import { buildTreeTableRows as u } from "../tree-table/index.js";
|
|
4
|
+
import { stableStringify as d } from "../utils/index.js";
|
|
5
|
+
import { compileTableFormula as f } from "../formulas/index.js";
|
|
6
|
+
import { Bt as p, hn as m, kn as h, pn as g } from "../chunks/odata-service-CWkHASdw.js";
|
|
7
|
+
import { t as _ } from "../chunks/string-comparison-BKT7PXmq.js";
|
|
8
|
+
//#region src/analytical-table/aggregation.ts
|
|
9
|
+
function v(e, t) {
|
|
10
|
+
let n = e.filter((e) => e != null && e !== "");
|
|
11
|
+
if (t === "count") return n.length;
|
|
12
|
+
let r = 0, i = 0, a = Infinity, o = -Infinity;
|
|
13
|
+
for (let e of n) typeof e != "number" || !Number.isFinite(e) || (r += 1, i += e, a = Math.min(a, e), o = Math.max(o, e));
|
|
14
|
+
if (r === 0) return null;
|
|
15
|
+
switch (t) {
|
|
16
|
+
case "sum": return i;
|
|
17
|
+
case "min": return a;
|
|
18
|
+
case "max": return o;
|
|
19
|
+
case "avg": return i / r;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/analytical-table/calculations.ts
|
|
24
|
+
function y(e, t = e.map((e) => e.id)) {
|
|
25
|
+
let n = new Map(e.map((e) => [e.id, e]));
|
|
26
|
+
if (n.size !== e.length) throw Error("Идентификаторы аналитических столбцов должны быть уникальны.");
|
|
27
|
+
let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = [], o = [], s = (e) => {
|
|
28
|
+
if (r.has(e)) return;
|
|
29
|
+
if (i.has(e)) throw Error(`Циклическая зависимость аналитического столбца: ${e}`);
|
|
30
|
+
let t = n.get(e);
|
|
31
|
+
if (!t) throw Error(`Неизвестная зависимость аналитического столбца: ${e}`);
|
|
32
|
+
if (t.formula && t.calculate) throw Error(`Столбец ${e} содержит два способа вычисления.`);
|
|
33
|
+
i.add(e);
|
|
34
|
+
let l = c(t.formula?.dependencies ?? t.calculate?.dependencies ?? []);
|
|
35
|
+
for (let e of l) s(e);
|
|
36
|
+
if (t.formula) {
|
|
37
|
+
let n = f({
|
|
38
|
+
formulaId: t.formula.formulaId,
|
|
39
|
+
keys: t.formula.dependencies
|
|
40
|
+
});
|
|
41
|
+
if (!n.ok) throw Error(`Формула столбца ${e} не зарегистрирована: ${t.formula.formulaId}`);
|
|
42
|
+
o.push({
|
|
43
|
+
columnId: e,
|
|
44
|
+
dependencies: l,
|
|
45
|
+
compute: (t) => {
|
|
46
|
+
let r = n.execute({ ...t });
|
|
47
|
+
if (!r.ok) throw Error(`Ошибка формулы столбца ${e}: ${r.reason}`);
|
|
48
|
+
return r.value;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
} else t.calculate && o.push({
|
|
52
|
+
columnId: e,
|
|
53
|
+
dependencies: l,
|
|
54
|
+
compute: t.calculate.compute
|
|
55
|
+
});
|
|
56
|
+
i.delete(e), r.add(e), a.push(e);
|
|
57
|
+
};
|
|
58
|
+
for (let e of t) s(e);
|
|
59
|
+
return {
|
|
60
|
+
steps: o,
|
|
61
|
+
requiredColumnIds: a
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function b(e, t) {
|
|
65
|
+
let n = { ...e };
|
|
66
|
+
for (let e of t.steps) n[e.columnId] = e.compute(n);
|
|
67
|
+
return n;
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/analytical-table/valueComparison.ts
|
|
71
|
+
function x(e, t) {
|
|
72
|
+
return d(t.map((t) => {
|
|
73
|
+
let n = e[t];
|
|
74
|
+
return [
|
|
75
|
+
t,
|
|
76
|
+
n === null ? "null" : typeof n,
|
|
77
|
+
n
|
|
78
|
+
];
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
function S(e, t, n) {
|
|
82
|
+
if (Object.is(e, t)) return 0;
|
|
83
|
+
if (e == null) return 1;
|
|
84
|
+
if (t == null) return -1;
|
|
85
|
+
if (n?.compare) return n.compare(e, t);
|
|
86
|
+
if (n?.valueType === "date") {
|
|
87
|
+
let n = g(e), r = g(t);
|
|
88
|
+
if (n && r) return n.getTime() - r.getTime();
|
|
89
|
+
}
|
|
90
|
+
return typeof e == "number" && typeof t == "number" ? e - t : typeof e == "boolean" && typeof t == "boolean" ? Number(e) - Number(t) : _(String(e), String(t));
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/analytical-table/filtering.ts
|
|
94
|
+
function C(e, t, n) {
|
|
95
|
+
let r = e.values[t.id];
|
|
96
|
+
if (n?.filter) return n.filter(r, t, e);
|
|
97
|
+
let i = t.value, a = (e) => S(r, e, n), o = r == null || r === "";
|
|
98
|
+
switch (t.operator ?? "equals") {
|
|
99
|
+
case "equals": return a(i) === 0;
|
|
100
|
+
case "notEquals": return a(i) !== 0;
|
|
101
|
+
case "contains": return l(String(r ?? "")).includes(l(String(i ?? "")));
|
|
102
|
+
case "startsWith": return l(String(r ?? "")).startsWith(l(String(i ?? "")));
|
|
103
|
+
case "in": return Array.isArray(i) && i.some((e) => a(e) === 0);
|
|
104
|
+
case "between": return Array.isArray(i) && i.length === 2 && !o && a(i[0]) >= 0 && a(i[1]) <= 0;
|
|
105
|
+
case "gt": return !o && a(i) > 0;
|
|
106
|
+
case "gte": return !o && a(i) >= 0;
|
|
107
|
+
case "lt": return !o && a(i) < 0;
|
|
108
|
+
case "lte": return !o && a(i) <= 0;
|
|
109
|
+
case "empty": return o;
|
|
110
|
+
case "notEmpty": return !o;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/analytical-table/indexAnalyticalRows.ts
|
|
115
|
+
function w(e) {
|
|
116
|
+
let t = [], n = [], r = /* @__PURE__ */ new Map(), i = (e, a) => {
|
|
117
|
+
for (let o of e) t.push(o), r.set(o.id, o), a && n.push(o), i(o.children, a && o.isExpanded);
|
|
118
|
+
};
|
|
119
|
+
return i(e, !0), {
|
|
120
|
+
flatRows: t,
|
|
121
|
+
visibleRows: n,
|
|
122
|
+
rowById: r
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
//#region src/analytical-table/buildAnalyticalTableModel.ts
|
|
127
|
+
function T(e) {
|
|
128
|
+
let { snapshot: t, columns: n, state: r = {} } = e, i = y(n), a = new Map(n.map((e) => [e.id, e])), o = r.grouping ?? [], s = r.sorting ?? [], l = r.filters ?? [];
|
|
129
|
+
for (let e of [...s.map((e) => e.id), ...l.map((e) => e.id)]) if (!a.has(e)) throw Error(`Неизвестный аналитический столбец: ${e}`);
|
|
130
|
+
if (c(o.map((e) => e.id)).length !== o.length) throw Error("Идентификаторы уровней группировки должны быть уникальны.");
|
|
131
|
+
for (let e of o) if (e.keyColumnIds.length === 0) throw Error(`Уровень ${e.id} не содержит ключей группировки.`);
|
|
132
|
+
let f = t.rows.map((e) => ({
|
|
133
|
+
...e,
|
|
134
|
+
values: b(e.values, i)
|
|
135
|
+
}));
|
|
136
|
+
if (f.some((e) => e.id.length === 0)) throw Error("Идентификатор аналитической строки не может быть пустым.");
|
|
137
|
+
let p = u(f, {
|
|
138
|
+
getRowId: (e) => e.id,
|
|
139
|
+
getParentRowId: (e) => e.parentId
|
|
140
|
+
}), m = new Set(p.rootRowIds), h = e.isAggregateRow ?? ((e) => m.has(e.id)), g = (e) => ({
|
|
141
|
+
id: e.id,
|
|
142
|
+
kind: "data",
|
|
143
|
+
sourceRow: p.rowById.get(e.id),
|
|
144
|
+
values: e.values,
|
|
145
|
+
children: (e.children ?? []).map(g)
|
|
146
|
+
}), _ = p.rows.map(g), T = (e) => {
|
|
147
|
+
let t = [], n = (e) => {
|
|
148
|
+
e.sourceRow && h(e.sourceRow) && t.push(e.sourceRow);
|
|
149
|
+
for (let t of e.children) n(t);
|
|
150
|
+
};
|
|
151
|
+
for (let t of e) n(t);
|
|
152
|
+
return t;
|
|
153
|
+
}, E = (t, r, a) => {
|
|
154
|
+
let o = {
|
|
155
|
+
scope: r,
|
|
156
|
+
rows: T(t),
|
|
157
|
+
groupingPath: a
|
|
158
|
+
}, s = { ...a };
|
|
159
|
+
for (let e of n) e.aggregate && (s[e.id] = typeof e.aggregate == "function" ? e.aggregate(o) : v(o.rows.map((t) => t.values[e.id]), e.aggregate));
|
|
160
|
+
return Object.assign(s, e.aggregate?.(o)), b(s, {
|
|
161
|
+
...i,
|
|
162
|
+
steps: i.steps.filter((e) => !Object.hasOwn(s, e.columnId))
|
|
163
|
+
});
|
|
164
|
+
}, D = (e) => e.flatMap((e) => {
|
|
165
|
+
let t = e.sourceRow;
|
|
166
|
+
if (t && l.every((e) => C(t, e, a.get(e.id)))) return [e];
|
|
167
|
+
let n = D(e.children);
|
|
168
|
+
return n.length > 0 ? [{
|
|
169
|
+
...e,
|
|
170
|
+
children: n
|
|
171
|
+
}] : [];
|
|
172
|
+
}), O = l.length > 0 ? D(_) : _, k = (e, t, n, r) => {
|
|
173
|
+
let i = o[t];
|
|
174
|
+
if (!i) return e;
|
|
175
|
+
let a = /* @__PURE__ */ new Map();
|
|
176
|
+
for (let t of e) {
|
|
177
|
+
let e = x(t.values, i.keyColumnIds), n = a.get(e);
|
|
178
|
+
n ? n.push(t) : a.set(e, [t]);
|
|
179
|
+
}
|
|
180
|
+
return Array.from(a, ([e, a]) => {
|
|
181
|
+
let o = [
|
|
182
|
+
...r,
|
|
183
|
+
i.id,
|
|
184
|
+
e
|
|
185
|
+
], s = `analytical-group:${d(o)}`;
|
|
186
|
+
if (p.rowById.has(s)) throw Error(`Идентификатор исходной строки совпал с группой: ${s}`);
|
|
187
|
+
let c = { ...n };
|
|
188
|
+
for (let e of [...i.keyColumnIds, ...i.displayColumnIds ?? []]) c[e] = a[0].values[e];
|
|
189
|
+
return {
|
|
190
|
+
id: s,
|
|
191
|
+
kind: "group",
|
|
192
|
+
groupingLevelId: i.id,
|
|
193
|
+
values: E(a, "group", c),
|
|
194
|
+
children: k(a, t + 1, c, o)
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
}, A = k(O, 0, {}, []), j = new Set(r.expandedRowIds === "all" ? [] : r.expandedRowIds ?? []), M = (e) => [...e].sort((e, t) => {
|
|
198
|
+
for (let n of s) {
|
|
199
|
+
let r = S(e.values[n.id], t.values[n.id], a.get(n.id));
|
|
200
|
+
if (r !== 0) return n.desc ? -r : r;
|
|
201
|
+
}
|
|
202
|
+
return 0;
|
|
203
|
+
}), N = (e, t, n) => M(e).map((e) => ({
|
|
204
|
+
id: e.id,
|
|
205
|
+
parentId: t,
|
|
206
|
+
kind: e.kind,
|
|
207
|
+
sourceRow: e.sourceRow,
|
|
208
|
+
original: e.sourceRow?.original,
|
|
209
|
+
values: e.values,
|
|
210
|
+
level: n,
|
|
211
|
+
children: N(e.children, e.id, n + 1),
|
|
212
|
+
isExpandable: e.children.length > 0,
|
|
213
|
+
isExpanded: e.children.length > 0 && (r.expandedRowIds === "all" || j.has(e.id)),
|
|
214
|
+
groupingLevelId: e.groupingLevelId
|
|
215
|
+
})), P = N(A, null, 0);
|
|
216
|
+
return {
|
|
217
|
+
columns: n,
|
|
218
|
+
rows: P,
|
|
219
|
+
...w(P),
|
|
220
|
+
grandTotals: e.grandTotals === !1 ? null : E(e.grandTotalsScope === "all" ? _ : O, "grand", {}),
|
|
221
|
+
diagnostics: {
|
|
222
|
+
orphanRowIds: p.orphanRowIds,
|
|
223
|
+
duplicateRowIds: p.duplicateRowIds,
|
|
224
|
+
cyclicRowIds: p.cyclicRowIds
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
//#endregion
|
|
229
|
+
//#region src/analytical-table/dateColumns.ts
|
|
230
|
+
var E = h("yyyy-MM-dd"), D = h("dd.MM.yyyy");
|
|
231
|
+
function O(e) {
|
|
232
|
+
if (typeof e != "string" || e.length !== 10) return null;
|
|
233
|
+
let t = m(e, "yyyy-MM-dd");
|
|
234
|
+
return t?.kind === "date-time" ? t.date : null;
|
|
235
|
+
}
|
|
236
|
+
function k(e) {
|
|
237
|
+
return p(e, E);
|
|
238
|
+
}
|
|
239
|
+
function A(e, t) {
|
|
240
|
+
switch (t) {
|
|
241
|
+
case "day": return o(e);
|
|
242
|
+
case "week": return r(e, 1);
|
|
243
|
+
case "month": return n(e);
|
|
244
|
+
case "quarter": return s(e.getFullYear(), Math.floor(e.getMonth() / 3) * 3, 1);
|
|
245
|
+
case "year": return a(e);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function j(n, r) {
|
|
249
|
+
switch (r) {
|
|
250
|
+
case "day": return t(n, 1);
|
|
251
|
+
case "week": return t(n, 7);
|
|
252
|
+
case "month": return e(n, 1);
|
|
253
|
+
case "quarter": return e(n, 3);
|
|
254
|
+
case "year": return i(n, 1);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function M(e) {
|
|
258
|
+
let n = O(e.from), r = O(e.to);
|
|
259
|
+
if (!n || !r || k(n) !== e.from || k(r) !== e.to || e.from > e.to) throw Error("Некорректный календарный диапазон аналитических столбцов.");
|
|
260
|
+
let i = e.maxColumns ?? 366;
|
|
261
|
+
if (!Number.isSafeInteger(i) || i < 1) throw Error("Лимит динамических столбцов должен быть положительным целым числом.");
|
|
262
|
+
if (!e.id || e.identityColumnIds.length === 0) throw Error("Динамическим столбцам нужны идентификатор и ключи сопоставления фактов.");
|
|
263
|
+
let a = [];
|
|
264
|
+
for (let o = A(n, e.granularity); o <= r; o = j(o, e.granularity)) {
|
|
265
|
+
if (a.length >= i) throw Error(`Превышен лимит динамических столбцов: ${i}`);
|
|
266
|
+
let n = k(o), r = k(t(j(o, e.granularity), -1));
|
|
267
|
+
a.push({
|
|
268
|
+
id: `${e.id}:${e.granularity}:${n}`,
|
|
269
|
+
label: e.granularity === "day" ? p(o, D) : `${n} — ${r}`,
|
|
270
|
+
from: n < e.from ? e.from : n,
|
|
271
|
+
to: r > e.to ? e.to : r
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
options: {
|
|
276
|
+
...e,
|
|
277
|
+
identityColumnIds: [...e.identityColumnIds]
|
|
278
|
+
},
|
|
279
|
+
columns: a
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
function N(e, t) {
|
|
283
|
+
if (t.options.identityColumnIds.some((t) => e[t] === void 0 || e[t] === null)) return;
|
|
284
|
+
let n = O(e[t.options.dateColumnId]);
|
|
285
|
+
if (!n) return;
|
|
286
|
+
let r = k(n);
|
|
287
|
+
if (!(r < t.options.from || r > t.options.to)) return `${t.options.id}:${t.options.granularity}:${k(A(n, t.options.granularity))}`;
|
|
288
|
+
}
|
|
289
|
+
function P(e) {
|
|
290
|
+
let { rows: t, facts: n, plan: r } = e, i = /* @__PURE__ */ new Map();
|
|
291
|
+
for (let e of n) {
|
|
292
|
+
let t = N(e, r);
|
|
293
|
+
if (!t) continue;
|
|
294
|
+
let n = x(e, r.options.identityColumnIds), a = i.get(n);
|
|
295
|
+
a || (a = /* @__PURE__ */ new Map(), i.set(n, a));
|
|
296
|
+
let o = a.get(t);
|
|
297
|
+
o ? o.push(e[r.options.measureColumnId]) : a.set(t, [e[r.options.measureColumnId]]);
|
|
298
|
+
}
|
|
299
|
+
return t.map((e) => {
|
|
300
|
+
let t = i.get(x(e.values, r.options.identityColumnIds)), n = { ...e.values };
|
|
301
|
+
for (let e of r.columns) {
|
|
302
|
+
if (Object.hasOwn(n, e.id)) throw Error(`Динамический столбец перезаписывает исходное поле: ${e.id}`);
|
|
303
|
+
let i = t?.get(e.id);
|
|
304
|
+
n[e.id] = i ? v(i, r.options.aggregation) : null;
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
...e,
|
|
308
|
+
values: n
|
|
309
|
+
};
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
function F(e, t) {
|
|
313
|
+
let n = /* @__PURE__ */ new Map();
|
|
314
|
+
for (let r of e) {
|
|
315
|
+
let e = N(r, t);
|
|
316
|
+
if (!e) continue;
|
|
317
|
+
let i = n.get(e);
|
|
318
|
+
i ? i.push(r[t.options.measureColumnId]) : n.set(e, [r[t.options.measureColumnId]]);
|
|
319
|
+
}
|
|
320
|
+
return Object.fromEntries(t.columns.map((e) => [e.id, n.has(e.id) ? v(n.get(e.id) ?? [], t.options.aggregation) : null]));
|
|
321
|
+
}
|
|
322
|
+
//#endregion
|
|
323
|
+
//#region src/analytical-table/expansion.ts
|
|
324
|
+
function I(e, t) {
|
|
325
|
+
let n = new Set(t === "all" ? [] : t), r = (e) => e.map((e) => ({
|
|
326
|
+
...e,
|
|
327
|
+
isExpanded: e.isExpandable && (t === "all" || n.has(e.id)),
|
|
328
|
+
children: r(e.children)
|
|
329
|
+
})), i = r(e.rows);
|
|
330
|
+
return {
|
|
331
|
+
...e,
|
|
332
|
+
rows: i,
|
|
333
|
+
...w(i)
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
//#endregion
|
|
337
|
+
//#region src/analytical-table/exportProjection.ts
|
|
338
|
+
function L(e) {
|
|
339
|
+
let { model: t } = e, n = e.columns ?? t.columns, r = new Set(e.selectedRowIds ?? []), i = (e.scope === "visible" ? t.visibleRows : t.flatRows).filter((t) => (e.includeGroups !== !1 || t.kind !== "group") && (e.scope !== "selected" || r.has(t.id))).map((e) => ({
|
|
340
|
+
id: e.id,
|
|
341
|
+
level: e.level,
|
|
342
|
+
kind: e.kind,
|
|
343
|
+
values: n.map((t) => t.format ? t.format(e.values[t.id], e) : e.values[t.id])
|
|
344
|
+
}));
|
|
345
|
+
return e.includeGrandTotals && t.grandTotals && i.push({
|
|
346
|
+
id: "analytical-grand-total",
|
|
347
|
+
level: 0,
|
|
348
|
+
kind: "grand",
|
|
349
|
+
values: n.map((e) => {
|
|
350
|
+
let n = t.grandTotals?.[e.id];
|
|
351
|
+
return e.formatTotal ? e.formatTotal(n) : n;
|
|
352
|
+
})
|
|
353
|
+
}), {
|
|
354
|
+
columns: n.map((e) => ({
|
|
355
|
+
id: e.id,
|
|
356
|
+
label: e.label ?? e.id
|
|
357
|
+
})),
|
|
358
|
+
rows: i
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
//#endregion
|
|
362
|
+
export { F as aggregateAnalyticalDateFacts, v as aggregateAnalyticalValues, T as buildAnalyticalTableModel, b as calculateAnalyticalValues, y as createAnalyticalCalculationPlan, M as createAnalyticalDateColumnsPlan, P as projectAnalyticalDateFacts, I as projectAnalyticalTableExpansion, L as projectAnalyticalTableExport };
|
|
363
|
+
|
|
364
|
+
//# sourceMappingURL=index.js.map
|