angular-my-report 0.1.0 → 0.1.1
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 +124 -40
- package/fesm2022/angular-my-report.mjs +7931 -0
- package/fesm2022/angular-my-report.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/engine/barcode.d.ts +17 -0
- package/lib/engine/chart.d.ts +26 -0
- package/lib/engine/chartLayout.d.ts +45 -0
- package/lib/engine/crosstab.d.ts +22 -0
- package/lib/engine/dataSources.d.ts +35 -0
- package/lib/engine/expressions.d.ts +46 -0
- package/lib/engine/measure.d.ts +7 -0
- package/lib/engine/parameters.d.ts +15 -0
- package/lib/engine/qr.d.ts +8 -0
- package/lib/engine/renderer.d.ts +43 -0
- package/lib/engine/table.d.ts +22 -0
- package/lib/model/defaults.d.ts +31 -0
- package/lib/model/factories.d.ts +31 -0
- package/lib/model/types.d.ts +244 -0
- package/lib/ui/css.d.ts +2 -0
- package/lib/ui/designer/banded-table-dialog.component.d.ts +27 -0
- package/lib/ui/designer/canvas.component.d.ts +41 -0
- package/lib/ui/designer/data-source-dialog.component.d.ts +37 -0
- package/lib/ui/designer/element-box.component.d.ts +32 -0
- package/lib/ui/designer/graphics.components.d.ts +36 -0
- package/lib/ui/designer/left-panel.component.d.ts +37 -0
- package/lib/ui/designer/safe-image.pipe.d.ts +13 -0
- package/lib/ui/designer/table-view.component.d.ts +19 -0
- package/lib/ui/designer.component.d.ts +59 -0
- package/lib/ui/designer.store.d.ts +82 -0
- package/lib/ui/inputs.d.ts +8 -0
- package/lib/ui/properties/band-props.component.d.ts +15 -0
- package/lib/ui/properties/element-props.component.d.ts +46 -0
- package/lib/ui/properties/expr-input.component.d.ts +43 -0
- package/lib/ui/properties/graphics-props.component.d.ts +52 -0
- package/lib/ui/properties/image-picker.component.d.ts +15 -0
- package/lib/ui/properties/properties-panel.component.d.ts +13 -0
- package/lib/ui/properties/report-extras.component.d.ts +40 -0
- package/lib/ui/properties/report-props.component.d.ts +34 -0
- package/lib/ui/properties/table-props.component.d.ts +31 -0
- package/lib/ui/viewer/page-view.component.d.ts +17 -0
- package/lib/ui/viewer/render.d.ts +43 -0
- package/lib/ui/viewer/viewer.component.d.ts +99 -0
- package/lib/ui/viewer.component.d.ts +40 -0
- package/package.json +16 -5
- package/{src/public-api.ts → public-api.d.ts} +0 -5
- package/ng-package.json +0 -7
- package/src/lib/engine/barcode.ts +0 -118
- package/src/lib/engine/chart.ts +0 -85
- package/src/lib/engine/chartLayout.ts +0 -265
- package/src/lib/engine/crosstab.ts +0 -96
- package/src/lib/engine/dataSources.ts +0 -204
- package/src/lib/engine/expressions.ts +0 -734
- package/src/lib/engine/measure.ts +0 -62
- package/src/lib/engine/parameters.ts +0 -96
- package/src/lib/engine/qr.ts +0 -26
- package/src/lib/engine/renderer.ts +0 -324
- package/src/lib/engine/table.ts +0 -58
- package/src/lib/model/defaults.ts +0 -249
- package/src/lib/model/factories.ts +0 -324
- package/src/lib/model/types.ts +0 -281
- package/src/lib/ui/css.ts +0 -12
- package/src/lib/ui/designer/banded-table-dialog.component.ts +0 -127
- package/src/lib/ui/designer/canvas.component.ts +0 -281
- package/src/lib/ui/designer/data-source-dialog.component.ts +0 -201
- package/src/lib/ui/designer/element-box.component.ts +0 -138
- package/src/lib/ui/designer/graphics.components.ts +0 -140
- package/src/lib/ui/designer/left-panel.component.ts +0 -189
- package/src/lib/ui/designer/safe-image.pipe.ts +0 -16
- package/src/lib/ui/designer/table-view.component.ts +0 -120
- package/src/lib/ui/designer.component.ts +0 -296
- package/src/lib/ui/designer.store.ts +0 -230
- package/src/lib/ui/inputs.ts +0 -34
- package/src/lib/ui/myreport.css +0 -267
- package/src/lib/ui/properties/band-props.component.ts +0 -86
- package/src/lib/ui/properties/element-props.component.ts +0 -326
- package/src/lib/ui/properties/expr-input.component.ts +0 -191
- package/src/lib/ui/properties/graphics-props.component.ts +0 -260
- package/src/lib/ui/properties/image-picker.component.ts +0 -62
- package/src/lib/ui/properties/properties-panel.component.ts +0 -37
- package/src/lib/ui/properties/report-extras.component.ts +0 -198
- package/src/lib/ui/properties/report-props.component.ts +0 -211
- package/src/lib/ui/properties/table-props.component.ts +0 -197
- package/src/lib/ui/viewer/page-view.component.ts +0 -73
- package/src/lib/ui/viewer/render.ts +0 -161
- package/src/lib/ui/viewer/viewer.component.ts +0 -555
- package/src/lib/ui/viewer.component.ts +0 -107
- package/tsconfig.lib.json +0 -12
- package/tsconfig.lib.prod.json +0 -5
package/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { BarcodeSymbology } from '../model/types';
|
|
2
|
+
export interface BarcodeResult {
|
|
3
|
+
/** One char per module: '1' = bar, '0' = space. Empty when `error` is set. */
|
|
4
|
+
modules: string;
|
|
5
|
+
/** Human-readable text printed under the bars. */
|
|
6
|
+
text: string;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Code 128: code set B for text, switching to code set C for runs of 4+ digits (denser).
|
|
11
|
+
* Supports printable ASCII (32–126).
|
|
12
|
+
*/
|
|
13
|
+
export declare function encodeCode128(value: string): BarcodeResult;
|
|
14
|
+
export declare function ean13CheckDigit(first12: string): number;
|
|
15
|
+
/** EAN-13 from 12 digits (check digit added) or 13 digits (check digit verified). */
|
|
16
|
+
export declare function encodeEan13(value: string): BarcodeResult;
|
|
17
|
+
export declare function encodeBarcode(symbology: BarcodeSymbology, value: string): BarcodeResult;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ChartSpec } from '../model/types';
|
|
2
|
+
import { type Row } from './expressions';
|
|
3
|
+
/** Validated categorical palette (light surface), assigned in fixed order — never cycled. */
|
|
4
|
+
export declare const SERIES_COLORS: string[];
|
|
5
|
+
export declare const OTHER_COLOR = "#9a9a96";
|
|
6
|
+
export declare const MAX_SERIES: number;
|
|
7
|
+
export interface ChartData {
|
|
8
|
+
categories: string[];
|
|
9
|
+
series: {
|
|
10
|
+
name: string;
|
|
11
|
+
values: number[];
|
|
12
|
+
color: string;
|
|
13
|
+
}[];
|
|
14
|
+
}
|
|
15
|
+
/** Groups rows by category and aggregates each value field into a series. */
|
|
16
|
+
export declare function chartData(spec: ChartSpec, rows: Row[]): ChartData;
|
|
17
|
+
/** Pie slice colors: one fixed-order hue per category, "Other" in neutral gray. */
|
|
18
|
+
export declare const sliceColor: (name: string, i: number) => string;
|
|
19
|
+
/** "Nice" axis: rounded max and tick step for values in [min, max]. */
|
|
20
|
+
export declare function niceScale(min: number, max: number, ticks?: number): {
|
|
21
|
+
min: number;
|
|
22
|
+
max: number;
|
|
23
|
+
step: number;
|
|
24
|
+
};
|
|
25
|
+
/** Short tick label: 1.2K, 3.4M. */
|
|
26
|
+
export declare function compactNumber(n: number): string;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ChartSpec } from '../model/types';
|
|
2
|
+
import { type Row } from './expressions';
|
|
3
|
+
/** SVG drawing primitives (coordinates in element pixels). */
|
|
4
|
+
export type Prim = {
|
|
5
|
+
t: 'path';
|
|
6
|
+
d: string;
|
|
7
|
+
fill: string;
|
|
8
|
+
stroke?: string;
|
|
9
|
+
sw?: number;
|
|
10
|
+
opacity?: number;
|
|
11
|
+
title?: string;
|
|
12
|
+
} | {
|
|
13
|
+
t: 'line';
|
|
14
|
+
x1: number;
|
|
15
|
+
y1: number;
|
|
16
|
+
x2: number;
|
|
17
|
+
y2: number;
|
|
18
|
+
stroke: string;
|
|
19
|
+
sw: number;
|
|
20
|
+
} | {
|
|
21
|
+
t: 'poly';
|
|
22
|
+
points: string;
|
|
23
|
+
stroke: string;
|
|
24
|
+
sw: number;
|
|
25
|
+
} | {
|
|
26
|
+
t: 'circle';
|
|
27
|
+
cx: number;
|
|
28
|
+
cy: number;
|
|
29
|
+
r: number;
|
|
30
|
+
fill: string;
|
|
31
|
+
stroke: string;
|
|
32
|
+
sw: number;
|
|
33
|
+
title?: string;
|
|
34
|
+
} | {
|
|
35
|
+
t: 'text';
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
text: string;
|
|
39
|
+
anchor: 'start' | 'middle' | 'end';
|
|
40
|
+
size: number;
|
|
41
|
+
weight: number;
|
|
42
|
+
fill: string;
|
|
43
|
+
};
|
|
44
|
+
/** Lays out a chart into SVG primitives for a w×h box. */
|
|
45
|
+
export declare function layoutChart(spec: ChartSpec, rows: Row[], w: number, h: number, fontSize: number, textColor: string): Prim[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReportElement } from '../model/types';
|
|
2
|
+
import { type Row } from './expressions';
|
|
3
|
+
import type { TableRenderData } from './table';
|
|
4
|
+
export interface Pivot {
|
|
5
|
+
rowKeys: string[];
|
|
6
|
+
colKeys: string[];
|
|
7
|
+
/** cells[r][c] = aggregate, null when no rows fall in the cell. */
|
|
8
|
+
cells: (number | null)[][];
|
|
9
|
+
rowTotals: (number | null)[];
|
|
10
|
+
colTotals: (number | null)[];
|
|
11
|
+
grandTotal: number | null;
|
|
12
|
+
}
|
|
13
|
+
export declare function pivot(el: ReportElement, rows: Row[]): Pivot;
|
|
14
|
+
/**
|
|
15
|
+
* Turns a cross table into an ordinary table element + data rows (cells pre-formatted), so the
|
|
16
|
+
* renderer can paginate it with the table code: header repeats, rows flow, totals form the footer.
|
|
17
|
+
*/
|
|
18
|
+
export declare function crosstabAsTable(el: ReportElement, rows: Row[]): {
|
|
19
|
+
table: ReportElement;
|
|
20
|
+
data: Row[];
|
|
21
|
+
render: TableRenderData;
|
|
22
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DataSourceDef } from '../model/types';
|
|
2
|
+
import { type Row } from './expressions';
|
|
3
|
+
export type FieldType = 'string' | 'number' | 'boolean' | 'date' | 'object';
|
|
4
|
+
export interface FieldInfo {
|
|
5
|
+
name: string;
|
|
6
|
+
type: FieldType;
|
|
7
|
+
}
|
|
8
|
+
export interface LoadResult {
|
|
9
|
+
rows: Row[];
|
|
10
|
+
fields: FieldInfo[];
|
|
11
|
+
requestUrl: string;
|
|
12
|
+
/** Non-fatal note, e.g. the array path was not found and auto-detect was used. */
|
|
13
|
+
warning?: string;
|
|
14
|
+
/** The whole JSON document (first page for OData), readable in formulas as root.x. */
|
|
15
|
+
root?: unknown;
|
|
16
|
+
}
|
|
17
|
+
export declare function parseHeaders(text: string): Record<string, string>;
|
|
18
|
+
export declare const hasSource: (ds: DataSourceDef) => boolean;
|
|
19
|
+
export declare function buildODataUrl(ds: DataSourceDef): string;
|
|
20
|
+
export declare function loadData(ds: DataSourceDef, signal?: AbortSignal): Promise<LoadResult>;
|
|
21
|
+
/** Infers field names (flattening nested objects into dot paths) from a sample of rows. */
|
|
22
|
+
export declare function inferFields(rows: Row[]): FieldInfo[];
|
|
23
|
+
/** Lists entity sets from an OData service ($metadata XML, falling back to the JSON service document). */
|
|
24
|
+
export declare function loadODataEntitySets(serviceUrl: string, headersText: string): Promise<string[]>;
|
|
25
|
+
export interface DetectedSource {
|
|
26
|
+
dataSource: DataSourceDef;
|
|
27
|
+
/** Human-readable summary of what was detected. */
|
|
28
|
+
note: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Builds a data source from a pasted URL: fetches it once and decides between plain JSON and OData
|
|
32
|
+
* (OData responses carry @odata.context / odata.metadata / a "d" wrapper). An OData service root
|
|
33
|
+
* is resolved to its first entity set. Previous settings (array path, query options) are reset.
|
|
34
|
+
*/
|
|
35
|
+
export declare function detectDataSource(rawUrl: string, headers?: string): Promise<DetectedSource>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { FormatSpec } from '../model/types';
|
|
2
|
+
export type Row = Record<string, unknown>;
|
|
3
|
+
export interface EvalContext {
|
|
4
|
+
row: Row | undefined;
|
|
5
|
+
/** Rows in the current scope (current group, or all rows for report bands). */
|
|
6
|
+
rows: Row[];
|
|
7
|
+
allRows: Row[];
|
|
8
|
+
pageRows: Row[];
|
|
9
|
+
rowNumber: number;
|
|
10
|
+
pageNumber: number;
|
|
11
|
+
totalPages: number;
|
|
12
|
+
reportName: string;
|
|
13
|
+
/** Report parameter values, by name. */
|
|
14
|
+
params?: Record<string, unknown>;
|
|
15
|
+
/** The whole loaded document (e.g. a receipt object whose items are the rows); read as root.x. */
|
|
16
|
+
root?: unknown;
|
|
17
|
+
}
|
|
18
|
+
export declare function getPath(obj: unknown, path: string): unknown;
|
|
19
|
+
export declare const truthy: (v: unknown) => boolean;
|
|
20
|
+
export declare const AGGREGATES: string[];
|
|
21
|
+
/** Aggregates a field (or expression) over rows — used by charts and cross tables. */
|
|
22
|
+
export declare function aggregate(fn: string, field: string, rows: Row[]): unknown;
|
|
23
|
+
/** Evaluates one expression (the part inside `{}`). */
|
|
24
|
+
export declare function evaluate(expr: string, ctx: EvalContext): unknown;
|
|
25
|
+
/** Parse error message for an expression, or null when valid. */
|
|
26
|
+
export declare function checkExpression(expr: string): string | null;
|
|
27
|
+
/** First parse error among the `{…}` parts of a template, or null. */
|
|
28
|
+
export declare function checkTemplate(template: string): string | null;
|
|
29
|
+
/** yyyy yy MMM MM M dd d HH H mm ss */
|
|
30
|
+
export declare function formatDatePattern(d: Date, pattern: string): string;
|
|
31
|
+
export declare function formatValue(v: unknown, f: FormatSpec): string;
|
|
32
|
+
/** Replaces every `{expr}` in the template with its formatted value. */
|
|
33
|
+
export declare function renderTemplate(template: string, ctx: EvalContext, format: FormatSpec): string;
|
|
34
|
+
export interface FunctionInfo {
|
|
35
|
+
name: string;
|
|
36
|
+
signature: string;
|
|
37
|
+
description: string;
|
|
38
|
+
group: 'Aggregate' | 'Logic' | 'Text' | 'Math' | 'Date' | 'Format';
|
|
39
|
+
}
|
|
40
|
+
export declare const FUNCTIONS: FunctionInfo[];
|
|
41
|
+
export declare const SPECIAL_FIELDS: string[];
|
|
42
|
+
/** Scalar values of a document as root.x paths (arrays skipped) — for the field list and autocomplete. */
|
|
43
|
+
export declare function documentFields(root: unknown): {
|
|
44
|
+
name: string;
|
|
45
|
+
type: string;
|
|
46
|
+
}[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReportElement } from '../model/types';
|
|
2
|
+
/** Must match the line-height used by ElementBox when rendering text. */
|
|
3
|
+
export declare const LINE_HEIGHT = 1.2;
|
|
4
|
+
/** Whether the element grows vertically to fit its text (default: on for text and fields). */
|
|
5
|
+
export declare const canGrow: (el: ReportElement) => boolean;
|
|
6
|
+
/** Height (px) the element needs to show `text` fully at its current width, wrapping like the renderer. */
|
|
7
|
+
export declare function measureTextHeight(text: string, el: ReportElement): number;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DataSourceDef, ReportDefinition, ReportParameter } from '../model/types';
|
|
2
|
+
import { type Row } from './expressions';
|
|
3
|
+
export type ParamValues = Record<string, unknown>;
|
|
4
|
+
/** Converts a raw (text) value to the parameter's type. */
|
|
5
|
+
export declare function coerceParam(p: ReportParameter, raw: unknown): unknown;
|
|
6
|
+
/** Default values for all parameters, overridden by `overrides` (e.g. from the page URL). */
|
|
7
|
+
export declare function resolveParams(report: ReportDefinition, overrides?: Record<string, unknown>): ParamValues;
|
|
8
|
+
export declare const paramChoices: (p: ReportParameter) => string[];
|
|
9
|
+
/**
|
|
10
|
+
* Applies parameters to a data source: `{@Country}` in the URL (URL-encoded), OData options,
|
|
11
|
+
* headers and array path. Pasted JSON is left alone (it contains braces of its own).
|
|
12
|
+
*/
|
|
13
|
+
export declare function applyParamsToDataSource(ds: DataSourceDef, params: ParamValues): DataSourceDef;
|
|
14
|
+
/** Rows that pass the report filter expression (all rows when there is none). */
|
|
15
|
+
export declare function filterRows(report: ReportDefinition, rows: Row[], params: ParamValues): Row[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { QrSpec } from '../model/types';
|
|
2
|
+
export interface QrResult {
|
|
3
|
+
/** size × size, true = dark module. */
|
|
4
|
+
modules: boolean[][];
|
|
5
|
+
size: number;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function encodeQr(value: string, level: QrSpec['errorCorrection']): QrResult;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Band, ReportDefinition, ReportElement } from '../model/types';
|
|
2
|
+
import { type EvalContext, type Row } from './expressions';
|
|
3
|
+
import { type ParamValues } from './parameters';
|
|
4
|
+
type BandContext = Pick<EvalContext, 'row' | 'rows' | 'allRows' | 'rowNumber' | 'reportName' | 'params' | 'root'>;
|
|
5
|
+
/** The slice of a table rendered inside one band instance (tables can span pages). */
|
|
6
|
+
export interface PlacedTable {
|
|
7
|
+
rows: Row[];
|
|
8
|
+
rowHeights: number[];
|
|
9
|
+
/** Index of rows[0] within the full table (for striping and RowNumber). */
|
|
10
|
+
startIndex: number;
|
|
11
|
+
header: boolean;
|
|
12
|
+
headerHeight: number;
|
|
13
|
+
footer: boolean;
|
|
14
|
+
footerHeight: number;
|
|
15
|
+
}
|
|
16
|
+
export interface PlacedElement {
|
|
17
|
+
el: ReportElement;
|
|
18
|
+
top: number;
|
|
19
|
+
height: number;
|
|
20
|
+
table?: PlacedTable;
|
|
21
|
+
}
|
|
22
|
+
export interface PlacedBand {
|
|
23
|
+
band: Band;
|
|
24
|
+
top: number;
|
|
25
|
+
/** Actual height of this band instance (>= band.height when fields grew). */
|
|
26
|
+
height: number;
|
|
27
|
+
items: PlacedElement[];
|
|
28
|
+
ctx: BandContext;
|
|
29
|
+
}
|
|
30
|
+
export interface RenderedPage {
|
|
31
|
+
index: number;
|
|
32
|
+
bands: PlacedBand[];
|
|
33
|
+
rows: Row[];
|
|
34
|
+
/** Set for continuous (receipt) pages: the actual page height. */
|
|
35
|
+
height?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Lays out bands onto pages. Text is evaluated later (needs TotalPages).
|
|
39
|
+
* `params` are the report parameter values (also used by the report filter).
|
|
40
|
+
*/
|
|
41
|
+
export declare function paginate(report: ReportDefinition, inputRows: Row[], params?: ParamValues, root?: unknown): RenderedPage[];
|
|
42
|
+
export declare function contextFor(placed: PlacedBand, page: RenderedPage, totalPages: number): EvalContext;
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ElementStyle, FormatSpec, ReportElement, TableColumn, TableSpec } from '../model/types';
|
|
2
|
+
/** Already-evaluated cell strings for drawing a table (designer and preview). */
|
|
3
|
+
export interface TableRenderData {
|
|
4
|
+
header: string[] | null;
|
|
5
|
+
headerHeight: number;
|
|
6
|
+
rows: {
|
|
7
|
+
cells: string[];
|
|
8
|
+
height: number;
|
|
9
|
+
index: number;
|
|
10
|
+
}[];
|
|
11
|
+
footer: string[] | null;
|
|
12
|
+
footerHeight: number;
|
|
13
|
+
}
|
|
14
|
+
export declare const hasGrid: (t: TableSpec) => boolean;
|
|
15
|
+
/** Pixel width of each column (relative widths scaled to the table width). */
|
|
16
|
+
export declare function columnWidths(el: ReportElement): number[];
|
|
17
|
+
/** Style used for measuring/drawing one cell (1px grid line counts as a border). */
|
|
18
|
+
export declare function tableCellStyle(el: ReportElement, header: boolean): ElementStyle;
|
|
19
|
+
/** Height shown in the designer: header + one sample row + footer. */
|
|
20
|
+
export declare function designTableHeight(t: TableSpec): number;
|
|
21
|
+
export declare function defaultTableSpec(columns: TableColumn[]): TableSpec;
|
|
22
|
+
export declare function createColumn(field: string, type?: string, format?: Partial<FormatSpec>): TableColumn;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Band, BandType, DataSourceDef, ElementKind, ElementStyle, FormatSpec, PageSettings, ReportDefinition, ReportElement } from './types';
|
|
2
|
+
export declare const uid: (prefix?: string) => string;
|
|
3
|
+
export declare const PAGE_SIZES: Record<string, {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const BAND_LABELS: Record<BandType, string>;
|
|
8
|
+
export declare const FOOTER_TYPES: BandType[];
|
|
9
|
+
export declare const defaultStyle: () => ElementStyle;
|
|
10
|
+
export declare const defaultFormat: () => FormatSpec;
|
|
11
|
+
export declare function createElement(kind: ElementKind, x: number, y: number, overrides?: Partial<Omit<ReportElement, 'style' | 'format'>> & {
|
|
12
|
+
style?: Partial<ElementStyle>;
|
|
13
|
+
format?: Partial<FormatSpec>;
|
|
14
|
+
}): ReportElement;
|
|
15
|
+
/** A table with one column per field (up to 6), or two blank columns. */
|
|
16
|
+
export declare function createTable(x: number, y: number, w: number, fields: {
|
|
17
|
+
name: string;
|
|
18
|
+
type?: string;
|
|
19
|
+
}[]): ReportElement;
|
|
20
|
+
export declare const createBand: (type: BandType, height: number, groupId?: string) => Band;
|
|
21
|
+
export declare const emptyDataSource: () => DataSourceDef;
|
|
22
|
+
export declare const defaultPage: () => PageSettings;
|
|
23
|
+
export declare const contentWidth: (p: PageSettings) => number;
|
|
24
|
+
export declare function newReport(): ReportDefinition;
|
|
25
|
+
/** Bands in the order they are laid out on the page. */
|
|
26
|
+
export declare function orderedBands(r: ReportDefinition): Band[];
|
|
27
|
+
/** A ready-made report bound to the bundled sample JSON file. */
|
|
28
|
+
export declare function sampleReport(): ReportDefinition;
|
|
29
|
+
export declare const defaultWatermark: () => import("./types").Watermark;
|
|
30
|
+
export declare const defaultBackground: () => import("./types").PageBackground;
|
|
31
|
+
export declare const defaultFieldOptions: () => import("./types").FieldOptions;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ReportDefinition, ReportElement } from './types';
|
|
2
|
+
export interface FieldRef {
|
|
3
|
+
name: string;
|
|
4
|
+
type?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function createChart(x: number, y: number, w: number, fields: FieldRef[]): ReportElement;
|
|
7
|
+
export declare function createBarcode(x: number, y: number, fields: FieldRef[]): ReportElement;
|
|
8
|
+
export declare function createQr(x: number, y: number, fields: FieldRef[]): ReportElement;
|
|
9
|
+
export declare function createCrosstab(x: number, y: number, w: number, fields: FieldRef[]): ReportElement;
|
|
10
|
+
export interface BandedTableOptions {
|
|
11
|
+
fields: FieldRef[];
|
|
12
|
+
/** Band that receives the column titles. */
|
|
13
|
+
titleBand: 'pageHeader' | 'reportHeader' | 'groupHeader';
|
|
14
|
+
/** For titleBand 'groupHeader': which group. Defaults to the innermost. */
|
|
15
|
+
groupId?: string;
|
|
16
|
+
grid: boolean;
|
|
17
|
+
headerBackground: string;
|
|
18
|
+
headerColor: string;
|
|
19
|
+
/** Adds sum() of numeric columns to the Report Footer. */
|
|
20
|
+
totals: boolean;
|
|
21
|
+
rowHeight: number;
|
|
22
|
+
/** Clear the title band and Detail band first (otherwise the table is appended below). */
|
|
23
|
+
replace: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** Adds the banded table to the report; returns the ids of the created elements. */
|
|
26
|
+
export declare function addBandedTable(r: ReportDefinition, o: BandedTableOptions): string[];
|
|
27
|
+
export declare const RECEIPT_WIDTHS: {
|
|
28
|
+
readonly 80: 302;
|
|
29
|
+
readonly 58: 219;
|
|
30
|
+
};
|
|
31
|
+
export declare function receiptReport(paper?: 80 | 58): ReportDefinition;
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
export type BandType = 'reportHeader' | 'pageHeader' | 'groupHeader' | 'detail' | 'groupFooter' | 'pageFooter' | 'reportFooter';
|
|
2
|
+
export type ElementKind = 'text' | 'field' | 'line' | 'rect' | 'image' | 'table' | 'chart' | 'barcode' | 'qrcode' | 'crosstab';
|
|
3
|
+
export type HAlign = 'left' | 'center' | 'right';
|
|
4
|
+
export type VAlign = 'top' | 'middle' | 'bottom';
|
|
5
|
+
export interface ElementStyle {
|
|
6
|
+
fontFamily: string;
|
|
7
|
+
fontSize: number;
|
|
8
|
+
bold: boolean;
|
|
9
|
+
italic: boolean;
|
|
10
|
+
underline: boolean;
|
|
11
|
+
color: string;
|
|
12
|
+
background: string;
|
|
13
|
+
align: HAlign;
|
|
14
|
+
vAlign: VAlign;
|
|
15
|
+
borderWidth: number;
|
|
16
|
+
borderColor: string;
|
|
17
|
+
padding: number;
|
|
18
|
+
}
|
|
19
|
+
export type FormatKind = 'none' | 'number' | 'currency' | 'percent' | 'date' | 'datetime' | 'time';
|
|
20
|
+
export interface FormatSpec {
|
|
21
|
+
kind: FormatKind;
|
|
22
|
+
decimals: number;
|
|
23
|
+
currency: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ReportElement {
|
|
26
|
+
id: string;
|
|
27
|
+
kind: ElementKind;
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
w: number;
|
|
31
|
+
h: number;
|
|
32
|
+
/** Template text. `{Field}`, `{sum(Amount)}`, `{PageNumber}`… For images: the URL (may contain {Field}). */
|
|
33
|
+
text: string;
|
|
34
|
+
format: FormatSpec;
|
|
35
|
+
style: ElementStyle;
|
|
36
|
+
/** Text/field grows taller to fit its content (pushing elements below down). Default true. */
|
|
37
|
+
canGrow?: boolean;
|
|
38
|
+
/** Only for kind 'table'. */
|
|
39
|
+
table?: TableSpec;
|
|
40
|
+
/** Only for kind 'chart'. */
|
|
41
|
+
chart?: ChartSpec;
|
|
42
|
+
/** Only for kind 'barcode' (the value is the `text` template). */
|
|
43
|
+
barcode?: BarcodeSpec;
|
|
44
|
+
/** Only for kind 'qrcode' (the value is the `text` template). */
|
|
45
|
+
qr?: QrSpec;
|
|
46
|
+
/** Only for kind 'crosstab'. */
|
|
47
|
+
crosstab?: CrossTabSpec;
|
|
48
|
+
/** Expression; the element is hidden when it evaluates to false, e.g. "Amount > 100". */
|
|
49
|
+
visibleWhen?: string;
|
|
50
|
+
/** Extra options for labels and fields. */
|
|
51
|
+
fieldOptions?: FieldOptions;
|
|
52
|
+
/** Lines and rectangles: stroke style. */
|
|
53
|
+
dash?: 'solid' | 'dashed' | 'dotted';
|
|
54
|
+
/** Images: how the picture fits its box. */
|
|
55
|
+
imageFit?: 'contain' | 'cover' | 'fill';
|
|
56
|
+
}
|
|
57
|
+
export interface FieldOptions {
|
|
58
|
+
/** Shown when the text evaluates to empty. */
|
|
59
|
+
nullText: string;
|
|
60
|
+
/** In repeating bands, leave the box empty when the value equals the previous row's (per page). */
|
|
61
|
+
hideDuplicates: boolean;
|
|
62
|
+
/** Conditional formatting: first matching rule wins. */
|
|
63
|
+
rules: StyleRule[];
|
|
64
|
+
}
|
|
65
|
+
export interface StyleRule {
|
|
66
|
+
/** Expression, e.g. "Amount > 1000". */
|
|
67
|
+
when: string;
|
|
68
|
+
color: string;
|
|
69
|
+
/** '' = unchanged */
|
|
70
|
+
background: string;
|
|
71
|
+
bold: boolean;
|
|
72
|
+
}
|
|
73
|
+
export interface TableColumn {
|
|
74
|
+
id: string;
|
|
75
|
+
header: string;
|
|
76
|
+
/** Cell template evaluated per row, e.g. "{Amount}". */
|
|
77
|
+
text: string;
|
|
78
|
+
/** Optional footer (totals) template, e.g. "{sum(Amount)}". */
|
|
79
|
+
footer: string;
|
|
80
|
+
/** Relative width; columns share the table width in proportion. */
|
|
81
|
+
width: number;
|
|
82
|
+
align: HAlign;
|
|
83
|
+
format: FormatSpec;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A table lists the rows in its band's scope: all rows in Report Header/Footer, the group's
|
|
87
|
+
* rows in Group Header/Footer, the current record in Detail. It flows across pages.
|
|
88
|
+
*/
|
|
89
|
+
export interface TableSpec {
|
|
90
|
+
columns: TableColumn[];
|
|
91
|
+
showHeader: boolean;
|
|
92
|
+
repeatHeader: boolean;
|
|
93
|
+
showFooter: boolean;
|
|
94
|
+
headerHeight: number;
|
|
95
|
+
rowHeight: number;
|
|
96
|
+
headerBackground: string;
|
|
97
|
+
headerColor: string;
|
|
98
|
+
/** Alternate-row background or 'transparent'. */
|
|
99
|
+
stripeBackground: string;
|
|
100
|
+
/** Grid line color or 'transparent'. */
|
|
101
|
+
gridColor: string;
|
|
102
|
+
}
|
|
103
|
+
export interface Band {
|
|
104
|
+
id: string;
|
|
105
|
+
type: BandType;
|
|
106
|
+
height: number;
|
|
107
|
+
visible: boolean;
|
|
108
|
+
groupId?: string;
|
|
109
|
+
elements: ReportElement[];
|
|
110
|
+
}
|
|
111
|
+
export interface Group {
|
|
112
|
+
id: string;
|
|
113
|
+
field: string;
|
|
114
|
+
direction: 'asc' | 'desc';
|
|
115
|
+
}
|
|
116
|
+
export interface SortSpec {
|
|
117
|
+
field: string;
|
|
118
|
+
direction: 'asc' | 'desc';
|
|
119
|
+
}
|
|
120
|
+
export interface PageSettings {
|
|
121
|
+
width: number;
|
|
122
|
+
height: number;
|
|
123
|
+
marginTop: number;
|
|
124
|
+
marginBottom: number;
|
|
125
|
+
marginLeft: number;
|
|
126
|
+
marginRight: number;
|
|
127
|
+
/** Receipt roll: one page as long as its content, no page breaks; the page footer follows the content. */
|
|
128
|
+
continuous?: boolean;
|
|
129
|
+
}
|
|
130
|
+
export type DataSourceType = 'json' | 'odata';
|
|
131
|
+
export interface DataSourceDef {
|
|
132
|
+
type: DataSourceType;
|
|
133
|
+
/** JSON: file/API URL. OData: service root URL (or full entity-set URL). */
|
|
134
|
+
url: string;
|
|
135
|
+
/** JSON only: pasted JSON used instead of the URL when non-empty. */
|
|
136
|
+
inline: string;
|
|
137
|
+
/** JSON only: dot path to the array inside the response, e.g. "data.items". */
|
|
138
|
+
dataPath: string;
|
|
139
|
+
/** Extra request headers, one "Name: value" per line. */
|
|
140
|
+
headers: string;
|
|
141
|
+
entitySet: string;
|
|
142
|
+
select: string;
|
|
143
|
+
filter: string;
|
|
144
|
+
orderby: string;
|
|
145
|
+
expand: string;
|
|
146
|
+
top: number | null;
|
|
147
|
+
/** Safety cap when following OData nextLink paging. */
|
|
148
|
+
maxRows: number;
|
|
149
|
+
}
|
|
150
|
+
export interface ReportDefinition {
|
|
151
|
+
version: 1;
|
|
152
|
+
name: string;
|
|
153
|
+
page: PageSettings;
|
|
154
|
+
dataSource: DataSourceDef;
|
|
155
|
+
groups: Group[];
|
|
156
|
+
sort: SortSpec[];
|
|
157
|
+
bands: Band[];
|
|
158
|
+
/** Values the user supplies at run time; used as @Name in formulas and {@Name} in the data source. */
|
|
159
|
+
parameters?: ReportParameter[];
|
|
160
|
+
/** Expression applied to every data row; rows where it is false are left out, e.g. "Country == @Country". */
|
|
161
|
+
filter?: string;
|
|
162
|
+
watermark?: Watermark;
|
|
163
|
+
background?: PageBackground;
|
|
164
|
+
}
|
|
165
|
+
export type ParameterType = 'string' | 'number' | 'date' | 'boolean';
|
|
166
|
+
export interface ReportParameter {
|
|
167
|
+
name: string;
|
|
168
|
+
label: string;
|
|
169
|
+
type: ParameterType;
|
|
170
|
+
defaultValue: string;
|
|
171
|
+
/** Comma-separated choices; empty = free input. */
|
|
172
|
+
options: string;
|
|
173
|
+
}
|
|
174
|
+
export interface Watermark {
|
|
175
|
+
enabled: boolean;
|
|
176
|
+
kind: 'text' | 'image';
|
|
177
|
+
text: string;
|
|
178
|
+
/** URL or data: URL. */
|
|
179
|
+
image: string;
|
|
180
|
+
/** 0–1 */
|
|
181
|
+
opacity: number;
|
|
182
|
+
/** Degrees, e.g. -45. */
|
|
183
|
+
angle: number;
|
|
184
|
+
fontSize: number;
|
|
185
|
+
color: string;
|
|
186
|
+
bold: boolean;
|
|
187
|
+
/** Image width as % of the page width. */
|
|
188
|
+
imageScale: number;
|
|
189
|
+
layer: 'behind' | 'front';
|
|
190
|
+
pages: 'all' | 'first';
|
|
191
|
+
}
|
|
192
|
+
export interface PageBackground {
|
|
193
|
+
enabled: boolean;
|
|
194
|
+
/** URL or data: URL. */
|
|
195
|
+
image: string;
|
|
196
|
+
fit: 'cover' | 'contain' | 'stretch' | 'center';
|
|
197
|
+
pages: 'all' | 'first';
|
|
198
|
+
}
|
|
199
|
+
export type AggregateKind = 'sum' | 'count' | 'avg' | 'min' | 'max';
|
|
200
|
+
export type ChartType = 'bar' | 'hbar' | 'line' | 'area' | 'pie' | 'doughnut';
|
|
201
|
+
/** A chart over the rows in its band's scope, grouped by a category field. */
|
|
202
|
+
export interface ChartSpec {
|
|
203
|
+
type: ChartType;
|
|
204
|
+
title: string;
|
|
205
|
+
categoryField: string;
|
|
206
|
+
/** One series per value field (pie/doughnut use the first). */
|
|
207
|
+
valueFields: string[];
|
|
208
|
+
aggregate: AggregateKind;
|
|
209
|
+
sort: 'none' | 'category' | 'valueDesc' | 'valueAsc';
|
|
210
|
+
/** Extra categories fold into "Other". */
|
|
211
|
+
maxCategories: number;
|
|
212
|
+
showLegend: boolean;
|
|
213
|
+
showValues: boolean;
|
|
214
|
+
showGrid: boolean;
|
|
215
|
+
valueFormat: FormatSpec;
|
|
216
|
+
}
|
|
217
|
+
export type BarcodeSymbology = 'code128' | 'ean13';
|
|
218
|
+
export interface BarcodeSpec {
|
|
219
|
+
symbology: BarcodeSymbology;
|
|
220
|
+
showText: boolean;
|
|
221
|
+
color: string;
|
|
222
|
+
}
|
|
223
|
+
export interface QrSpec {
|
|
224
|
+
errorCorrection: 'L' | 'M' | 'Q' | 'H';
|
|
225
|
+
color: string;
|
|
226
|
+
}
|
|
227
|
+
/** Pivot: one row per rowField value, one column per columnField value, cells = aggregate(valueField). */
|
|
228
|
+
export interface CrossTabSpec {
|
|
229
|
+
rowField: string;
|
|
230
|
+
columnField: string;
|
|
231
|
+
valueField: string;
|
|
232
|
+
aggregate: AggregateKind;
|
|
233
|
+
cornerText: string;
|
|
234
|
+
showRowTotals: boolean;
|
|
235
|
+
showColumnTotals: boolean;
|
|
236
|
+
valueFormat: FormatSpec;
|
|
237
|
+
headerHeight: number;
|
|
238
|
+
rowHeight: number;
|
|
239
|
+
headerBackground: string;
|
|
240
|
+
headerColor: string;
|
|
241
|
+
stripeBackground: string;
|
|
242
|
+
gridColor: string;
|
|
243
|
+
repeatHeader: boolean;
|
|
244
|
+
}
|
package/lib/ui/css.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type BandedTableOptions } from '../../model/factories';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Header/Detail table wizard: titles go in a header band, one field per column in Detail.
|
|
5
|
+
* Everything it creates is ordinary labels/fields, editable afterwards.
|
|
6
|
+
*/
|
|
7
|
+
export declare class BandedTableDialogComponent {
|
|
8
|
+
private readonly store;
|
|
9
|
+
readonly closed: import("@angular/core").OutputEmitterRef<void>;
|
|
10
|
+
protected readonly fields: import("@angular/core").Signal<import("angular-my-report").FieldInfo[]>;
|
|
11
|
+
protected readonly hasGroups: import("@angular/core").Signal<boolean>;
|
|
12
|
+
protected readonly picked: import("@angular/core").WritableSignal<Record<string, boolean>>;
|
|
13
|
+
protected readonly selectedCount: import("@angular/core").Signal<number>;
|
|
14
|
+
protected titleBand: BandedTableOptions['titleBand'];
|
|
15
|
+
protected rowHeight: number;
|
|
16
|
+
protected headerBackground: string;
|
|
17
|
+
protected headerColor: string;
|
|
18
|
+
protected grid: boolean;
|
|
19
|
+
protected totals: boolean;
|
|
20
|
+
protected replace: boolean;
|
|
21
|
+
protected onBackdropDown(e: PointerEvent): void;
|
|
22
|
+
protected toggle(name: string, on: boolean): void;
|
|
23
|
+
protected all(on: boolean): void;
|
|
24
|
+
protected create(): void;
|
|
25
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BandedTableDialogComponent, never>;
|
|
26
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<BandedTableDialogComponent, "rpt-banded-table-dialog", never, {}, { "closed": "closed"; }, never, never, true, never>;
|
|
27
|
+
}
|