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.
Files changed (185) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +477 -0
  3. package/esm2022/bways-report.mjs +5 -0
  4. package/esm2022/lib/core/errors/index.mjs +2 -0
  5. package/esm2022/lib/core/errors/reporting-errors.mjs +65 -0
  6. package/esm2022/lib/core/index.mjs +8 -0
  7. package/esm2022/lib/core/models/component-event.model.mjs +8 -0
  8. package/esm2022/lib/core/models/index.mjs +5 -0
  9. package/esm2022/lib/core/models/report-component.model.mjs +10 -0
  10. package/esm2022/lib/core/models/report-datasource.model.mjs +9 -0
  11. package/esm2022/lib/core/models/report-definition.model.mjs +13 -0
  12. package/esm2022/lib/core/models/report-grid.model.mjs +10 -0
  13. package/esm2022/lib/core/models/report-layout.model.mjs +9 -0
  14. package/esm2022/lib/core/models/report-parameter.model.mjs +9 -0
  15. package/esm2022/lib/core/models/validation.model.mjs +8 -0
  16. package/esm2022/lib/core/registry/component-category.mjs +8 -0
  17. package/esm2022/lib/core/registry/component-registry.mjs +90 -0
  18. package/esm2022/lib/core/registry/index.mjs +2 -0
  19. package/esm2022/lib/core/registry/property-definition.model.mjs +10 -0
  20. package/esm2022/lib/core/services/dynamic-form-builder.service.mjs +55 -0
  21. package/esm2022/lib/core/services/index.mjs +3 -0
  22. package/esm2022/lib/core/services/report-session-context.service.mjs +314 -0
  23. package/esm2022/lib/core/tokens/index.mjs +3 -0
  24. package/esm2022/lib/core/tokens/reporting-config.token.mjs +26 -0
  25. package/esm2022/lib/core/tokens/session-context.token.mjs +18 -0
  26. package/esm2022/lib/core/utilities/id-generator.mjs +17 -0
  27. package/esm2022/lib/core/utilities/index.mjs +3 -0
  28. package/esm2022/lib/core/utilities/schema-migration.mjs +38 -0
  29. package/esm2022/lib/core/utils/identifier-humanizer.mjs +88 -0
  30. package/esm2022/lib/core/validation/index.mjs +2 -0
  31. package/esm2022/lib/core/validation/validation-factory.mjs +70 -0
  32. package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +107 -0
  33. package/esm2022/lib/data-access/adapters/http-schema-discovery.adapter.mjs +119 -0
  34. package/esm2022/lib/data-access/adapters/index.mjs +3 -0
  35. package/esm2022/lib/data-access/contracts/data-source.contract.mjs +28 -0
  36. package/esm2022/lib/data-access/contracts/index.mjs +7 -0
  37. package/esm2022/lib/data-access/contracts/lookup.contract.mjs +6 -0
  38. package/esm2022/lib/data-access/contracts/master-data.provider.mjs +24 -0
  39. package/esm2022/lib/data-access/contracts/report-persistence.contract.mjs +25 -0
  40. package/esm2022/lib/data-access/contracts/schema-discovery.contract.mjs +7 -0
  41. package/esm2022/lib/data-access/contracts/translation.contract.mjs +9 -0
  42. package/esm2022/lib/data-access/index.mjs +3 -0
  43. package/esm2022/lib/features/designer/components/component-palette/component-palette.component.mjs +542 -0
  44. package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +843 -0
  45. package/esm2022/lib/features/designer/components/property-editor/parameter-binding-editor.component.mjs +556 -0
  46. package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +845 -0
  47. package/esm2022/lib/features/designer/components/property-editor/property-editor-general.component.mjs +185 -0
  48. package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +452 -0
  49. package/esm2022/lib/features/designer/components/property-editor/property-editor-layout.component.mjs +350 -0
  50. package/esm2022/lib/features/designer/components/property-editor/property-editor-report.component.mjs +175 -0
  51. package/esm2022/lib/features/designer/components/property-editor/property-editor-validation.component.mjs +137 -0
  52. package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +608 -0
  53. package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +225 -0
  54. package/esm2022/lib/features/designer/designer.component.mjs +285 -0
  55. package/esm2022/lib/features/designer/index.mjs +7 -0
  56. package/esm2022/lib/features/designer/services/designer-state.service.mjs +310 -0
  57. package/esm2022/lib/features/designer/services/index.mjs +2 -0
  58. package/esm2022/lib/features/designer/utilities/canvas-layout.util.mjs +124 -0
  59. package/esm2022/lib/features/export/index.mjs +2 -0
  60. package/esm2022/lib/features/export/models/export.models.mjs +2 -0
  61. package/esm2022/lib/features/export/services/report-export.service.mjs +107 -0
  62. package/esm2022/lib/features/index.mjs +6 -0
  63. package/esm2022/lib/features/persistence/index.mjs +2 -0
  64. package/esm2022/lib/features/persistence/services/index.mjs +4 -0
  65. package/esm2022/lib/features/persistence/services/report-store.service.mjs +183 -0
  66. package/esm2022/lib/features/persistence/services/report-versioning.service.mjs +81 -0
  67. package/esm2022/lib/features/persistence/services/schema-validator.service.mjs +102 -0
  68. package/esm2022/lib/features/routing/components/routed-report-designer.component.mjs +156 -0
  69. package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +163 -0
  70. package/esm2022/lib/features/routing/index.mjs +6 -0
  71. package/esm2022/lib/features/routing/models/report-route.models.mjs +2 -0
  72. package/esm2022/lib/features/routing/report-routes.mjs +49 -0
  73. package/esm2022/lib/features/routing/resolvers/report.resolver.mjs +22 -0
  74. package/esm2022/lib/features/routing/services/report-menu.service.mjs +77 -0
  75. package/esm2022/lib/features/runtime/dynamic-renderer.component.mjs +222 -0
  76. package/esm2022/lib/features/runtime/index.mjs +4 -0
  77. package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +409 -0
  78. package/esm2022/lib/features/runtime/report-runtime.component.mjs +147 -0
  79. package/esm2022/lib/primitives/components/button/rpt-button.component.mjs +88 -0
  80. package/esm2022/lib/primitives/components/chart-bridge/report-chart-bridge.component.mjs +361 -0
  81. package/esm2022/lib/primitives/components/checkbox/rpt-checkbox.component.mjs +86 -0
  82. package/esm2022/lib/primitives/components/date/rpt-date.component.mjs +91 -0
  83. package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +204 -0
  84. package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +476 -0
  85. package/esm2022/lib/primitives/components/index.mjs +10 -0
  86. package/esm2022/lib/primitives/components/input/rpt-input.component.mjs +88 -0
  87. package/esm2022/lib/primitives/components/kpi-card/rpt-kpi-card.component.mjs +197 -0
  88. package/esm2022/lib/primitives/components/number/rpt-number.component.mjs +110 -0
  89. package/esm2022/lib/primitives/index.mjs +3 -0
  90. package/esm2022/lib/primitives/register-builtins.mjs +328 -0
  91. package/esm2022/lib/provide-reporting.mjs +92 -0
  92. package/esm2022/public-api.mjs +9 -0
  93. package/fesm2022/bways-report.mjs +10360 -0
  94. package/fesm2022/bways-report.mjs.map +1 -0
  95. package/index.d.ts +5 -0
  96. package/lib/core/errors/index.d.ts +1 -0
  97. package/lib/core/errors/reporting-errors.d.ts +42 -0
  98. package/lib/core/index.d.ts +7 -0
  99. package/lib/core/models/component-event.model.d.ts +37 -0
  100. package/lib/core/models/index.d.ts +11 -0
  101. package/lib/core/models/report-component.model.d.ts +95 -0
  102. package/lib/core/models/report-datasource.model.d.ts +39 -0
  103. package/lib/core/models/report-definition.model.d.ts +100 -0
  104. package/lib/core/models/report-grid.model.d.ts +73 -0
  105. package/lib/core/models/report-layout.model.d.ts +43 -0
  106. package/lib/core/models/report-parameter.model.d.ts +22 -0
  107. package/lib/core/models/validation.model.d.ts +30 -0
  108. package/lib/core/registry/component-category.d.ts +16 -0
  109. package/lib/core/registry/component-registry.d.ts +101 -0
  110. package/lib/core/registry/index.d.ts +4 -0
  111. package/lib/core/registry/property-definition.model.d.ts +38 -0
  112. package/lib/core/services/dynamic-form-builder.service.d.ts +30 -0
  113. package/lib/core/services/index.d.ts +3 -0
  114. package/lib/core/services/report-session-context.service.d.ts +87 -0
  115. package/lib/core/tokens/index.d.ts +4 -0
  116. package/lib/core/tokens/reporting-config.token.d.ts +42 -0
  117. package/lib/core/tokens/session-context.token.d.ts +36 -0
  118. package/lib/core/utilities/id-generator.d.ts +9 -0
  119. package/lib/core/utilities/index.d.ts +3 -0
  120. package/lib/core/utilities/schema-migration.d.ts +10 -0
  121. package/lib/core/utils/identifier-humanizer.d.ts +22 -0
  122. package/lib/core/validation/index.d.ts +1 -0
  123. package/lib/core/validation/validation-factory.d.ts +31 -0
  124. package/lib/data-access/adapters/http-lookup.adapter.d.ts +19 -0
  125. package/lib/data-access/adapters/http-schema-discovery.adapter.d.ts +20 -0
  126. package/lib/data-access/adapters/index.d.ts +2 -0
  127. package/lib/data-access/contracts/data-source.contract.d.ts +37 -0
  128. package/lib/data-access/contracts/index.d.ts +9 -0
  129. package/lib/data-access/contracts/lookup.contract.d.ts +32 -0
  130. package/lib/data-access/contracts/master-data.provider.d.ts +54 -0
  131. package/lib/data-access/contracts/report-persistence.contract.d.ts +36 -0
  132. package/lib/data-access/contracts/schema-discovery.contract.d.ts +52 -0
  133. package/lib/data-access/contracts/translation.contract.d.ts +16 -0
  134. package/lib/data-access/index.d.ts +2 -0
  135. package/lib/features/designer/components/component-palette/component-palette.component.d.ts +39 -0
  136. package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +42 -0
  137. package/lib/features/designer/components/property-editor/parameter-binding-editor.component.d.ts +36 -0
  138. package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +68 -0
  139. package/lib/features/designer/components/property-editor/property-editor-general.component.d.ts +20 -0
  140. package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +20 -0
  141. package/lib/features/designer/components/property-editor/property-editor-layout.component.d.ts +18 -0
  142. package/lib/features/designer/components/property-editor/property-editor-report.component.d.ts +15 -0
  143. package/lib/features/designer/components/property-editor/property-editor-validation.component.d.ts +12 -0
  144. package/lib/features/designer/components/property-editor/property-editor.component.d.ts +44 -0
  145. package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +18 -0
  146. package/lib/features/designer/designer.component.d.ts +36 -0
  147. package/lib/features/designer/index.d.ts +7 -0
  148. package/lib/features/designer/services/designer-state.service.d.ts +103 -0
  149. package/lib/features/designer/services/index.d.ts +2 -0
  150. package/lib/features/designer/utilities/canvas-layout.util.d.ts +55 -0
  151. package/lib/features/export/index.d.ts +2 -0
  152. package/lib/features/export/models/export.models.d.ts +16 -0
  153. package/lib/features/export/services/report-export.service.d.ts +27 -0
  154. package/lib/features/index.d.ts +5 -0
  155. package/lib/features/persistence/index.d.ts +1 -0
  156. package/lib/features/persistence/services/index.d.ts +5 -0
  157. package/lib/features/persistence/services/report-store.service.d.ts +53 -0
  158. package/lib/features/persistence/services/report-versioning.service.d.ts +29 -0
  159. package/lib/features/persistence/services/schema-validator.service.d.ts +34 -0
  160. package/lib/features/routing/components/routed-report-designer.component.d.ts +18 -0
  161. package/lib/features/routing/components/routed-report-runtime.component.d.ts +18 -0
  162. package/lib/features/routing/index.d.ts +6 -0
  163. package/lib/features/routing/models/report-route.models.d.ts +41 -0
  164. package/lib/features/routing/report-routes.d.ts +16 -0
  165. package/lib/features/routing/resolvers/report.resolver.d.ts +7 -0
  166. package/lib/features/routing/services/report-menu.service.d.ts +30 -0
  167. package/lib/features/runtime/dynamic-renderer.component.d.ts +30 -0
  168. package/lib/features/runtime/index.d.ts +3 -0
  169. package/lib/features/runtime/report-grid-bridge.component.d.ts +94 -0
  170. package/lib/features/runtime/report-runtime.component.d.ts +26 -0
  171. package/lib/primitives/components/button/rpt-button.component.d.ts +19 -0
  172. package/lib/primitives/components/chart-bridge/report-chart-bridge.component.d.ts +45 -0
  173. package/lib/primitives/components/checkbox/rpt-checkbox.component.d.ts +14 -0
  174. package/lib/primitives/components/date/rpt-date.component.d.ts +17 -0
  175. package/lib/primitives/components/dropdown/rpt-dropdown.component.d.ts +32 -0
  176. package/lib/primitives/components/icon/rpt-icon.component.d.ts +41 -0
  177. package/lib/primitives/components/index.d.ts +12 -0
  178. package/lib/primitives/components/input/rpt-input.component.d.ts +16 -0
  179. package/lib/primitives/components/kpi-card/rpt-kpi-card.component.d.ts +43 -0
  180. package/lib/primitives/components/number/rpt-number.component.d.ts +20 -0
  181. package/lib/primitives/index.d.ts +2 -0
  182. package/lib/primitives/register-builtins.d.ts +11 -0
  183. package/lib/provide-reporting.d.ts +75 -0
  184. package/package.json +55 -0
  185. package/public-api.d.ts +5 -0
