bways-report 0.1.9 → 0.2.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 (93) hide show
  1. package/README.md +463 -316
  2. package/esm2022/lib/core/config/bways-report-config.mjs +29 -32
  3. package/esm2022/lib/core/models/report-datasource.model.mjs +1 -1
  4. package/esm2022/lib/core/services/report-api-execution.service.mjs +33 -11
  5. package/esm2022/lib/core/services/report-session-context.service.mjs +72 -3
  6. package/esm2022/lib/core/tokens/designer-config.token.mjs +4 -0
  7. package/esm2022/lib/core/tokens/reporting-config.token.mjs +1 -1
  8. package/esm2022/lib/core/utils/report-endpoint.util.mjs +22 -0
  9. package/esm2022/lib/core/utils/report-request-scope.mjs +48 -0
  10. package/esm2022/lib/data-access/adapters/endpoint-datasource.adapter.mjs +8 -1
  11. package/esm2022/lib/data-access/adapters/endpoint-lookup.adapter.mjs +5 -2
  12. package/esm2022/lib/data-access/adapters/endpoint-masterdata.adapter.mjs +5 -2
  13. package/esm2022/lib/data-access/adapters/endpoint-persistence.adapter.mjs +30 -14
  14. package/esm2022/lib/data-access/adapters/endpoint-schema-discovery.adapter.mjs +32 -28
  15. package/esm2022/lib/data-access/adapters/endpoint-tokens.mjs +1 -1
  16. package/esm2022/lib/data-access/adapters/http-datasource.adapter.mjs +4 -37
  17. package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +4 -50
  18. package/esm2022/lib/data-access/adapters/http-persistence.adapter.mjs +43 -194
  19. package/esm2022/lib/data-access/adapters/http-schema-discovery.adapter.mjs +17 -65
  20. package/esm2022/lib/data-access/adapters/index.mjs +1 -1
  21. package/esm2022/lib/data-access/adapters/local-storage-persistence.adapter.mjs +13 -4
  22. package/esm2022/lib/data-access/adapters/report-id-availability.mjs +20 -0
  23. package/esm2022/lib/data-access/adapters/session-headers.mjs +11 -0
  24. package/esm2022/lib/data-access/contracts/index.mjs +1 -1
  25. package/esm2022/lib/data-access/contracts/report-persistence.contract.mjs +13 -1
  26. package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +50 -40
  27. package/esm2022/lib/features/designer/components/dialogs/report-saved-dialog.component.mjs +546 -119
  28. package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +12 -6
  29. package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +9 -8
  30. package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +9 -4
  31. package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +54 -32
  32. package/esm2022/lib/features/designer/designer.component.mjs +100 -67
  33. package/esm2022/lib/features/designer/rpt-report-designer.component.mjs +10 -4
  34. package/esm2022/lib/features/designer/services/designer-config.service.mjs +56 -0
  35. package/esm2022/lib/features/designer/services/designer-endpoints.service.mjs +155 -0
  36. package/esm2022/lib/features/designer/services/designer-state.service.mjs +3 -2
  37. package/esm2022/lib/features/embed/bways-report-builder.component.mjs +3 -3
  38. package/esm2022/lib/features/export/services/report-export.service.mjs +11 -6
  39. package/esm2022/lib/features/persistence/services/report-store.service.mjs +78 -23
  40. package/esm2022/lib/features/persistence/services/schema-validator.service.mjs +59 -3
  41. package/esm2022/lib/features/routing/components/routed-report-designer.component.mjs +12 -17
  42. package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +5 -3
  43. package/esm2022/lib/features/routing/report-routes.mjs +6 -6
  44. package/esm2022/lib/features/routing/resolvers/report-route-identifier.mjs +5 -0
  45. package/esm2022/lib/features/routing/resolvers/report.resolver.mjs +3 -2
  46. package/esm2022/lib/features/runtime/report-execution.service.mjs +18 -5
  47. package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +4 -2
  48. package/esm2022/lib/features/runtime/report-runtime.component.mjs +94 -71
  49. package/esm2022/lib/features/runtime/rpt-report.component.mjs +49 -41
  50. package/esm2022/lib/primitives/components/chart-bridge/report-chart-bridge.component.mjs +7 -2
  51. package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +13 -1
  52. package/esm2022/lib/provide-reporting.mjs +9 -29
  53. package/fesm2022/bways-report.mjs +1789 -1041
  54. package/fesm2022/bways-report.mjs.map +1 -1
  55. package/lib/core/config/bways-report-config.d.ts +14 -5
  56. package/lib/core/models/report-datasource.model.d.ts +5 -0
  57. package/lib/core/services/report-session-context.service.d.ts +9 -0
  58. package/lib/core/tokens/designer-config.token.d.ts +4 -0
  59. package/lib/core/tokens/reporting-config.token.d.ts +4 -0
  60. package/lib/core/utils/report-endpoint.util.d.ts +12 -0
  61. package/lib/core/utils/report-request-scope.d.ts +14 -0
  62. package/lib/data-access/adapters/endpoint-persistence.adapter.d.ts +6 -2
  63. package/lib/data-access/adapters/endpoint-schema-discovery.adapter.d.ts +4 -2
  64. package/lib/data-access/adapters/endpoint-tokens.d.ts +4 -0
  65. package/lib/data-access/adapters/http-datasource.adapter.d.ts +1 -3
  66. package/lib/data-access/adapters/http-lookup.adapter.d.ts +1 -3
  67. package/lib/data-access/adapters/http-persistence.adapter.d.ts +11 -16
  68. package/lib/data-access/adapters/http-schema-discovery.adapter.d.ts +3 -5
  69. package/lib/data-access/adapters/index.d.ts +1 -1
  70. package/lib/data-access/adapters/local-storage-persistence.adapter.d.ts +2 -2
  71. package/lib/data-access/adapters/report-id-availability.d.ts +6 -0
  72. package/lib/data-access/adapters/session-headers.d.ts +3 -0
  73. package/lib/data-access/contracts/index.d.ts +1 -0
  74. package/lib/data-access/contracts/report-persistence.contract.d.ts +16 -1
  75. package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +2 -0
  76. package/lib/features/designer/components/dialogs/report-saved-dialog.component.d.ts +37 -5
  77. package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +4 -3
  78. package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +1 -0
  79. package/lib/features/designer/components/property-editor/property-editor.component.d.ts +1 -0
  80. package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +7 -1
  81. package/lib/features/designer/designer.component.d.ts +15 -2
  82. package/lib/features/designer/rpt-report-designer.component.d.ts +5 -1
  83. package/lib/features/designer/services/designer-config.service.d.ts +13 -0
  84. package/lib/features/designer/services/designer-endpoints.service.d.ts +25 -0
  85. package/lib/features/persistence/services/report-store.service.d.ts +15 -1
  86. package/lib/features/persistence/services/schema-validator.service.d.ts +2 -0
  87. package/lib/features/routing/resolvers/report-route-identifier.d.ts +2 -0
  88. package/lib/features/runtime/report-execution.service.d.ts +3 -0
  89. package/lib/features/runtime/report-grid-bridge.component.d.ts +1 -0
  90. package/lib/features/runtime/report-runtime.component.d.ts +1 -0
  91. package/lib/features/runtime/rpt-report.component.d.ts +5 -0
  92. package/lib/primitives/components/chart-bridge/report-chart-bridge.component.d.ts +3 -1
  93. package/package.json +2 -1
