bways-report 0.1.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/LICENSE +26 -0
- package/README.md +477 -0
- package/esm2022/bways-report.mjs +5 -0
- package/esm2022/lib/core/errors/index.mjs +2 -0
- package/esm2022/lib/core/errors/reporting-errors.mjs +65 -0
- package/esm2022/lib/core/index.mjs +8 -0
- package/esm2022/lib/core/models/component-event.model.mjs +8 -0
- package/esm2022/lib/core/models/index.mjs +5 -0
- package/esm2022/lib/core/models/report-component.model.mjs +10 -0
- package/esm2022/lib/core/models/report-datasource.model.mjs +9 -0
- package/esm2022/lib/core/models/report-definition.model.mjs +13 -0
- package/esm2022/lib/core/models/report-grid.model.mjs +10 -0
- package/esm2022/lib/core/models/report-layout.model.mjs +9 -0
- package/esm2022/lib/core/models/report-parameter.model.mjs +9 -0
- package/esm2022/lib/core/models/validation.model.mjs +8 -0
- package/esm2022/lib/core/registry/component-category.mjs +8 -0
- package/esm2022/lib/core/registry/component-registry.mjs +90 -0
- package/esm2022/lib/core/registry/index.mjs +2 -0
- package/esm2022/lib/core/registry/property-definition.model.mjs +10 -0
- package/esm2022/lib/core/services/dynamic-form-builder.service.mjs +55 -0
- package/esm2022/lib/core/services/index.mjs +3 -0
- package/esm2022/lib/core/services/report-session-context.service.mjs +314 -0
- package/esm2022/lib/core/tokens/index.mjs +3 -0
- package/esm2022/lib/core/tokens/reporting-config.token.mjs +26 -0
- package/esm2022/lib/core/tokens/session-context.token.mjs +18 -0
- package/esm2022/lib/core/utilities/id-generator.mjs +17 -0
- package/esm2022/lib/core/utilities/index.mjs +3 -0
- package/esm2022/lib/core/utilities/schema-migration.mjs +38 -0
- package/esm2022/lib/core/utils/identifier-humanizer.mjs +88 -0
- package/esm2022/lib/core/validation/index.mjs +2 -0
- package/esm2022/lib/core/validation/validation-factory.mjs +70 -0
- package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +107 -0
- package/esm2022/lib/data-access/adapters/http-schema-discovery.adapter.mjs +119 -0
- package/esm2022/lib/data-access/adapters/index.mjs +3 -0
- package/esm2022/lib/data-access/contracts/data-source.contract.mjs +28 -0
- package/esm2022/lib/data-access/contracts/index.mjs +7 -0
- package/esm2022/lib/data-access/contracts/lookup.contract.mjs +6 -0
- package/esm2022/lib/data-access/contracts/master-data.provider.mjs +24 -0
- package/esm2022/lib/data-access/contracts/report-persistence.contract.mjs +25 -0
- package/esm2022/lib/data-access/contracts/schema-discovery.contract.mjs +7 -0
- package/esm2022/lib/data-access/contracts/translation.contract.mjs +9 -0
- package/esm2022/lib/data-access/index.mjs +3 -0
- package/esm2022/lib/features/designer/components/component-palette/component-palette.component.mjs +542 -0
- package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +843 -0
- package/esm2022/lib/features/designer/components/property-editor/parameter-binding-editor.component.mjs +556 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +845 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-general.component.mjs +185 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +452 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-layout.component.mjs +350 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-report.component.mjs +175 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-validation.component.mjs +137 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +608 -0
- package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +225 -0
- package/esm2022/lib/features/designer/designer.component.mjs +285 -0
- package/esm2022/lib/features/designer/index.mjs +7 -0
- package/esm2022/lib/features/designer/services/designer-state.service.mjs +310 -0
- package/esm2022/lib/features/designer/services/index.mjs +2 -0
- package/esm2022/lib/features/designer/utilities/canvas-layout.util.mjs +124 -0
- package/esm2022/lib/features/export/index.mjs +2 -0
- package/esm2022/lib/features/export/models/export.models.mjs +2 -0
- package/esm2022/lib/features/export/services/report-export.service.mjs +107 -0
- package/esm2022/lib/features/index.mjs +6 -0
- package/esm2022/lib/features/persistence/index.mjs +2 -0
- package/esm2022/lib/features/persistence/services/index.mjs +4 -0
- package/esm2022/lib/features/persistence/services/report-store.service.mjs +183 -0
- package/esm2022/lib/features/persistence/services/report-versioning.service.mjs +81 -0
- package/esm2022/lib/features/persistence/services/schema-validator.service.mjs +102 -0
- package/esm2022/lib/features/routing/components/routed-report-designer.component.mjs +156 -0
- package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +163 -0
- package/esm2022/lib/features/routing/index.mjs +6 -0
- package/esm2022/lib/features/routing/models/report-route.models.mjs +2 -0
- package/esm2022/lib/features/routing/report-routes.mjs +49 -0
- package/esm2022/lib/features/routing/resolvers/report.resolver.mjs +22 -0
- package/esm2022/lib/features/routing/services/report-menu.service.mjs +77 -0
- package/esm2022/lib/features/runtime/dynamic-renderer.component.mjs +222 -0
- package/esm2022/lib/features/runtime/index.mjs +4 -0
- package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +409 -0
- package/esm2022/lib/features/runtime/report-runtime.component.mjs +147 -0
- package/esm2022/lib/primitives/components/button/rpt-button.component.mjs +88 -0
- package/esm2022/lib/primitives/components/chart-bridge/report-chart-bridge.component.mjs +361 -0
- package/esm2022/lib/primitives/components/checkbox/rpt-checkbox.component.mjs +86 -0
- package/esm2022/lib/primitives/components/date/rpt-date.component.mjs +91 -0
- package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +204 -0
- package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +476 -0
- package/esm2022/lib/primitives/components/index.mjs +10 -0
- package/esm2022/lib/primitives/components/input/rpt-input.component.mjs +88 -0
- package/esm2022/lib/primitives/components/kpi-card/rpt-kpi-card.component.mjs +197 -0
- package/esm2022/lib/primitives/components/number/rpt-number.component.mjs +110 -0
- package/esm2022/lib/primitives/index.mjs +3 -0
- package/esm2022/lib/primitives/register-builtins.mjs +328 -0
- package/esm2022/lib/provide-reporting.mjs +92 -0
- package/esm2022/public-api.mjs +9 -0
- package/fesm2022/bways-report.mjs +10360 -0
- package/fesm2022/bways-report.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/core/errors/index.d.ts +1 -0
- package/lib/core/errors/reporting-errors.d.ts +42 -0
- package/lib/core/index.d.ts +7 -0
- package/lib/core/models/component-event.model.d.ts +37 -0
- package/lib/core/models/index.d.ts +11 -0
- package/lib/core/models/report-component.model.d.ts +95 -0
- package/lib/core/models/report-datasource.model.d.ts +39 -0
- package/lib/core/models/report-definition.model.d.ts +100 -0
- package/lib/core/models/report-grid.model.d.ts +73 -0
- package/lib/core/models/report-layout.model.d.ts +43 -0
- package/lib/core/models/report-parameter.model.d.ts +22 -0
- package/lib/core/models/validation.model.d.ts +30 -0
- package/lib/core/registry/component-category.d.ts +16 -0
- package/lib/core/registry/component-registry.d.ts +101 -0
- package/lib/core/registry/index.d.ts +4 -0
- package/lib/core/registry/property-definition.model.d.ts +38 -0
- package/lib/core/services/dynamic-form-builder.service.d.ts +30 -0
- package/lib/core/services/index.d.ts +3 -0
- package/lib/core/services/report-session-context.service.d.ts +87 -0
- package/lib/core/tokens/index.d.ts +4 -0
- package/lib/core/tokens/reporting-config.token.d.ts +42 -0
- package/lib/core/tokens/session-context.token.d.ts +36 -0
- package/lib/core/utilities/id-generator.d.ts +9 -0
- package/lib/core/utilities/index.d.ts +3 -0
- package/lib/core/utilities/schema-migration.d.ts +10 -0
- package/lib/core/utils/identifier-humanizer.d.ts +22 -0
- package/lib/core/validation/index.d.ts +1 -0
- package/lib/core/validation/validation-factory.d.ts +31 -0
- package/lib/data-access/adapters/http-lookup.adapter.d.ts +19 -0
- package/lib/data-access/adapters/http-schema-discovery.adapter.d.ts +20 -0
- package/lib/data-access/adapters/index.d.ts +2 -0
- package/lib/data-access/contracts/data-source.contract.d.ts +37 -0
- package/lib/data-access/contracts/index.d.ts +9 -0
- package/lib/data-access/contracts/lookup.contract.d.ts +32 -0
- package/lib/data-access/contracts/master-data.provider.d.ts +54 -0
- package/lib/data-access/contracts/report-persistence.contract.d.ts +36 -0
- package/lib/data-access/contracts/schema-discovery.contract.d.ts +52 -0
- package/lib/data-access/contracts/translation.contract.d.ts +16 -0
- package/lib/data-access/index.d.ts +2 -0
- package/lib/features/designer/components/component-palette/component-palette.component.d.ts +39 -0
- package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +42 -0
- package/lib/features/designer/components/property-editor/parameter-binding-editor.component.d.ts +36 -0
- package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +68 -0
- package/lib/features/designer/components/property-editor/property-editor-general.component.d.ts +20 -0
- package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +20 -0
- package/lib/features/designer/components/property-editor/property-editor-layout.component.d.ts +18 -0
- package/lib/features/designer/components/property-editor/property-editor-report.component.d.ts +15 -0
- package/lib/features/designer/components/property-editor/property-editor-validation.component.d.ts +12 -0
- package/lib/features/designer/components/property-editor/property-editor.component.d.ts +44 -0
- package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +18 -0
- package/lib/features/designer/designer.component.d.ts +36 -0
- package/lib/features/designer/index.d.ts +7 -0
- package/lib/features/designer/services/designer-state.service.d.ts +103 -0
- package/lib/features/designer/services/index.d.ts +2 -0
- package/lib/features/designer/utilities/canvas-layout.util.d.ts +55 -0
- package/lib/features/export/index.d.ts +2 -0
- package/lib/features/export/models/export.models.d.ts +16 -0
- package/lib/features/export/services/report-export.service.d.ts +27 -0
- package/lib/features/index.d.ts +5 -0
- package/lib/features/persistence/index.d.ts +1 -0
- package/lib/features/persistence/services/index.d.ts +5 -0
- package/lib/features/persistence/services/report-store.service.d.ts +53 -0
- package/lib/features/persistence/services/report-versioning.service.d.ts +29 -0
- package/lib/features/persistence/services/schema-validator.service.d.ts +34 -0
- package/lib/features/routing/components/routed-report-designer.component.d.ts +18 -0
- package/lib/features/routing/components/routed-report-runtime.component.d.ts +18 -0
- package/lib/features/routing/index.d.ts +6 -0
- package/lib/features/routing/models/report-route.models.d.ts +41 -0
- package/lib/features/routing/report-routes.d.ts +16 -0
- package/lib/features/routing/resolvers/report.resolver.d.ts +7 -0
- package/lib/features/routing/services/report-menu.service.d.ts +30 -0
- package/lib/features/runtime/dynamic-renderer.component.d.ts +30 -0
- package/lib/features/runtime/index.d.ts +3 -0
- package/lib/features/runtime/report-grid-bridge.component.d.ts +94 -0
- package/lib/features/runtime/report-runtime.component.d.ts +26 -0
- package/lib/primitives/components/button/rpt-button.component.d.ts +19 -0
- package/lib/primitives/components/chart-bridge/report-chart-bridge.component.d.ts +45 -0
- package/lib/primitives/components/checkbox/rpt-checkbox.component.d.ts +14 -0
- package/lib/primitives/components/date/rpt-date.component.d.ts +17 -0
- package/lib/primitives/components/dropdown/rpt-dropdown.component.d.ts +32 -0
- package/lib/primitives/components/icon/rpt-icon.component.d.ts +41 -0
- package/lib/primitives/components/index.d.ts +12 -0
- package/lib/primitives/components/input/rpt-input.component.d.ts +16 -0
- package/lib/primitives/components/kpi-card/rpt-kpi-card.component.d.ts +43 -0
- package/lib/primitives/components/number/rpt-number.component.d.ts +20 -0
- package/lib/primitives/index.d.ts +2 -0
- package/lib/primitives/register-builtins.d.ts +11 -0
- package/lib/provide-reporting.d.ts +75 -0
- package/package.json +55 -0
- package/public-api.d.ts +5 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { computed, inject, Injectable, signal } from '@angular/core';
|
|
2
|
+
import { ComponentRegistry } from '../../../core/registry/component-registry';
|
|
3
|
+
import { generateId } from '../../../core/utilities/id-generator';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
const MAX_HISTORY = 30;
|
|
6
|
+
/**
|
|
7
|
+
* DesignerStateService coordinates state for the visual report designer.
|
|
8
|
+
*
|
|
9
|
+
* Scoped at the Designer component level (not root) to ensure multiple designer
|
|
10
|
+
* instances or navigation flows remain strictly isolated.
|
|
11
|
+
*/
|
|
12
|
+
export class DesignerStateService {
|
|
13
|
+
registry = inject(ComponentRegistry);
|
|
14
|
+
/** Current active report definition */
|
|
15
|
+
definition = signal({
|
|
16
|
+
id: generateId('rpt'),
|
|
17
|
+
name: 'Untitled Report',
|
|
18
|
+
schemaVersion: 1,
|
|
19
|
+
version: 1,
|
|
20
|
+
layout: { columns: 12, gap: 16, padding: 24, direction: 'ltr' },
|
|
21
|
+
components: [],
|
|
22
|
+
parameters: [],
|
|
23
|
+
dataSources: [],
|
|
24
|
+
});
|
|
25
|
+
/** Selected component ID in canvas */
|
|
26
|
+
selectedComponentId = signal(null);
|
|
27
|
+
/** Active property editor tab */
|
|
28
|
+
activeTab = signal('properties');
|
|
29
|
+
/** Current view mode (design, preview, or raw json) */
|
|
30
|
+
viewMode = signal('design');
|
|
31
|
+
/** Dirty flag indicating unsaved changes */
|
|
32
|
+
isDirty = signal(false);
|
|
33
|
+
// History stack for Undo / Redo
|
|
34
|
+
history = signal([]);
|
|
35
|
+
historyIndex = signal(-1);
|
|
36
|
+
canUndo = computed(() => this.historyIndex() > 0);
|
|
37
|
+
canRedo = computed(() => this.historyIndex() >= 0 && this.historyIndex() < this.history().length - 1);
|
|
38
|
+
/** Currently selected component instance, or null if none */
|
|
39
|
+
selectedComponent = computed(() => {
|
|
40
|
+
const id = this.selectedComponentId();
|
|
41
|
+
if (!id)
|
|
42
|
+
return null;
|
|
43
|
+
return this.definition().components.find((c) => c.id === id) ?? null;
|
|
44
|
+
});
|
|
45
|
+
/**
|
|
46
|
+
* Initializes or reloads a report definition into the designer.
|
|
47
|
+
*/
|
|
48
|
+
loadDefinition(def) {
|
|
49
|
+
const cloned = JSON.parse(JSON.stringify(def));
|
|
50
|
+
this.definition.set(cloned);
|
|
51
|
+
this.selectedComponentId.set(null);
|
|
52
|
+
this.isDirty.set(false);
|
|
53
|
+
this.history.set([JSON.parse(JSON.stringify(cloned))]);
|
|
54
|
+
this.historyIndex.set(0);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Selects a component for property editing.
|
|
58
|
+
*/
|
|
59
|
+
selectComponent(id) {
|
|
60
|
+
this.selectedComponentId.set(id);
|
|
61
|
+
if (id) {
|
|
62
|
+
this.activeTab.set('properties');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Sets the active view mode (design, live preview, json schema).
|
|
67
|
+
*/
|
|
68
|
+
setViewMode(mode) {
|
|
69
|
+
this.viewMode.set(mode);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Sets the active editor tab.
|
|
73
|
+
*/
|
|
74
|
+
setActiveTab(tab) {
|
|
75
|
+
this.activeTab.set(tab);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Adds a new component of the specified type onto the canvas.
|
|
79
|
+
*/
|
|
80
|
+
addComponent(type, targetIndex) {
|
|
81
|
+
const meta = this.registry.resolve(type);
|
|
82
|
+
const defaultConfig = meta?.createDefaultConfig() ?? {
|
|
83
|
+
id: generateId(type),
|
|
84
|
+
type,
|
|
85
|
+
label: meta?.displayName ?? type,
|
|
86
|
+
key: `${type}_${Math.random().toString(36).substring(2, 6)}`,
|
|
87
|
+
};
|
|
88
|
+
const newComponent = {
|
|
89
|
+
id: generateId(type),
|
|
90
|
+
type,
|
|
91
|
+
label: defaultConfig.label ?? meta?.displayName ?? type,
|
|
92
|
+
key: defaultConfig.key ?? `${type}_${Math.random().toString(36).substring(2, 6)}`,
|
|
93
|
+
order: 0,
|
|
94
|
+
layout: {
|
|
95
|
+
columnSpan: defaultConfig.layout?.columnSpan ?? (type === 'button' ? 2 : 4),
|
|
96
|
+
...defaultConfig.layout,
|
|
97
|
+
},
|
|
98
|
+
properties: { ...(defaultConfig.properties ?? {}) },
|
|
99
|
+
validation: defaultConfig.validation ? { ...defaultConfig.validation } : undefined,
|
|
100
|
+
dataSource: defaultConfig.dataSource ? { ...defaultConfig.dataSource } : undefined,
|
|
101
|
+
enabled: defaultConfig.enabled ?? true,
|
|
102
|
+
};
|
|
103
|
+
const currentComponents = [...this.definition().components].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
104
|
+
if (targetIndex !== undefined && targetIndex >= 0 && targetIndex <= currentComponents.length) {
|
|
105
|
+
currentComponents.splice(targetIndex, 0, newComponent);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
currentComponents.push(newComponent);
|
|
109
|
+
}
|
|
110
|
+
// Recalculate order indices
|
|
111
|
+
currentComponents.forEach((c, idx) => (c.order = idx + 1));
|
|
112
|
+
this.mutateDefinition((def) => ({
|
|
113
|
+
...def,
|
|
114
|
+
components: currentComponents,
|
|
115
|
+
}));
|
|
116
|
+
this.selectComponent(newComponent.id);
|
|
117
|
+
return newComponent;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Removes a component by its ID.
|
|
121
|
+
*/
|
|
122
|
+
removeComponent(id) {
|
|
123
|
+
const currentComponents = this.definition().components.filter((c) => c.id !== id);
|
|
124
|
+
currentComponents.forEach((c, idx) => (c.order = idx + 1));
|
|
125
|
+
if (this.selectedComponentId() === id) {
|
|
126
|
+
this.selectedComponentId.set(null);
|
|
127
|
+
}
|
|
128
|
+
this.mutateDefinition((def) => ({
|
|
129
|
+
...def,
|
|
130
|
+
components: currentComponents,
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Duplicates an existing component.
|
|
135
|
+
*/
|
|
136
|
+
duplicateComponent(id) {
|
|
137
|
+
const existing = this.definition().components.find((c) => c.id === id);
|
|
138
|
+
if (!existing)
|
|
139
|
+
return null;
|
|
140
|
+
const duplicated = {
|
|
141
|
+
...JSON.parse(JSON.stringify(existing)),
|
|
142
|
+
id: generateId(existing.type),
|
|
143
|
+
key: existing.key ? `${existing.key}_copy` : undefined,
|
|
144
|
+
label: existing.label ? `${existing.label} (Copy)` : undefined,
|
|
145
|
+
};
|
|
146
|
+
const currentComponents = [...this.definition().components].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
147
|
+
const index = currentComponents.findIndex((c) => c.id === id);
|
|
148
|
+
currentComponents.splice(index + 1, 0, duplicated);
|
|
149
|
+
currentComponents.forEach((c, idx) => (c.order = idx + 1));
|
|
150
|
+
this.mutateDefinition((def) => ({
|
|
151
|
+
...def,
|
|
152
|
+
components: currentComponents,
|
|
153
|
+
}));
|
|
154
|
+
this.selectComponent(duplicated.id);
|
|
155
|
+
return duplicated;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Moves a component from previous index to current index (e.g. from CDK drag drop).
|
|
159
|
+
*/
|
|
160
|
+
moveComponent(previousIndex, currentIndex) {
|
|
161
|
+
if (previousIndex === currentIndex)
|
|
162
|
+
return;
|
|
163
|
+
const currentComponents = [...this.definition().components].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
164
|
+
if (previousIndex < 0 || previousIndex >= currentComponents.length)
|
|
165
|
+
return;
|
|
166
|
+
const targetIdx = Math.max(0, Math.min(currentIndex, currentComponents.length - 1));
|
|
167
|
+
const [moved] = currentComponents.splice(previousIndex, 1);
|
|
168
|
+
currentComponents.splice(targetIdx, 0, moved);
|
|
169
|
+
currentComponents.forEach((c, idx) => (c.order = idx + 1));
|
|
170
|
+
this.mutateDefinition((def) => ({
|
|
171
|
+
...def,
|
|
172
|
+
components: currentComponents,
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Updates partial properties of a component.
|
|
177
|
+
*/
|
|
178
|
+
updateComponent(id, updates) {
|
|
179
|
+
const currentComponents = this.definition().components.map((c) => {
|
|
180
|
+
if (c.id === id) {
|
|
181
|
+
return { ...c, ...updates };
|
|
182
|
+
}
|
|
183
|
+
return c;
|
|
184
|
+
});
|
|
185
|
+
this.mutateDefinition((def) => ({
|
|
186
|
+
...def,
|
|
187
|
+
components: currentComponents,
|
|
188
|
+
}));
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Updates a single component property value within `properties`.
|
|
192
|
+
*/
|
|
193
|
+
updateComponentProperty(id, propKey, value) {
|
|
194
|
+
const currentComponents = this.definition().components.map((c) => {
|
|
195
|
+
if (c.id === id) {
|
|
196
|
+
return {
|
|
197
|
+
...c,
|
|
198
|
+
properties: {
|
|
199
|
+
...(c.properties ?? {}),
|
|
200
|
+
[propKey]: value,
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
return c;
|
|
205
|
+
});
|
|
206
|
+
this.mutateDefinition((def) => ({
|
|
207
|
+
...def,
|
|
208
|
+
components: currentComponents,
|
|
209
|
+
}));
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Updates layout properties for a component (e.g. columnSpan).
|
|
213
|
+
*/
|
|
214
|
+
updateComponentLayout(id, layout) {
|
|
215
|
+
const currentComponents = this.definition().components.map((c) => {
|
|
216
|
+
if (c.id === id) {
|
|
217
|
+
const nextLayout = {
|
|
218
|
+
...(c.layout ?? {}),
|
|
219
|
+
...layout,
|
|
220
|
+
};
|
|
221
|
+
for (const key of Object.keys(layout)) {
|
|
222
|
+
if (layout[key] === undefined) {
|
|
223
|
+
delete nextLayout[key];
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
...c,
|
|
228
|
+
layout: nextLayout,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
return c;
|
|
232
|
+
});
|
|
233
|
+
this.mutateDefinition((def) => ({
|
|
234
|
+
...def,
|
|
235
|
+
components: currentComponents,
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Updates report-level settings (name, description, layout).
|
|
240
|
+
*/
|
|
241
|
+
updateReportSettings(settings) {
|
|
242
|
+
this.mutateDefinition((def) => ({
|
|
243
|
+
...def,
|
|
244
|
+
...settings,
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Updates grid definition settings.
|
|
249
|
+
*/
|
|
250
|
+
updateGridSettings(grid) {
|
|
251
|
+
this.mutateDefinition((def) => ({
|
|
252
|
+
...def,
|
|
253
|
+
grid,
|
|
254
|
+
}));
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Reverts to the previous state in history.
|
|
258
|
+
*/
|
|
259
|
+
undo() {
|
|
260
|
+
if (!this.canUndo())
|
|
261
|
+
return;
|
|
262
|
+
const newIndex = this.historyIndex() - 1;
|
|
263
|
+
this.historyIndex.set(newIndex);
|
|
264
|
+
const restored = JSON.parse(JSON.stringify(this.history()[newIndex]));
|
|
265
|
+
this.definition.set(restored);
|
|
266
|
+
this.isDirty.set(true);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Advances to the next state in history.
|
|
270
|
+
*/
|
|
271
|
+
redo() {
|
|
272
|
+
if (!this.canRedo())
|
|
273
|
+
return;
|
|
274
|
+
const newIndex = this.historyIndex() + 1;
|
|
275
|
+
this.historyIndex.set(newIndex);
|
|
276
|
+
const restored = JSON.parse(JSON.stringify(this.history()[newIndex]));
|
|
277
|
+
this.definition.set(restored);
|
|
278
|
+
this.isDirty.set(true);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Marks the current definition state as saved.
|
|
282
|
+
*/
|
|
283
|
+
markSaved() {
|
|
284
|
+
this.isDirty.set(false);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Applies an immutable state change and pushes to history.
|
|
288
|
+
*/
|
|
289
|
+
mutateDefinition(updater) {
|
|
290
|
+
const next = updater(this.definition());
|
|
291
|
+
this.definition.set(next);
|
|
292
|
+
this.isDirty.set(true);
|
|
293
|
+
this.pushHistory(next);
|
|
294
|
+
}
|
|
295
|
+
pushHistory(def) {
|
|
296
|
+
const currentHist = this.history().slice(0, this.historyIndex() + 1);
|
|
297
|
+
currentHist.push(JSON.parse(JSON.stringify(def)));
|
|
298
|
+
if (currentHist.length > MAX_HISTORY) {
|
|
299
|
+
currentHist.shift();
|
|
300
|
+
}
|
|
301
|
+
this.history.set(currentHist);
|
|
302
|
+
this.historyIndex.set(currentHist.length - 1);
|
|
303
|
+
}
|
|
304
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DesignerStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
305
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DesignerStateService });
|
|
306
|
+
}
|
|
307
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DesignerStateService, decorators: [{
|
|
308
|
+
type: Injectable
|
|
309
|
+
}] });
|
|
310
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVzaWduZXItc3RhdGUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2J3YXlzLXJlcG9ydC9zcmMvbGliL2ZlYXR1cmVzL2Rlc2lnbmVyL3NlcnZpY2VzL2Rlc2lnbmVyLXN0YXRlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUtyRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0NBQXNDLENBQUM7O0FBS2xFLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQztBQUV2Qjs7Ozs7R0FLRztBQUVILE1BQU0sT0FBTyxvQkFBb0I7SUFDZCxRQUFRLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFFdEQsdUNBQXVDO0lBQzlCLFVBQVUsR0FBRyxNQUFNLENBQW1CO1FBQzdDLEVBQUUsRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDO1FBQ3JCLElBQUksRUFBRSxpQkFBaUI7UUFDdkIsYUFBYSxFQUFFLENBQUM7UUFDaEIsT0FBTyxFQUFFLENBQUM7UUFDVixNQUFNLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFO1FBQy9ELFVBQVUsRUFBRSxFQUFFO1FBQ2QsVUFBVSxFQUFFLEVBQUU7UUFDZCxXQUFXLEVBQUUsRUFBRTtLQUNoQixDQUFDLENBQUM7SUFFSCxzQ0FBc0M7SUFDN0IsbUJBQW1CLEdBQUcsTUFBTSxDQUFnQixJQUFJLENBQUMsQ0FBQztJQUUzRCxpQ0FBaUM7SUFDeEIsU0FBUyxHQUFHLE1BQU0sQ0FBb0IsWUFBWSxDQUFDLENB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O1FBQ3ZCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVPLFdBQVcsQ0FBQyxHQUFxQjtRQUN2QyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDckUsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xELElBQUksV0FBVyxDQUFDLE1BQU0sR0FBRyxXQUFXLEVBQUUsQ0FBQztZQUNyQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdEIsQ0FBQztRQUNELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzlCLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDaEQsQ0FBQzt3R0E3VVUsb0JBQW9COzRHQUFwQixvQkFBb0I7OzRGQUFwQixvQkFBb0I7a0JBRGhDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb21wdXRlZCwgaW5qZWN0LCBJbmplY3RhYmxlLCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJlcG9ydERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtZGVmaW5pdGlvbi5tb2RlbCc7XG5pbXBvcnQgeyBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vLi4vY29yZS9tb2RlbHMvcmVwb3J0LWNvbXBvbmVudC5tb2RlbCc7XG5pbXBvcnQgeyBDb21wb25lbnRMYXlvdXREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vLi4vY29yZS9tb2RlbHMvcmVwb3J0LWxheW91dC5tb2RlbCc7XG5pbXBvcnQgeyBSZXBvcnRHcmlkRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uLy4uL2NvcmUvbW9kZWxzL3JlcG9ydC1ncmlkLm1vZGVsJztcbmltcG9ydCB7IENvbXBvbmVudFJlZ2lzdHJ5IH0gZnJvbSAnLi4vLi4vLi4vY29yZS9yZWdpc3RyeS9jb21wb25lbnQtcmVnaXN0cnknO1xuaW1wb3J0IHsgZ2VuZXJhdGVJZCB9IGZyb20gJy4uLy4uLy4uL2NvcmUvdXRpbGl0aWVzL2lkLWdlbmVyYXRvcic7XG5cbmV4cG9ydCB0eXBlIERlc2lnbmVyVmlld01vZGUgPSAnZGVzaWduJyB8ICdwcmV2aWV3JyB8ICdqc29uJztcbmV4cG9ydCB0eXBlIERlc2lnbmVyQWN0aXZlVGFiID0gJ3Byb3BlcnRpZXMnIHwgJ3JlcG9ydCcgfCAnZ3JpZCc7XG5cbmNvbnN0IE1BWF9ISVNUT1JZID0gMzA7XG5cbi8qKlxuICogRGVzaWduZXJTdGF0ZVNlcnZpY2UgY29vcmRpbmF0ZXMgc3RhdGUgZm9yIHRoZSB2aXN1YWwgcmVwb3J0IGRlc2lnbmVyLlxuICpcbiAqIFNjb3BlZCBhdCB0aGUgRGVzaWduZXIgY29tcG9uZW50IGxldmVsIChub3Qgcm9vdCkgdG8gZW5zdXJlIG11bHRpcGxlIGRlc2lnbmVyXG4gKiBpbnN0YW5jZXMgb3IgbmF2aWdhdGlvbiBmbG93cyByZW1haW4gc3RyaWN0bHkgaXNvbGF0ZWQuXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBEZXNpZ25lclN0YXRlU2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVnaXN0cnkgPSBpbmplY3QoQ29tcG9uZW50UmVnaXN0cnkpO1xuXG4gIC8qKiBDdXJyZW50IGFjdGl2ZSByZXBvcnQgZGVmaW5pdGlvbiAqL1xuICByZWFkb25seSBkZWZpbml0aW9uID0gc2lnbmFsPFJlcG9ydERlZmluaXRpb24+KHtcbiAgICBpZDogZ2VuZXJhdGVJZCgncnB0JyksXG4gICAgbmFtZTogJ1VudGl0bGVkIFJlcG9ydCcsXG4gICAgc2NoZW1hVmVyc2lvbjogMSxcbiAgICB2ZXJzaW9uOiAxLFxuICAgIGxheW91dDogeyBjb2x1bW5zOiAxMiwgZ2FwOiAxNiwgcGFkZGluZzogMjQsIGRpcmVjdGlvbjogJ2x0cicgfSxcbiAgICBjb21wb25lbnRzOiBbXSxcbiAgICBwYXJhbWV0ZXJzOiBbXSxcbiAgICBkYXRhU291cmNlczogW10sXG4gIH0pO1xuXG4gIC8qKiBTZWxlY3RlZCBjb21wb25lbnQgSUQgaW4gY2FudmFzICovXG4gIHJlYWRvbmx5IHNlbGVjdGVkQ29tcG9uZW50SWQgPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG5cbiAgLyoqIEFjdGl2ZSBwcm9wZXJ0eSBlZGl0b3IgdGFiICovXG4gIHJlYWRvbmx5IGFjdGl2ZVRhYiA9IHNpZ25hbDxEZXNpZ25lckFjdGl2ZVRhYj4oJ3Byb3BlcnRpZXMnKTtcblxuICAvKiogQ3VycmVudCB2aWV3IG1vZGUgKGRlc2lnbiwgcHJldmlldywgb3IgcmF3IGpzb24pICovXG4gIHJlYWRvbmx5IHZpZXdNb2RlID0gc2lnbmFsPERlc2lnbmVyVmlld01vZGU+KCdkZXNpZ24nKTtcblxuICAvKiogRGlydHkgZmxhZyBpbmRpY2F0aW5nIHVuc2F2ZWQgY2hhbmdlcyAqL1xuICByZWFkb25seSBpc0RpcnR5ID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcblxuICAvLyBIaXN0b3J5IHN0YWNrIGZvciBVbmRvIC8gUmVkb1xuICBwcml2YXRlIHJlYWRvbmx5IGhpc3RvcnkgPSBzaWduYWw8UmVwb3J0RGVmaW5pdGlvbltdPihbXSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgaGlzdG9yeUluZGV4ID0gc2lnbmFsPG51bWJlcj4oLTEpO1xuXG4gIHJlYWRvbmx5IGNhblVuZG8gPSBjb21wdXRlZCgoKSA9PiB0aGlzLmhpc3RvcnlJbmRleCgpID4gMCk7XG4gIHJlYWRvbmx5IGNhblJlZG8gPSBjb21wdXRlZCgoKSA9PiB0aGlzLmhpc3RvcnlJbmRleCgpID49IDAgJiYgdGhpcy5oaXN0b3J5SW5kZXgoKSA8IHRoaXMuaGlzdG9yeSgpLmxlbmd0aCAtIDEpO1xuXG4gIC8qKiBDdXJyZW50bHkgc2VsZWN0ZWQgY29tcG9uZW50IGluc3RhbmNlLCBvciBudWxsIGlmIG5vbmUgKi9cbiAgcmVhZG9ubHkgc2VsZWN0ZWRDb21wb25lbnQgPSBjb21wdXRlZDxSZXBvcnRDb21wb25lbnREZWZpbml0aW9uIHwgbnVsbD4oKCkgPT4ge1xuICAgIGNvbnN0IGlkID0gdGhpcy5zZWxlY3RlZENvbXBvbmVudElkKCk7XG4gICAgaWYgKCFpZCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHRoaXMuZGVmaW5pdGlvbigpLmNvbXBvbmVudHMuZmluZCgoYykgPT4gYy5pZCA9PT0gaWQpID8/IG51bGw7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyBvciByZWxvYWRzIGEgcmVwb3J0IGRlZmluaXRpb24gaW50byB0aGUgZGVzaWduZXIuXG4gICAqL1xuICBsb2FkRGVmaW5pdGlvbihkZWY6IFJlcG9ydERlZmluaXRpb24pOiB2b2lkIHtcbiAgICBjb25zdCBjbG9uZWQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGRlZikpIGFzIFJlcG9ydERlZmluaXRpb247XG4gICAgdGhpcy5kZWZpbml0aW9uLnNldChjbG9uZWQpO1xuICAgIHRoaXMuc2VsZWN0ZWRDb21wb25lbnRJZC5zZXQobnVsbCk7XG4gICAgdGhpcy5pc0RpcnR5LnNldChmYWxzZSk7XG4gICAgdGhpcy5oaXN0b3J5LnNldChbSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShjbG9uZWQpKV0pO1xuICAgIHRoaXMuaGlzdG9yeUluZGV4LnNldCgwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3RzIGEgY29tcG9uZW50IGZvciBwcm9wZXJ0eSBlZGl0aW5nLlxuICAgKi9cbiAgc2VsZWN0Q29tcG9uZW50KGlkOiBzdHJpbmcgfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZENvbXBvbmVudElkLnNldChpZCk7XG4gICAgaWYgKGlkKSB7XG4gICAgICB0aGlzLmFjdGl2ZVRhYi5zZXQoJ3Byb3BlcnRpZXMnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgYWN0aXZlIHZpZXcgbW9kZSAoZGVzaWduLCBsaXZlIHByZXZpZXcsIGpzb24gc2NoZW1hKS5cbiAgICovXG4gIHNldFZpZXdNb2RlKG1vZGU6IERlc2lnbmVyVmlld01vZGUpOiB2b2lkIHtcbiAgICB0aGlzLnZpZXdNb2RlLnNldChtb2RlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBhY3RpdmUgZWRpdG9yIHRhYi5cbiAgICovXG4gIHNldEFjdGl2ZVRhYih0YWI6IERlc2lnbmVyQWN0aXZlVGFiKTogdm9pZCB7XG4gICAgdGhpcy5hY3RpdmVUYWIuc2V0KHRhYik7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIG5ldyBjb21wb25lbnQgb2YgdGhlIHNwZWNpZmllZCB0eXBlIG9udG8gdGhlIGNhbnZhcy5cbiAgICovXG4gIGFkZENvbXBvbmVudCh0eXBlOiBzdHJpbmcsIHRhcmdldEluZGV4PzogbnVtYmVyKTogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbiB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMucmVnaXN0cnkucmVzb2x2ZSh0eXBlKTtcbiAgICBjb25zdCBkZWZhdWx0Q29uZmlnID0gbWV0YT8uY3JlYXRlRGVmYXVsdENvbmZpZygpID8/IHtcbiAgICAgIGlkOiBnZW5lcmF0ZUlkKHR5cGUpLFxuICAgICAgdHlwZSxcbiAgICAgIGxhYmVsOiBtZXRhPy5kaXNwbGF5TmFtZSA/PyB0eXBlLFxuICAgICAga2V5OiBgJHt0eXBlfV8ke01hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZygyLCA2KX1gLFxuICAgIH07XG5cbiAgICBjb25zdCBuZXdDb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24gPSB7XG4gICAgICBpZDogZ2VuZXJhdGVJZCh0eXBlKSxcbiAgICAgIHR5cGUsXG4gICAgICBsYWJlbDogZGVmYXVsdENvbmZpZy5sYWJlbCA/PyBtZXRhPy5kaXNwbGF5TmFtZSA/PyB0eXBlLFxuICAgICAga2V5OiBkZWZhdWx0Q29uZmlnLmtleSA/PyBgJHt0eXBlfV8ke01hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZygyLCA2KX1gLFxuICAgICAgb3JkZXI6IDAsXG4gICAgICBsYXlvdXQ6IHtcbiAgICAgICAgY29sdW1uU3BhbjogZGVmYXVsdENvbmZpZy5sYXlvdXQ/LmNvbHVtblNwYW4gPz8gKHR5cGUgPT09ICdidXR0b24nID8gMiA6IDQpLFxuICAgICAgICAuLi5kZWZhdWx0Q29uZmlnLmxheW91dCxcbiAgICAgIH0sXG4gICAgICBwcm9wZXJ0aWVzOiB7IC4uLihkZWZhdWx0Q29uZmlnLnByb3BlcnRpZXMgPz8ge30pIH0sXG4gICAgICB2YWxpZGF0aW9uOiBkZWZhdWx0Q29uZmlnLnZhbGlkYXRpb24gPyB7IC4uLmRlZmF1bHRDb25maWcudmFsaWRhdGlvbiB9IDogdW5kZWZpbmVkLFxuICAgICAgZGF0YVNvdXJjZTogZGVmYXVsdENvbmZpZy5kYXRhU291cmNlID8geyAuLi5kZWZhdWx0Q29uZmlnLmRhdGFTb3VyY2UgfSA6IHVuZGVmaW5lZCxcbiAgICAgIGVuYWJsZWQ6IGRlZmF1bHRDb25maWcuZW5hYmxlZCA/PyB0cnVlLFxuICAgIH07XG5cbiAgICBjb25zdCBjdXJyZW50Q29tcG9uZW50cyA9IFsuLi50aGlzLmRlZmluaXRpb24oKS5jb21wb25lbnRzXS5zb3J0KFxuICAgICAgKGEsIGIpID0+IChhLm9yZGVyID8/IDApIC0gKGIub3JkZXIgPz8gMClcbiAgICApO1xuICAgIGlmICh0YXJnZXRJbmRleCAhPT0gdW5kZWZpbmVkICYmIHRhcmdldEluZGV4ID49IDAgJiYgdGFyZ2V0SW5kZXggPD0gY3VycmVudENvbXBvbmVudHMubGVuZ3RoKSB7XG4gICAgICBjdXJyZW50Q29tcG9uZW50cy5zcGxpY2UodGFyZ2V0SW5kZXgsIDAsIG5ld0NvbXBvbmVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJlbnRDb21wb25lbnRzLnB1c2gobmV3Q29tcG9uZW50KTtcbiAgICB9XG5cbiAgICAvLyBSZWNhbGN1bGF0ZSBvcmRlciBpbmRpY2VzXG4gICAgY3VycmVudENvbXBvbmVudHMuZm9yRWFjaCgoYywgaWR4KSA9PiAoYy5vcmRlciA9IGlkeCArIDEpKTtcblxuICAgIHRoaXMubXV0YXRlRGVmaW5pdGlvbigoZGVmKSA9PiAoe1xuICAgICAgLi4uZGVmLFxuICAgICAgY29tcG9uZW50czogY3VycmVudENvbXBvbmVudHMsXG4gICAgfSkpO1xuXG4gICAgdGhpcy5zZWxlY3RDb21wb25lbnQobmV3Q29tcG9uZW50LmlkKTtcbiAgICByZXR1cm4gbmV3Q29tcG9uZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSBjb21wb25lbnQgYnkgaXRzIElELlxuICAgKi9cbiAgcmVtb3ZlQ29tcG9uZW50KGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50Q29tcG9uZW50cyA9IHRoaXMuZGVmaW5pdGlvbigpLmNvbXBvbmVudHMuZmlsdGVyKChjKSA9PiBjLmlkICE9PSBpZCk7XG4gICAgY3VycmVudENvbXBvbmVudHMuZm9yRWFjaCgoYywgaWR4KSA9PiAoYy5vcmRlciA9IGlkeCArIDEpKTtcblxuICAgIGlmICh0aGlzLnNlbGVjdGVkQ29tcG9uZW50SWQoKSA9PT0gaWQpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDb21wb25lbnRJZC5zZXQobnVsbCk7XG4gICAgfVxuXG4gICAgdGhpcy5tdXRhdGVEZWZpbml0aW9uKChkZWYpID0+ICh7XG4gICAgICAuLi5kZWYsXG4gICAgICBjb21wb25lbnRzOiBjdXJyZW50Q29tcG9uZW50cyxcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogRHVwbGljYXRlcyBhbiBleGlzdGluZyBjb21wb25lbnQuXG4gICAqL1xuICBkdXBsaWNhdGVDb21wb25lbnQoaWQ6IHN0cmluZyk6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24gfCBudWxsIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuZGVmaW5pdGlvbigpLmNvbXBvbmVudHMuZmluZCgoYykgPT4gYy5pZCA9PT0gaWQpO1xuICAgIGlmICghZXhpc3RpbmcpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgZHVwbGljYXRlZDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbiA9IHtcbiAgICAgIC4uLkpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZXhpc3RpbmcpKSxcbiAgICAgIGlkOiBnZW5lcmF0ZUlkKGV4aXN0aW5nLnR5cGUpLFxuICAgICAga2V5OiBleGlzdGluZy5rZXkgPyBgJHtleGlzdGluZy5rZXl9X2NvcHlgIDogdW5kZWZpbmVkLFxuICAgICAgbGFiZWw6IGV4aXN0aW5nLmxhYmVsID8gYCR7ZXhpc3RpbmcubGFiZWx9IChDb3B5KWAgOiB1bmRlZmluZWQsXG4gICAgfTtcblxuICAgIGNvbnN0IGN1cnJlbnRDb21wb25lbnRzID0gWy4uLnRoaXMuZGVmaW5pdGlvbigpLmNvbXBvbmVudHNdLnNvcnQoXG4gICAgICAoYSwgYikgPT4gKGEub3JkZXIgPz8gMCkgLSAoYi5vcmRlciA/PyAwKVxuICAgICk7XG4gICAgY29uc3QgaW5kZXggPSBjdXJyZW50Q29tcG9uZW50cy5maW5kSW5kZXgoKGMpID0+IGMuaWQgPT09IGlkKTtcbiAgICBjdXJyZW50Q29tcG9uZW50cy5zcGxpY2UoaW5kZXggKyAxLCAwLCBkdXBsaWNhdGVkKTtcbiAgICBjdXJyZW50Q29tcG9uZW50cy5mb3JFYWNoKChjLCBpZHgpID0+IChjLm9yZGVyID0gaWR4ICsgMSkpO1xuXG4gICAgdGhpcy5tdXRhdGVEZWZpbml0aW9uKChkZWYpID0+ICh7XG4gICAgICAuLi5kZWYsXG4gICAgICBjb21wb25lbnRzOiBjdXJyZW50Q29tcG9uZW50cyxcbiAgICB9KSk7XG5cbiAgICB0aGlzLnNlbGVjdENvbXBvbmVudChkdXBsaWNhdGVkLmlkKTtcbiAgICByZXR1cm4gZHVwbGljYXRlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlcyBhIGNvbXBvbmVudCBmcm9tIHByZXZpb3VzIGluZGV4IHRvIGN1cnJlbnQgaW5kZXggKGUuZy4gZnJvbSBDREsgZHJhZyBkcm9wKS5cbiAgICovXG4gIG1vdmVDb21wb25lbnQocHJldmlvdXNJbmRleDogbnVtYmVyLCBjdXJyZW50SW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChwcmV2aW91c0luZGV4ID09PSBjdXJyZW50SW5kZXgpIHJldHVybjtcblxuICAgIGNvbnN0IGN1cnJlbnRDb21wb25lbnRzID0gWy4uLnRoaXMuZGVmaW5pdGlvbigpLmNvbXBvbmVudHNdLnNvcnQoXG4gICAgICAoYSwgYikgPT4gKGEub3JkZXIgPz8gMCkgLSAoYi5vcmRlciA/PyAwKVxuICAgICk7XG4gICAgaWYgKHByZXZpb3VzSW5kZXggPCAwIHx8IHByZXZpb3VzSW5kZXggPj0gY3VycmVudENvbXBvbmVudHMubGVuZ3RoKSByZXR1cm47XG4gICAgY29uc3QgdGFyZ2V0SWR4ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oY3VycmVudEluZGV4LCBjdXJyZW50Q29tcG9uZW50cy5sZW5ndGggLSAxKSk7XG5cbiAgICBjb25zdCBbbW92ZWRdID0gY3VycmVudENvbXBvbmVudHMuc3BsaWNlKHByZXZpb3VzSW5kZXgsIDEpO1xuICAgIGN1cnJlbnRDb21wb25lbnRzLnNwbGljZSh0YXJnZXRJZHgsIDAsIG1vdmVkKTtcbiAgICBjdXJyZW50Q29tcG9uZW50cy5mb3JFYWNoKChjLCBpZHgpID0+IChjLm9yZGVyID0gaWR4ICsgMSkpO1xuXG4gICAgdGhpcy5tdXRhdGVEZWZpbml0aW9uKChkZWYpID0+ICh7XG4gICAgICAuLi5kZWYsXG4gICAgICBjb21wb25lbnRzOiBjdXJyZW50Q29tcG9uZW50cyxcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyBwYXJ0aWFsIHByb3BlcnRpZXMgb2YgYSBjb21wb25lbnQuXG4gICAqL1xuICB1cGRhdGVDb21wb25lbnQoaWQ6IHN0cmluZywgdXBkYXRlczogUGFydGlhbDxSZXBvcnRDb21wb25lbnREZWZpbml0aW9uPik6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRDb21wb25lbnRzID0gdGhpcy5kZWZpbml0aW9uKCkuY29tcG9uZW50cy5tYXAoKGMpID0+IHtcbiAgICAgIGlmIChjLmlkID09PSBpZCkge1xuICAgICAgICByZXR1cm4geyAuLi5jLCAuLi51cGRhdGVzIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gYztcbiAgICB9KTtcblxuICAgIHRoaXMubXV0YXRlRGVmaW5pdGlvbigoZGVmKSA9PiAoe1xuICAgICAgLi4uZGVmLFxuICAgICAgY29tcG9uZW50czogY3VycmVudENvbXBvbmVudHMsXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgYSBzaW5nbGUgY29tcG9uZW50IHByb3BlcnR5IHZhbHVlIHdpdGhpbiBgcHJvcGVydGllc2AuXG4gICAqL1xuICB1cGRhdGVDb21wb25lbnRQcm9wZXJ0eShpZDogc3RyaW5nLCBwcm9wS2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudENvbXBvbmVudHMgPSB0aGlzLmRlZmluaXRpb24oKS5jb21wb25lbnRzLm1hcCgoYykgPT4ge1xuICAgICAgaWYgKGMuaWQgPT09IGlkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uYyxcbiAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAuLi4oYy5wcm9wZXJ0aWVzID8/IHt9KSxcbiAgICAgICAgICAgIFtwcm9wS2V5XTogdmFsdWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjO1xuICAgIH0pO1xuXG4gICAgdGhpcy5tdXRhdGVEZWZpbml0aW9uKChkZWYpID0+ICh7XG4gICAgICAuLi5kZWYsXG4gICAgICBjb21wb25lbnRzOiBjdXJyZW50Q29tcG9uZW50cyxcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyBsYXlvdXQgcHJvcGVydGllcyBmb3IgYSBjb21wb25lbnQgKGUuZy4gY29sdW1uU3BhbikuXG4gICAqL1xuICB1cGRhdGVDb21wb25lbnRMYXlvdXQoaWQ6IHN0cmluZywgbGF5b3V0OiBQYXJ0aWFsPENvbXBvbmVudExheW91dERlZmluaXRpb24+KTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudENvbXBvbmVudHMgPSB0aGlzLmRlZmluaXRpb24oKS5jb21wb25lbnRzLm1hcCgoYykgPT4ge1xuICAgICAgaWYgKGMuaWQgPT09IGlkKSB7XG4gICAgICAgIGNvbnN0IG5leHRMYXlvdXQgPSB7XG4gICAgICAgICAgLi4uKGMubGF5b3V0ID8/IHt9KSxcbiAgICAgICAgICAuLi5sYXlvdXQsXG4gICAgICAgIH07XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGxheW91dCkgYXMgKGtleW9mIENvbXBvbmVudExheW91dERlZmluaXRpb24pW10pIHtcbiAgICAgICAgICBpZiAobGF5b3V0W2tleV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZGVsZXRlIG5leHRMYXlvdXRba2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5jLFxuICAgICAgICAgIGxheW91dDogbmV4dExheW91dCxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjO1xuICAgIH0pO1xuXG4gICAgdGhpcy5tdXRhdGVEZWZpbml0aW9uKChkZWYpID0+ICh7XG4gICAgICAuLi5kZWYsXG4gICAgICBjb21wb25lbnRzOiBjdXJyZW50Q29tcG9uZW50cyxcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyByZXBvcnQtbGV2ZWwgc2V0dGluZ3MgKG5hbWUsIGRlc2NyaXB0aW9uLCBsYXlvdXQpLlxuICAgKi9cbiAgdXBkYXRlUmVwb3J0U2V0dGluZ3Moc2V0dGluZ3M6IFBhcnRpYWw8UmVwb3J0RGVmaW5pdGlvbj4pOiB2b2lkIHtcbiAgICB0aGlzLm11dGF0ZURlZmluaXRpb24oKGRlZikgPT4gKHtcbiAgICAgIC4uLmRlZixcbiAgICAgIC4uLnNldHRpbmdzLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIGdyaWQgZGVmaW5pdGlvbiBzZXR0aW5ncy5cbiAgICovXG4gIHVwZGF0ZUdyaWRTZXR0aW5ncyhncmlkOiBSZXBvcnRHcmlkRGVmaW5pdGlvbiB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgIHRoaXMubXV0YXRlRGVmaW5pdGlvbigoZGVmKSA9PiAoe1xuICAgICAgLi4uZGVmLFxuICAgICAgZ3JpZCxcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogUmV2ZXJ0cyB0byB0aGUgcHJldmlvdXMgc3RhdGUgaW4gaGlzdG9yeS5cbiAgICovXG4gIHVuZG8oKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmNhblVuZG8oKSkgcmV0dXJuO1xuICAgIGNvbnN0IG5ld0luZGV4ID0gdGhpcy5oaXN0b3J5SW5kZXgoKSAtIDE7XG4gICAgdGhpcy5oaXN0b3J5SW5kZXguc2V0KG5ld0luZGV4KTtcbiAgICBjb25zdCByZXN0b3JlZCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5oaXN0b3J5KClbbmV3SW5kZXhdKSkgYXMgUmVwb3J0RGVmaW5pdGlvbjtcbiAgICB0aGlzLmRlZmluaXRpb24uc2V0KHJlc3RvcmVkKTtcbiAgICB0aGlzLmlzRGlydHkuc2V0KHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkdmFuY2VzIHRvIHRoZSBuZXh0IHN0YXRlIGluIGhpc3RvcnkuXG4gICAqL1xuICByZWRvKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jYW5SZWRvKCkpIHJldHVybjtcbiAgICBjb25zdCBuZXdJbmRleCA9IHRoaXMuaGlzdG9yeUluZGV4KCkgKyAxO1xuICAgIHRoaXMuaGlzdG9yeUluZGV4LnNldChuZXdJbmRleCk7XG4gICAgY29uc3QgcmVzdG9yZWQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuaGlzdG9yeSgpW25ld0luZGV4XSkpIGFzIFJlcG9ydERlZmluaXRpb247XG4gICAgdGhpcy5kZWZpbml0aW9uLnNldChyZXN0b3JlZCk7XG4gICAgdGhpcy5pc0RpcnR5LnNldCh0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXJrcyB0aGUgY3VycmVudCBkZWZpbml0aW9uIHN0YXRlIGFzIHNhdmVkLlxuICAgKi9cbiAgbWFya1NhdmVkKCk6IHZvaWQge1xuICAgIHRoaXMuaXNEaXJ0eS5zZXQoZmFsc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgYW4gaW1tdXRhYmxlIHN0YXRlIGNoYW5nZSBhbmQgcHVzaGVzIHRvIGhpc3RvcnkuXG4gICAqL1xuICBwcml2YXRlIG11dGF0ZURlZmluaXRpb24odXBkYXRlcjogKGN1cnJlbnQ6IFJlcG9ydERlZmluaXRpb24pID0+IFJlcG9ydERlZmluaXRpb24pOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0ID0gdXBkYXRlcih0aGlzLmRlZmluaXRpb24oKSk7XG4gICAgdGhpcy5kZWZpbml0aW9uLnNldChuZXh0KTtcbiAgICB0aGlzLmlzRGlydHkuc2V0KHRydWUpO1xuICAgIHRoaXMucHVzaEhpc3RvcnkobmV4dCk7XG4gIH1cblxuICBwcml2YXRlIHB1c2hIaXN0b3J5KGRlZjogUmVwb3J0RGVmaW5pdGlvbik6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRIaXN0ID0gdGhpcy5oaXN0b3J5KCkuc2xpY2UoMCwgdGhpcy5oaXN0b3J5SW5kZXgoKSArIDEpO1xuICAgIGN1cnJlbnRIaXN0LnB1c2goSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkZWYpKSk7XG4gICAgaWYgKGN1cnJlbnRIaXN0Lmxlbmd0aCA+IE1BWF9ISVNUT1JZKSB7XG4gICAgICBjdXJyZW50SGlzdC5zaGlmdCgpO1xuICAgIH1cbiAgICB0aGlzLmhpc3Rvcnkuc2V0KGN1cnJlbnRIaXN0KTtcbiAgICB0aGlzLmhpc3RvcnlJbmRleC5zZXQoY3VycmVudEhpc3QubGVuZ3RoIC0gMSk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { DesignerStateService } from './designer-state.service';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9kZXNpZ25lci9zZXJ2aWNlcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IERlc2lnbmVyU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi9kZXNpZ25lci1zdGF0ZS5zZXJ2aWNlJztcbmV4cG9ydCB0eXBlIHtcbiAgRGVzaWduZXJWaWV3TW9kZSxcbiAgRGVzaWduZXJBY3RpdmVUYWIsXG59IGZyb20gJy4vZGVzaWduZXItc3RhdGUuc2VydmljZSc7XG4iXX0=
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure utility functions for design canvas layout, grid calculations, and sizing.
|
|
3
|
+
*
|
|
4
|
+
* Implemented as framework-independent pure functions per Rule 10 & 11 (Pure Logic First).
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Resolves the effective column span for a component.
|
|
8
|
+
* Uses layout.columnSpan if specified, otherwise defaults based on component type (e.g. 2 for button, 4 for others).
|
|
9
|
+
*/
|
|
10
|
+
export function resolveComponentSpan(comp, totalColumns = 12, overrideSpan) {
|
|
11
|
+
if (overrideSpan !== undefined && overrideSpan !== null) {
|
|
12
|
+
return Math.max(1, Math.min(totalColumns, overrideSpan));
|
|
13
|
+
}
|
|
14
|
+
const defaultSpan = comp.type === 'button' ? 2 : 4;
|
|
15
|
+
const rawSpan = comp.layout?.columnSpan ?? defaultSpan;
|
|
16
|
+
return Math.max(1, Math.min(totalColumns, rawSpan));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Computes the CSS `grid-column` specification string for a component.
|
|
20
|
+
*/
|
|
21
|
+
export function calculateGridColumn(comp, totalColumns = 12, span) {
|
|
22
|
+
const effectiveSpan = span ?? resolveComponentSpan(comp, totalColumns);
|
|
23
|
+
const clamped = Math.max(1, Math.min(effectiveSpan, totalColumns));
|
|
24
|
+
const col = comp.layout?.column;
|
|
25
|
+
if (col && col >= 1 && col <= totalColumns) {
|
|
26
|
+
return `${col} / span ${clamped}`;
|
|
27
|
+
}
|
|
28
|
+
return comp.layout?.newRow ? `1 / span ${clamped}` : `span ${clamped}`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Computes the CSS `grid-row` specification string for a component.
|
|
32
|
+
*/
|
|
33
|
+
export function calculateGridRow(comp) {
|
|
34
|
+
const rowSpan = comp.layout?.rowSpan;
|
|
35
|
+
if (rowSpan && rowSpan > 1) {
|
|
36
|
+
return `span ${rowSpan}`;
|
|
37
|
+
}
|
|
38
|
+
return 'auto';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Overhead in pixels for the Visual Canvas card (card header 32px + card body vertical padding 16px).
|
|
42
|
+
* Adding this overhead to the component's logical height ensures that the canvas card body
|
|
43
|
+
* renders at the exact same pixel dimensions as the live preview component.
|
|
44
|
+
*/
|
|
45
|
+
export const CANVAS_CARD_OVERHEAD = 48;
|
|
46
|
+
/**
|
|
47
|
+
* Resolves the CSS height property for the canvas component card.
|
|
48
|
+
* Accounts for the card header and padding overhead so the inner mock body
|
|
49
|
+
* accurately mirrors the runtime component height.
|
|
50
|
+
*/
|
|
51
|
+
export function resolveCanvasCardHeight(comp, overrideComponentHeight, overhead = CANVAS_CARD_OVERHEAD) {
|
|
52
|
+
if (overrideComponentHeight !== undefined && overrideComponentHeight !== null) {
|
|
53
|
+
return `${overrideComponentHeight + overhead}px`;
|
|
54
|
+
}
|
|
55
|
+
const h = comp.layout?.height;
|
|
56
|
+
if (!h || h === 'auto')
|
|
57
|
+
return 'auto';
|
|
58
|
+
const parsed = parseInt(h, 10);
|
|
59
|
+
return isNaN(parsed) ? h : `${parsed + overhead}px`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Resolves the CSS min-height property for the canvas component card.
|
|
63
|
+
*/
|
|
64
|
+
export function resolveCanvasCardMinHeight(comp, overrideComponentHeight, overhead = CANVAS_CARD_OVERHEAD) {
|
|
65
|
+
if (overrideComponentHeight !== undefined && overrideComponentHeight !== null) {
|
|
66
|
+
return `${overrideComponentHeight + overhead}px`;
|
|
67
|
+
}
|
|
68
|
+
const minH = comp.layout?.minHeight;
|
|
69
|
+
if (!minH || minH === 'auto')
|
|
70
|
+
return 'auto';
|
|
71
|
+
const parsed = parseInt(minH, 10);
|
|
72
|
+
return isNaN(parsed) ? minH : `${parsed + overhead}px`;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Resolves the CSS height property for a runtime component.
|
|
76
|
+
*/
|
|
77
|
+
export function resolveComponentHeight(comp, overrideHeight) {
|
|
78
|
+
if (overrideHeight !== undefined && overrideHeight !== null) {
|
|
79
|
+
return `${overrideHeight}px`;
|
|
80
|
+
}
|
|
81
|
+
return comp.layout?.height || 'auto';
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Resolves the CSS min-height property for a runtime component.
|
|
85
|
+
*/
|
|
86
|
+
export function resolveComponentMinHeight(comp, overrideHeight) {
|
|
87
|
+
if (overrideHeight !== undefined && overrideHeight !== null) {
|
|
88
|
+
return `${overrideHeight}px`;
|
|
89
|
+
}
|
|
90
|
+
return comp.layout?.minHeight || 'auto';
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Calculates new snapped span given drag deltaX, column width, and grid gap.
|
|
94
|
+
*/
|
|
95
|
+
export function calculateSnappedSpan(deltaX, startSpan, colWidth, gap, totalCols) {
|
|
96
|
+
const step = colWidth + gap;
|
|
97
|
+
if (step <= 0)
|
|
98
|
+
return startSpan;
|
|
99
|
+
const spanDelta = Math.round(deltaX / step);
|
|
100
|
+
return Math.max(1, Math.min(totalCols, startSpan + spanDelta));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Calculates new height given drag deltaY and minimum height constraint.
|
|
104
|
+
*/
|
|
105
|
+
export function calculateSnappedHeight(deltaY, startHeight, minHeight = 50) {
|
|
106
|
+
return Math.max(minHeight, Math.round(startHeight + deltaY));
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Maps component type to standard icon identifier.
|
|
110
|
+
*/
|
|
111
|
+
export function getComponentIconName(type) {
|
|
112
|
+
switch (type) {
|
|
113
|
+
case 'input': return 'text-fields';
|
|
114
|
+
case 'dropdown': return 'dropdown';
|
|
115
|
+
case 'date': return 'calendar';
|
|
116
|
+
case 'number': return 'number';
|
|
117
|
+
case 'checkbox': return 'checkbox';
|
|
118
|
+
case 'button': return 'button';
|
|
119
|
+
case 'kpi-card': return 'kpi';
|
|
120
|
+
case 'chart': return 'chart-bar';
|
|
121
|
+
default: return 'box';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FudmFzLWxheW91dC51dGlsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvZmVhdHVyZXMvZGVzaWduZXIvdXRpbGl0aWVzL2NhbnZhcy1sYXlvdXQudXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7OztHQUlHO0FBRUg7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxJQUErQixFQUMvQixlQUF1QixFQUFFLEVBQ3pCLFlBQTRCO0lBRTVCLElBQUksWUFBWSxLQUFLLFNBQVMsSUFBSSxZQUFZLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDeEQsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFDRCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxVQUFVLElBQUksV0FBVyxDQUFDO0lBQ3ZELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUN0RCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQ2pDLElBQStCLEVBQy9CLGVBQXVCLEVBQUUsRUFDekIsSUFBYTtJQUViLE1BQU0sYUFBYSxHQUFHLElBQUksSUFBSSxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDdkUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdB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TyxRQUFRLENBQUM7UUFDL0IsS0FBSyxVQUFVLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQztRQUNuQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLE9BQU8sUUFBUSxDQUFDO1FBQy9CLEtBQUssVUFBVSxDQUFDLENBQUMsT0FBTyxLQUFLLENBQUM7UUFDOUIsS0FBSyxPQUFPLENBQUMsQ0FBQyxPQUFPLFdBQVcsQ0FBQztRQUNqQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEtBQUssQ0FBQztJQUN4QixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtY29tcG9uZW50Lm1vZGVsJztcblxuLyoqXG4gKiBQdXJlIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBkZXNpZ24gY2FudmFzIGxheW91dCwgZ3JpZCBjYWxjdWxhdGlvbnMsIGFuZCBzaXppbmcuXG4gKlxuICogSW1wbGVtZW50ZWQgYXMgZnJhbWV3b3JrLWluZGVwZW5kZW50IHB1cmUgZnVuY3Rpb25zIHBlciBSdWxlIDEwICYgMTEgKFB1cmUgTG9naWMgRmlyc3QpLlxuICovXG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIGVmZmVjdGl2ZSBjb2x1bW4gc3BhbiBmb3IgYSBjb21wb25lbnQuXG4gKiBVc2VzIGxheW91dC5jb2x1bW5TcGFuIGlmIHNwZWNpZmllZCwgb3RoZXJ3aXNlIGRlZmF1bHRzIGJhc2VkIG9uIGNvbXBvbmVudCB0eXBlIChlLmcuIDIgZm9yIGJ1dHRvbiwgNCBmb3Igb3RoZXJzKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVDb21wb25lbnRTcGFuKFxuICBjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLFxuICB0b3RhbENvbHVtbnM6IG51bWJlciA9IDEyLFxuICBvdmVycmlkZVNwYW4/OiBudW1iZXIgfCBudWxsXG4pOiBudW1iZXIge1xuICBpZiAob3ZlcnJpZGVTcGFuICE9PSB1bmRlZmluZWQgJiYgb3ZlcnJpZGVTcGFuICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDEsIE1hdGgubWluKHRvdGFsQ29sdW1ucywgb3ZlcnJpZGVTcGFuKSk7XG4gIH1cbiAgY29uc3QgZGVmYXVsdFNwYW4gPSBjb21wLnR5cGUgPT09ICdidXR0b24nID8gMiA6IDQ7XG4gIGNvbnN0IHJhd1NwYW4gPSBjb21wLmxheW91dD8uY29sdW1uU3BhbiA/PyBkZWZhdWx0U3BhbjtcbiAgcmV0dXJuIE1hdGgubWF4KDEsIE1hdGgubWluKHRvdGFsQ29sdW1ucywgcmF3U3BhbikpO1xufVxuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBDU1MgYGdyaWQtY29sdW1uYCBzcGVjaWZpY2F0aW9uIHN0cmluZyBmb3IgYSBjb21wb25lbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVHcmlkQ29sdW1uKFxuICBjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLFxuICB0b3RhbENvbHVtbnM6IG51bWJlciA9IDEyLFxuICBzcGFuPzogbnVtYmVyXG4pOiBzdHJpbmcge1xuICBjb25zdCBlZmZlY3RpdmVTcGFuID0gc3BhbiA/PyByZXNvbHZlQ29tcG9uZW50U3Bhbihjb21wLCB0b3RhbENvbHVtbnMpO1xuICBjb25zdCBjbGFtcGVkID0gTWF0aC5tYXgoMSwgTWF0aC5taW4oZWZmZWN0aXZlU3BhbiwgdG90YWxDb2x1bW5zKSk7XG4gIGNvbnN0IGNvbCA9IGNvbXAubGF5b3V0Py5jb2x1bW47XG5cbiAgaWYgKGNvbCAmJiBjb2wgPj0gMSAmJiBjb2wgPD0gdG90YWxDb2x1bW5zKSB7XG4gICAgcmV0dXJuIGAke2NvbH0gLyBzcGFuICR7Y2xhbXBlZH1gO1xuICB9XG5cbiAgcmV0dXJuIGNvbXAubGF5b3V0Py5uZXdSb3cgPyBgMSAvIHNwYW4gJHtjbGFtcGVkfWAgOiBgc3BhbiAke2NsYW1wZWR9YDtcbn1cblxuLyoqXG4gKiBDb21wdXRlcyB0aGUgQ1NTIGBncmlkLXJvd2Agc3BlY2lmaWNhdGlvbiBzdHJpbmcgZm9yIGEgY29tcG9uZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlR3JpZFJvdyhjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogc3RyaW5nIHtcbiAgY29uc3Qgcm93U3BhbiA9IGNvbXAubGF5b3V0Py5yb3dTcGFuO1xuICBpZiAocm93U3BhbiAmJiByb3dTcGFuID4gMSkge1xuICAgIHJldHVybiBgc3BhbiAke3Jvd1NwYW59YDtcbiAgfVxuICByZXR1cm4gJ2F1dG8nO1xufVxuXG4vKipcbiAqIE92ZXJoZWFkIGluIHBpeGVscyBmb3IgdGhlIFZpc3VhbCBDYW52YXMgY2FyZCAoY2FyZCBoZWFkZXIgMzJweCArIGNhcmQgYm9keSB2ZXJ0aWNhbCBwYWRkaW5nIDE2cHgpLlxuICogQWRkaW5nIHRoaXMgb3ZlcmhlYWQgdG8gdGhlIGNvbXBvbmVudCdzIGxvZ2ljYWwgaGVpZ2h0IGVuc3VyZXMgdGhhdCB0aGUgY2FudmFzIGNhcmQgYm9keVxuICogcmVuZGVycyBhdCB0aGUgZXhhY3Qgc2FtZSBwaXhlbCBkaW1lbnNpb25zIGFzIHRoZSBsaXZlIHByZXZpZXcgY29tcG9uZW50LlxuICovXG5leHBvcnQgY29uc3QgQ0FOVkFTX0NBUkRfT1ZFUkhFQUQgPSA0ODtcblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgQ1NTIGhlaWdodCBwcm9wZXJ0eSBmb3IgdGhlIGNhbnZhcyBjb21wb25lbnQgY2FyZC5cbiAqIEFjY291bnRzIGZvciB0aGUgY2FyZCBoZWFkZXIgYW5kIHBhZGRpbmcgb3ZlcmhlYWQgc28gdGhlIGlubmVyIG1vY2sgYm9keVxuICogYWNjdXJhdGVseSBtaXJyb3JzIHRoZSBydW50aW1lIGNvbXBvbmVudCBoZWlnaHQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQ2FudmFzQ2FyZEhlaWdodChcbiAgY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbixcbiAgb3ZlcnJpZGVDb21wb25lbnRIZWlnaHQ/OiBudW1iZXIgfCBudWxsLFxuICBvdmVyaGVhZDogbnVtYmVyID0gQ0FOVkFTX0NBUkRfT1ZFUkhFQURcbik6IHN0cmluZyB7XG4gIGlmIChvdmVycmlkZUNvbXBvbmVudEhlaWdodCAhPT0gdW5kZWZpbmVkICYmIG92ZXJyaWRlQ29tcG9uZW50SGVpZ2h0ICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIGAke292ZXJyaWRlQ29tcG9uZW50SGVpZ2h0ICsgb3ZlcmhlYWR9cHhgO1xuICB9XG4gIGNvbnN0IGggPSBjb21wLmxheW91dD8uaGVpZ2h0O1xuICBpZiAoIWggfHwgaCA9PT0gJ2F1dG8nKSByZXR1cm4gJ2F1dG8nO1xuICBjb25zdCBwYXJzZWQgPSBwYXJzZUludChoLCAxMCk7XG4gIHJldHVybiBpc05hTihwYXJzZWQpID8gaCA6IGAke3BhcnNlZCArIG92ZXJoZWFkfXB4YDtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgQ1NTIG1pbi1oZWlnaHQgcHJvcGVydHkgZm9yIHRoZSBjYW52YXMgY29tcG9uZW50IGNhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQ2FudmFzQ2FyZE1pbkhlaWdodChcbiAgY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbixcbiAgb3ZlcnJpZGVDb21wb25lbnRIZWlnaHQ/OiBudW1iZXIgfCBudWxsLFxuICBvdmVyaGVhZDogbnVtYmVyID0gQ0FOVkFTX0NBUkRfT1ZFUkhFQURcbik6IHN0cmluZyB7XG4gIGlmIChvdmVycmlkZUNvbXBvbmVudEhlaWdodCAhPT0gdW5kZWZpbmVkICYmIG92ZXJyaWRlQ29tcG9uZW50SGVpZ2h0ICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIGAke292ZXJyaWRlQ29tcG9uZW50SGVpZ2h0ICsgb3ZlcmhlYWR9cHhgO1xuICB9XG4gIGNvbnN0IG1pbkggPSBjb21wLmxheW91dD8ubWluSGVpZ2h0O1xuICBpZiAoIW1pbkggfHwgbWluSCA9PT0gJ2F1dG8nKSByZXR1cm4gJ2F1dG8nO1xuICBjb25zdCBwYXJzZWQgPSBwYXJzZUludChtaW5ILCAxMCk7XG4gIHJldHVybiBpc05hTihwYXJzZWQpID8gbWluSCA6IGAke3BhcnNlZCArIG92ZXJoZWFkfXB4YDtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgQ1NTIGhlaWdodCBwcm9wZXJ0eSBmb3IgYSBydW50aW1lIGNvbXBvbmVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVDb21wb25lbnRIZWlnaHQoXG4gIGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24sXG4gIG92ZXJyaWRlSGVpZ2h0PzogbnVtYmVyIHwgbnVsbFxuKTogc3RyaW5nIHtcbiAgaWYgKG92ZXJyaWRlSGVpZ2h0ICE9PSB1bmRlZmluZWQgJiYgb3ZlcnJpZGVIZWlnaHQgIT09IG51bGwpIHtcbiAgICByZXR1cm4gYCR7b3ZlcnJpZGVIZWlnaHR9cHhgO1xuICB9XG4gIHJldHVybiBjb21wLmxheW91dD8uaGVpZ2h0IHx8ICdhdXRvJztcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgQ1NTIG1pbi1oZWlnaHQgcHJvcGVydHkgZm9yIGEgcnVudGltZSBjb21wb25lbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQ29tcG9uZW50TWluSGVpZ2h0KFxuICBjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLFxuICBvdmVycmlkZUhlaWdodD86IG51bWJlciB8IG51bGxcbik6IHN0cmluZyB7XG4gIGlmIChvdmVycmlkZUhlaWdodCAhPT0gdW5kZWZpbmVkICYmIG92ZXJyaWRlSGVpZ2h0ICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIGAke292ZXJyaWRlSGVpZ2h0fXB4YDtcbiAgfVxuICByZXR1cm4gY29tcC5sYXlvdXQ/Lm1pbkhlaWdodCB8fCAnYXV0byc7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyBuZXcgc25hcHBlZCBzcGFuIGdpdmVuIGRyYWcgZGVsdGFYLCBjb2x1bW4gd2lkdGgsIGFuZCBncmlkIGdhcC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVNuYXBwZWRTcGFuKFxuICBkZWx0YVg6IG51bWJlcixcbiAgc3RhcnRTcGFuOiBudW1iZXIsXG4gIGNvbFdpZHRoOiBudW1iZXIsXG4gIGdhcDogbnVtYmVyLFxuICB0b3RhbENvbHM6IG51bWJlclxuKTogbnVtYmVyIHtcbiAgY29uc3Qgc3RlcCA9IGNvbFdpZHRoICsgZ2FwO1xuICBpZiAoc3RlcCA8PSAwKSByZXR1cm4gc3RhcnRTcGFuO1xuICBjb25zdCBzcGFuRGVsdGEgPSBNYXRoLnJvdW5kKGRlbHRhWCAvIHN0ZXApO1xuICByZXR1cm4gTWF0aC5tYXgoMSwgTWF0aC5taW4odG90YWxDb2xzLCBzdGFydFNwYW4gKyBzcGFuRGVsdGEpKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGVzIG5ldyBoZWlnaHQgZ2l2ZW4gZHJhZyBkZWx0YVkgYW5kIG1pbmltdW0gaGVpZ2h0IGNvbnN0cmFpbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVTbmFwcGVkSGVpZ2h0KFxuICBkZWx0YVk6IG51bWJlcixcbiAgc3RhcnRIZWlnaHQ6IG51bWJlcixcbiAgbWluSGVpZ2h0OiBudW1iZXIgPSA1MFxuKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGgubWF4KG1pbkhlaWdodCwgTWF0aC5yb3VuZChzdGFydEhlaWdodCArIGRlbHRhWSkpO1xufVxuXG4vKipcbiAqIE1hcHMgY29tcG9uZW50IHR5cGUgdG8gc3RhbmRhcmQgaWNvbiBpZGVudGlmaWVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29tcG9uZW50SWNvbk5hbWUodHlwZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnaW5wdXQnOiByZXR1cm4gJ3RleHQtZmllbGRzJztcbiAgICBjYXNlICdkcm9wZG93bic6IHJldHVybiAnZHJvcGRvd24nO1xuICAgIGNhc2UgJ2RhdGUnOiByZXR1cm4gJ2NhbGVuZGFyJztcbiAgICBjYXNlICdudW1iZXInOiByZXR1cm4gJ251bWJlcic7XG4gICAgY2FzZSAnY2hlY2tib3gnOiByZXR1cm4gJ2NoZWNrYm94JztcbiAgICBjYXNlICdidXR0b24nOiByZXR1cm4gJ2J1dHRvbic7XG4gICAgY2FzZSAna3BpLWNhcmQnOiByZXR1cm4gJ2twaSc7XG4gICAgY2FzZSAnY2hhcnQnOiByZXR1cm4gJ2NoYXJ0LWJhcic7XG4gICAgZGVmYXVsdDogcmV0dXJuICdib3gnO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { ReportExportService, sanitizeCsvCell, generateCsvContent } from './services/report-export.service';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9leHBvcnQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixlQUFlLEVBQ2Ysa0JBQWtCLEVBQ25CLE1BQU0sa0NBQWtDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdHlwZSB7IEV4cG9ydENvbHVtbiwgQ3N2RXhwb3J0T3B0aW9ucywgSnNvbkV4cG9ydE9wdGlvbnMgfSBmcm9tICcuL21vZGVscy9leHBvcnQubW9kZWxzJztcbmV4cG9ydCB7XG4gIFJlcG9ydEV4cG9ydFNlcnZpY2UsXG4gIHNhbml0aXplQ3N2Q2VsbCxcbiAgZ2VuZXJhdGVDc3ZDb250ZW50XG59IGZyb20gJy4vc2VydmljZXMvcmVwb3J0LWV4cG9ydC5zZXJ2aWNlJztcbiJdfQ==
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0Lm1vZGVscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2J3YXlzLXJlcG9ydC9zcmMvbGliL2ZlYXR1cmVzL2V4cG9ydC9tb2RlbHMvZXhwb3J0Lm1vZGVscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGludGVyZmFjZSBFeHBvcnRDb2x1bW4ge1xuICBmaWVsZDogc3RyaW5nO1xuICBoZWFkZXI6IHN0cmluZztcbiAgZm9ybWF0dGVyPzogKHZhbHVlOiBhbnksIHJvdz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3N2RXhwb3J0T3B0aW9ucyB7XG4gIGZpbGVOYW1lPzogc3RyaW5nO1xuICBjb2x1bW5zPzogRXhwb3J0Q29sdW1uW107XG4gIGluY2x1ZGVIZWFkZXI/OiBib29sZWFuO1xuICBkZWxpbWl0ZXI/OiBzdHJpbmc7XG4gIGFkZEJvbT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSnNvbkV4cG9ydE9wdGlvbnMge1xuICBmaWxlTmFtZT86IHN0cmluZztcbiAgcHJldHR5PzogYm9vbGVhbjtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Injectable, inject } from '@angular/core';
|
|
2
|
+
import { DOCUMENT } from '@angular/common';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Sanitizes and escapes a single cell value for CSV output.
|
|
6
|
+
*/
|
|
7
|
+
export function sanitizeCsvCell(value, delimiter = ',') {
|
|
8
|
+
if (value === null || value === undefined) {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
let str = String(value);
|
|
12
|
+
// If value contains delimiter, quote, or newline, escape and wrap in quotes
|
|
13
|
+
const mustQuote = str.includes(delimiter) ||
|
|
14
|
+
str.includes('"') ||
|
|
15
|
+
str.includes('\n') ||
|
|
16
|
+
str.includes('\r');
|
|
17
|
+
if (mustQuote) {
|
|
18
|
+
str = '"' + str.replace(/"/g, '""') + '"';
|
|
19
|
+
}
|
|
20
|
+
return str;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Pure generator function to create CSV content string from row data and columns.
|
|
24
|
+
*/
|
|
25
|
+
export function generateCsvContent(rows, columns, delimiter = ',', includeHeader = true, addBom = true) {
|
|
26
|
+
const lines = [];
|
|
27
|
+
if (includeHeader) {
|
|
28
|
+
const headerLine = columns
|
|
29
|
+
.map((col) => sanitizeCsvCell(col.header, delimiter))
|
|
30
|
+
.join(delimiter);
|
|
31
|
+
lines.push(headerLine);
|
|
32
|
+
}
|
|
33
|
+
for (const row of rows) {
|
|
34
|
+
const rowValues = columns.map((col) => {
|
|
35
|
+
const val = row[col.field];
|
|
36
|
+
const formatted = col.formatter ? col.formatter(val, row) : val;
|
|
37
|
+
return sanitizeCsvCell(formatted, delimiter);
|
|
38
|
+
});
|
|
39
|
+
lines.push(rowValues.join(delimiter));
|
|
40
|
+
}
|
|
41
|
+
const csvBody = lines.join('\r\n');
|
|
42
|
+
return addBom ? '\uFEFF' + csvBody : csvBody;
|
|
43
|
+
}
|
|
44
|
+
export class ReportExportService {
|
|
45
|
+
document = inject(DOCUMENT);
|
|
46
|
+
/**
|
|
47
|
+
* Generates and triggers browser download of a CSV file.
|
|
48
|
+
*/
|
|
49
|
+
exportCsv(rows, options = {}) {
|
|
50
|
+
if (!rows || rows.length === 0) {
|
|
51
|
+
console.warn('[bways-report] No rows to export');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const delimiter = options.delimiter ?? ',';
|
|
55
|
+
const includeHeader = options.includeHeader !== false;
|
|
56
|
+
const addBom = options.addBom !== false;
|
|
57
|
+
const fileName = options.fileName || `report-export-${Date.now()}.csv`;
|
|
58
|
+
// If columns not provided, infer from first row keys
|
|
59
|
+
const columns = options.columns && options.columns.length > 0
|
|
60
|
+
? options.columns
|
|
61
|
+
: Object.keys(rows[0]).map((key) => ({
|
|
62
|
+
field: key,
|
|
63
|
+
header: key
|
|
64
|
+
}));
|
|
65
|
+
const csvContent = generateCsvContent(rows, columns, delimiter, includeHeader, addBom);
|
|
66
|
+
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
|
67
|
+
this.downloadBlob(blob, fileName);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Generates and triggers browser download of a JSON file.
|
|
71
|
+
*/
|
|
72
|
+
exportJson(data, options = {}) {
|
|
73
|
+
const fileName = options.fileName || `report-export-${Date.now()}.json`;
|
|
74
|
+
const pretty = options.pretty !== false;
|
|
75
|
+
const jsonString = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
76
|
+
const blob = new Blob([jsonString], { type: 'application/json;charset=utf-8;' });
|
|
77
|
+
this.downloadBlob(blob, fileName);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Safe file download trigger via temporary anchor tag.
|
|
81
|
+
*/
|
|
82
|
+
downloadBlob(blob, fileName) {
|
|
83
|
+
if (!this.document || !this.document.createElement) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const url = URL.createObjectURL(blob);
|
|
87
|
+
const link = this.document.createElement('a');
|
|
88
|
+
link.href = url;
|
|
89
|
+
link.download = fileName;
|
|
90
|
+
link.style.display = 'none';
|
|
91
|
+
this.document.body.appendChild(link);
|
|
92
|
+
link.click();
|
|
93
|
+
setTimeout(() => {
|
|
94
|
+
this.document.body.removeChild(link);
|
|
95
|
+
URL.revokeObjectURL(url);
|
|
96
|
+
}, 100);
|
|
97
|
+
}
|
|
98
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportExportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
99
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportExportService, providedIn: 'root' });
|
|
100
|
+
}
|
|
101
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportExportService, decorators: [{
|
|
102
|
+
type: Injectable,
|
|
103
|
+
args: [{
|
|
104
|
+
providedIn: 'root'
|
|
105
|
+
}]
|
|
106
|
+
}] });
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWV4cG9ydC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvZmVhdHVyZXMvZXhwb3J0L3NlcnZpY2VzL3JlcG9ydC1leHBvcnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7O0FBRzNDOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxLQUFjLEVBQUUsWUFBb0IsR0FBRztJQUNyRSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzFDLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUV4Qiw0RUFBNEU7SUFDNUUsTUFBTSxTQUFTLEdBQ2IsR0FBRyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7UUFDdkIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7UUFDakIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7UUFDbEIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVyQixJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ2QsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUM7SUFDNUMsQ0FBQztJQUVELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUNoQyxJQUErQixFQUMvQixPQUF1QixFQUN2QixZQUFvQixHQUFHLEVBQ3ZCLGdCQUF5QixJQUFJ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LENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUViLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDckMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMzQixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDVixDQUFDO3dHQWhFVSxtQkFBbUI7NEdBQW5CLG1CQUFtQixjQUZsQixNQUFNOzs0RkFFUCxtQkFBbUI7a0JBSC9CLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDc3ZFeHBvcnRPcHRpb25zLCBFeHBvcnRDb2x1bW4sIEpzb25FeHBvcnRPcHRpb25zIH0gZnJvbSAnLi4vbW9kZWxzL2V4cG9ydC5tb2RlbHMnO1xuXG4vKipcbiAqIFNhbml0aXplcyBhbmQgZXNjYXBlcyBhIHNpbmdsZSBjZWxsIHZhbHVlIGZvciBDU1Ygb3V0cHV0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2FuaXRpemVDc3ZDZWxsKHZhbHVlOiB1bmtub3duLCBkZWxpbWl0ZXI6IHN0cmluZyA9ICcsJyk6IHN0cmluZyB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgbGV0IHN0ciA9IFN0cmluZyh2YWx1ZSk7XG5cbiAgLy8gSWYgdmFsdWUgY29udGFpbnMgZGVsaW1pdGVyLCBxdW90ZSwgb3IgbmV3bGluZSwgZXNjYXBlIGFuZCB3cmFwIGluIHF1b3Rlc1xuICBjb25zdCBtdXN0UXVvdGUgPVxuICAgIHN0ci5pbmNsdWRlcyhkZWxpbWl0ZXIpIHx8XG4gICAgc3RyLmluY2x1ZGVzKCdcIicpIHx8XG4gICAgc3RyLmluY2x1ZGVzKCdcXG4nKSB8fFxuICAgIHN0ci5pbmNsdWRlcygnXFxyJyk7XG5cbiAgaWYgKG11c3RRdW90ZSkge1xuICAgIHN0ciA9ICdcIicgKyBzdHIucmVwbGFjZSgvXCIvZywgJ1wiXCInKSArICdcIic7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufVxuXG4vKipcbiAqIFB1cmUgZ2VuZXJhdG9yIGZ1bmN0aW9uIHRvIGNyZWF0ZSBDU1YgY29udGVudCBzdHJpbmcgZnJvbSByb3cgZGF0YSBhbmQgY29sdW1ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlQ3N2Q29udGVudChcbiAgcm93czogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSxcbiAgY29sdW1uczogRXhwb3J0Q29sdW1uW10sXG4gIGRlbGltaXRlcjogc3RyaW5nID0gJywnLFxuICBpbmNsdWRlSGVhZGVyOiBib29sZWFuID0gdHJ1ZSxcbiAgYWRkQm9tOiBib29sZWFuID0gdHJ1ZVxuKTogc3RyaW5nIHtcbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKGluY2x1ZGVIZWFkZXIpIHtcbiAgICBjb25zdCBoZWFkZXJMaW5lID0gY29sdW1uc1xuICAgICAgLm1hcCgoY29sKSA9PiBzYW5pdGl6ZUNzdkNlbGwoY29sLmhlYWRlciwgZGVsaW1pdGVyKSlcbiAgICAgIC5qb2luKGRlbGltaXRlcik7XG4gICAgbGluZXMucHVzaChoZWFkZXJMaW5lKTtcbiAgfVxuXG4gIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICBjb25zdCByb3dWYWx1ZXMgPSBjb2x1bW5zLm1hcCgoY29sKSA9PiB7XG4gICAgICBjb25zdCB2YWwgPSByb3dbY29sLmZpZWxkXTtcbiAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IGNvbC5mb3JtYXR0ZXIgPyBjb2wuZm9ybWF0dGVyKHZhbCwgcm93KSA6IHZhbDtcbiAgICAgIHJldHVybiBzYW5pdGl6ZUNzdkNlbGwoZm9ybWF0dGVkLCBkZWxpbWl0ZXIpO1xuICAgIH0pO1xuICAgIGxpbmVzLnB1c2gocm93VmFsdWVzLmpvaW4oZGVsaW1pdGVyKSk7XG4gIH1cblxuICBjb25zdCBjc3ZCb2R5ID0gbGluZXMuam9pbignXFxyXFxuJyk7XG4gIHJldHVybiBhZGRCb20gPyAnXFx1RkVGRicgKyBjc3ZCb2R5IDogY3N2Qm9keTtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgUmVwb3J0RXhwb3J0U2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZG9jdW1lbnQgPSBpbmplY3QoRE9DVU1FTlQpO1xuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIHRyaWdnZXJzIGJyb3dzZXIgZG93bmxvYWQgb2YgYSBDU1YgZmlsZS5cbiAgICovXG4gIGV4cG9ydENzdihyb3dzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLCBvcHRpb25zOiBDc3ZFeHBvcnRPcHRpb25zID0ge30pOiB2b2lkIHtcbiAgICBpZiAoIXJvd3MgfHwgcm93cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUud2FybignW2J3YXlzLXJlcG9ydF0gTm8gcm93cyB0byBleHBvcnQnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBkZWxpbWl0ZXIgPSBvcHRpb25zLmRlbGltaXRlciA/PyAnLCc7XG4gICAgY29uc3QgaW5jbHVkZUhlYWRlciA9IG9wdGlvbnMuaW5jbHVkZUhlYWRlciAhPT0gZmFsc2U7XG4gICAgY29uc3QgYWRkQm9tID0gb3B0aW9ucy5hZGRCb20gIT09IGZhbHNlO1xuICAgIGNvbnN0IGZpbGVOYW1lID0gb3B0aW9ucy5maWxlTmFtZSB8fCBgcmVwb3J0LWV4cG9ydC0ke0RhdGUubm93KCl9LmNzdmA7XG5cbiAgICAvLyBJZiBjb2x1bW5zIG5vdCBwcm92aWRlZCwgaW5mZXIgZnJvbSBmaXJzdCByb3cga2V5c1xuICAgIGNvbnN0IGNvbHVtbnM6IEV4cG9ydENvbHVtbltdID1cbiAgICAgIG9wdGlvbnMuY29sdW1ucyAmJiBvcHRpb25zLmNvbHVtbnMubGVuZ3RoID4gMFxuICAgICAgICA/IG9wdGlvbnMuY29sdW1uc1xuICAgICAgICA6IE9iamVjdC5rZXlzKHJvd3NbMF0pLm1hcCgoa2V5KSA9PiAoe1xuICAgICAgICAgICAgZmllbGQ6IGtleSxcbiAgICAgICAgICAgIGhlYWRlcjoga2V5XG4gICAgICAgICAgfSkpO1xuXG4gICAgY29uc3QgY3N2Q29udGVudCA9IGdlbmVyYXRlQ3N2Q29udGVudChyb3dzLCBjb2x1bW5zLCBkZWxpbWl0ZXIsIGluY2x1ZGVIZWFkZXIsIGFkZEJvbSk7XG4gICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtjc3ZDb250ZW50XSwgeyB0eXBlOiAndGV4dC9jc3Y7Y2hhcnNldD11dGYtODsnIH0pO1xuICAgIHRoaXMuZG93bmxvYWRCbG9iKGJsb2IsIGZpbGVOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIHRyaWdnZXJzIGJyb3dzZXIgZG93bmxvYWQgb2YgYSBKU09OIGZpbGUuXG4gICAqL1xuICBleHBvcnRKc29uKGRhdGE6IHVua25vd24sIG9wdGlvbnM6IEpzb25FeHBvcnRPcHRpb25zID0ge30pOiB2b2lkIHtcbiAgICBjb25zdCBmaWxlTmFtZSA9IG9wdGlvbnMuZmlsZU5hbWUgfHwgYHJlcG9ydC1leHBvcnQtJHtEYXRlLm5vdygpfS5qc29uYDtcbiAgICBjb25zdCBwcmV0dHkgPSBvcHRpb25zLnByZXR0eSAhPT0gZmFsc2U7XG4gICAgY29uc3QganNvblN0cmluZyA9IHByZXR0eSA/IEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpIDogSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG5cbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW2pzb25TdHJpbmddLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7JyB9KTtcbiAgICB0aGlzLmRvd25sb2FkQmxvYihibG9iLCBmaWxlTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogU2FmZSBmaWxlIGRvd25sb2FkIHRyaWdnZXIgdmlhIHRlbXBvcmFyeSBhbmNob3IgdGFnLlxuICAgKi9cbiAgcHJpdmF0ZSBkb3dubG9hZEJsb2IoYmxvYjogQmxvYiwgZmlsZU5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5kb2N1bWVudCB8fCAhdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICBjb25zdCBsaW5rID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgbGluay5ocmVmID0gdXJsO1xuICAgIGxpbmsuZG93bmxvYWQgPSBmaWxlTmFtZTtcbiAgICBsaW5rLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cbiAgICB0aGlzLmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgbGluay5jbGljaygpO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XG4gICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgfSwgMTAwKTtcbiAgfVxufVxuIl19
|