@@ -0,0 +1,6 @@
1
+ export * from './runtime';
2
+ export * from './designer';
3
+ export * from './persistence';
4
+ export * from './routing';
5
+ export * from './export';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLFdBQVcsQ0FBQztBQUMxQixjQUFjLFlBQVksQ0FBQztBQUMzQixjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLFdBQVcsQ0FBQztBQUMxQixjQUFjLFVBQVUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vcnVudGltZSc7XG5leHBvcnQgKiBmcm9tICcuL2Rlc2lnbmVyJztcbmV4cG9ydCAqIGZyb20gJy4vcGVyc2lzdGVuY2UnO1xuZXhwb3J0ICogZnJvbSAnLi9yb3V0aW5nJztcbmV4cG9ydCAqIGZyb20gJy4vZXhwb3J0JztcbiJdfQ==
@@ -0,0 +1,2 @@
1
+ export * from './services';
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9wZXJzaXN0ZW5jZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLFlBQVksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vc2VydmljZXMnO1xuIl19
@@ -0,0 +1,4 @@
1
+ export { SchemaValidatorService, validateReportSchema, } from './schema-validator.service';
2
+ export { ReportVersioningService } from './report-versioning.service';
3
+ export { ReportStoreService } from './report-store.service';
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9wZXJzaXN0ZW5jZS9zZXJ2aWNlcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLG9CQUFvQixHQUNyQixNQUFNLDRCQUE0QixDQUFDO0FBR3BDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBR3RFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHtcbiAgU2NoZW1hVmFsaWRhdG9yU2VydmljZSxcbiAgdmFsaWRhdGVSZXBvcnRTY2hlbWEsXG59IGZyb20gJy4vc2NoZW1hLXZhbGlkYXRvci5zZXJ2aWNlJztcbmV4cG9ydCB0eXBlIHsgU2NoZW1hVmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJy4vc2NoZW1hLXZhbGlkYXRvci5zZXJ2aWNlJztcblxuZXhwb3J0IHsgUmVwb3J0VmVyc2lvbmluZ1NlcnZpY2UgfSBmcm9tICcuL3JlcG9ydC12ZXJzaW9uaW5nLnNlcnZpY2UnO1xuZXhwb3J0IHR5cGUgeyBSZXBvcnREaWZmU3VtbWFyeSB9IGZyb20gJy4vcmVwb3J0LXZlcnNpb25pbmcuc2VydmljZSc7XG5cbmV4cG9ydCB7IFJlcG9ydFN0b3JlU2VydmljZSB9IGZyb20gJy4vcmVwb3J0LXN0b3JlLnNlcnZpY2UnO1xuIl19
@@ -0,0 +1,183 @@
1
+ import { computed, inject, Injectable, signal, } from '@angular/core';
2
+ import { of, tap, throwError } from 'rxjs';
3
+ import { ReportPersistenceAdapter } from '../../../data-access/contracts/report-persistence.contract';
4
+ import { SchemaValidatorService } from './schema-validator.service';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * ReportStoreService manages application-wide cached report states,
8
+ * listing, and reactive access via Angular signals.
9
+ */
10
+ export class ReportStoreService {
11
+ adapter = inject(ReportPersistenceAdapter, { optional: true });
12
+ validator = inject(SchemaValidatorService);
13
+ /** List of all known report summaries */
14
+ summaries = signal([]);
15
+ /** In-memory cache of loaded full report definitions by ID */
16
+ cache = signal(new Map());
17
+ /** Currently selected report ID */
18
+ activeReportId = signal(null);
19
+ /** Loading state indicator */
20
+ isLoading = signal(false);
21
+ /** Current error message */
22
+ error = signal(null);
23
+ /** Active report definition computed from cache */
24
+ activeReport = computed(() => {
25
+ const id = this.activeReportId();
26
+ if (!id)
27
+ return null;
28
+ return this.cache().get(id) ?? null;
29
+ });
30
+ /**
31
+ * Fetches the list of all available reports.
32
+ */
33
+ loadSummaries() {
34
+ if (!this.adapter) {
35
+ return of(this.summaries());
36
+ }
37
+ this.isLoading.set(true);
38
+ this.error.set(null);
39
+ return this.adapter.list().pipe(tap({
40
+ next: (list) => {
41
+ this.summaries.set(list);
42
+ this.isLoading.set(false);
43
+ },
44
+ error: (err) => {
45
+ this.error.set(err?.message ?? 'Failed to load report list.');
46
+ this.isLoading.set(false);
47
+ },
48
+ }));
49
+ }
50
+ /**
51
+ * Loads a report definition by ID, using cached instance if available.
52
+ *
53
+ * @param reportId - ID of the report to load.
54
+ * @param forceRefresh - If true, bypasses the in-memory cache.
55
+ */
56
+ loadReport(reportId, forceRefresh = false) {
57
+ if (!forceRefresh) {
58
+ const cached = this.cache().get(reportId);
59
+ if (cached) {
60
+ this.activeReportId.set(reportId);
61
+ return of(cached);
62
+ }
63
+ }
64
+ if (!this.adapter) {
65
+ return throwError(() => new Error('ReportPersistenceAdapter not configured.'));
66
+ }
67
+ this.isLoading.set(true);
68
+ this.error.set(null);
69
+ return this.adapter.load(reportId).pipe(tap({
70
+ next: (def) => {
71
+ this.validator.assertValid(def);
72
+ const nextCache = new Map(this.cache());
73
+ nextCache.set(reportId, def);
74
+ this.cache.set(nextCache);
75
+ this.activeReportId.set(reportId);
76
+ this.isLoading.set(false);
77
+ },
78
+ error: (err) => {
79
+ this.error.set(err?.message ?? `Failed to load report "${reportId}".`);
80
+ this.isLoading.set(false);
81
+ },
82
+ }));
83
+ }
84
+ /**
85
+ * Saves a report definition, validates it, and updates local cache.
86
+ */
87
+ saveReport(report) {
88
+ this.validator.assertValid(report);
89
+ if (!this.adapter) {
90
+ // In-memory update if no adapter configured
91
+ const nextCache = new Map(this.cache());
92
+ nextCache.set(report.id, report);
93
+ this.cache.set(nextCache);
94
+ this.updateSummaryInList(report);
95
+ return of(report);
96
+ }
97
+ this.isLoading.set(true);
98
+ this.error.set(null);
99
+ return this.adapter.save(report).pipe(tap({
100
+ next: (saved) => {
101
+ const nextCache = new Map(this.cache());
102
+ nextCache.set(saved.id, saved);
103
+ this.cache.set(nextCache);
104
+ this.updateSummaryInList(saved);
105
+ this.isLoading.set(false);
106
+ },
107
+ error: (err) => {
108
+ this.error.set(err?.message ?? `Failed to save report "${report.id}".`);
109
+ this.isLoading.set(false);
110
+ },
111
+ }));
112
+ }
113
+ /**
114
+ * Deletes a report definition by ID.
115
+ */
116
+ deleteReport(reportId) {
117
+ if (!this.adapter) {
118
+ const nextCache = new Map(this.cache());
119
+ nextCache.delete(reportId);
120
+ this.cache.set(nextCache);
121
+ this.summaries.set(this.summaries().filter((s) => s.id !== reportId));
122
+ if (this.activeReportId() === reportId) {
123
+ this.activeReportId.set(null);
124
+ }
125
+ return of(void 0);
126
+ }
127
+ this.isLoading.set(true);
128
+ return this.adapter.delete(reportId).pipe(tap({
129
+ next: () => {
130
+ const nextCache = new Map(this.cache());
131
+ nextCache.delete(reportId);
132
+ this.cache.set(nextCache);
133
+ this.summaries.set(this.summaries().filter((s) => s.id !== reportId));
134
+ if (this.activeReportId() === reportId) {
135
+ this.activeReportId.set(null);
136
+ }
137
+ this.isLoading.set(false);
138
+ },
139
+ error: (err) => {
140
+ this.error.set(err?.message ?? `Failed to delete report "${reportId}".`);
141
+ this.isLoading.set(false);
142
+ },
143
+ }));
144
+ }
145
+ /**
146
+ * Sets the active report ID.
147
+ */
148
+ setActiveReport(id) {
149
+ this.activeReportId.set(id);
150
+ }
151
+ /**
152
+ * Clears the in-memory cache.
153
+ */
154
+ clearCache() {
155
+ this.cache.set(new Map());
156
+ }
157
+ updateSummaryInList(def) {
158
+ const list = [...this.summaries()];
159
+ const idx = list.findIndex((s) => s.id === def.id);
160
+ const summary = {
161
+ id: def.id,
162
+ name: def.name,
163
+ description: def.description,
164
+ version: def.version,
165
+ isPublished: !def.metadata?.['isDraft'],
166
+ lastModified: new Date().toISOString(),
167
+ };
168
+ if (idx >= 0) {
169
+ list[idx] = summary;
170
+ }
171
+ else {
172
+ list.push(summary);
173
+ }
174
+ this.summaries.set(list);
175
+ }
176
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportStoreService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
177
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportStoreService, providedIn: 'root' });
178
+ }
179
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportStoreService, decorators: [{
180
+ type: Injectable,
181
+ args: [{ providedIn: 'root' }]
182
+ }] });
183
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXN0b3JlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9wZXJzaXN0ZW5jZS9zZXJ2aWNlcy9yZXBvcnQtc3RvcmUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsUUFBUSxFQUNSLE1BQU0sRUFDTixVQUFVLEVBQ1YsTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBYyxFQUFFLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUt2RCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw0REFBNEQsQ0FBQztBQUN0RyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7QUFFcEU7OztHQUdHO0FBRUgsTUFBTSxPQUFPLGtCQUFrQjtJQUNaLE9BQU8sR0FBRyxNQUFNLENBQUMsd0JBQXdCLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMvRCxTQUFTLEdBQUcsTUFBTSxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFFNUQseUNBQXlDO0lBQ2hDLFNBQVMsR0FBRyxNQUFNLENBQWtCLEVBQUUsQ0FBQyxDQUFDO0lBRWpELDhEQUE4RDtJQUM3QyxLQUFLLEdBQUcsTUFBTSxDQUFnQyxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFFMUUsbUNBQW1DO0lBQzFCLGNBQWMsR0FBRyxNQUFNLENBQWdCLElBQUksQ0FBQyxDQUFDO0lBRXRELDhCQUE4QjtJQUNyQixTQUFTLEdBQUcsTUFBTSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBRTVDLDRCQUE0QjtJQUNuQixLQUFLLEdBQUcsTUFBTSxDQUFnQixJQUFJLENBQUMsQ0FBQztJQUU3QyxtREFBbUQ7SUFDMUMsWUFBWSxHQUFHLFFBQVEsQ0FBMEIs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QjtrQkFEOUIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBjb21wdXRlZCxcbiAgaW5qZWN0LFxuICBJbmplY3RhYmxlLFxuICBzaWduYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YsIHRhcCwgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgUmVwb3J0RGVmaW5pdGlvbixcbiAgUmVwb3J0U3VtbWFyeSxcbn0gZnJvbSAnLi4vLi4vLi4vY29yZS9tb2RlbHMvcmVwb3J0LWRlZmluaXRpb24ubW9kZWwnO1xuaW1wb3J0IHsgUmVwb3J0UGVyc2lzdGVuY2VBZGFwdGVyIH0gZnJvbSAnLi4vLi4vLi4vZGF0YS1hY2Nlc3MvY29udHJhY3RzL3JlcG9ydC1wZXJzaXN0ZW5jZS5jb250cmFjdCc7XG5pbXBvcnQgeyBTY2hlbWFWYWxpZGF0b3JTZXJ2aWNlIH0gZnJvbSAnLi9zY2hlbWEtdmFsaWRhdG9yLnNlcnZpY2UnO1xuXG4vKipcbiAqIFJlcG9ydFN0b3JlU2VydmljZSBtYW5hZ2VzIGFwcGxpY2F0aW9uLXdpZGUgY2FjaGVkIHJlcG9ydCBzdGF0ZXMsXG4gKiBsaXN0aW5nLCBhbmQgcmVhY3RpdmUgYWNjZXNzIHZpYSBBbmd1bGFyIHNpZ25hbHMuXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgUmVwb3J0U3RvcmVTZXJ2aWNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBhZGFwdGVyID0gaW5qZWN0KFJlcG9ydFBlcnNpc3RlbmNlQWRhcHRlciwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbiAgcHJpdmF0ZSByZWFkb25seSB2YWxpZGF0b3IgPSBpbmplY3QoU2NoZW1hVmFsaWRhdG9yU2VydmljZSk7XG5cbiAgLyoqIExpc3Qgb2YgYWxsIGtub3duIHJlcG9ydCBzdW1tYXJpZXMgKi9cbiAgcmVhZG9ubHkgc3VtbWFyaWVzID0gc2lnbmFsPFJlcG9ydFN1bW1hcnlbXT4oW10pO1xuXG4gIC8qKiBJbi1tZW1vcnkgY2FjaGUgb2YgbG9hZGVkIGZ1bGwgcmVwb3J0IGRlZmluaXRpb25zIGJ5IElEICovXG4gIHByaXZhdGUgcmVhZG9ubHkgY2FjaGUgPSBzaWduYWw8TWFwPHN0cmluZywgUmVwb3J0RGVmaW5pdGlvbj4+KG5ldyBNYXAoKSk7XG5cbiAgLyoqIEN1cnJlbnRseSBzZWxlY3RlZCByZXBvcnQgSUQgKi9cbiAgcmVhZG9ubHkgYWN0aXZlUmVwb3J0SWQgPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG5cbiAgLyoqIExvYWRpbmcgc3RhdGUgaW5kaWNhdG9yICovXG4gIHJlYWRvbmx5IGlzTG9hZGluZyA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG5cbiAgLyoqIEN1cnJlbnQgZXJyb3IgbWVzc2FnZSAqL1xuICByZWFkb25seSBlcnJvciA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcblxuICAvKiogQWN0aXZlIHJlcG9ydCBkZWZpbml0aW9uIGNvbXB1dGVkIGZyb20gY2FjaGUgKi9cbiAgcmVhZG9ubHkgYWN0aXZlUmVwb3J0ID0gY29tcHV0ZWQ8UmVwb3J0RGVmaW5pdGlvbiB8IG51bGw+KCgpID0+IHtcbiAgICBjb25zdCBpZCA9IHRoaXMuYWN0aXZlUmVwb3J0SWQoKTtcbiAgICBpZiAoIWlkKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gdGhpcy5jYWNoZSgpLmdldChpZCkgPz8gbnVsbDtcbiAgfSk7XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgdGhlIGxpc3Qgb2YgYWxsIGF2YWlsYWJsZSByZXBvcnRzLlxuICAgKi9cbiAgbG9hZFN1bW1hcmllcygpOiBPYnNlcnZhYmxlPFJlcG9ydFN1bW1hcnlbXT4ge1xuICAgIGlmICghdGhpcy5hZGFwdGVyKSB7XG4gICAgICByZXR1cm4gb2YodGhpcy5zdW1tYXJpZXMoKSk7XG4gICAgfVxuXG4gICAgdGhpcy5pc0xvYWRpbmcuc2V0KHRydWUpO1xuICAgIHRoaXMuZXJyb3Iuc2V0KG51bGwpO1xuXG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5saXN0KCkucGlwZShcbiAgICAgIHRhcCh7XG4gICAgICAgIG5leHQ6IChsaXN0KSA9PiB7XG4gICAgICAgICAgdGhpcy5zdW1tYXJpZXMuc2V0KGxpc3QpO1xuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgICAgdGhpcy5lcnJvci5zZXQoZXJyPy5tZXNzYWdlID8/ICdGYWlsZWQgdG8gbG9hZCByZXBvcnQgbGlzdC4nKTtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICB9LFxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIGEgcmVwb3J0IGRlZmluaXRpb24gYnkgSUQsIHVzaW5nIGNhY2hlZCBpbnN0YW5jZSBpZiBhdmFpbGFibGUuXG4gICAqXG4gICAqIEBwYXJhbSByZXBvcnRJZCAtIElEIG9mIHRoZSByZXBvcnQgdG8gbG9hZC5cbiAgICogQHBhcmFtIGZvcmNlUmVmcmVzaCAtIElmIHRydWUsIGJ5cGFzc2VzIHRoZSBpbi1tZW1vcnkgY2FjaGUuXG4gICAqL1xuICBsb2FkUmVwb3J0KHJlcG9ydElkOiBzdHJpbmcsIGZvcmNlUmVmcmVzaCA9IGZhbHNlKTogT2JzZXJ2YWJsZTxSZXBvcnREZWZpbml0aW9uPiB7XG4gICAgaWYgKCFmb3JjZVJlZnJlc2gpIHtcbiAgICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMuY2FjaGUoKS5nZXQocmVwb3J0SWQpO1xuICAgICAgaWYgKGNhY2hlZCkge1xuICAgICAgICB0aGlzLmFjdGl2ZVJlcG9ydElkLnNldChyZXBvcnRJZCk7XG4gICAgICAgIHJldHVybiBvZihjYWNoZWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGhpcy5hZGFwdGVyKSB7XG4gICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgRXJyb3IoJ1JlcG9ydFBlcnNpc3RlbmNlQWRhcHRlciBub3QgY29uZmlndXJlZC4nKSk7XG4gICAgfVxuXG4gICAgdGhpcy5pc0xvYWRpbmcuc2V0KHRydWUpO1xuICAgIHRoaXMuZXJyb3Iuc2V0KG51bGwpO1xuXG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5sb2FkKHJlcG9ydElkKS5waXBlKFxuICAgICAgdGFwKHtcbiAgICAgICAgbmV4dDogKGRlZikgPT4ge1xuICAgICAgICAgIHRoaXMudmFsaWRhdG9yLmFzc2VydFZhbGlkKGRlZik7XG4gICAgICAgICAgY29uc3QgbmV4dENhY2hlID0gbmV3IE1hcCh0aGlzLmNhY2hlKCkpO1xuICAgICAgICAgIG5leHRDYWNoZS5zZXQocmVwb3J0SWQsIGRlZik7XG4gICAgICAgICAgdGhpcy5jYWNoZS5zZXQobmV4dENhY2hlKTtcbiAgICAgICAgICB0aGlzLmFjdGl2ZVJlcG9ydElkLnNldChyZXBvcnRJZCk7XG4gICAgICAgICAgdGhpcy5pc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICB0aGlzLmVycm9yLnNldChlcnI/Lm1lc3NhZ2UgPz8gYEZhaWxlZCB0byBsb2FkIHJlcG9ydCBcIiR7cmVwb3J0SWR9XCIuYCk7XG4gICAgICAgICAgdGhpcy5pc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTYXZlcyBhIHJlcG9ydCBkZWZpbml0aW9uLCB2YWxpZGF0ZXMgaXQsIGFuZCB1cGRhdGVzIGxvY2FsIGNhY2hlLlxuICAgKi9cbiAgc2F2ZVJlcG9ydChyZXBvcnQ6IFJlcG9ydERlZmluaXRpb24pOiBPYnNlcnZhYmxlPFJlcG9ydERlZmluaXRpb24+IHtcbiAgICB0aGlzLnZhbGlkYXRvci5hc3NlcnRWYWxpZChyZXBvcnQpO1xuXG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpIHtcbiAgICAgIC8vIEluLW1lbW9yeSB1cGRhdGUgaWYgbm8gYWRhcHRlciBjb25maWd1cmVkXG4gICAgICBjb25zdCBuZXh0Q2FjaGUgPSBuZXcgTWFwKHRoaXMuY2FjaGUoKSk7XG4gICAgICBuZXh0Q2FjaGUuc2V0KHJlcG9ydC5pZCwgcmVwb3J0KTtcbiAgICAgIHRoaXMuY2FjaGUuc2V0KG5leHRDYWNoZSk7XG4gICAgICB0aGlzLnVwZGF0ZVN1bW1hcnlJbkxpc3QocmVwb3J0KTtcbiAgICAgIHJldHVybiBvZihyZXBvcnQpO1xuICAgIH1cblxuICAgIHRoaXMuaXNMb2FkaW5nLnNldCh0cnVlKTtcbiAgICB0aGlzLmVycm9yLnNldChudWxsKTtcblxuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuc2F2ZShyZXBvcnQpLnBpcGUoXG4gICAgICB0YXAoe1xuICAgICAgICBuZXh0OiAoc2F2ZWQpID0+IHtcbiAgICAgICAgICBjb25zdCBuZXh0Q2FjaGUgPSBuZXcgTWFwKHRoaXMuY2FjaGUoKSk7XG4gICAgICAgICAgbmV4dENhY2hlLnNldChzYXZlZC5pZCwgc2F2ZWQpO1xuICAgICAgICAgIHRoaXMuY2FjaGUuc2V0KG5leHRDYWNoZSk7XG4gICAgICAgICAgdGhpcy51cGRhdGVTdW1tYXJ5SW5MaXN0KHNhdmVkKTtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgIHRoaXMuZXJyb3Iuc2V0KGVycj8ubWVzc2FnZSA/PyBgRmFpbGVkIHRvIHNhdmUgcmVwb3J0IFwiJHtyZXBvcnQuaWR9XCIuYCk7XG4gICAgICAgICAgdGhpcy5pc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGEgcmVwb3J0IGRlZmluaXRpb24gYnkgSUQuXG4gICAqL1xuICBkZWxldGVSZXBvcnQocmVwb3J0SWQ6IHN0cmluZyk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIGlmICghdGhpcy5hZGFwdGVyKSB7XG4gICAgICBjb25zdCBuZXh0Q2FjaGUgPSBuZXcgTWFwKHRoaXMuY2FjaGUoKSk7XG4gICAgICBuZXh0Q2FjaGUuZGVsZXRlKHJlcG9ydElkKTtcbiAgICAgIHRoaXMuY2FjaGUuc2V0KG5leHRDYWNoZSk7XG4gICAgICB0aGlzLnN1bW1hcmllcy5zZXQodGhpcy5zdW1tYXJpZXMoKS5maWx0ZXIoKHMpID0+IHMuaWQgIT09IHJlcG9ydElkKSk7XG4gICAgICBpZiAodGhpcy5hY3RpdmVSZXBvcnRJZCgpID09PSByZXBvcnRJZCkge1xuICAgICAgICB0aGlzLmFjdGl2ZVJlcG9ydElkLnNldChudWxsKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvZih2b2lkIDApO1xuICAgIH1cblxuICAgIHRoaXMuaXNMb2FkaW5nLnNldCh0cnVlKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmRlbGV0ZShyZXBvcnRJZCkucGlwZShcbiAgICAgIHRhcCh7XG4gICAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgICBjb25zdCBuZXh0Q2FjaGUgPSBuZXcgTWFwKHRoaXMuY2FjaGUoKSk7XG4gICAgICAgICAgbmV4dENhY2hlLmRlbGV0ZShyZXBvcnRJZCk7XG4gICAgICAgICAgdGhpcy5jYWNoZS5zZXQobmV4dENhY2hlKTtcbiAgICAgICAgICB0aGlzLnN1bW1hcmllcy5zZXQodGhpcy5zdW1tYXJpZXMoKS5maWx0ZXIoKHMpID0+IHMuaWQgIT09IHJlcG9ydElkKSk7XG4gICAgICAgICAgaWYgKHRoaXMuYWN0aXZlUmVwb3J0SWQoKSA9PT0gcmVwb3J0SWQpIHtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlUmVwb3J0SWQuc2V0KG51bGwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmlzTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgIHRoaXMuZXJyb3Iuc2V0KGVycj8ubWVzc2FnZSA/PyBgRmFpbGVkIHRvIGRlbGV0ZSByZXBvcnQgXCIke3JlcG9ydElkfVwiLmApO1xuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgYWN0aXZlIHJlcG9ydCBJRC5cbiAgICovXG4gIHNldEFjdGl2ZVJlcG9ydChpZDogc3RyaW5nIHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuYWN0aXZlUmVwb3J0SWQuc2V0KGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgdGhlIGluLW1lbW9yeSBjYWNoZS5cbiAgICovXG4gIGNsZWFyQ2FjaGUoKTogdm9pZCB7XG4gICAgdGhpcy5jYWNoZS5zZXQobmV3IE1hcCgpKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlU3VtbWFyeUluTGlzdChkZWY6IFJlcG9ydERlZmluaXRpb24pOiB2b2lkIHtcbiAgICBjb25zdCBsaXN0ID0gWy4uLnRoaXMuc3VtbWFyaWVzKCldO1xuICAgIGNvbnN0IGlkeCA9IGxpc3QuZmluZEluZGV4KChzKSA9PiBzLmlkID09PSBkZWYuaWQpO1xuICAgIGNvbnN0IHN1bW1hcnk6IFJlcG9ydFN1bW1hcnkgPSB7XG4gICAgICBpZDogZGVmLmlkLFxuICAgICAgbmFtZTogZGVmLm5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogZGVmLmRlc2NyaXB0aW9uLFxuICAgICAgdmVyc2lvbjogZGVmLnZlcnNpb24sXG4gICAgICBpc1B1Ymxpc2hlZDogIWRlZi5tZXRhZGF0YT8uWydpc0RyYWZ0J10sXG4gICAgICBsYXN0TW9kaWZpZWQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICB9O1xuXG4gICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICBsaXN0W2lkeF0gPSBzdW1tYXJ5O1xuICAgIH0gZWxzZSB7XG4gICAgICBsaXN0LnB1c2goc3VtbWFyeSk7XG4gICAgfVxuICAgIHRoaXMuc3VtbWFyaWVzLnNldChsaXN0KTtcbiAgfVxufVxuIl19
@@ -0,0 +1,81 @@
1
+ import { inject, Injectable } from '@angular/core';
2
+ import { SchemaValidatorService } from './schema-validator.service';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * ReportVersioningService manages the draft and publishing lifecycle of report definitions.
6
+ */
7
+ export class ReportVersioningService {
8
+ validator = inject(SchemaValidatorService);
9
+ /**
10
+ * Prepares a new draft version from an existing definition.
11
+ */
12
+ createDraft(report) {
13
+ return {
14
+ ...JSON.parse(JSON.stringify(report)),
15
+ metadata: {
16
+ ...(report.metadata ?? {}),
17
+ isDraft: true,
18
+ draftCreatedAt: new Date().toISOString(),
19
+ },
20
+ };
21
+ }
22
+ /**
23
+ * Publishes a draft report definition, validating its integrity and incrementing its version.
24
+ */
25
+ publish(report) {
26
+ this.validator.assertValid(report);
27
+ const nextVersion = (report.version ?? 1) + 1;
28
+ const publishedMeta = {
29
+ ...(report.metadata ?? {}),
30
+ isDraft: false,
31
+ publishedAt: new Date().toISOString(),
32
+ };
33
+ return {
34
+ ...JSON.parse(JSON.stringify(report)),
35
+ version: nextVersion,
36
+ metadata: publishedMeta,
37
+ };
38
+ }
39
+ /**
40
+ * Compares two versions of a report definition to produce a structured diff summary.
41
+ */
42
+ compareVersions(v1, v2) {
43
+ const v1CompMap = new Map(v1.components.map((c) => [c.id, c]));
44
+ const v2CompMap = new Map(v2.components.map((c) => [c.id, c]));
45
+ const addedComponentIds = [];
46
+ const removedComponentIds = [];
47
+ const modifiedComponentIds = [];
48
+ for (const [id, comp] of v2CompMap) {
49
+ if (!v1CompMap.has(id)) {
50
+ addedComponentIds.push(id);
51
+ }
52
+ else {
53
+ const original = v1CompMap.get(id);
54
+ if (JSON.stringify(original) !== JSON.stringify(comp)) {
55
+ modifiedComponentIds.push(id);
56
+ }
57
+ }
58
+ }
59
+ for (const id of v1CompMap.keys()) {
60
+ if (!v2CompMap.has(id)) {
61
+ removedComponentIds.push(id);
62
+ }
63
+ }
64
+ const hasLayoutChanges = JSON.stringify(v1.layout) !== JSON.stringify(v2.layout);
65
+ const hasGridChanges = JSON.stringify(v1.grid) !== JSON.stringify(v2.grid);
66
+ return {
67
+ hasLayoutChanges,
68
+ hasGridChanges,
69
+ addedComponentIds,
70
+ removedComponentIds,
71
+ modifiedComponentIds,
72
+ };
73
+ }
74
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportVersioningService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
75
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportVersioningService, providedIn: 'root' });
76
+ }
77
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportVersioningService, decorators: [{
78
+ type: Injectable,
79
+ args: [{ providedIn: 'root' }]
80
+ }] });
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXZlcnNpb25pbmcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2J3YXlzLXJlcG9ydC9zcmMvbGliL2ZlYXR1cmVzL3BlcnNpc3RlbmNlL3NlcnZpY2VzL3JlcG9ydC12ZXJzaW9uaW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbkQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7O0FBVXBFOztHQUVHO0FBRUgsTUFBTSxPQUFPLHVCQUF1QjtJQUNqQixTQUFTLEdBQUcsTUFBTSxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFFNUQ7O09BRUc7SUFDSCxXQUFXLENBQUMsTUFBd0I7UUFDbEMsT0FBTztZQUNMLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3JDLFFBQVEsRUFBRTtnQkFDUixHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7Z0JBQzFCLE9BQU8sRUFBRSxJQUFJO2dCQUNiLGNBQWMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTthQUN6QztTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxPQUFPLENBQUMsTUFBd0I7UUFDOUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFbkMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM5QyxNQUFNLGFBQWEsR0FBRztZQUNwQixHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7WUFDMUIsT0FBTyxFQUFFLEtBQUs7WUFDZCxXQUFXLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7U0FDdEMsQ0FBQztRQUVGLE9BQU87WUFDTCxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyQyxPQUFPLEVBQUUsV0FBVztZQUNwQixRQUFRLEVBQUUsYUFBYTtTQUN4QixDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0gsZUFBZSxDQUFDLEVBQW9CLEVBQUUsRUFBb0I7UUFDeEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFL0QsTUFBTSxpQkFBaUIsR0FBYSxFQUFFLENBQUM7UUFDdkMsTUFBTSxtQkFBbUIsR0FBYSxFQUFFLENBQUM7UUFDekMsTUFBTSxvQkFBb0IsR0FBYSxFQUFFLENBQUM7UUFFMUMsS0FBSyxNQUFNLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZCLGlCQUFpQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUM3QixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUUsQ0FBQztnQkFDcEMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxLQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztvQkFDdEQsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNoQyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxLQUFLLE1BQU0sRUFBRSxJQUFJLFNBQVMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZCLG1CQUFtQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMvQixDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQ3BCLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTFELE1BQU0sY0FBYyxHQUNsQixJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV0RCxPQUFPO1lBQ0wsZ0JBQWdCO1lBQ2hCLGNBQWM7WUFDZCxpQkFBaUI7WUFDakIsbUJBQW1CO1lBQ25CLG9CQUFvQjtTQUNyQixDQUFDO0lBQ0osQ0FBQzt3R0E5RVUsdUJBQXVCOzRHQUF2Qix1QkFBdUIsY0FEVixNQUFNOzs0RkFDbkIsdUJBQXVCO2tCQURuQyxVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVwb3J0RGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uLy4uL2NvcmUvbW9kZWxzL3JlcG9ydC1kZWZpbml0aW9uLm1vZGVsJztcbmltcG9ydCB7IFNjaGVtYVZhbGlkYXRvclNlcnZpY2UgfSBmcm9tICcuL3NjaGVtYS12YWxpZGF0b3Iuc2VydmljZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RGlmZlN1bW1hcnkge1xuICBoYXNMYXlvdXRDaGFuZ2VzOiBib29sZWFuO1xuICBoYXNHcmlkQ2hhbmdlczogYm9vbGVhbjtcbiAgYWRkZWRDb21wb25lbnRJZHM6IHN0cmluZ1tdO1xuICByZW1vdmVkQ29tcG9uZW50SWRzOiBzdHJpbmdbXTtcbiAgbW9kaWZpZWRDb21wb25lbnRJZHM6IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFJlcG9ydFZlcnNpb25pbmdTZXJ2aWNlIG1hbmFnZXMgdGhlIGRyYWZ0IGFuZCBwdWJsaXNoaW5nIGxpZmVjeWNsZSBvZiByZXBvcnQgZGVmaW5pdGlvbnMuXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgUmVwb3J0VmVyc2lvbmluZ1NlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IHZhbGlkYXRvciA9IGluamVjdChTY2hlbWFWYWxpZGF0b3JTZXJ2aWNlKTtcblxuICAvKipcbiAgICogUHJlcGFyZXMgYSBuZXcgZHJhZnQgdmVyc2lvbiBmcm9tIGFuIGV4aXN0aW5nIGRlZmluaXRpb24uXG4gICAqL1xuICBjcmVhdGVEcmFmdChyZXBvcnQ6IFJlcG9ydERlZmluaXRpb24pOiBSZXBvcnREZWZpbml0aW9uIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyZXBvcnQpKSxcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIC4uLihyZXBvcnQubWV0YWRhdGEgPz8ge30pLFxuICAgICAgICBpc0RyYWZ0OiB0cnVlLFxuICAgICAgICBkcmFmdENyZWF0ZWRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2hlcyBhIGRyYWZ0IHJlcG9ydCBkZWZpbml0aW9uLCB2YWxpZGF0aW5nIGl0cyBpbnRlZ3JpdHkgYW5kIGluY3JlbWVudGluZyBpdHMgdmVyc2lvbi5cbiAgICovXG4gIHB1Ymxpc2gocmVwb3J0OiBSZXBvcnREZWZpbml0aW9uKTogUmVwb3J0RGVmaW5pdGlvbiB7XG4gICAgdGhpcy52YWxpZGF0b3IuYXNzZXJ0VmFsaWQocmVwb3J0KTtcblxuICAgIGNvbnN0IG5leHRWZXJzaW9uID0gKHJlcG9ydC52ZXJzaW9uID8/IDEpICsgMTtcbiAgICBjb25zdCBwdWJsaXNoZWRNZXRhID0ge1xuICAgICAgLi4uKHJlcG9ydC5tZXRhZGF0YSA/PyB7fSksXG4gICAgICBpc0RyYWZ0OiBmYWxzZSxcbiAgICAgIHB1Ymxpc2hlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHJlcG9ydCkpLFxuICAgICAgdmVyc2lvbjogbmV4dFZlcnNpb24sXG4gICAgICBtZXRhZGF0YTogcHVibGlzaGVkTWV0YSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXBhcmVzIHR3byB2ZXJzaW9ucyBvZiBhIHJlcG9ydCBkZWZpbml0aW9uIHRvIHByb2R1Y2UgYSBzdHJ1Y3R1cmVkIGRpZmYgc3VtbWFyeS5cbiAgICovXG4gIGNvbXBhcmVWZXJzaW9ucyh2MTogUmVwb3J0RGVmaW5pdGlvbiwgdjI6IFJlcG9ydERlZmluaXRpb24pOiBSZXBvcnREaWZmU3VtbWFyeSB7XG4gICAgY29uc3QgdjFDb21wTWFwID0gbmV3IE1hcCh2MS5jb21wb25lbnRzLm1hcCgoYykgPT4gW2MuaWQsIGNdKSk7XG4gICAgY29uc3QgdjJDb21wTWFwID0gbmV3IE1hcCh2Mi5jb21wb25lbnRzLm1hcCgoYykgPT4gW2MuaWQsIGNdKSk7XG5cbiAgICBjb25zdCBhZGRlZENvbXBvbmVudElkczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCByZW1vdmVkQ29tcG9uZW50SWRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IG1vZGlmaWVkQ29tcG9uZW50SWRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBbaWQsIGNvbXBdIG9mIHYyQ29tcE1hcCkge1xuICAgICAgaWYgKCF2MUNvbXBNYXAuaGFzKGlkKSkge1xuICAgICAgICBhZGRlZENvbXBvbmVudElkcy5wdXNoKGlkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsID0gdjFDb21wTWFwLmdldChpZCkhO1xuICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkob3JpZ2luYWwpICE9PSBKU09OLnN0cmluZ2lmeShjb21wKSkge1xuICAgICAgICAgIG1vZGlmaWVkQ29tcG9uZW50SWRzLnB1c2goaWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBpZCBvZiB2MUNvbXBNYXAua2V5cygpKSB7XG4gICAgICBpZiAoIXYyQ29tcE1hcC5oYXMoaWQpKSB7XG4gICAgICAgIHJlbW92ZWRDb21wb25lbnRJZHMucHVzaChpZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaGFzTGF5b3V0Q2hhbmdlcyA9XG4gICAgICBKU09OLnN0cmluZ2lmeSh2MS5sYXlvdXQpICE9PSBKU09OLnN0cmluZ2lmeSh2Mi5sYXlvdXQpO1xuXG4gICAgY29uc3QgaGFzR3JpZENoYW5nZXMgPVxuICAgICAgSlNPTi5zdHJpbmdpZnkodjEuZ3JpZCkgIT09IEpTT04uc3RyaW5naWZ5KHYyLmdyaWQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGhhc0xheW91dENoYW5nZXMsXG4gICAgICBoYXNHcmlkQ2hhbmdlcyxcbiAgICAgIGFkZGVkQ29tcG9uZW50SWRzLFxuICAgICAgcmVtb3ZlZENvbXBvbmVudElkcyxcbiAgICAgIG1vZGlmaWVkQ29tcG9uZW50SWRzLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,102 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { ReportDefinitionError } from '../../../core/errors/reporting-errors';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Pure function that validates the integrity and constraints of a ReportDefinition.
6
+ *
7
+ * Checks:
8
+ * - ID and Name presence
9
+ * - Unique component IDs
10
+ * - Unique parameter/input keys
11
+ * - Grid data source references
12
+ * - Column span boundary violations
13
+ */
14
+ export function validateReportSchema(definition) {
15
+ const errors = [];
16
+ const warnings = [];
17
+ if (!definition) {
18
+ return { valid: false, errors: ['Report definition is null or undefined.'], warnings: [] };
19
+ }
20
+ if (!definition.id || !definition.id.trim()) {
21
+ errors.push('Report definition missing required "id".');
22
+ }
23
+ if (!definition.name || !definition.name.trim()) {
24
+ errors.push('Report definition missing required "name".');
25
+ }
26
+ const columns = definition.layout?.columns ?? 12;
27
+ if (columns < 1 || columns > 36) {
28
+ errors.push(`Invalid layout columns count: ${columns}. Must be between 1 and 36.`);
29
+ }
30
+ // Verify component IDs and keys
31
+ const componentIds = new Set();
32
+ const componentKeys = new Set();
33
+ for (const comp of definition.components ?? []) {
34
+ if (!comp.id) {
35
+ errors.push('Encountered component missing unique "id".');
36
+ }
37
+ else if (componentIds.has(comp.id)) {
38
+ errors.push(`Duplicate component ID found: "${comp.id}".`);
39
+ }
40
+ else {
41
+ componentIds.add(comp.id);
42
+ }
43
+ if (comp.key) {
44
+ if (componentKeys.has(comp.key)) {
45
+ errors.push(`Duplicate form field key found: "${comp.key}".`);
46
+ }
47
+ else {
48
+ componentKeys.add(comp.key);
49
+ }
50
+ }
51
+ else if (comp.type !== 'button' && comp.type !== 'display') {
52
+ warnings.push(`Input component "${comp.id}" (${comp.type}) has no "key" defined for form binding.`);
53
+ }
54
+ if (comp.layout?.columnSpan && comp.layout.columnSpan > columns) {
55
+ warnings.push(`Component "${comp.id}" columnSpan (${comp.layout.columnSpan}) exceeds page total columns (${columns}).`);
56
+ }
57
+ }
58
+ // Verify grid & data source integrity
59
+ if (definition.grid) {
60
+ const dsId = definition.grid.dataSourceId;
61
+ const dsExists = (definition.dataSources ?? []).some((ds) => ds.id === dsId);
62
+ if (!dsExists) {
63
+ errors.push(`Grid references dataSourceId "${dsId}", but no matching data source was found.`);
64
+ }
65
+ if (!definition.grid.columns || definition.grid.columns.length === 0) {
66
+ warnings.push('Grid definition has no columns configured.');
67
+ }
68
+ }
69
+ return {
70
+ valid: errors.length === 0,
71
+ errors,
72
+ warnings,
73
+ };
74
+ }
75
+ /**
76
+ * SchemaValidatorService provides schema verification methods.
77
+ */
78
+ export class SchemaValidatorService {
79
+ /**
80
+ * Validates a report definition and returns errors/warnings without throwing.
81
+ */
82
+ validate(definition) {
83
+ return validateReportSchema(definition);
84
+ }
85
+ /**
86
+ * Asserts that a report definition is valid.
87
+ * Throws `ReportDefinitionError` if any validation error is detected.
88
+ */
89
+ assertValid(definition) {
90
+ const result = this.validate(definition);
91
+ if (!result.valid) {
92
+ throw new ReportDefinitionError(result.errors.join('; '), definition?.id);
93
+ }
94
+ }
95
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SchemaValidatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
96
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SchemaValidatorService, providedIn: 'root' });
97
+ }
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SchemaValidatorService, decorators: [{
99
+ type: Injectable,
100
+ args: [{ providedIn: 'root' }]
101
+ }] });
102
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLXZhbGlkYXRvci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvZmVhdHVyZXMvcGVyc2lzdGVuY2Uvc2VydmljZXMvc2NoZW1hLXZhbGlkYXRvci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7O0FBUTlFOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxVQUE0QjtJQUMvRCxNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7SUFDNUIsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO0lBRTlCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNoQixPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQyx5Q0FBeUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQztJQUM3RixDQUFDO0lBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7UUFDNUMsTUFBTSxDQUFDLElBQUksQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFRCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztRQUNoRCxNQUFNLENBQUMsSUFBSSxDQUFDLDRDQUE0QyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUNqRCxJQUFJLE9BQU8sR0FBRyxDQUFD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SUFDakM7O09BRUc7SUFDSCxRQUFRLENBQUMsVUFBNEI7UUFDbkMsT0FBTyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsV0FBVyxDQUFDLFVBQTRCO1FBQ3RDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNsQixNQUFNLElBQUkscUJBQXFCLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzVFLENBQUM7SUFDSCxDQUFDO3dHQWpCVSxzQkFBc0I7NEdBQXRCLHNCQUFzQixjQURULE1BQU07OzRGQUNuQixzQkFBc0I7a0JBRGxDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVwb3J0RGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uLy4uL2NvcmUvbW9kZWxzL3JlcG9ydC1kZWZpbml0aW9uLm1vZGVsJztcbmltcG9ydCB7IFJlcG9ydERlZmluaXRpb25FcnJvciB9IGZyb20gJy4uLy4uLy4uL2NvcmUvZXJyb3JzL3JlcG9ydGluZy1lcnJvcnMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNjaGVtYVZhbGlkYXRpb25SZXN1bHQge1xuICB2YWxpZDogYm9vbGVhbjtcbiAgZXJyb3JzOiBzdHJpbmdbXTtcbiAgd2FybmluZ3M6IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFB1cmUgZnVuY3Rpb24gdGhhdCB2YWxpZGF0ZXMgdGhlIGludGVncml0eSBhbmQgY29uc3RyYWludHMgb2YgYSBSZXBvcnREZWZpbml0aW9uLlxuICpcbiAqIENoZWNrczpcbiAqIC0gSUQgYW5kIE5hbWUgcHJlc2VuY2VcbiAqIC0gVW5pcXVlIGNvbXBvbmVudCBJRHNcbiAqIC0gVW5pcXVlIHBhcmFtZXRlci9pbnB1dCBrZXlzXG4gKiAtIEdyaWQgZGF0YSBzb3VyY2UgcmVmZXJlbmNlc1xuICogLSBDb2x1bW4gc3BhbiBib3VuZGFyeSB2aW9sYXRpb25zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVJlcG9ydFNjaGVtYShkZWZpbml0aW9uOiBSZXBvcnREZWZpbml0aW9uKTogU2NoZW1hVmFsaWRhdGlvblJlc3VsdCB7XG4gIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKCFkZWZpbml0aW9uKSB7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlLCBlcnJvcnM6IFsnUmVwb3J0IGRlZmluaXRpb24gaXMgbnVsbCBvciB1bmRlZmluZWQuJ10sIHdhcm5pbmdzOiBbXSB9O1xuICB9XG5cbiAgaWYgKCFkZWZpbml0aW9uLmlkIHx8ICFkZWZpbml0aW9uLmlkLnRyaW0oKSkge1xuICAgIGVycm9ycy5wdXNoKCdSZXBvcnQgZGVmaW5pdGlvbiBtaXNzaW5nIHJlcXVpcmVkIFwiaWRcIi4nKTtcbiAgfVxuXG4gIGlmICghZGVmaW5pdGlvbi5uYW1lIHx8ICFkZWZpbml0aW9uLm5hbWUudHJpbSgpKSB7XG4gICAgZXJyb3JzLnB1c2goJ1JlcG9ydCBkZWZpbml0aW9uIG1pc3NpbmcgcmVxdWlyZWQgXCJuYW1lXCIuJyk7XG4gIH1cblxuICBjb25zdCBjb2x1bW5zID0gZGVmaW5pdGlvbi5sYXlvdXQ/LmNvbHVtbnMgPz8gMTI7XG4gIGlmIChjb2x1bW5zIDwgMSB8fCBjb2x1bW5zID4gMzYpIHtcbiAgICBlcnJvcnMucHVzaChgSW52YWxpZCBsYXlvdXQgY29sdW1ucyBjb3VudDogJHtjb2x1bW5zfS4gTXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDM2LmApO1xuICB9XG5cbiAgLy8gVmVyaWZ5IGNvbXBvbmVudCBJRHMgYW5kIGtleXNcbiAgY29uc3QgY29tcG9uZW50SWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGNvbnN0IGNvbXBvbmVudEtleXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBmb3IgKGNvbnN0IGNvbXAgb2YgZGVmaW5pdGlvbi5jb21wb25lbnRzID8/IFtdKSB7XG4gICAgaWYgKCFjb21wLmlkKSB7XG4gICAgICBlcnJvcnMucHVzaCgnRW5jb3VudGVyZWQgY29tcG9uZW50IG1pc3NpbmcgdW5pcXVlIFwiaWRcIi4nKTtcbiAgICB9IGVsc2UgaWYgKGNvbXBvbmVudElkcy5oYXMoY29tcC5pZCkpIHtcbiAgICAgIGVycm9ycy5wdXNoKGBEdXBsaWNhdGUgY29tcG9uZW50IElEIGZvdW5kOiBcIiR7Y29tcC5pZH1cIi5gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tcG9uZW50SWRzLmFkZChjb21wLmlkKTtcbiAgICB9XG5cbiAgICBpZiAoY29tcC5rZXkpIHtcbiAgICAgIGlmIChjb21wb25lbnRLZXlzLmhhcyhjb21wLmtleSkpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goYER1cGxpY2F0ZSBmb3JtIGZpZWxkIGtleSBmb3VuZDogXCIke2NvbXAua2V5fVwiLmApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29tcG9uZW50S2V5cy5hZGQoY29tcC5rZXkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY29tcC50eXBlICE9PSAnYnV0dG9uJyAmJiBjb21wLnR5cGUgIT09ICdkaXNwbGF5Jykge1xuICAgICAgd2FybmluZ3MucHVzaChgSW5wdXQgY29tcG9uZW50IFwiJHtjb21wLmlkfVwiICgke2NvbXAudHlwZX0pIGhhcyBubyBcImtleVwiIGRlZmluZWQgZm9yIGZvcm0gYmluZGluZy5gKTtcbiAgICB9XG5cbiAgICBpZiAoY29tcC5sYXlvdXQ/LmNvbHVtblNwYW4gJiYgY29tcC5sYXlvdXQuY29sdW1uU3BhbiA+IGNvbHVtbnMpIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goXG4gICAgICAgIGBDb21wb25lbnQgXCIke2NvbXAuaWR9XCIgY29sdW1uU3BhbiAoJHtjb21wLmxheW91dC5jb2x1bW5TcGFufSkgZXhjZWVkcyBwYWdlIHRvdGFsIGNvbHVtbnMgKCR7Y29sdW1uc30pLmBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gVmVyaWZ5IGdyaWQgJiBkYXRhIHNvdXJjZSBpbnRlZ3JpdHlcbiAgaWYgKGRlZmluaXRpb24uZ3JpZCkge1xuICAgIGNvbnN0IGRzSWQgPSBkZWZpbml0aW9uLmdyaWQuZGF0YVNvdXJjZUlkO1xuICAgIGNvbnN0IGRzRXhpc3RzID0gKGRlZmluaXRpb24uZGF0YVNvdXJjZXMgPz8gW10pLnNvbWUoKGRzKSA9PiBkcy5pZCA9PT0gZHNJZCk7XG5cbiAgICBpZiAoIWRzRXhpc3RzKSB7XG4gICAgICBlcnJvcnMucHVzaChgR3JpZCByZWZlcmVuY2VzIGRhdGFTb3VyY2VJZCBcIiR7ZHNJZH1cIiwgYnV0IG5vIG1hdGNoaW5nIGRhdGEgc291cmNlIHdhcyBmb3VuZC5gKTtcbiAgICB9XG5cbiAgICBpZiAoIWRlZmluaXRpb24uZ3JpZC5jb2x1bW5zIHx8IGRlZmluaXRpb24uZ3JpZC5jb2x1bW5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgd2FybmluZ3MucHVzaCgnR3JpZCBkZWZpbml0aW9uIGhhcyBubyBjb2x1bW5zIGNvbmZpZ3VyZWQuJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB2YWxpZDogZXJyb3JzLmxlbmd0aCA9PT0gMCxcbiAgICBlcnJvcnMsXG4gICAgd2FybmluZ3MsXG4gIH07XG59XG5cbi8qKlxuICogU2NoZW1hVmFsaWRhdG9yU2VydmljZSBwcm92aWRlcyBzY2hlbWEgdmVyaWZpY2F0aW9uIG1ldGhvZHMuXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgU2NoZW1hVmFsaWRhdG9yU2VydmljZSB7XG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYSByZXBvcnQgZGVmaW5pdGlvbiBhbmQgcmV0dXJucyBlcnJvcnMvd2FybmluZ3Mgd2l0aG91dCB0aHJvd2luZy5cbiAgICovXG4gIHZhbGlkYXRlKGRlZmluaXRpb246IFJlcG9ydERlZmluaXRpb24pOiBTY2hlbWFWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICByZXR1cm4gdmFsaWRhdGVSZXBvcnRTY2hlbWEoZGVmaW5pdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQXNzZXJ0cyB0aGF0IGEgcmVwb3J0IGRlZmluaXRpb24gaXMgdmFsaWQuXG4gICAqIFRocm93cyBgUmVwb3J0RGVmaW5pdGlvbkVycm9yYCBpZiBhbnkgdmFsaWRhdGlvbiBlcnJvciBpcyBkZXRlY3RlZC5cbiAgICovXG4gIGFzc2VydFZhbGlkKGRlZmluaXRpb246IFJlcG9ydERlZmluaXRpb24pOiB2b2lkIHtcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLnZhbGlkYXRlKGRlZmluaXRpb24pO1xuICAgIGlmICghcmVzdWx0LnZhbGlkKSB7XG4gICAgICB0aHJvdyBuZXcgUmVwb3J0RGVmaW5pdGlvbkVycm9yKHJlc3VsdC5lcnJvcnMuam9pbignOyAnKSwgZGVmaW5pdGlvbj8uaWQpO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,156 @@
1
+ import { ChangeDetectionStrategy, Component, DestroyRef, inject, signal } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { ActivatedRoute, Router } from '@angular/router';
4
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import { ReportStoreService } from '../../persistence/services/report-store.service';
6
+ import { DesignerComponent } from '../../designer/designer.component';
7
+ import { RptIconComponent } from '../../../primitives/components/icon/rpt-icon.component';
8
+ import * as i0 from "@angular/core";
9
+ export class RoutedReportDesignerComponent {
10
+ route = inject(ActivatedRoute);
11
+ router = inject(Router);
12
+ store = inject(ReportStoreService);
13
+ destroyRef = inject(DestroyRef);
14
+ report = signal(null);
15
+ loading = signal(true);
16
+ savedFeedback = signal(false);
17
+ ngOnInit() {
18
+ const reportId = this.route.snapshot.paramMap.get('reportId');
19
+ if (!reportId || reportId === 'new') {
20
+ // Create blank report
21
+ this.report.set(this.createBlankReport());
22
+ this.loading.set(false);
23
+ return;
24
+ }
25
+ this.store.loadReport(reportId)
26
+ .pipe(takeUntilDestroyed(this.destroyRef))
27
+ .subscribe({
28
+ next: (rep) => {
29
+ this.report.set(rep ?? this.createBlankReport());
30
+ this.loading.set(false);
31
+ },
32
+ error: () => {
33
+ this.report.set(this.createBlankReport());
34
+ this.loading.set(false);
35
+ }
36
+ });
37
+ }
38
+ onSaveReport(updatedReport) {
39
+ this.store.saveReport(updatedReport)
40
+ .pipe(takeUntilDestroyed(this.destroyRef))
41
+ .subscribe({
42
+ next: () => {
43
+ this.savedFeedback.set(true);
44
+ setTimeout(() => this.savedFeedback.set(false), 2500);
45
+ },
46
+ error: (err) => {
47
+ console.error('[bways-report] Save report failed:', err);
48
+ }
49
+ });
50
+ }
51
+ goBack() {
52
+ const reportId = this.route.snapshot.paramMap.get('reportId');
53
+ if (reportId && reportId !== 'new') {
54
+ this.router.navigate(['../'], { relativeTo: this.route });
55
+ }
56
+ else {
57
+ this.router.navigate(['../'], { relativeTo: this.route });
58
+ }
59
+ }
60
+ createBlankReport() {
61
+ return {
62
+ id: `report-${Date.now()}`,
63
+ name: 'Untitled Report',
64
+ description: 'Newly created report',
65
+ category: 'General',
66
+ schemaVersion: 1,
67
+ version: 1,
68
+ components: [],
69
+ parameters: [],
70
+ dataSources: [
71
+ {
72
+ id: 'ds-default',
73
+ name: 'Default Data Source',
74
+ endpoint: '/api/reports/data'
75
+ }
76
+ ],
77
+ grid: {
78
+ dataSourceId: 'ds-default',
79
+ columns: []
80
+ },
81
+ layout: {
82
+ columns: 12,
83
+ gap: 16
84
+ }
85
+ };
86
+ }
87
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RoutedReportDesignerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
88
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: RoutedReportDesignerComponent, isStandalone: true, selector: "rpt-routed-designer", ngImport: i0, template: `
89
+ <div class="rpt-routed-designer-host">
90
+ @if (loading()) {
91
+ <div class="rpt-routed-loading">
92
+ <div class="rpt-spinner"></div>
93
+ <p>Loading report designer...</p>
94
+ </div>
95
+ } @else {
96
+ <div class="rpt-routed-designer-bar">
97
+ <button
98
+ type="button"
99
+ class="rpt-btn rpt-btn-ghost rpt-btn-sm"
100
+ (click)="goBack()"
101
+ title="Return to report view"
102
+ >
103
+ <rpt-icon name="arrow-left" [size]="14" />
104
+ <span>Exit Designer</span>
105
+ </button>
106
+ @if (savedFeedback()) {
107
+ <span class="rpt-saved-pill">
108
+ <rpt-icon name="check" [size]="14" />
109
+ <span>Saved successfully</span>
110
+ </span>
111
+ }
112
+ </div>
113
+ <rpt-designer
114
+ [initialReport]="report()"
115
+ (save)="onSaveReport($event)"
116
+ />
117
+ }
118
+ </div>
119
+ `, isInline: true, styles: [".rpt-routed-designer-host{display:flex;flex-direction:column;height:100%;min-height:calc(100vh - 80px);box-sizing:border-box}.rpt-routed-designer-bar{display:flex;align-items:center;justify-content:space-between;padding:6px 16px;background:var(--rpt-surface-bg, #ffffff);border-bottom:1px solid var(--rpt-border-color, #e2e8f0)}.rpt-saved-pill{display:inline-flex;align-items:center;gap:5px;font-size:.8125rem;color:#166534;background:#dcfce7;padding:3px 10px;border-radius:9999px;font-weight:500;animation:rptFadeInOut 2.5s ease-in-out forwards}@keyframes rptFadeInOut{0%{opacity:0;transform:translateY(-4px)}15%{opacity:1;transform:translateY(0)}85%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-4px)}}.rpt-routed-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;height:300px;color:var(--rpt-text-muted, #64748b)}.rpt-spinner{width:36px;height:36px;border:3px solid var(--rpt-border-color, #e2e8f0);border-top-color:var(--rpt-primary, #2563eb);border-radius:50%;animation:rpt-spin .8s linear infinite;margin-bottom:12px}@keyframes rpt-spin{to{transform:rotate(360deg)}}.rpt-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:6px 12px;font-size:.8125rem;font-weight:500;border-radius:var(--rpt-radius-md, 6px);cursor:pointer;border:1px solid transparent;background:transparent;color:var(--rpt-text-muted, #64748b);transition:all .15s ease}.rpt-btn:hover{color:var(--rpt-text-color, #1e293b);background:var(--rpt-bg-subtle, #f1f5f9)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DesignerComponent, selector: "rpt-designer", inputs: ["reportId", "initialReport"], outputs: ["save", "definitionChange"] }, { kind: "component", type: RptIconComponent, selector: "rpt-icon", inputs: ["name", "size", "color", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
120
+ }
121
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RoutedReportDesignerComponent, decorators: [{
122
+ type: Component,
123
+ args: [{ selector: 'rpt-routed-designer', standalone: true, imports: [CommonModule, DesignerComponent, RptIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
124
+ <div class="rpt-routed-designer-host">
125
+ @if (loading()) {
126
+ <div class="rpt-routed-loading">
127
+ <div class="rpt-spinner"></div>
128
+ <p>Loading report designer...</p>
129
+ </div>
130
+ } @else {
131
+ <div class="rpt-routed-designer-bar">
132
+ <button
133
+ type="button"
134
+ class="rpt-btn rpt-btn-ghost rpt-btn-sm"
135
+ (click)="goBack()"
136
+ title="Return to report view"
137
+ >
138
+ <rpt-icon name="arrow-left" [size]="14" />
139
+ <span>Exit Designer</span>
140
+ </button>
141
+ @if (savedFeedback()) {
142
+ <span class="rpt-saved-pill">
143
+ <rpt-icon name="check" [size]="14" />
144
+ <span>Saved successfully</span>
145
+ </span>
146
+ }
147
+ </div>
148
+ <rpt-designer
149
+ [initialReport]="report()"
150
+ (save)="onSaveReport($event)"
151
+ />
152
+ }
153
+ </div>
154
+ `, styles: [".rpt-routed-designer-host{display:flex;flex-direction:column;height:100%;min-height:calc(100vh - 80px);box-sizing:border-box}.rpt-routed-designer-bar{display:flex;align-items:center;justify-content:space-between;padding:6px 16px;background:var(--rpt-surface-bg, #ffffff);border-bottom:1px solid var(--rpt-border-color, #e2e8f0)}.rpt-saved-pill{display:inline-flex;align-items:center;gap:5px;font-size:.8125rem;color:#166534;background:#dcfce7;padding:3px 10px;border-radius:9999px;font-weight:500;animation:rptFadeInOut 2.5s ease-in-out forwards}@keyframes rptFadeInOut{0%{opacity:0;transform:translateY(-4px)}15%{opacity:1;transform:translateY(0)}85%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-4px)}}.rpt-routed-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;height:300px;color:var(--rpt-text-muted, #64748b)}.rpt-spinner{width:36px;height:36px;border:3px solid var(--rpt-border-color, #e2e8f0);border-top-color:var(--rpt-primary, #2563eb);border-radius:50%;animation:rpt-spin .8s linear infinite;margin-bottom:12px}@keyframes rpt-spin{to{transform:rotate(360deg)}}.rpt-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:6px 12px;font-size:.8125rem;font-weight:500;border-radius:var(--rpt-radius-md, 6px);cursor:pointer;border:1px solid transparent;background:transparent;color:var(--rpt-text-muted, #64748b);transition:all .15s ease}.rpt-btn:hover{color:var(--rpt-text-color, #1e293b);background:var(--rpt-bg-subtle, #f1f5f9)}\n"] }]
155
+ }] });
156
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVkLXJlcG9ydC1kZXNpZ25lci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9yb3V0aW5nL2NvbXBvbmVudHMvcm91dGVkLXJlcG9ydC1kZXNpZ25lci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsVUFBVSxFQUVWLE1BQU0sRUFDTixNQUFNLEVBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDekQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFaEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0saURBQWlELENBQUM7QUFDckYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0RBQXdELENBQUM7O0FBMkgxRixNQUFNLE9BQU8sNkJBQTZCO0lBQ3ZCLEtBQUssR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDL0IsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN4QixLQUFLLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDbkMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUV4QyxNQUFNLEdBQUcsTUFBTSxDQUEwQixJQUFJLENBQUMsQ0FBQztJQUMvQyxPQUFPLEdBQUcsTUFBTSxDQUFVLElBQUksQ0FBQyxDQUFDO0lBQ2hDLGFBQWEsR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7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LEVBQUUsRUFBRTtZQUNkLFdBQVcsRUFBRTtnQkFDWDtvQkFDRSxFQUFFLEVBQUUsWUFBWTtvQkFDaEIsSUFBSSxFQUFFLHFCQUFxQjtvQkFDM0IsUUFBUSxFQUFFLG1CQUFtQjtpQkFDOUI7YUFDRjtZQUNELElBQUksRUFBRTtnQkFDSixZQUFZLEVBQUUsWUFBWTtnQkFDMUIsT0FBTyxFQUFFLEVBQUU7YUFDWjtZQUNELE1BQU0sRUFBRTtnQkFDTixPQUFPLEVBQUUsRUFBRTtnQkFDWCxHQUFHLEVBQUUsRUFBRTthQUNSO1NBQ0YsQ0FBQztJQUNKLENBQUM7d0dBbkZVLDZCQUE2Qjs0RkFBN0IsNkJBQTZCLCtFQW5IOUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0ErQlQsOGpEQWpDUyxZQUFZLCtCQUFFLGlCQUFpQix1SUFBRSxnQkFBZ0I7OzRGQXFIaEQsNkJBQTZCO2tCQXhIekMsU0FBUzsrQkFDRSxxQkFBcUIsY0FDbkIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixDQUFDLG1CQUMzQyx1QkFBdUIsQ0FBQyxNQUFNLFlBQ3JDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBK0JUIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRGVzdHJveVJlZixcbiAgT25Jbml0LFxuICBpbmplY3QsXG4gIHNpZ25hbFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IFJlcG9ydERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi9jb3JlL21vZGVscyc7XG5pbXBvcnQgeyBSZXBvcnRTdG9yZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9wZXJzaXN0ZW5jZS9zZXJ2aWNlcy9yZXBvcnQtc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgeyBEZXNpZ25lckNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2Rlc2lnbmVyL2Rlc2lnbmVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBScHRJY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vcHJpbWl0aXZlcy9jb21wb25lbnRzL2ljb24vcnB0LWljb24uY29tcG9uZW50JztcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdycHQtcm91dGVkLWRlc2lnbmVyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRGVzaWduZXJDb21wb25lbnQsIFJwdEljb25Db21wb25lbnRdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwicnB0LXJvdXRlZC1kZXNpZ25lci1ob3N0XCI+XG4gICAgICBAaWYgKGxvYWRpbmcoKSkge1xuICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXJvdXRlZC1sb2FkaW5nXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInJwdC1zcGlubmVyXCI+PC9kaXY+XG4gICAgICAgICAgPHA+TG9hZGluZyByZXBvcnQgZGVzaWduZXIuLi48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgfSBAZWxzZSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJycHQtcm91dGVkLWRlc2lnbmVyLWJhclwiPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJycHQtYnRuIHJwdC1idG4tZ2hvc3QgcnB0LWJ0bi1zbVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiZ29CYWNrKClcIlxuICAgICAgICAgICAgdGl0bGU9XCJSZXR1cm4gdG8gcmVwb3J0IHZpZXdcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiYXJyb3ctbGVmdFwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgIDxzcGFuPkV4aXQgRGVzaWduZXI8L3NwYW4+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgQGlmIChzYXZlZEZlZWRiYWNrKCkpIHtcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicnB0LXNhdmVkLXBpbGxcIj5cbiAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjaGVja1wiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgPHNwYW4+U2F2ZWQgc3VjY2Vzc2Z1bGx5PC9zcGFuPlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxycHQtZGVzaWduZXJcbiAgICAgICAgICBbaW5pdGlhbFJlcG9ydF09XCJyZXBvcnQoKVwiXG4gICAgICAgICAgKHNhdmUpPVwib25TYXZlUmVwb3J0KCRldmVudClcIlxuICAgICAgICAvPlxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZXM6IFtgXG4gICAgLnJwdC1yb3V0ZWQtZGVzaWduZXItaG9zdCB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgIG1pbi1oZWlnaHQ6IGNhbGMoMTAwdmggLSA4MHB4KTtcbiAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgfVxuXG4gICAgLnJwdC1yb3V0ZWQtZGVzaWduZXItYmFyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgcGFkZGluZzogNnB4IDE2cHg7XG4gICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1ycHQtc3VyZmFjZS1iZywgI2ZmZmZmZik7XG4gICAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tcnB0LWJvcmRlci1jb2xvciwgI2UyZThmMCk7XG4gICAgfVxuXG4gICAgLnJwdC1zYXZlZC1waWxsIHtcbiAgICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGdhcDogNXB4O1xuICAgICAgZm9udC1zaXplOiAwLjgxMjVyZW07XG4gICAgICBjb2xvcjogIzE2NjUzNDtcbiAgICAgIGJhY2tncm91bmQ6ICNkY2ZjZTc7XG4gICAgICBwYWRkaW5nOiAzcHggMTBweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDk5OTlweDtcbiAgICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgICBhbmltYXRpb246IHJwdEZhZGVJbk91dCAyLjVzIGVhc2UtaW4tb3V0IGZvcndhcmRzO1xuICAgIH1cblxuICAgIEBrZXlmcmFtZXMgcnB0RmFkZUluT3V0IHtcbiAgICAgIDAlIHsgb3BhY2l0eTogMDsgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC00cHgpOyB9XG4gICAgICAxNSUgeyBvcGFjaXR5OiAxOyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMCk7IH1cbiAgICAgIDg1JSB7IG9wYWNpdHk6IDE7IHRyYW5zZm9ybTogdHJhbnNsYXRlWSgwKTsgfVxuICAgICAgMTAwJSB7IG9wYWNpdHk6IDA7IHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNHB4KTsgfVxuICAgIH1cblxuICAgIC5ycHQtcm91dGVkLWxvYWRpbmcge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICBoZWlnaHQ6IDMwMHB4O1xuICAgICAgY29sb3I6IHZhcigtLXJwdC10ZXh0LW11dGVkLCAjNjQ3NDhiKTtcbiAgICB9XG5cbiAgICAucnB0LXNwaW5uZXIge1xuICAgICAgd2lkdGg6IDM2cHg7XG4gICAgICBoZWlnaHQ6IDM2cHg7XG4gICAgICBib3JkZXI6IDNweCBzb2xpZCB2YXIoLS1ycHQtYm9yZGVyLWNvbG9yLCAjZTJlOGYwKTtcbiAgICAgIGJvcmRlci10b3AtY29sb3I6IHZhcigtLXJwdC1wcmltYXJ5LCAjMjU2M2ViKTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICAgIGFuaW1hdGlvbjogcnB0LXNwaW4gMC44cyBsaW5lYXIgaW5maW5pdGU7XG4gICAgICBtYXJnaW4tYm90dG9tOiAxMnB4O1xuICAgIH1cblxuICAgIEBrZXlmcmFtZXMgcnB0LXNwaW4ge1xuICAgICAgdG8geyB0cmFuc2Zvcm06IHJvdGF0ZSgzNjBkZWcpOyB9XG4gICAgfVxuXG4gICAgLnJwdC1idG4ge1xuICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICBnYXA6IDZweDtcbiAgICAgIHBhZGRpbmc6IDZweCAxMnB4O1xuICAgICAgZm9udC1zaXplOiAwLjgxMjVyZW07XG4gICAgICBmb250LXdlaWdodDogNTAwO1xuICAgICAgYm9yZGVyLXJhZGl1czogdmFyKC0tcnB0LXJhZGl1cy1tZCwgNnB4KTtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICBjb2xvcjogdmFyKC0tcnB0LXRleHQtbXV0ZWQsICM2NDc0OGIpO1xuICAgICAgdHJhbnNpdGlvbjogYWxsIDAuMTVzIGVhc2U7XG4gICAgfVxuXG4gICAgLnJwdC1idG46aG92ZXIge1xuICAgICAgY29sb3I6IHZhcigtLXJwdC10ZXh0LWNvbG9yLCAjMWUyOTNiKTtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLXJwdC1iZy1zdWJ0bGUsICNmMWY1ZjkpO1xuICAgIH1cbiAgYF1cbn0pXG5leHBvcnQgY2xhc3MgUm91dGVkUmVwb3J0RGVzaWduZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlID0gaW5qZWN0KEFjdGl2YXRlZFJvdXRlKTtcbiAgcHJpdmF0ZSByZWFkb25seSByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzdG9yZSA9IGluamVjdChSZXBvcnRTdG9yZVNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cbiAgcmVhZG9ubHkgcmVwb3J0ID0gc2lnbmFsPFJlcG9ydERlZmluaXRpb24gfCBudWxsPihudWxsKTtcbiAgcmVhZG9ubHkgbG9hZGluZyA9IHNpZ25hbDxib29sZWFuPih0cnVlKTtcbiAgcmVhZG9ubHkgc2F2ZWRGZWVkYmFjayA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgY29uc3QgcmVwb3J0SWQgPSB0aGlzLnJvdXRlLnNuYXBzaG90LnBhcmFtTWFwLmdldCgncmVwb3J0SWQnKTtcblxuICAgIGlmICghcmVwb3J0SWQgfHwgcmVwb3J0SWQgPT09ICduZXcnKSB7XG4gICAgICAvLyBDcmVhdGUgYmxhbmsgcmVwb3J0XG4gICAgICB0aGlzLnJlcG9ydC5zZXQodGhpcy5jcmVhdGVCbGFua1JlcG9ydCgpKTtcbiAgICAgIHRoaXMubG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc3RvcmUubG9hZFJlcG9ydChyZXBvcnRJZClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXApID0+IHtcbiAgICAgICAgICB0aGlzLnJlcG9ydC5zZXQocmVwID8/IHRoaXMuY3JlYXRlQmxhbmtSZXBvcnQoKSk7XG4gICAgICAgICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5yZXBvcnQuc2V0KHRoaXMuY3JlYXRlQmxhbmtSZXBvcnQoKSk7XG4gICAgICAgICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgb25TYXZlUmVwb3J0KHVwZGF0ZWRSZXBvcnQ6IFJlcG9ydERlZmluaXRpb24pOiB2b2lkIHtcbiAgICB0aGlzLnN0b3JlLnNhdmVSZXBvcnQodXBkYXRlZFJlcG9ydClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLnNhdmVkRmVlZGJhY2suc2V0KHRydWUpO1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zYXZlZEZlZWRiYWNrLnNldChmYWxzZSksIDI1MDApO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tid2F5cy1yZXBvcnRdIFNhdmUgcmVwb3J0IGZhaWxlZDonLCBlcnIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIGdvQmFjaygpOiB2b2lkIHtcbiAgICBjb25zdCByZXBvcnRJZCA9IHRoaXMucm91dGUuc25hcHNob3QucGFyYW1NYXAuZ2V0KCdyZXBvcnRJZCcpO1xuICAgIGlmIChyZXBvcnRJZCAmJiByZXBvcnRJZCAhPT0gJ25ldycpIHtcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnLi4vJ10sIHsgcmVsYXRpdmVUbzogdGhpcy5yb3V0ZSB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycuLi8nXSwgeyByZWxhdGl2ZVRvOiB0aGlzLnJvdXRlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQmxhbmtSZXBvcnQoKTogUmVwb3J0RGVmaW5pdGlvbiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBgcmVwb3J0LSR7RGF0ZS5ub3coKX1gLFxuICAgICAgbmFtZTogJ1VudGl0bGVkIFJlcG9ydCcsXG4gICAgICBkZXNjcmlwdGlvbjogJ05ld2x5IGNyZWF0ZWQgcmVwb3J0JyxcbiAgICAgIGNhdGVnb3J5OiAnR2VuZXJhbCcsXG4gICAgICBzY2hlbWFWZXJzaW9uOiAxLFxuICAgICAgdmVyc2lvbjogMSxcbiAgICAgIGNvbXBvbmVudHM6IFtdLFxuICAgICAgcGFyYW1ldGVyczogW10sXG4gICAgICBkYXRhU291cmNlczogW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICdkcy1kZWZhdWx0JyxcbiAgICAgICAgICBuYW1lOiAnRGVmYXVsdCBEYXRhIFNvdXJjZScsXG4gICAgICAgICAgZW5kcG9pbnQ6ICcvYXBpL3JlcG9ydHMvZGF0YSdcbiAgICAgICAgfVxuICAgICAgXSxcbiAgICAgIGdyaWQ6IHtcbiAgICAgICAgZGF0YVNvdXJjZUlkOiAnZHMtZGVmYXVsdCcsXG4gICAgICAgIGNvbHVtbnM6IFtdXG4gICAgICB9LFxuICAgICAgbGF5b3V0OiB7XG4gICAgICAgIGNvbHVtbnM6IDEyLFxuICAgICAgICBnYXA6IDE2XG4gICAgICB9XG4gICAgfTtcbiAgfVxufVxuXG5cbiJdfQ==