@@ -47,18 +47,18 @@ export interface BwaysReportConfig {
47
47
  * GET endpoint returning the list of stored procedures with their parameters.
48
48
  * Response: `[{ name, schema, parameters: [{ name, sqlType, required, defaultValue? }] }]`
49
49
  */
50
- spEndpoint: string;
50
+ spEndpoint?: string;
51
51
  /**
52
52
  * GET endpoint returning the list of tables/views with their columns.
53
53
  * Response: `[{ name, schema, type: 'table'|'view', columns: [{ name, sqlType }] }]`
54
54
  */
55
- tablesEndpoint: string;
55
+ tablesEndpoint?: string;
56
56
  /**
57
57
  * POST endpoint that runs a stored procedure or table query and returns rows.
58
58
  * Body: `{ kind: 'procedure'|'table', name, schema, parameters, columns?, top? }`
59
59
  * Response: `rows[]`
60
60
  */
61
- executeEndpoint: string;
61
+ executeEndpoint?: string;
62
62
  /**
63
63
  * Optional POST endpoint for fetching dropdown master data and lookup options.
64
64
  * Defaults to replacing `/execute` with `/lookup` if omitted.
@@ -66,7 +66,8 @@ export interface BwaysReportConfig {
66
66
  lookupEndpoint?: string;
67
67
  /**
68
68
  * Optional CRUD endpoint for saving/loading report page definitions.
69
- * When omitted, reports are saved to browser localStorage with a console warning.
69
+ * When omitted, uses the reporting service base inferred from the configured endpoints.
70
+ * Defaults to /api/reporting/reports; the backend stores definitions in dbo.CNFREPORTDEF.
70
71
  * - GET → list saved reports
71
72
  * - GET /:id → load a specific report
72
73
  * - POST → save a new or updated report
@@ -136,6 +137,10 @@ export interface BwaysReportConfig {
136
137
  dateFormat?: string;
137
138
  /** Timeout in ms for lookup/execute queries. @default 300000 */
138
139
  lookupTimeoutMs?: number;
140
+ /** Maximum duration of an execution request (defaults to lookupTimeoutMs). */
141
+ executionTimeoutMs?: number;
142
+ /** Exact HTTP(S) origins permitted to receive API credentials and custom headers. Same-origin is trusted by default. */
143
+ trustedApiOrigins?: string[];
139
144
  }
140
145
  /**
141
146
  * Result of normalizing a `BwaysReportConfig` for internal use.
@@ -166,9 +171,13 @@ export interface NormalizedBwaysConfig {
166
171
  defaultPageSize: number;
167
172
  dateFormat: string;
168
173
  lookupTimeoutMs: number;
174
+ /** Maximum duration of an execution request (defaults to lookupTimeoutMs). */
175
+ executionTimeoutMs?: number;
176
+ /** Exact HTTP(S) origins permitted to receive API credentials and custom headers. Same-origin is trusted by default. */
177
+ trustedApiOrigins?: string[];
169
178
  }
170
179
  /**
171
180
  * Normalizes a `BwaysReportConfig` into the internal format.
172
- * Validates required fields and maps friendly names to internal IDs.
181
+ * Validates supplied endpoints and maps friendly names to internal IDs.
173
182
  */
174
183
  export declare function normalizeBwaysConfig(config: BwaysReportConfig): NormalizedBwaysConfig;
