arilekh-report-viewer 1.0.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.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arilekh-report-viewer.mjs","sources":["../../../projects/arilekh-report-viewer/src/lib/arilekh-report-viewer/components/page-renderer.component.ts","../../../projects/arilekh-report-viewer/src/lib/arilekh-report-viewer/services/report-viewer-api.service.ts","../../../projects/arilekh-report-viewer/src/lib/arilekh-report-viewer/components/left-panel.component.ts","../../../projects/arilekh-report-viewer/src/lib/arilekh-report-viewer/components/report-viewer.component.ts","../../../projects/arilekh-report-viewer/src/public-api.ts","../../../projects/arilekh-report-viewer/src/arilekh-report-viewer.ts"],"sourcesContent":["import {\n Component, Input, OnChanges, SimpleChanges,\n ChangeDetectionStrategy, ElementRef, ViewChild\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ElementDto, PageResponse, StyleDto } from '../services/report-viewer-api.service';\n\nconst PT_TO_PX = 1.333; // 1pt = 1.333px at 96dpi\n\n@Component({\n selector: 'arv-page-renderer',\n standalone: true,\n imports: [CommonModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"arv-page\"\n #pageEl\n [style.width.px]=\"widthPx\"\n [style.height.px]=\"heightPx\"\n [attr.data-page]=\"page?.pageNumber\">\n\n @if (page) {\n @for (el of page.elements; track $index) {\n <!-- TEXT -->\n @if (el.type === 'text') {\n <div [style]=\"textStyle(el)\"\n [class.arv-hyperlink]=\"!!el.hyperlinkUrl\"\n (click)=\"el.hyperlinkUrl && openLink(el.hyperlinkUrl)\">\n {{ el.text }}\n </div>\n }\n <!-- RECT -->\n @else if (el.type === 'rect') {\n <div [style]=\"rectStyle(el)\"></div>\n }\n <!-- LINE -->\n @else if (el.type === 'line') {\n <svg [style]=\"lineSvgStyle(el)\" xmlns=\"http://www.w3.org/2000/svg\">\n <line\n [attr.x1]=\"lineX1(el)\" [attr.y1]=\"lineY1(el)\"\n [attr.x2]=\"lineX2(el)\" [attr.y2]=\"lineY2(el)\"\n [attr.stroke]=\"el.strokeColor || '#000'\"\n [attr.stroke-width]=\"(el.strokeWidth || 1) * scale\" />\n </svg>\n }\n <!-- ELLIPSE -->\n @else if (el.type === 'ellipse') {\n <svg [style]=\"ellipseSvgStyle(el)\" xmlns=\"http://www.w3.org/2000/svg\">\n <ellipse\n [attr.cx]=\"(el.width * scale / 2)\"\n [attr.cy]=\"(el.height * scale / 2)\"\n [attr.rx]=\"Math.max(0, el.width * scale / 2 - (el.strokeWidth||1)*scale/2)\"\n [attr.ry]=\"Math.max(0, el.height * scale / 2 - (el.strokeWidth||1)*scale/2)\"\n [attr.fill]=\"el.fillColor || 'none'\"\n [attr.stroke]=\"el.strokeColor || '#000'\"\n [attr.stroke-width]=\"(el.strokeWidth || 1) * scale\" />\n </svg>\n }\n <!-- IMAGE -->\n @else if (el.type === 'image') {\n <img [style]=\"imageStyle(el)\"\n [src]=\"el.src\"\n alt=\"\" />\n }\n }\n }\n </div>\n `,\n styles: [`\n :host { display: block; }\n .arv-page {\n position: relative;\n background: white;\n overflow: hidden;\n box-shadow: 0 2px 12px rgba(0,0,0,0.3);\n }\n .arv-hyperlink { cursor: pointer; }\n .arv-hyperlink:hover { opacity: 0.8; }\n svg { overflow: visible; }\n `]\n})\nexport class PageRendererComponent implements OnChanges {\n @Input() page?: PageResponse;\n @Input() scale: number = PT_TO_PX;\n @ViewChild('pageEl') pageEl?: ElementRef<HTMLDivElement>;\n\n protected Math = Math;\n\n get widthPx(): number { return (this.page?.widthPt ?? 595) * this.scale; }\n get heightPx(): number { return (this.page?.heightPt ?? 842) * this.scale; }\n\n ngOnChanges(c: SimpleChanges): void {}\n\n // ── Style builders ────────────────────────────────────────────────────────\n\n textStyle(el: ElementDto): Record<string, string> {\n const s = el.style;\n const rot = el.rotation ? `rotate(${el.rotation}deg)` : '';\n const vAlign = el.verticalAlign === 'middle' ? 'center'\n : el.verticalAlign === 'bottom' ? 'flex-end'\n : 'flex-start';\n return {\n position: 'absolute',\n left: `${el.x * this.scale}px`,\n top: `${el.y * this.scale}px`,\n width: `${el.width * this.scale}px`,\n height: `${el.height * this.scale}px`,\n overflow: 'hidden',\n fontSize: `${(s?.fontSize ?? 9) * this.scale}px`,\n fontFamily: s?.fontFamily ?? 'inherit',\n fontWeight: s?.bold ? 'bold' : 'normal',\n fontStyle: s?.italic ? 'italic' : 'normal',\n textDecoration: s?.underline ? 'underline' : 'none',\n color: s?.foreColor ?? '#000',\n background: s?.backColor ?? 'transparent',\n textAlign: el.alignment ?? 'left',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: vAlign,\n paddingLeft: `${(s?.paddingLeft ?? 0) * this.scale}px`,\n paddingRight: `${(s?.paddingRight ?? 0) * this.scale}px`,\n transform: rot,\n transformOrigin: rot ? 'center center' : '',\n boxSizing: 'border-box',\n };\n }\n\n rectStyle(el: ElementDto): Record<string, string> {\n const rot = el.rotation ? `rotate(${el.rotation}deg)` : '';\n return {\n position: 'absolute',\n left: `${el.x * this.scale}px`,\n top: `${el.y * this.scale}px`,\n width: `${el.width * this.scale}px`,\n height: `${el.height * this.scale}px`,\n background: el.fillColor ?? 'transparent',\n border: el.strokeColor\n ? `${(el.strokeWidth ?? 1) * this.scale}px solid ${el.strokeColor}`\n : 'none',\n borderRadius: el.borderRadius ? `${el.borderRadius}%` : '0',\n transform: rot,\n transformOrigin: rot ? 'center center' : '',\n boxSizing: 'border-box',\n };\n }\n\n lineSvgStyle(el: ElementDto): Record<string, string> {\n const x1 = el.x, y1 = el.y;\n const x2 = el.x2 ?? el.x, y2 = el.y2 ?? el.y;\n const left = Math.min(x1, x2) * this.scale;\n const top = Math.min(y1, y2) * this.scale;\n const width = Math.max(Math.abs(x2 - x1) * this.scale, (el.strokeWidth ?? 1) * this.scale + 2);\n const height = Math.max(Math.abs(y2 - y1) * this.scale, (el.strokeWidth ?? 1) * this.scale + 2);\n const rot = el.rotation ? `rotate(${el.rotation}deg)` : '';\n return {\n position: 'absolute',\n left: `${left}px`, top: `${top}px`,\n width: `${width}px`, height: `${height}px`,\n transform: rot, transformOrigin: rot ? 'center center' : '',\n };\n }\n\n lineX1(el: ElementDto): number {\n return (el.x * this.scale) - Math.min(el.x, el.x2 ?? el.x) * this.scale;\n }\n lineY1(el: ElementDto): number {\n return (el.y * this.scale) - Math.min(el.y, el.y2 ?? el.y) * this.scale;\n }\n lineX2(el: ElementDto): number {\n return ((el.x2 ?? el.x) * this.scale) - Math.min(el.x, el.x2 ?? el.x) * this.scale;\n }\n lineY2(el: ElementDto): number {\n return ((el.y2 ?? el.y) * this.scale) - Math.min(el.y, el.y2 ?? el.y) * this.scale;\n }\n\n ellipseSvgStyle(el: ElementDto): Record<string, string> {\n const rot = el.rotation ? `rotate(${el.rotation}deg)` : '';\n return {\n position: 'absolute',\n left: `${el.x * this.scale}px`, top: `${el.y * this.scale}px`,\n width: `${el.width * this.scale}px`, height: `${el.height * this.scale}px`,\n transform: rot, transformOrigin: rot ? 'center center' : '',\n };\n }\n\n imageStyle(el: ElementDto): Record<string, string> {\n const rot = el.rotation ? `rotate(${el.rotation}deg)` : '';\n return {\n position: 'absolute',\n left: `${el.x * this.scale}px`,\n top: `${el.y * this.scale}px`,\n width: `${el.width * this.scale}px`,\n height: `${el.height * this.scale}px`,\n objectFit: (el.stretch as any) ?? 'contain',\n transform: rot, transformOrigin: rot ? 'center center' : '',\n };\n }\n\n openLink(url: string): void {\n window.open(url, '_blank', 'noopener');\n }\n\n /** Expose the page div for screenshot (called by parent). */\n getPageElement(): HTMLDivElement | undefined {\n return this.pageEl?.nativeElement;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { HttpClient, HttpParams } from '@angular/common/http';\nimport { Observable, BehaviorSubject, Subject } from 'rxjs';\nimport { tap } from 'rxjs/operators';\n\n// ── DTOs matching the .NET API ─────────────────────────────────────────────\n\nexport interface RenderRequest {\n reportXml: string;\n data?: Record<string, Record<string, unknown>[]>;\n parameters?: Record<string, unknown>;\n ttlMinutes?: number;\n}\n\nexport interface RenderResponse {\n sessionId: string;\n pageCount: number;\n pageWidthPt: number;\n pageHeightPt: number;\n renderedAt: string;\n renderMs: number;\n}\n\nexport interface StyleDto {\n fontFamily?: string;\n fontSize?: number;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n foreColor?: string;\n backColor?: string;\n paddingLeft: number;\n paddingRight: number;\n}\n\nexport interface ElementDto {\n type: 'text' | 'rect' | 'line' | 'ellipse' | 'image';\n x: number; y: number;\n width: number; height: number;\n rotation: number;\n // text\n text?: string;\n alignment?: 'left' | 'center' | 'right';\n verticalAlign?: 'top' | 'middle' | 'bottom';\n hyperlinkUrl?: string;\n style?: StyleDto;\n // rect / ellipse\n fillColor?: string;\n strokeColor?: string;\n strokeWidth?: number;\n borderRadius?: number;\n // line\n x2?: number; y2?: number;\n // image\n src?: string;\n stretch?: string;\n}\n\nexport interface PageResponse {\n pageNumber: number;\n totalPages: number;\n widthPt: number;\n heightPt: number;\n elements: ElementDto[];\n}\n\nexport interface PageSummary {\n pageNumber: number;\n firstText: string;\n groupLabel: string;\n}\n\nexport interface ThumbnailListResponse {\n sessionId: string;\n pageCount: number;\n pages: PageSummary[];\n}\n\nexport interface SearchHit {\n pageNumber: number;\n snippet: string;\n x: number; y: number;\n}\n\nexport interface SearchResponse {\n query: string;\n hits: number;\n results: SearchHit[];\n}\n\n// ── Service ────────────────────────────────────────────────────────────────\n\n@Injectable({ providedIn: 'root' })\nexport class ReportViewerApiService {\n private baseUrl = '';\n\n // ── Observable state ───────────────────────────────────────────────────────\n\n private _session = new BehaviorSubject<RenderResponse | null>(null);\n private _loading = new BehaviorSubject<boolean>(false);\n private _error = new BehaviorSubject<string | null>(null);\n private _pageCache = new Map<number, PageResponse>();\n private _navigateTo$ = new Subject<number>();\n\n readonly session$ = this._session.asObservable();\n readonly loading$ = this._loading.asObservable();\n readonly error$ = this._error.asObservable();\n readonly navigateTo$ = this._navigateTo$.asObservable();\n\n // ── Configuration ──────────────────────────────────────────────────────────\n\n configure(apiBaseUrl: string): void {\n this.baseUrl = apiBaseUrl.replace(/\\/$/, '');\n }\n\n get sessionId(): string | null {\n return this._session.value?.sessionId ?? null;\n }\n\n get pageCount(): number {\n return this._session.value?.pageCount ?? 0;\n }\n\n get pageWidthPt(): number {\n return this._session.value?.pageWidthPt ?? 595;\n }\n\n get pageHeightPt(): number {\n return this._session.value?.pageHeightPt ?? 842;\n }\n\n // ── Render ────────────────────────────────────────────────────────────────\n\n constructor(private http: HttpClient) {}\n\n render(req: RenderRequest): Observable<RenderResponse> {\n this._loading.next(true);\n this._error.next(null);\n this._pageCache.clear();\n this._session.next(null);\n\n return this.http\n .post<RenderResponse>(`${this.baseUrl}/api/reports/render`, req)\n .pipe(\n tap({\n next: r => { this._session.next(r); this._loading.next(false); },\n error: e => {\n this._error.next(e?.error?.error ?? 'Render failed');\n this._loading.next(false);\n }\n })\n );\n }\n\n // ── Page retrieval (cached) ────────────────────────────────────────────────\n\n getPage(pageNumber: number): Observable<PageResponse> {\n const id = this.sessionId;\n if (!id) throw new Error('No active session.');\n\n // Check cache first\n const cached = this._pageCache.get(pageNumber);\n if (cached) {\n return new Observable(o => { o.next(cached); o.complete(); });\n }\n\n return this.http\n .get<PageResponse>(`${this.baseUrl}/api/reports/${id}/pages/${pageNumber}`)\n .pipe(tap(p => this._pageCache.set(pageNumber, p)));\n }\n\n getPageRange(from: number, to: number): Observable<PageResponse[]> {\n const id = this.sessionId;\n if (!id) throw new Error('No active session.');\n const params = new HttpParams()\n .set('from', from.toString())\n .set('to', to.toString());\n return this.http.get<PageResponse[]>(`${this.baseUrl}/api/reports/${id}/pages`, { params });\n }\n\n // ── Thumbnails ────────────────────────────────────────────────────────────\n\n getThumbnails(): Observable<ThumbnailListResponse> {\n const id = this.sessionId!;\n return this.http.get<ThumbnailListResponse>(`${this.baseUrl}/api/reports/${id}/thumbnails`);\n }\n\n // ── Search ────────────────────────────────────────────────────────────────\n\n search(query: string): Observable<SearchResponse> {\n const id = this.sessionId!;\n const params = new HttpParams().set('q', query);\n return this.http.get<SearchResponse>(\n `${this.baseUrl}/api/reports/${id}/search`, { params });\n }\n\n // ── Navigation helper ─────────────────────────────────────────────────────\n\n navigateTo(page: number): void {\n this._navigateTo$.next(Math.max(1, Math.min(page, this.pageCount)));\n }\n\n // ── Cache management ──────────────────────────────────────────────────────\n\n evictPage(pageNumber: number): void {\n this._pageCache.delete(pageNumber);\n }\n\n clearCache(): void {\n this._pageCache.clear();\n }\n\n isPageCached(pageNumber: number): boolean {\n return this._pageCache.has(pageNumber);\n }\n}\n","import {\n Component, Input, Output, EventEmitter,\n OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport {\n ReportViewerApiService, ThumbnailListResponse, PageSummary, SearchHit\n} from '../services/report-viewer-api.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil, debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';\n\n@Component({\n selector: 'arv-left-panel',\n standalone: true,\n imports: [CommonModule, FormsModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"arv-left\">\n\n <!-- Header -->\n <div class=\"arv-left__header\">\n <span class=\"arv-left__title\">Pages</span>\n <span class=\"arv-left__badge\">{{ api.pageCount }}</span>\n </div>\n\n <!-- Search -->\n <div class=\"arv-left__search\">\n <input class=\"arv-input\"\n placeholder=\"Search in report…\"\n [(ngModel)]=\"searchQuery\"\n (ngModelChange)=\"onSearchChange($event)\" />\n @if (searching) {\n <span class=\"arv-spinner-sm\"></span>\n }\n </div>\n\n <!-- Search results -->\n @if (searchResults.length > 0) {\n <div class=\"arv-left__section-title\">\n {{ searchResults.length }} result(s) for \"{{ lastQuery }}\"\n </div>\n <div class=\"arv-left__list\">\n @for (hit of searchResults; track hit.pageNumber) {\n <div class=\"arv-bm arv-bm--search\"\n [class.arv-bm--active]=\"currentPage === hit.pageNumber\"\n (click)=\"goTo(hit.pageNumber)\">\n <span class=\"arv-bm__icon\">🔍</span>\n <div class=\"arv-bm__col\">\n <span class=\"arv-bm__label\">Page {{ hit.pageNumber }}</span>\n <span class=\"arv-bm__snippet\">{{ hit.snippet }}</span>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Page thumbnails -->\n @if (searchResults.length === 0) {\n <div class=\"arv-left__section-title\">All Pages</div>\n <div class=\"arv-left__list\">\n @if (thumbnails) {\n @for (pg of thumbnails.pages; track pg.pageNumber) {\n <div class=\"arv-bm arv-thumb\"\n [class.arv-bm--active]=\"currentPage === pg.pageNumber\"\n (click)=\"goTo(pg.pageNumber)\">\n <!-- Mini thumbnail placeholder -->\n <div class=\"arv-thumb__box\">\n <span class=\"arv-thumb__num\">{{ pg.pageNumber }}</span>\n </div>\n <div class=\"arv-bm__col\">\n <span class=\"arv-bm__label\">Page {{ pg.pageNumber }}</span>\n @if (pg.firstText) {\n <span class=\"arv-bm__snippet\">{{ pg.firstText | slice:0:40 }}</span>\n }\n </div>\n </div>\n }\n } @else {\n <div class=\"arv-left__loading\">Loading…</div>\n }\n </div>\n }\n\n <!-- Footer info -->\n <div class=\"arv-left__footer\">\n <span>{{ api.pageCount }} pages</span>\n @if (api.pageCount > 0) {\n <span>· Page {{ currentPage }}</span>\n }\n </div>\n </div>\n `,\n styles: [`\n .arv-left {\n width: 200px;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n background: var(--arv-surface, #2a2a3e);\n border-right: 1px solid var(--arv-border, #3d3d5c);\n overflow: hidden;\n height: 100%;\n }\n .arv-left__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 10px 4px;\n font-weight: 700;\n font-size: 11px;\n color: var(--arv-text-muted, #888);\n text-transform: uppercase;\n flex-shrink: 0;\n }\n .arv-left__badge {\n font-size: 9px;\n background: var(--arv-border, #3d3d5c);\n border-radius: 8px;\n padding: 1px 6px;\n color: var(--arv-text, #ccc);\n }\n .arv-left__search {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n flex-shrink: 0;\n }\n .arv-input {\n flex: 1;\n padding: 4px 8px;\n background: var(--arv-surface2, #313148);\n border: 1px solid var(--arv-border, #3d3d5c);\n border-radius: 4px;\n color: var(--arv-text, #ccc);\n font-size: 11px;\n outline: none;\n width: 100%;\n box-sizing: border-box;\n }\n .arv-left__section-title {\n font-size: 9px;\n color: var(--arv-text-muted, #888);\n text-transform: uppercase;\n padding: 4px 10px 2px;\n flex-shrink: 0;\n }\n .arv-left__list {\n flex: 1;\n overflow-y: auto;\n min-height: 0;\n }\n .arv-left__loading { padding: 12px; font-size: 11px; color: var(--arv-text-muted, #888); }\n .arv-bm {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n padding: 5px 10px;\n cursor: pointer;\n font-size: 11px;\n border-radius: 2px;\n margin: 1px 4px;\n }\n .arv-bm:hover { background: var(--arv-surface2, #313148); }\n .arv-bm--active { background: rgba(91,142,240,0.15); color: var(--arv-accent, #5b8ef0); }\n .arv-bm__col { display: flex; flex-direction: column; gap: 2px; overflow: hidden; }\n .arv-bm__label { font-size: 11px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .arv-bm__snippet { font-size: 9px; color: var(--arv-text-muted, #888); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .arv-bm__icon { flex-shrink: 0; font-size: 12px; }\n .arv-thumb__box {\n width: 30px; height: 40px;\n background: white;\n border: 1px solid var(--arv-border, #3d3d5c);\n border-radius: 2px;\n display: flex; align-items: center; justify-content: center;\n flex-shrink: 0;\n }\n .arv-thumb__num { font-size: 8px; color: #999; }\n .arv-left__footer {\n padding: 6px 10px;\n font-size: 10px;\n color: var(--arv-text-muted, #888);\n border-top: 1px solid var(--arv-border, #3d3d5c);\n flex-shrink: 0;\n display: flex; gap: 4px;\n }\n .arv-spinner-sm {\n width: 14px; height: 14px;\n border: 2px solid var(--arv-border, #3d3d5c);\n border-top-color: var(--arv-accent, #5b8ef0);\n border-radius: 50%;\n animation: arv-spin 0.7s linear infinite;\n flex-shrink: 0;\n }\n @keyframes arv-spin { to { transform: rotate(360deg); } }\n `]\n})\nexport class LeftPanelComponent implements OnInit, OnDestroy {\n @Input() currentPage = 1;\n @Output() pageSelected = new EventEmitter<number>();\n\n thumbnails?: ThumbnailListResponse;\n searchQuery = '';\n lastQuery = '';\n searching = false;\n searchResults: SearchHit[] = [];\n\n private destroy$ = new Subject<void>();\n private search$ = new Subject<string>();\n\n constructor(\n public api: ReportViewerApiService,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnInit(): void {\n // Load thumbnails when session is ready\n this.api.session$\n .pipe(takeUntil(this.destroy$))\n .subscribe(s => {\n if (s) this.loadThumbnails();\n });\n\n // Debounced search\n this.search$.pipe(\n takeUntil(this.destroy$),\n debounceTime(400),\n distinctUntilChanged(),\n switchMap(q => {\n if (!q.trim()) {\n this.searchResults = [];\n this.searching = false;\n this.cdr.markForCheck();\n return [];\n }\n this.searching = true;\n this.cdr.markForCheck();\n return this.api.search(q);\n })\n ).subscribe({\n next: r => {\n this.searchResults = r.results;\n this.lastQuery = r.query;\n this.searching = false;\n this.cdr.markForCheck();\n },\n error: () => { this.searching = false; this.cdr.markForCheck(); }\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private loadThumbnails(): void {\n this.api.getThumbnails()\n .pipe(takeUntil(this.destroy$))\n .subscribe(t => {\n this.thumbnails = t;\n this.cdr.markForCheck();\n });\n }\n\n onSearchChange(q: string): void {\n this.search$.next(q);\n }\n\n goTo(page: number): void {\n this.pageSelected.emit(page);\n }\n}\n","import {\n Component, Input, OnInit, OnDestroy, AfterViewInit,\n ViewChild, ViewChildren, QueryList, ElementRef,\n ChangeDetectionStrategy, ChangeDetectorRef\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { Subject, fromEvent } from 'rxjs';\nimport { takeUntil, debounceTime } from 'rxjs/operators';\n\nimport { ReportViewerApiService, PageResponse } from '../services/report-viewer-api.service';\nimport { PageRendererComponent } from './page-renderer.component';\nimport { LeftPanelComponent } from './left-panel.component';\n\nconst PT_TO_PX = 1.333;\nconst WINDOW_RADIUS = 5; // render ±5 pages around current\n\n@Component({\n selector: 'arv-report-viewer',\n standalone: true,\n imports: [CommonModule, FormsModule, PageRendererComponent, LeftPanelComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"arv-shell\" [attr.data-theme]=\"theme\">\n\n <!-- ═══ TOOLBAR ════════════════════════════════════════════════ -->\n <div class=\"arv-toolbar arv-no-print\">\n\n <span class=\"arv-toolbar__brand\">📄 Report Viewer</span>\n\n <!-- Navigation -->\n <div class=\"arv-nav\">\n <button class=\"arv-btn arv-btn--icon\" title=\"First\" [disabled]=\"currentPage <= 1\"\n (click)=\"navigateTo(1)\">⏮</button>\n <button class=\"arv-btn arv-btn--icon\" title=\"Previous\" [disabled]=\"currentPage <= 1\"\n (click)=\"navigateTo(currentPage - 1)\">◀</button>\n\n <input class=\"arv-page-input\" type=\"number\"\n [min]=\"1\" [max]=\"api.pageCount\"\n [ngModel]=\"currentPage\"\n (change)=\"onPageInputChange($event)\" />\n <span class=\"arv-nav__of\">/ {{ api.pageCount }}</span>\n\n <button class=\"arv-btn arv-btn--icon\" title=\"Next\"\n [disabled]=\"currentPage >= api.pageCount\"\n (click)=\"navigateTo(currentPage + 1)\">▶</button>\n <button class=\"arv-btn arv-btn--icon\" title=\"Last\"\n [disabled]=\"currentPage >= api.pageCount\"\n (click)=\"navigateTo(api.pageCount)\">⏭</button>\n </div>\n\n <!-- Zoom -->\n <div class=\"arv-zoom\">\n <button class=\"arv-btn arv-btn--icon\" title=\"Zoom out\" (click)=\"zoomOut()\">−</button>\n <span class=\"arv-zoom__val\">{{ zoomPercent }}%</span>\n <button class=\"arv-btn arv-btn--icon\" title=\"Zoom in\" (click)=\"zoomIn()\">+</button>\n <button class=\"arv-btn arv-btn--sm\" (click)=\"zoomReset()\">1:1</button>\n </div>\n\n <!-- Refresh -->\n <button class=\"arv-btn arv-btn--sm\" title=\"Refresh\" (click)=\"refresh()\">🔄</button>\n\n <!-- Print -->\n <div class=\"arv-btn-group\">\n <button class=\"arv-btn arv-btn--sm\" title=\"Print all pages\" (click)=\"printAll()\">🖨 Print All</button>\n <button class=\"arv-btn arv-btn--sm\" title=\"Print current page\" (click)=\"printCurrent()\">🖨 Page</button>\n </div>\n\n <!-- Download page as image -->\n <button class=\"arv-btn arv-btn--sm\" title=\"Download current page as image\"\n (click)=\"downloadPageImage()\">⬇ Image</button>\n\n <!-- Status -->\n <div class=\"arv-status\">\n @if (api.loading$ | async) {\n <span class=\"arv-spinner-sm\"></span> Rendering…\n } @else if (api.pageCount > 0) {\n <span class=\"arv-status__ok\">✓ {{ api.pageCount }} pages</span>\n }\n </div>\n </div>\n\n <!-- ═══ BODY ════════════════════════════════════════════════════ -->\n <div class=\"arv-body\">\n\n <!-- Left panel -->\n <arv-left-panel\n class=\"arv-no-print\"\n [currentPage]=\"currentPage\"\n (pageSelected)=\"navigateTo($event)\">\n </arv-left-panel>\n\n <!-- Virtual page list -->\n <div class=\"arv-canvas-scroll\"\n #scrollEl\n (scroll)=\"onScroll()\">\n\n @if (api.loading$ | async) {\n <div class=\"arv-loading\">\n <div class=\"arv-spinner\"></div>\n <div>Rendering report…</div>\n </div>\n }\n\n @else if ((api.session$ | async) === null) {\n <div class=\"arv-empty\">\n No report loaded.\n </div>\n }\n\n @else {\n <div class=\"arv-page-list\"\n [style.width.px]=\"pageListWidth\">\n\n @for (p of pageNumbers; track p) {\n <div class=\"arv-page-wrap\"\n [id]=\"'arv-pw-' + p\"\n [style.height.px]=\"pageWrapHeight\">\n\n <div class=\"arv-page-num-label arv-no-print\">{{ p }}</div>\n\n @if (isInWindow(p)) {\n <!-- Rendered page -->\n <arv-page-renderer\n #pageRenderers\n [page]=\"getPage(p)\"\n [scale]=\"scale\"\n [attr.data-page]=\"p\">\n </arv-page-renderer>\n } @else {\n <!-- Placeholder (correct height to keep scrollbar accurate) -->\n <div class=\"arv-placeholder\"\n [style.width.px]=\"pageWidthPx\"\n [style.height.px]=\"pageHeightPx\">\n Page {{ p }}\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- ═══ PRINT STYLES ═══════════════════════════════════════════════ -->\n <style id=\"arv-print-css\">\n @media print {\n .arv-no-print { display: none !important; }\n .arv-shell { height: auto !important; }\n .arv-body { overflow: visible !important; }\n .arv-canvas-scroll { overflow: visible !important; height: auto !important; }\n .arv-page-wrap { page-break-after: always; }\n .arv-page-wrap:last-child { page-break-after: avoid; }\n }\n </style>\n `,\n styles: [`\n :host { display: block; height: 100%; }\n\n /* Shell */\n .arv-shell {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--arv-bg, #1e1e2e);\n color: var(--arv-text, #abb2bf);\n font-family: system-ui, -apple-system, sans-serif;\n font-size: 12px;\n }\n [data-theme=\"light\"] {\n --arv-bg: #f0f0f5;\n --arv-surface: #ffffff;\n --arv-surface2: #f5f5fa;\n --arv-border: #d0d0e0;\n --arv-accent: #3b6fd4;\n --arv-text: #333;\n --arv-text-muted: #888;\n }\n\n /* Toolbar */\n .arv-toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 0 12px;\n height: 44px;\n flex-shrink: 0;\n background: var(--arv-surface, #2a2a3e);\n border-bottom: 1px solid var(--arv-border, #3d3d5c);\n flex-wrap: wrap;\n }\n .arv-toolbar__brand {\n font-weight: 700; font-size: 13px;\n color: var(--arv-text-strong, #eee);\n margin-right: 8px;\n }\n\n /* Nav */\n .arv-nav { display: flex; align-items: center; gap: 4px; }\n .arv-nav__of { font-size: 11px; color: var(--arv-text-muted, #888); }\n .arv-page-input {\n width: 52px; text-align: center;\n padding: 2px 4px;\n background: var(--arv-surface, #2a2a3e);\n border: 1px solid var(--arv-border, #3d3d5c);\n border-radius: 4px;\n color: var(--arv-text, #ccc);\n font-size: 12px;\n }\n\n /* Zoom */\n .arv-zoom { display: flex; align-items: center; gap: 4px; }\n .arv-zoom__val { min-width: 42px; text-align: center; font-size: 11px; color: var(--arv-text-muted, #888); }\n\n /* Buttons */\n .arv-btn {\n display: inline-flex; align-items: center; gap: 3px;\n padding: 3px 8px;\n background: var(--arv-surface2, #313148);\n border: 1px solid var(--arv-border, #3d3d5c);\n border-radius: 4px;\n color: var(--arv-text, #ccc);\n font-size: 11px;\n cursor: pointer;\n white-space: nowrap;\n }\n .arv-btn:hover { background: var(--arv-border, #3d3d5c); }\n .arv-btn:disabled { opacity: 0.4; pointer-events: none; }\n .arv-btn--icon { padding: 3px 6px; font-size: 13px; }\n .arv-btn--sm { padding: 2px 7px; }\n .arv-btn-group { display: flex; gap: 1px; }\n .arv-btn-group .arv-btn:first-child { border-radius: 4px 0 0 4px; }\n .arv-btn-group .arv-btn:last-child { border-radius: 0 4px 4px 0; }\n\n /* Status */\n .arv-status { margin-left: auto; display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--arv-text-muted, #888); }\n .arv-status__ok { color: #4caf50; }\n\n /* Body */\n .arv-body { display: flex; flex: 1; overflow: hidden; min-height: 0; }\n\n /* Canvas scroll */\n .arv-canvas-scroll {\n flex: 1;\n overflow: auto;\n background: var(--arv-bg, #1e1e2e);\n padding: 20px;\n display: flex;\n flex-direction: column;\n align-items: center;\n }\n\n /* Page list */\n .arv-page-list { display: flex; flex-direction: column; align-items: center; }\n .arv-page-wrap { position: relative; display: flex; flex-direction: column; align-items: center; padding-bottom: 16px; }\n .arv-page-num-label { font-size: 10px; color: var(--arv-text-muted, #888); margin-bottom: 4px; align-self: flex-start; }\n .arv-placeholder {\n background: var(--arv-surface, #2a2a3e);\n border: 1px dashed var(--arv-border, #3d3d5c);\n display: flex; align-items: center; justify-content: center;\n color: var(--arv-text-muted, #888); font-size: 11px;\n }\n\n /* Loading */\n .arv-loading { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 60px; color: var(--arv-text-muted, #888); }\n .arv-spinner {\n width: 32px; height: 32px;\n border: 3px solid var(--arv-border, #3d3d5c);\n border-top-color: var(--arv-accent, #5b8ef0);\n border-radius: 50%;\n animation: arv-spin 0.8s linear infinite;\n }\n .arv-spinner-sm {\n display: inline-block;\n width: 14px; height: 14px;\n border: 2px solid var(--arv-border, #3d3d5c);\n border-top-color: var(--arv-accent, #5b8ef0);\n border-radius: 50%;\n animation: arv-spin 0.7s linear infinite;\n }\n @keyframes arv-spin { to { transform: rotate(360deg); } }\n .arv-empty { padding: 60px; text-align: center; color: var(--arv-text-muted, #888); }\n `]\n})\nexport class ReportViewerComponent implements OnInit, OnDestroy, AfterViewInit {\n\n /** API base URL, e.g. 'http://localhost:5000' */\n @Input() set apiBaseUrl(url: string) {\n if (url) this.api.configure(url);\n }\n\n /** Light or dark theme */\n @Input() theme: 'light' | 'dark' = 'dark';\n\n /** If provided, render this report on init */\n @Input() renderRequest?: { reportXml: string; data?: any; parameters?: any };\n\n @ViewChild('scrollEl') scrollEl!: ElementRef<HTMLDivElement>;\n @ViewChildren('pageRenderers') pageRenderers!: QueryList<PageRendererComponent>;\n\n currentPage = 1;\n scale = PT_TO_PX;\n pageCache = new Map<number, PageResponse>();\n\n private destroy$ = new Subject<void>();\n private printPage?: number; // undefined = all, number = single page\n\n constructor(\n public api: ReportViewerApiService,\n private cdr: ChangeDetectorRef\n ) {}\n\n // ── Lifecycle ──────────────────────────────────────────────────────────────\n\n ngOnInit(): void {\n // Subscribe to external navigation commands\n this.api.navigateTo$\n .pipe(takeUntil(this.destroy$))\n .subscribe(p => this.navigateTo(p));\n\n // Auto-render if input provided\n if (this.renderRequest) {\n this.api.render(this.renderRequest)\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => { this.currentPage = 1; this.cdr.markForCheck(); });\n }\n }\n\n ngAfterViewInit(): void {}\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ── Page numbers ───────────────────────────────────────────────────────────\n\n get pageNumbers(): number[] {\n const count = this.api.pageCount;\n return count > 0 ? Array.from({ length: count }, (_, i) => i + 1) : [];\n }\n\n get pageWidthPx(): number { return this.api.pageWidthPt * this.scale; }\n get pageHeightPx(): number { return this.api.pageHeightPt * this.scale; }\n get pageWrapHeight(): number { return this.pageHeightPx + 32; }\n get pageListWidth(): number { return this.pageWidthPx + 40; }\n get zoomPercent(): number { return Math.round(this.scale / PT_TO_PX * 100); }\n\n isInWindow(p: number): boolean {\n return Math.abs(p - this.currentPage) <= WINDOW_RADIUS;\n }\n\n getPage(p: number): PageResponse | undefined {\n if (!this.pageCache.has(p)) {\n // Trigger async load\n this.loadPage(p);\n return undefined;\n }\n return this.pageCache.get(p);\n }\n\n private loadPage(p: number): void {\n if (this.pageCache.has(p)) return;\n this.api.getPage(p)\n .pipe(takeUntil(this.destroy$))\n .subscribe(page => {\n this.pageCache.set(p, page);\n this.cdr.markForCheck();\n });\n }\n\n // Preload window pages whenever currentPage changes\n private preloadWindow(): void {\n const from = Math.max(1, this.currentPage - WINDOW_RADIUS);\n const to = Math.min(this.api.pageCount, this.currentPage + WINDOW_RADIUS);\n for (let p = from; p <= to; p++) this.loadPage(p);\n }\n\n // ── Navigation ─────────────────────────────────────────────────────────────\n\n navigateTo(page: number): void {\n this.currentPage = Math.max(1, Math.min(page, this.api.pageCount));\n this.preloadWindow();\n this.cdr.markForCheck();\n setTimeout(() => this.scrollToPage(this.currentPage), 50);\n }\n\n onPageInputChange(e: Event): void {\n const v = parseInt((e.target as HTMLInputElement).value, 10);\n if (!isNaN(v)) this.navigateTo(v);\n }\n\n private scrollToPage(p: number): void {\n const el = document.getElementById(`arv-pw-${p}`);\n const scroll = this.scrollEl?.nativeElement;\n if (el && scroll) {\n scroll.scrollTo({ top: el.offsetTop - 8, behavior: 'smooth' });\n }\n }\n\n onScroll(): void {\n const scroll = this.scrollEl?.nativeElement;\n if (!scroll) return;\n const list = scroll.querySelector('.arv-page-list') as HTMLElement;\n if (!list) return;\n const mid = scroll.scrollTop + scroll.clientHeight / 2;\n let best = 1, bestDist = Infinity;\n for (const child of Array.from(list.children) as HTMLElement[]) {\n if (!child.id?.startsWith('arv-pw-')) continue;\n const p = parseInt(child.id.replace('arv-pw-', ''), 10);\n const dist = Math.abs(child.offsetTop + child.offsetHeight / 2 - mid);\n if (dist < bestDist) { bestDist = dist; best = p; }\n }\n if (best !== this.currentPage) {\n this.currentPage = best;\n this.preloadWindow();\n this.cdr.markForCheck();\n }\n }\n\n // ── Zoom ───────────────────────────────────────────────────────────────────\n\n zoomIn(): void { this.scale = Math.min(this.scale * 1.2, PT_TO_PX * 4); this.cdr.markForCheck(); }\n zoomOut(): void { this.scale = Math.max(this.scale / 1.2, PT_TO_PX * 0.25); this.cdr.markForCheck(); }\n zoomReset(): void { this.scale = PT_TO_PX; this.cdr.markForCheck(); }\n\n // ── Refresh ────────────────────────────────────────────────────────────────\n\n refresh(): void {\n this.pageCache.clear();\n this.api.clearCache();\n this.preloadWindow();\n this.cdr.markForCheck();\n }\n\n // ── Print ──────────────────────────────────────────────────────────────────\n\n printAll(): void {\n this.ensureAllPagesLoaded(() => window.print());\n }\n\n printCurrent(): void {\n // Add temporary class to hide all other pages\n const list = document.querySelector('.arv-page-list');\n if (!list) { window.print(); return; }\n Array.from(list.querySelectorAll('.arv-page-wrap')).forEach((el: Element) => {\n const pageEl = el as HTMLElement;\n const id = pageEl.id?.replace('arv-pw-', '');\n pageEl.style.display = id === String(this.currentPage) ? '' : 'none';\n });\n window.print();\n // Restore\n Array.from(list.querySelectorAll('.arv-page-wrap'))\n .forEach((el: Element) => ((el as HTMLElement).style.display = ''));\n }\n\n private ensureAllPagesLoaded(callback: () => void): void {\n // Pre-load remaining pages then print\n const missing: number[] = [];\n for (let p = 1; p <= this.api.pageCount; p++) {\n if (!this.pageCache.has(p)) missing.push(p);\n }\n if (missing.length === 0) { callback(); return; }\n\n let loaded = 0;\n for (const p of missing) {\n this.api.getPage(p).pipe(takeUntil(this.destroy$)).subscribe(page => {\n this.pageCache.set(p, page);\n loaded++;\n this.cdr.markForCheck();\n if (loaded === missing.length) callback();\n });\n }\n }\n\n // ── Download page as image ─────────────────────────────────────────────────\n\n async downloadPageImage(): Promise<void> {\n // Find the current page's renderer\n const renderer = this.pageRenderers.find(r => {\n const el = r.getPageElement();\n return el?.getAttribute('data-page') === String(this.currentPage);\n });\n const pageEl = renderer?.getPageElement();\n if (!pageEl) { alert('Page not rendered yet. Please wait.'); return; }\n\n try {\n // Use html2canvas if available, otherwise canvas screenshot\n const h2c = (window as any).html2canvas;\n if (h2c) {\n const canvas = await h2c(pageEl, { scale: 2, useCORS: true });\n this.downloadCanvas(canvas, `page-${this.currentPage}.png`);\n } else {\n // Fallback: DOM-to-canvas via browser print screenshot prompt\n alert('html2canvas not loaded. Add <script src=\"https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js\"></script> to your index.html for image download.');\n }\n } catch (e) {\n console.error('Screenshot failed', e);\n }\n }\n\n private downloadCanvas(canvas: HTMLCanvasElement, filename: string): void {\n const a = document.createElement('a');\n a.href = canvas.toDataURL('image/png');\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n }\n}\n","// Public API for the report-viewer Angular library\r\nexport { ReportViewerComponent } from './lib/arilekh-report-viewer/components/report-viewer.component';\r\nexport { PageRendererComponent } from './lib/arilekh-report-viewer/components/page-renderer.component';\r\nexport { LeftPanelComponent } from './lib/arilekh-report-viewer/components/left-panel.component';\r\nexport { ReportViewerApiService } from './lib/arilekh-report-viewer/services/report-viewer-api.service';\r\nexport type {\r\n RenderRequest, RenderResponse,\r\n PageResponse, ElementDto, StyleDto,\r\n ThumbnailListResponse, PageSummary,\r\n SearchResponse, SearchHit,\r\n} from './lib/arilekh-report-viewer/services/report-viewer-api.service';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["PT_TO_PX","i1.ReportViewerApiService"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "arilekh-report-viewer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/common": "^21.2.0",
|
|
6
|
+
"@angular/core": "^21.2.0"
|
|
7
|
+
},
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"tslib": "^2.3.0"
|
|
10
|
+
},
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"module": "fesm2022/arilekh-report-viewer.mjs",
|
|
13
|
+
"typings": "types/arilekh-report-viewer.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
"./package.json": {
|
|
16
|
+
"default": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./types/arilekh-report-viewer.d.ts",
|
|
20
|
+
"default": "./fesm2022/arilekh-report-viewer.mjs"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"type": "module"
|
|
24
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { OnChanges, ElementRef, SimpleChanges, OnInit, OnDestroy, AfterViewInit, QueryList, ChangeDetectorRef, EventEmitter } from '@angular/core';
|
|
3
|
+
import { HttpClient } from '@angular/common/http';
|
|
4
|
+
import { Observable } from 'rxjs';
|
|
5
|
+
|
|
6
|
+
interface RenderRequest {
|
|
7
|
+
reportXml: string;
|
|
8
|
+
data?: Record<string, Record<string, unknown>[]>;
|
|
9
|
+
parameters?: Record<string, unknown>;
|
|
10
|
+
ttlMinutes?: number;
|
|
11
|
+
}
|
|
12
|
+
interface RenderResponse {
|
|
13
|
+
sessionId: string;
|
|
14
|
+
pageCount: number;
|
|
15
|
+
pageWidthPt: number;
|
|
16
|
+
pageHeightPt: number;
|
|
17
|
+
renderedAt: string;
|
|
18
|
+
renderMs: number;
|
|
19
|
+
}
|
|
20
|
+
interface StyleDto {
|
|
21
|
+
fontFamily?: string;
|
|
22
|
+
fontSize?: number;
|
|
23
|
+
bold: boolean;
|
|
24
|
+
italic: boolean;
|
|
25
|
+
underline: boolean;
|
|
26
|
+
foreColor?: string;
|
|
27
|
+
backColor?: string;
|
|
28
|
+
paddingLeft: number;
|
|
29
|
+
paddingRight: number;
|
|
30
|
+
}
|
|
31
|
+
interface ElementDto {
|
|
32
|
+
type: 'text' | 'rect' | 'line' | 'ellipse' | 'image';
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
width: number;
|
|
36
|
+
height: number;
|
|
37
|
+
rotation: number;
|
|
38
|
+
text?: string;
|
|
39
|
+
alignment?: 'left' | 'center' | 'right';
|
|
40
|
+
verticalAlign?: 'top' | 'middle' | 'bottom';
|
|
41
|
+
hyperlinkUrl?: string;
|
|
42
|
+
style?: StyleDto;
|
|
43
|
+
fillColor?: string;
|
|
44
|
+
strokeColor?: string;
|
|
45
|
+
strokeWidth?: number;
|
|
46
|
+
borderRadius?: number;
|
|
47
|
+
x2?: number;
|
|
48
|
+
y2?: number;
|
|
49
|
+
src?: string;
|
|
50
|
+
stretch?: string;
|
|
51
|
+
}
|
|
52
|
+
interface PageResponse {
|
|
53
|
+
pageNumber: number;
|
|
54
|
+
totalPages: number;
|
|
55
|
+
widthPt: number;
|
|
56
|
+
heightPt: number;
|
|
57
|
+
elements: ElementDto[];
|
|
58
|
+
}
|
|
59
|
+
interface PageSummary {
|
|
60
|
+
pageNumber: number;
|
|
61
|
+
firstText: string;
|
|
62
|
+
groupLabel: string;
|
|
63
|
+
}
|
|
64
|
+
interface ThumbnailListResponse {
|
|
65
|
+
sessionId: string;
|
|
66
|
+
pageCount: number;
|
|
67
|
+
pages: PageSummary[];
|
|
68
|
+
}
|
|
69
|
+
interface SearchHit {
|
|
70
|
+
pageNumber: number;
|
|
71
|
+
snippet: string;
|
|
72
|
+
x: number;
|
|
73
|
+
y: number;
|
|
74
|
+
}
|
|
75
|
+
interface SearchResponse {
|
|
76
|
+
query: string;
|
|
77
|
+
hits: number;
|
|
78
|
+
results: SearchHit[];
|
|
79
|
+
}
|
|
80
|
+
declare class ReportViewerApiService {
|
|
81
|
+
private http;
|
|
82
|
+
private baseUrl;
|
|
83
|
+
private _session;
|
|
84
|
+
private _loading;
|
|
85
|
+
private _error;
|
|
86
|
+
private _pageCache;
|
|
87
|
+
private _navigateTo$;
|
|
88
|
+
readonly session$: Observable<RenderResponse | null>;
|
|
89
|
+
readonly loading$: Observable<boolean>;
|
|
90
|
+
readonly error$: Observable<string | null>;
|
|
91
|
+
readonly navigateTo$: Observable<number>;
|
|
92
|
+
configure(apiBaseUrl: string): void;
|
|
93
|
+
get sessionId(): string | null;
|
|
94
|
+
get pageCount(): number;
|
|
95
|
+
get pageWidthPt(): number;
|
|
96
|
+
get pageHeightPt(): number;
|
|
97
|
+
constructor(http: HttpClient);
|
|
98
|
+
render(req: RenderRequest): Observable<RenderResponse>;
|
|
99
|
+
getPage(pageNumber: number): Observable<PageResponse>;
|
|
100
|
+
getPageRange(from: number, to: number): Observable<PageResponse[]>;
|
|
101
|
+
getThumbnails(): Observable<ThumbnailListResponse>;
|
|
102
|
+
search(query: string): Observable<SearchResponse>;
|
|
103
|
+
navigateTo(page: number): void;
|
|
104
|
+
evictPage(pageNumber: number): void;
|
|
105
|
+
clearCache(): void;
|
|
106
|
+
isPageCached(pageNumber: number): boolean;
|
|
107
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ReportViewerApiService, never>;
|
|
108
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ReportViewerApiService>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
declare class PageRendererComponent implements OnChanges {
|
|
112
|
+
page?: PageResponse;
|
|
113
|
+
scale: number;
|
|
114
|
+
pageEl?: ElementRef<HTMLDivElement>;
|
|
115
|
+
protected Math: Math;
|
|
116
|
+
get widthPx(): number;
|
|
117
|
+
get heightPx(): number;
|
|
118
|
+
ngOnChanges(c: SimpleChanges): void;
|
|
119
|
+
textStyle(el: ElementDto): Record<string, string>;
|
|
120
|
+
rectStyle(el: ElementDto): Record<string, string>;
|
|
121
|
+
lineSvgStyle(el: ElementDto): Record<string, string>;
|
|
122
|
+
lineX1(el: ElementDto): number;
|
|
123
|
+
lineY1(el: ElementDto): number;
|
|
124
|
+
lineX2(el: ElementDto): number;
|
|
125
|
+
lineY2(el: ElementDto): number;
|
|
126
|
+
ellipseSvgStyle(el: ElementDto): Record<string, string>;
|
|
127
|
+
imageStyle(el: ElementDto): Record<string, string>;
|
|
128
|
+
openLink(url: string): void;
|
|
129
|
+
/** Expose the page div for screenshot (called by parent). */
|
|
130
|
+
getPageElement(): HTMLDivElement | undefined;
|
|
131
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PageRendererComponent, never>;
|
|
132
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PageRendererComponent, "arv-page-renderer", never, { "page": { "alias": "page"; "required": false; }; "scale": { "alias": "scale"; "required": false; }; }, {}, never, never, true, never>;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
declare class ReportViewerComponent implements OnInit, OnDestroy, AfterViewInit {
|
|
136
|
+
api: ReportViewerApiService;
|
|
137
|
+
private cdr;
|
|
138
|
+
/** API base URL, e.g. 'http://localhost:5000' */
|
|
139
|
+
set apiBaseUrl(url: string);
|
|
140
|
+
/** Light or dark theme */
|
|
141
|
+
theme: 'light' | 'dark';
|
|
142
|
+
/** If provided, render this report on init */
|
|
143
|
+
renderRequest?: {
|
|
144
|
+
reportXml: string;
|
|
145
|
+
data?: any;
|
|
146
|
+
parameters?: any;
|
|
147
|
+
};
|
|
148
|
+
scrollEl: ElementRef<HTMLDivElement>;
|
|
149
|
+
pageRenderers: QueryList<PageRendererComponent>;
|
|
150
|
+
currentPage: number;
|
|
151
|
+
scale: number;
|
|
152
|
+
pageCache: Map<number, PageResponse>;
|
|
153
|
+
private destroy$;
|
|
154
|
+
private printPage?;
|
|
155
|
+
constructor(api: ReportViewerApiService, cdr: ChangeDetectorRef);
|
|
156
|
+
ngOnInit(): void;
|
|
157
|
+
ngAfterViewInit(): void;
|
|
158
|
+
ngOnDestroy(): void;
|
|
159
|
+
get pageNumbers(): number[];
|
|
160
|
+
get pageWidthPx(): number;
|
|
161
|
+
get pageHeightPx(): number;
|
|
162
|
+
get pageWrapHeight(): number;
|
|
163
|
+
get pageListWidth(): number;
|
|
164
|
+
get zoomPercent(): number;
|
|
165
|
+
isInWindow(p: number): boolean;
|
|
166
|
+
getPage(p: number): PageResponse | undefined;
|
|
167
|
+
private loadPage;
|
|
168
|
+
private preloadWindow;
|
|
169
|
+
navigateTo(page: number): void;
|
|
170
|
+
onPageInputChange(e: Event): void;
|
|
171
|
+
private scrollToPage;
|
|
172
|
+
onScroll(): void;
|
|
173
|
+
zoomIn(): void;
|
|
174
|
+
zoomOut(): void;
|
|
175
|
+
zoomReset(): void;
|
|
176
|
+
refresh(): void;
|
|
177
|
+
printAll(): void;
|
|
178
|
+
printCurrent(): void;
|
|
179
|
+
private ensureAllPagesLoaded;
|
|
180
|
+
downloadPageImage(): Promise<void>;
|
|
181
|
+
private downloadCanvas;
|
|
182
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ReportViewerComponent, never>;
|
|
183
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ReportViewerComponent, "arv-report-viewer", never, { "apiBaseUrl": { "alias": "apiBaseUrl"; "required": false; }; "theme": { "alias": "theme"; "required": false; }; "renderRequest": { "alias": "renderRequest"; "required": false; }; }, {}, never, never, true, never>;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
declare class LeftPanelComponent implements OnInit, OnDestroy {
|
|
187
|
+
api: ReportViewerApiService;
|
|
188
|
+
private cdr;
|
|
189
|
+
currentPage: number;
|
|
190
|
+
pageSelected: EventEmitter<number>;
|
|
191
|
+
thumbnails?: ThumbnailListResponse;
|
|
192
|
+
searchQuery: string;
|
|
193
|
+
lastQuery: string;
|
|
194
|
+
searching: boolean;
|
|
195
|
+
searchResults: SearchHit[];
|
|
196
|
+
private destroy$;
|
|
197
|
+
private search$;
|
|
198
|
+
constructor(api: ReportViewerApiService, cdr: ChangeDetectorRef);
|
|
199
|
+
ngOnInit(): void;
|
|
200
|
+
ngOnDestroy(): void;
|
|
201
|
+
private loadThumbnails;
|
|
202
|
+
onSearchChange(q: string): void;
|
|
203
|
+
goTo(page: number): void;
|
|
204
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<LeftPanelComponent, never>;
|
|
205
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<LeftPanelComponent, "arv-left-panel", never, { "currentPage": { "alias": "currentPage"; "required": false; }; }, { "pageSelected": "pageSelected"; }, never, never, true, never>;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export { LeftPanelComponent, PageRendererComponent, ReportViewerApiService, ReportViewerComponent };
|
|
209
|
+
export type { ElementDto, PageResponse, PageSummary, RenderRequest, RenderResponse, SearchHit, SearchResponse, StyleDto, ThumbnailListResponse };
|