@@ -19,6 +19,11 @@ export interface ReportDataSourceDefinition {
19
19
  method?: 'GET' | 'POST' | 'STORED_PROCEDURE' | 'CUSTOM';
20
20
  /** Database schema (defaults to 'dbo'). */
21
21
  schema?: string;
22
+ /** Optional table/view column projection and maximum result rows. */
23
+ columns?: string[];
24
+ top?: number;
25
+ /** Explicit table equality filters. Values can reference form/session tokens. */
26
+ filter?: Record<string, string | number | boolean>;
22
27
  /** Backend execution type. */
23
28
  type?: 'stored_procedure' | 'table' | 'view' | 'sql' | 'api' | string;
24
29
  /**
@@ -1,3 +1,4 @@
1
+ import { BwaysReportConfig } from '../config/bways-report-config';
1
2
  import { OnDestroy, Signal } from '@angular/core';
2
3
  import { Observable } from 'rxjs';
3
4
  import { SessionContextMap, SessionParamPrimitive } from '../tokens/session-context.token';
@@ -25,6 +26,12 @@ export interface DerivedParametersResult {
25
26
  * eliminating silent failures or thread crashes in host integrations.
26
27
  */
27
28
  export declare class ReportSessionContextService implements OnDestroy {
29
+ private readonly injector;
30
+ private readonly inheritedSession;
31
+ private readonly localReader;
32
+ private readonly localAsync;
33
+ private localCleanup?;
34
+ private configuredSource;
28
35
  private readonly rawSource;
29
36
  private readonly sessionProvider;
30
37
  private readonly reportingConfig;
@@ -46,6 +53,8 @@ export declare class ReportSessionContextService implements OnDestroy {
46
53
  readonly sessionContext$: Observable<SessionContextMap>;
47
54
  constructor();
48
55
  ngOnDestroy(): void;
56
+ /** Internal: changes only the session owned by an embedded designer. */
57
+ configureDesignerSession(config: BwaysReportConfig | null | undefined): void;
49
58
  private initSubscriptions;
50
59
  /**
51
60
  * Sets or replaces the runtime session context.
@@ -0,0 +1,4 @@
1
+ import { InjectionToken, Signal } from '@angular/core';
2
+ import { BwaysReportConfig } from '../config/bways-report-config';
3
+ /** Internal reactive configuration owned by one embedded designer. */
4
+ export declare const DESIGNER_LOCAL_CONFIG: InjectionToken<Signal<BwaysReportConfig | null>>;
@@ -23,6 +23,10 @@ export interface ReportingConfig {
23
23
  enableSchemaDiscovery?: boolean;
24
24
  /** Optional timeout in milliseconds for dropdown lookup queries (defaults to 300000ms / 5 minutes). */
25
25
  lookupTimeoutMs?: number;
26
+ /** Maximum duration of an execution request (defaults to lookupTimeoutMs). */
27
+ executionTimeoutMs?: number;
28
+ /** Exact HTTP(S) origins permitted to receive API credentials and custom headers. Same-origin is trusted by default. */
29
+ trustedApiOrigins?: string[];
26
30
  /**
27
31
  * Internal category IDs to show in the designer palette.
28
32
  * When null/undefined, all categories are shown.
@@ -0,0 +1,12 @@
1
+ interface ReportingEndpointSource {
2
+ reportsEndpoint?: string | null;
3
+ apiBaseUrl?: string | null;
4
+ executeEndpoint?: string | null;
5
+ spEndpoint?: string | null;
6
+ tablesEndpoint?: string | null;
7
+ lookupEndpoint?: string | null;
8
+ apisEndpoint?: string | null;
9
+ }
10
+ /** Built-in report storage uses the same reporting service; no separate save URL is required. */
11
+ export declare function resolveReportsEndpoint(source: ReportingEndpointSource): string;
12
+ export {};
@@ -0,0 +1,14 @@
1
+ import { Observable } from 'rxjs';
2
+ /** One owner per component. Replacing a channel cancels its previous request. */
3
+ export declare class ReportRequestScope {
4
+ private readonly session;
5
+ private readonly endpoints;
6
+ private readonly config;
7
+ private readonly active;
8
+ constructor();
9
+ context(): string;
10
+ cancel(channel: string, settle?: boolean): void;
11
+ isActive(channel: string): boolean;
12
+ cancelAll(): void;
13
+ run<T>(channel: string, factory: () => Observable<T>, next: (value: T) => void, error: (error: Error) => void, settled?: () => void): void;
14
+ }
@@ -1,12 +1,16 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { ReportDefinition, ReportSummary } from '../../core/models/report-definition.model';
3
- import { ReportPersistenceAdapter } from '../contracts/report-persistence.contract';
3
+ import { ReportPersistenceAdapter, ReportSaveOptions, ReportIdStatus } from '../contracts/report-persistence.contract';
4
4
  import * as i0 from "@angular/core";
5
5
  export declare class EndpointPersistenceAdapter extends ReportPersistenceAdapter {
6
+ private readonly session;
7
+ private get headers();
6
8
  private readonly http;
7
9
  private readonly endpoints;
10
+ checkId(reportId: string): Observable<boolean>;
11
+ inspectId(reportId: string): Observable<ReportIdStatus>;
8
12
  load(reportId: string): Observable<ReportDefinition>;
9
- save(report: ReportDefinition): Observable<ReportDefinition>;
13
+ save(report: ReportDefinition, options?: ReportSaveOptions): Observable<ReportDefinition>;
10
14
  list(): Observable<ReportSummary[]>;
11
15
  delete(reportId: string): Observable<void>;
12
16
  publish(reportId: string, version: number): Observable<void>;
@@ -7,8 +7,10 @@ export declare class EndpointSchemaDiscoveryAdapter extends ReportSchemaDiscover
7
7
  /** Cached list responses so we don't re-fetch on every getColumns/getParameters call */
8
8
  private spCache$;
9
9
  private tableCache$;
10
- private spItems;
11
- private tableItems;
10
+ private readonly session;
11
+ private spCacheKey;
12
+ private tableCacheKey;
13
+ private context;
12
14
  getEntities(types?: DatabaseEntityType[]): Observable<DatabaseEntityMetadata[]>;
13
15
  getColumns(entityName: string, schema?: string, type?: DatabaseEntityType): Observable<EntityColumnMetadata[]>;
14
16
  getParameters(entityName: string, schema?: string): Observable<ProcedureParameterMetadata[]>;
@@ -18,6 +18,10 @@ export interface BwaysReportEndpoints {
18
18
  apisEndpoint?: string | null;
19
19
  apiEndpoints?: ReportApiEndpointDefinition[];
20
20
  }
21
+ /** Per-designer URL overrides. Omitted/undefined properties inherit app defaults. */
22
+ export type BwaysReportApiUrls = {
23
+ [Key in 'spEndpoint' | 'tablesEndpoint' | 'executeEndpoint' | 'lookupEndpoint' | 'reportsEndpoint' | 'apisEndpoint']?: string;
24
+ };
21
25
  /**
22
26
  * Injection token for the endpoint URLs.
23
27
  */
@@ -5,16 +5,14 @@ import * as i0 from "@angular/core";
5
5
  /**
6
6
  * Built-in HTTP adapter for executing report data sources against the reporting backend.
7
7
  * Automatically injects active multi-tenant session headers (X-Company-Id, X-Branch-Id)
8
- * and includes rich development fallback data when the backend is unreachable.
8
+ * and propagates execution errors to the caller.
9
9
  */
10
10
  export declare class HttpReportDataSourceAdapter extends ReportDataSourceAdapter {
11
11
  private readonly http;
12
12
  private readonly config;
13
13
  private readonly sessionService;
14
14
  execute(dataSource: ReportDataSourceDefinition, parameters: Record<string, unknown>): Observable<unknown[]>;
15
- private getMockExecutionData;
16
15
  static ɵfac: i0.ɵɵFactoryDeclaration<HttpReportDataSourceAdapter, never>;
17
16
  static ɵprov: i0.ɵɵInjectableDeclaration<HttpReportDataSourceAdapter>;
18
17
  }
19
- /** Convenience alias */
20
18
  export declare const HttpDataSourceAdapter: typeof HttpReportDataSourceAdapter;
@@ -3,7 +3,7 @@ import { LookupOptionItem, LookupQueryRequest, ReportLookupAdapter } from '../co
3
3
  import * as i0 from "@angular/core";
4
4
  /**
5
5
  * Built-in HTTP adapter for fetching dropdown options from backend database tables, SPs, and REST APIs.
6
- * Includes in-memory caching with TTL, in-flight request deduplication, and fallback mock data.
6
+ * Includes in-memory caching with TTL, in-flight request deduplication, and explicit request errors.
7
7
  */
8
8
  export declare class HttpReportLookupAdapter extends ReportLookupAdapter {
9
9
  private readonly http;
@@ -12,11 +12,9 @@ export declare class HttpReportLookupAdapter extends ReportLookupAdapter {
12
12
  private readonly apiExecutionService;
13
13
  private readonly cache;
14
14
  private readonly inFlight;
15
- private readonly mockDataStore;
16
15
  fetchOptions(request: LookupQueryRequest): Observable<LookupOptionItem[]>;
17
16
  private setCache;
18
17
  private generateCacheKey;
19
- private resolveMockOptions;
20
18
  static ɵfac: i0.ɵɵFactoryDeclaration<HttpReportLookupAdapter, never>;
21
19
  static ɵprov: i0.ɵɵInjectableDeclaration<HttpReportLookupAdapter>;
22
20
  }
@@ -1,27 +1,22 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { ReportDefinition, ReportSummary } from '../../core/models/report-definition.model';
3
- import { ReportPersistenceAdapter } from '../contracts/report-persistence.contract';
3
+ import { ReportPersistenceAdapter, ReportSaveOptions, ReportIdStatus } from '../contracts/report-persistence.contract';
4
4
  import * as i0 from "@angular/core";
5
- /**
6
- * Built-in HTTP adapter for report definitions persistence.
7
- * Connects to NestJS `/api/reporting/reports` endpoints.
8
- * Includes in-memory mock fallback when the remote backend is unreachable.
9
- */
5
+ /** HTTP-only persistence. Use withLocalStorage() explicitly for offline demos. */
10
6
  export declare class HttpReportPersistenceAdapter extends ReportPersistenceAdapter {
7
+ private readonly session;
8
+ private get headers();
11
9
  private readonly http;
12
10
  private readonly config;
13
- private readonly mockStore;
14
- constructor();
15
- load(reportId: string): Observable<ReportDefinition>;
16
- save(report: ReportDefinition): Observable<ReportDefinition>;
11
+ checkId(reportId: string): Observable<boolean>;
12
+ inspectId(reportId: string): Observable<ReportIdStatus>;
13
+ load(id: string): Observable<ReportDefinition>;
14
+ save(report: ReportDefinition, options?: ReportSaveOptions): Observable<ReportDefinition>;
17
15
  list(): Observable<ReportSummary[]>;
18
- delete(reportId: string): Observable<void>;
19
- publish(reportId: string, version: number): Observable<void>;
20
- private getMockReport;
21
- private getMockSummaries;
22
- private seedDefaultMockReports;
16
+ delete(id: string): Observable<void>;
17
+ publish(id: string, version: number): Observable<void>;
18
+ private request;
23
19
  static ɵfac: i0.ɵɵFactoryDeclaration<HttpReportPersistenceAdapter, never>;
24
20
  static ɵprov: i0.ɵɵInjectableDeclaration<HttpReportPersistenceAdapter>;
25
21
  }
26
- /** Convenience alias */
27
22
  export declare const HttpPersistenceAdapter: typeof HttpReportPersistenceAdapter;
@@ -3,18 +3,16 @@ import { DatabaseEntityMetadata, DatabaseEntityType, EntityColumnMetadata, Proce
3
3
  import * as i0 from "@angular/core";
4
4
  /**
5
5
  * Built-in HTTP adapter for backend database schema discovery.
6
- * Connects to NestJS / REST backend endpoints, with fallback mock schema for development.
6
+ * Connects to NestJS / REST backend endpoints, without fabricating metadata when requests fail.
7
7
  */
8
8
  export declare class HttpReportSchemaDiscoveryAdapter extends ReportSchemaDiscoveryAdapter {
9
+ private readonly session;
10
+ private get headers();
9
11
  private readonly http;
10
12
  private readonly config;
11
- private readonly mockEntities;
12
- private readonly mockColumns;
13
- private readonly mockParameters;
14
13
  getEntities(types?: DatabaseEntityType[]): Observable<DatabaseEntityMetadata[]>;
15
14
  getColumns(entityName: string, schema?: string, type?: DatabaseEntityType): Observable<EntityColumnMetadata[]>;
16
15
  getParameters(entityName: string, schema?: string): Observable<ProcedureParameterMetadata[]>;
17
- private filterMockEntities;
18
16
  static ɵfac: i0.ɵɵFactoryDeclaration<HttpReportSchemaDiscoveryAdapter, never>;
19
17
  static ɵprov: i0.ɵɵInjectableDeclaration<HttpReportSchemaDiscoveryAdapter>;
20
18
  }
@@ -11,4 +11,4 @@ export { EndpointLookupAdapter } from './endpoint-lookup.adapter';
11
11
  export { EndpointPersistenceAdapter } from './endpoint-persistence.adapter';
12
12
  export { EndpointMasterDataAdapter } from './endpoint-masterdata.adapter';
13
13
  export { BWAYS_REPORT_ENDPOINTS } from './endpoint-tokens';
14
- export type { BwaysReportEndpoints } from './endpoint-tokens';
14
+ export type { BwaysReportEndpoints, BwaysReportApiUrls } from './endpoint-tokens';
@@ -1,5 +1,5 @@
1
1
  import { Observable } from 'rxjs';
2
- import { ReportPersistenceAdapter } from '../contracts/report-persistence.contract';
2
+ import { ReportPersistenceAdapter, ReportSaveOptions } from '../contracts/report-persistence.contract';
3
3
  import { ReportDefinition, ReportSummary } from '../../core/models/report-definition.model';
4
4
  import * as i0 from "@angular/core";
5
5
  export declare class LocalStorageReportPersistenceAdapter extends ReportPersistenceAdapter {
@@ -11,7 +11,7 @@ export declare class LocalStorageReportPersistenceAdapter extends ReportPersiste
11
11
  private saveIndex;
12
12
  private saveDirect;
13
13
  load(reportId: string): Observable<ReportDefinition>;
14
- save(report: ReportDefinition): Observable<ReportDefinition>;
14
+ save(report: ReportDefinition, options?: ReportSaveOptions): Observable<ReportDefinition>;
15
15
  list(): Observable<ReportSummary[]>;
16
16
  delete(reportId: string): Observable<void>;
17
17
  publish(reportId: string, version: number): Observable<void>;
@@ -0,0 +1,6 @@
1
+ import { ReportIdStatus } from '../contracts/report-persistence.contract';
2
+ import { HttpClient, HttpHeaders } from '@angular/common/http';
3
+ import { Observable } from 'rxjs';
4
+ export declare function reportIdAvailability(http: HttpClient, url: string, headers: HttpHeaders, fallback: () => Observable<boolean>): Observable<boolean>;
5
+ /** Version/name are optional for compatibility with earlier availability endpoints. */
6
+ export declare function reportIdInspection(http: HttpClient, url: string, headers: HttpHeaders, fallback: () => Observable<ReportIdStatus>): Observable<ReportIdStatus>;
@@ -0,0 +1,3 @@
1
+ import { HttpHeaders } from '@angular/common/http';
2
+ /** Authentication stays with host interceptors; reporting forwards tenant context. */
3
+ export declare function reportSessionHeaders(session: Record<string, unknown>): HttpHeaders;
@@ -1,6 +1,7 @@
1
1
  export { ReportDataSourceAdapter } from './data-source.contract';
2
2
  export { MasterDataProvider } from './master-data.provider';
3
3
  export type { MasterDataOptions, MasterDataItem } from './master-data.provider';
4
+ export type { ReportSaveOptions, ReportIdStatus } from './report-persistence.contract';
4
5
  export { ReportPersistenceAdapter } from './report-persistence.contract';
5
6
  export { ReportTranslationAdapter } from './translation.contract';
6
7
  export { ReportSchemaDiscoveryAdapter } from './schema-discovery.contract';
@@ -6,6 +6,17 @@
6
6
  */
7
7
  import { Observable } from 'rxjs';
8
8
  import { ReportDefinition, ReportSummary } from '../../core/models/report-definition.model';
9
+ export interface ReportSaveOptions {
10
+ /** Reject an existing ID instead of updating it. Hosts should enforce this atomically. */
11
+ createOnly?: boolean;
12
+ /** Update only an existing report at this version; reject missing or changed records. */
13
+ expectedVersion?: number;
14
+ }
15
+ export interface ReportIdStatus {
16
+ exists: boolean;
17
+ name?: string;
18
+ version?: number;
19
+ }
9
20
  /**
10
21
  * Contract for persisting report definitions.
11
22
  *
@@ -23,10 +34,14 @@ import { ReportDefinition, ReportSummary } from '../../core/models/report-defini
23
34
  * ```
24
35
  */
25
36
  export declare abstract class ReportPersistenceAdapter {
37
+ /** Returns true when this ID exists. Legacy host adapters may use the catalog fallback. */
38
+ checkId(reportId: string): Observable<boolean>;
39
+ /** Compact identity metadata used to confirm an overwrite. Legacy hosts use summaries. */
40
+ inspectId(reportId: string): Observable<ReportIdStatus>;
26
41
  /** Load a full report definition by ID. */
27
42
  abstract load(reportId: string): Observable<ReportDefinition>;
28
43
  /** Save (create or update) a report definition. */
29
- abstract save(report: ReportDefinition): Observable<ReportDefinition>;
44
+ abstract save(report: ReportDefinition, options?: ReportSaveOptions): Observable<ReportDefinition>;
30
45
  /** List available reports (summaries only). */
31
46
  abstract list(): Observable<ReportSummary[]>;
32
47
  /** Delete a report by ID. */
@@ -5,6 +5,8 @@ import { ReportComponentDefinition } from '../../../../core/models/report-compon
5
5
  import { getComponentIconName } from '../../utilities/canvas-layout.util';
6
6
  import * as i0 from "@angular/core";
7
7
  export declare class DesignCanvasComponent implements OnDestroy {
8
+ private readonly requests;
9
+ constructor();
8
10
  private readonly designerState;
9
11
  private gridFilterDebounceTimer;
10
12
  private pendingGridState;
@@ -8,27 +8,59 @@ export interface ReportSavedDialogResult {
8
8
  action: 'back_to_designer' | 'open_live_page';
9
9
  report: ReportDefinition;
10
10
  }
11
+ interface UpdateConfirmation {
12
+ report: ReportDefinition;
13
+ action: ReportSavedDialogResult['action'];
14
+ expectedVersion: number;
15
+ existingName: string;
16
+ contextKey: string;
17
+ }
11
18
  export declare class ReportSavedDialogComponent {
12
19
  private readonly dialogRef;
13
20
  private readonly data;
14
21
  private readonly store;
22
+ private readonly destroyRef;
15
23
  private readonly reportingConfig;
16
- private readonly router;
24
+ private idCheck?;
25
+ private customSlug;
17
26
  readonly report: ReportDefinition;
18
27
  readonly baseRoute: import("@angular/core").WritableSignal<string>;
28
+ readonly reportId: import("@angular/core").WritableSignal<string>;
29
+ readonly isCheckingId: import("@angular/core").WritableSignal<boolean>;
30
+ readonly isPreparingSave: import("@angular/core").WritableSignal<boolean>;
31
+ readonly updateConfirmation: import("@angular/core").WritableSignal<UpdateConfirmation | null>;
32
+ readonly idAttempted: import("@angular/core").WritableSignal<boolean>;
33
+ readonly idStatus: import("@angular/core").WritableSignal<"error" | "duplicate" | "unchecked" | "checking" | "available" | "current">;
34
+ readonly idMessage: import("@angular/core").WritableSignal<string>;
35
+ readonly idChanged: import("@angular/core").Signal<boolean>;
36
+ readonly idError: import("@angular/core").Signal<"Enter a report ID." | "Use a report ID of at most 100 characters." | "Use letters, numbers, underscores or hyphens, starting with a letter or number." | "Choose another ID; \"new\" is reserved for the report builder." | null>;
19
37
  readonly name: import("@angular/core").WritableSignal<string>;
38
+ readonly description: import("@angular/core").WritableSignal<string>;
39
+ readonly category: import("@angular/core").WritableSignal<string>;
20
40
  readonly slug: import("@angular/core").WritableSignal<string>;
21
41
  readonly menuGroup: import("@angular/core").WritableSignal<string>;
22
42
  readonly isPublished: import("@angular/core").WritableSignal<boolean>;
23
43
  readonly copied: import("@angular/core").WritableSignal<boolean>;
24
- readonly savedStateMessage: import("@angular/core").WritableSignal<string | null>;
44
+ readonly isSaving: import("@angular/core").WritableSignal<boolean>;
45
+ readonly attempted: import("@angular/core").WritableSignal<boolean>;
46
+ readonly saveError: import("@angular/core").WritableSignal<string | null>;
47
+ readonly nameError: import("@angular/core").Signal<"Enter a report name." | null>;
48
+ readonly slugError: import("@angular/core").Signal<"Enter a URL slug." | "Use lowercase letters, numbers, and single hyphens." | "Choose a different slug; \"new\" is reserved for the report builder." | null>;
25
49
  readonly fullRoute: import("@angular/core").Signal<string>;
26
50
  readonly currentPreviewDef: import("@angular/core").Signal<ReportDefinition>;
27
- onNameChange(newName: string): void;
51
+ onIdChange(value: string): void;
52
+ randomizeId(): void;
53
+ verifyId(): void;
54
+ onNameChange(value: string): void;
55
+ onSlugChange(value: string): void;
28
56
  copyRoute(): void;
29
- saveUpdatedDefinition(): ReportDefinition;
30
- close(action?: 'back_to_designer' | 'open_live_page'): void;
57
+ save(action?: ReportSavedDialogResult['action']): void;
58
+ cancelUpdate(): void;
59
+ confirmUpdate(): void;
60
+ private persist;
61
+ close(): void;
31
62
  openLivePage(): void;
32
63
  static ɵfac: i0.ɵɵFactoryDeclaration<ReportSavedDialogComponent, never>;
33
64
  static ɵcmp: i0.ɵɵComponentDeclaration<ReportSavedDialogComponent, "rpt-report-saved-dialog", never, {}, {}, never, never, true, never>;
34
65
  }
66
+ export {};
@@ -1,4 +1,4 @@
1
- import { OnDestroy, OnInit } from '@angular/core';
1
+ import { OnDestroy } from '@angular/core';
2
2
  import { ComponentDataSourceDefinition, DropdownSourceType, ReportComponentDefinition } from '../../../../core/models/report-component.model';
3
3
  import { DatabaseEntityMetadata, EntityColumnMetadata, ProcedureParameterMetadata } from '../../../../data-access/contracts/schema-discovery.contract';
4
4
  import { SearchableSelectOption } from '../../../../primitives/components';
@@ -7,7 +7,9 @@ export interface StaticOptionItem {
7
7
  key: string;
8
8
  label: string;
9
9
  }
10
- export declare class PropertyEditorDatasourceComponent implements OnInit, OnDestroy {
10
+ export declare class PropertyEditorDatasourceComponent implements OnDestroy {
11
+ private readonly endpointScope;
12
+ private entitiesSub?;
11
13
  private readonly discoveryAdapter;
12
14
  private readonly sessionService;
13
15
  private readonly designerState;
@@ -69,7 +71,6 @@ export declare class PropertyEditorDatasourceComponent implements OnInit, OnDest
69
71
  readonly valueFieldSelectOptions: import("@angular/core").Signal<SearchableSelectOption<any>[]>;
70
72
  readonly parentFieldSelectOptions: import("@angular/core").Signal<SearchableSelectOption<any>[]>;
71
73
  constructor();
72
- ngOnInit(): void;
73
74
  ngOnDestroy(): void;
74
75
  loadEntities(): void;
75
76
  loadEntityDetails(entityName: string, type: DropdownSourceType): void;
@@ -5,6 +5,7 @@ import { DatabaseEntityMetadata, ProcedureParameterMetadata } from '../../../../
5
5
  import { SearchableSelectOption } from '../../../../primitives/components';
6
6
  import * as i0 from "@angular/core";
7
7
  export declare class PropertyEditorGridComponent {
8
+ private readonly endpointScope;
8
9
  private readonly dataDiscovery;
9
10
  private readonly endpoints;
10
11
  readonly grid: import("@angular/core").InputSignal<ReportGridDefinition | undefined>;
@@ -18,6 +18,7 @@ export declare class PropertyEditorComponent {
18
18
  private readonly discoveryAdapter;
19
19
  private readonly lookupAdapter;
20
20
  private readonly sessionService;
21
+ private readonly endpointScope;
21
22
  private readonly dataDiscovery;
22
23
  readonly isDetectingColumns: import("@angular/core").WritableSignal<boolean>;
23
24
  readonly gridDetectionStatus: import("@angular/core").WritableSignal<{
@@ -3,8 +3,13 @@ import { ReportBlueprint } from '../../services/report-template.service';
3
3
  import { ReportDefinition } from '../../../../core/models/report-definition.model';
4
4
  import * as i0 from "@angular/core";
5
5
  export declare class DesignerToolbarComponent {
6
+ private readonly requests;
7
+ readonly catalogLoading: import("@angular/core").WritableSignal<boolean>;
8
+ readonly catalogError: import("@angular/core").WritableSignal<string | null>;
9
+ readonly isSwitchingReport: import("@angular/core").WritableSignal<boolean>;
6
10
  private readonly designerState;
7
11
  private readonly templateService;
12
+ private readonly endpointScope;
8
13
  private readonly reportStore;
9
14
  readonly definition: import("@angular/core").WritableSignal<ReportDefinition>;
10
15
  readonly viewMode: import("@angular/core").WritableSignal<DesignerViewMode>;
@@ -26,7 +31,8 @@ export declare class DesignerToolbarComponent {
26
31
  saveRename(): void;
27
32
  cancelRename(): void;
28
33
  createNewReport(): void;
29
- onSwitchReport(reportId: string): void;
34
+ refreshReports(): void;
35
+ onSwitchReport(reportId: string, select?: HTMLSelectElement): void;
30
36
  private toSlug;
31
37
  setMode(mode: DesignerViewMode): void;
32
38
  undo(): void;
@@ -1,8 +1,21 @@
1
+ import { BwaysReportConfig } from '../../core/config/bways-report-config';
1
2
  import { OnInit } from '@angular/core';
2
3
  import { ReportDefinition } from '../../core/models/report-definition.model';
3
4
  import { DesignerStateService } from './services/designer-state.service';
5
+ import { BwaysReportApiUrls } from '../../data-access/adapters/endpoint-tokens';
4
6
  import * as i0 from "@angular/core";
5
7
  export declare class DesignerComponent implements OnInit {
8
+ private readonly requests;
9
+ readonly loadError: import("@angular/core").WritableSignal<string | null>;
10
+ private readonly injector;
11
+ private readonly destroyRef;
12
+ private saveDialogOpen;
13
+ private readonly endpointScope;
14
+ private readonly configuration;
15
+ /** Page-local settings; omitted values inherit optional application defaults. */
16
+ set config(value: BwaysReportConfig | null | undefined);
17
+ /** Override any subset of configured URLs for this designer and its preview. */
18
+ set apiUrl(value: BwaysReportApiUrls | null | undefined);
6
19
  readonly designerState: DesignerStateService;
7
20
  private readonly persistenceAdapter;
8
21
  private readonly dataSourceAdapter;
@@ -46,8 +59,8 @@ export declare class DesignerComponent implements OnInit {
46
59
  private lastEmittedDef;
47
60
  constructor();
48
61
  ngOnInit(): void;
62
+ retryLoad(): void;
49
63
  onSave(): void;
50
- private openSavedDialog;
51
64
  onPreviewExecute(event: {
52
65
  definition: ReportDefinition;
53
66
  parameters: Record<string, unknown>;
@@ -59,5 +72,5 @@ export declare class DesignerComponent implements OnInit {
59
72
  private syntaxHighlightJson;
60
73
  private showToast;
61
74
  static ɵfac: i0.ɵɵFactoryDeclaration<DesignerComponent, never>;
62
- static ɵcmp: i0.ɵɵComponentDeclaration<DesignerComponent, "rpt-designer", never, { "reportId": { "alias": "reportId"; "required": false; "isSignal": true; }; "definition": { "alias": "initialReport"; "required": false; "isSignal": true; }; }, { "reportSaved": "save"; "definitionChanged": "definitionChange"; }, never, never, true, never>;
75
+ static ɵcmp: i0.ɵɵComponentDeclaration<DesignerComponent, "rpt-designer", never, { "config": { "alias": "config"; "required": false; }; "apiUrl": { "alias": "apiUrl"; "required": false; }; "reportId": { "alias": "reportId"; "required": false; "isSignal": true; }; "definition": { "alias": "initialReport"; "required": false; "isSignal": true; }; }, { "reportSaved": "save"; "definitionChanged": "definitionChange"; }, never, never, true, never>;
63
76
  }
@@ -1,3 +1,5 @@
1
+ import { BwaysReportConfig } from '../../core/config/bways-report-config';
2
+ import { BwaysReportApiUrls } from '../../data-access/adapters/endpoint-tokens';
1
3
  import { ReportDefinition } from '../../core/models/report-definition.model';
2
4
  import * as i0 from "@angular/core";
3
5
  /**
@@ -16,6 +18,8 @@ import * as i0 from "@angular/core";
16
18
  * ```
17
19
  */
18
20
  export declare class RptReportDesignerComponent {
21
+ readonly config: import("@angular/core").InputSignal<BwaysReportConfig | null>;
22
+ readonly apiUrl: import("@angular/core").InputSignal<BwaysReportApiUrls | null>;
19
23
  /** Report ID to automatically load via configured ReportPersistenceAdapter */
20
24
  readonly id: import("@angular/core").InputSignal<string | undefined>;
21
25
  /** Report definition to load directly in memory */
@@ -34,5 +38,5 @@ export declare class RptReportDesignerComponent {
34
38
  onDefinitionChange(definition: ReportDefinition): void;
35
39
  onClose(): void;
36
40
  static ɵfac: i0.ɵɵFactoryDeclaration<RptReportDesignerComponent, never>;
37
- static ɵcmp: i0.ɵɵComponentDeclaration<RptReportDesignerComponent, "rpt-report-designer, rpt-designer-view", never, { "id": { "alias": "id"; "required": false; "isSignal": true; }; "report": { "alias": "report"; "required": false; "isSignal": true; }; "showCloseButton": { "alias": "showCloseButton"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; }, { "saved": "saved"; "closed": "closed"; "definitionChange": "definitionChange"; }, never, never, true, never>;
41
+ static ɵcmp: i0.ɵɵComponentDeclaration<RptReportDesignerComponent, "rpt-report-designer, rpt-designer-view", never, { "config": { "alias": "config"; "required": false; "isSignal": true; }; "apiUrl": { "alias": "apiUrl"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "report": { "alias": "report"; "required": false; "isSignal": true; }; "showCloseButton": { "alias": "showCloseButton"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; }, { "saved": "saved"; "closed": "closed"; "definitionChange": "definitionChange"; }, never, never, true, never>;
38
42
  }
@@ -0,0 +1,13 @@
1
+ import { BwaysReportConfig } from '../../../core/config/bways-report-config';
2
+ import { ReportingConfig } from '../../../core/tokens/reporting-config.token';
3
+ import * as i0 from "@angular/core";
4
+ export declare class DesignerConfigService {
5
+ private readonly inherited;
6
+ readonly local: import("@angular/core").WritableSignal<BwaysReportConfig | null>;
7
+ private readonly effective;
8
+ readonly reporting: ReportingConfig;
9
+ constructor();
10
+ set(value: BwaysReportConfig | null | undefined): void;
11
+ static ɵfac: i0.ɵɵFactoryDeclaration<DesignerConfigService, never>;
12
+ static ɵprov: i0.ɵɵInjectableDeclaration<DesignerConfigService>;
13
+ }
@@ -0,0 +1,25 @@
1
+ import { Provider, Type } from '@angular/core';
2
+ import { BwaysReportApiUrls, BwaysReportEndpoints } from '../../../data-access/adapters/endpoint-tokens';
3
+ import * as i0 from "@angular/core";
4
+ /** Private state owned by one designer; never mutates application providers. */
5
+ export declare class DesignerEndpointsService {
6
+ private readonly defaults;
7
+ private readonly config;
8
+ private readonly injector;
9
+ private readonly pageConfig;
10
+ private readonly adapters;
11
+ private overrides;
12
+ readonly revision: import("@angular/core").WritableSignal<number>;
13
+ private readonly resolved;
14
+ readonly endpoints: BwaysReportEndpoints;
15
+ setOverrides(value: BwaysReportApiUrls | null | undefined): void;
16
+ hasOverride(keys: (keyof BwaysReportApiUrls)[]): boolean;
17
+ adapter<T>(type: Type<T>): T;
18
+ isConfigured(): boolean;
19
+ refresh(): void;
20
+ usesDefaultStorageBase(): boolean;
21
+ private merged;
22
+ static ɵfac: i0.ɵɵFactoryDeclaration<DesignerEndpointsService, never>;
23
+ static ɵprov: i0.ɵɵInjectableDeclaration<DesignerEndpointsService>;
24
+ }
25
+ export declare const DESIGNER_ENDPOINT_PROVIDERS: Provider[];