@nexterajs/report-viewer 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +16 -0
- package/README.md +96 -0
- package/fesm2022/nexterajs-report-viewer.mjs +1219 -0
- package/fesm2022/nexterajs-report-viewer.mjs.map +1 -0
- package/package.json +41 -0
- package/types/nexterajs-report-viewer.d.ts +387 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nexterajs-report-viewer.mjs","sources":["../../../projects/nextera-report-viewer/src/lib/protocol/nxr-protocol.const.ts","../../../projects/nextera-report-viewer/src/lib/page/nxr-page-html.util.ts","../../../projects/nextera-report-viewer/src/lib/page/nxr-report-page.component.ts","../../../projects/nextera-report-viewer/src/lib/strings/nxr-viewer-strings.const.ts","../../../projects/nextera-report-viewer/src/lib/protocol/nxr-protocol-reader.util.ts","../../../projects/nextera-report-viewer/src/lib/protocol/nxr-viewer-client.service.ts","../../../projects/nextera-report-viewer/src/lib/session/nxr-viewer-session.service.ts","../../../projects/nextera-report-viewer/src/lib/toolbar/nxr-viewer-toolbar.component.ts","../../../projects/nextera-report-viewer/src/lib/viewer/nxr-report-viewer.component.ts","../../../projects/nextera-report-viewer/src/public-api.ts","../../../projects/nextera-report-viewer/src/nexterajs-report-viewer.ts"],"sourcesContent":["/**\n * The version of the viewer protocol this package speaks: the `protocol` member of every\n * `AngularViewerData` answer from `Nextera.Report.AspNetCore`.\n */\nexport const NXR_VIEWER_PROTOCOL = 1;\n","/**\n * Page HTML from the server, made safe to place in the application's document.\n *\n * The report repository's HTML renderer escapes every attribute value and writes links only with\n * http, https, mailto, tel or no scheme, and its chart renderer strips event handlers from chart SVG.\n * This is the second layer: whatever reaches the viewer, a page can neither run script nor load active\n * content, and it cannot style the viewer around it.\n */\n\n/**\n * Elements that run script, load documents, plugins or media, submit, animate other attributes, or\n * carry CSS of their own. The renderer writes none of them into a page.\n */\nconst REMOVED_ELEMENTS = [\n 'script',\n 'noscript',\n 'template',\n 'style',\n 'link',\n 'meta',\n 'base',\n 'iframe',\n 'frame',\n 'frameset',\n 'object',\n 'embed',\n 'applet',\n 'portal',\n 'audio',\n 'video',\n 'source',\n 'track',\n 'picture',\n 'form',\n 'set',\n 'animate',\n].join(',');\n\n/** Attributes holding a URL that a click or a load would follow. */\nconst URL_ATTRIBUTES = new Set([\n 'href',\n 'xlink:href',\n 'src',\n 'action',\n 'formaction',\n 'poster',\n 'background',\n]);\n\n/** Attributes that make requests of their own and have no use in a page. */\nconst REMOVED_ATTRIBUTES = new Set(['srcset', 'ping']);\n\nconst LINK_SCHEMES = new Set(['http', 'https', 'mailto', 'tel']);\n\n/**\n * Whether a URL attribute's value can stay: no scheme (a relative or fragment URL), a link scheme, or,\n * for `src`, an image as a data URL. Browsers ignore spaces and control characters around and inside a\n * scheme, so the check drops them before reading it.\n */\nexport function isSafeUrl(attribute: string, value: string): boolean {\n let compact = '';\n for (const character of value) {\n if (character.charCodeAt(0) > 0x20) compact += character;\n }\n const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(compact)?.[1]?.toLowerCase();\n if (scheme === undefined || LINK_SCHEMES.has(scheme)) return true;\n return attribute === 'src' && scheme === 'data' && /^data:image\\//i.test(compact);\n}\n\n/**\n * Parses page HTML and returns it without anything active. A template's content is inert while it is\n * examined: its scripts do not run, its images do not load and its handlers do not fire.\n */\nexport function scrubPageHtml(html: string, document: Document): DocumentFragment {\n const template = document.createElement('template');\n template.innerHTML = html;\n const content = template.content;\n for (const element of Array.from(content.querySelectorAll(REMOVED_ELEMENTS))) {\n element.remove();\n }\n for (const element of Array.from(content.querySelectorAll('*'))) {\n for (const attribute of Array.from(element.attributes)) {\n const name = attribute.name.toLowerCase();\n const unsafe =\n name.startsWith('on') ||\n REMOVED_ATTRIBUTES.has(name) ||\n (URL_ATTRIBUTES.has(name) && !isSafeUrl(name, attribute.value));\n if (unsafe) element.removeAttribute(attribute.name);\n }\n }\n return content;\n}\n\n/** A stylesheet, or a rule that holds rules: anything whose rules can be listed and deleted by index. */\ninterface RuleContainer {\n readonly cssRules: CSSRuleList;\n deleteRule(index: number): void;\n}\n\n/**\n * Deletes every style rule whose selector names `:host` or `:host-context()`, also inside grouping rules\n * such as `@media` and inside nested rules. In a shadow root those rules style the shadow host, the\n * viewer's own page element, so a page's CSS could otherwise move or hide it.\n */\nfunction deleteHostRules(container: RuleContainer): void {\n for (let index = container.cssRules.length - 1; index >= 0; index--) {\n const rule = container.cssRules[index];\n if (rule instanceof CSSStyleRule && /:host/i.test(rule.selectorText)) {\n container.deleteRule(index);\n } else if ('cssRules' in rule && !(rule instanceof CSSKeyframesRule)) {\n deleteHostRules(rule as unknown as RuleContainer);\n }\n }\n}\n\nconst sheets = new Map<string, CSSStyleSheet>();\n\n/**\n * One constructed stylesheet per distinct CSS text, shared by every shadow root that adopts it. A\n * report's page CSS is the same for every page, so a long report parses it once. The sheet keeps no rule\n * that could style the shadow host. CSS that a constructed stylesheet refuses gives an empty sheet, so the\n * page shows unstyled instead of not at all.\n */\nexport function adoptedSheet(cssText: string): CSSStyleSheet {\n let sheet = sheets.get(cssText);\n if (!sheet) {\n sheet = new CSSStyleSheet();\n try {\n sheet.replaceSync(cssText);\n deleteHostRules(sheet);\n } catch {\n sheet = new CSSStyleSheet();\n }\n sheets.set(cssText, sheet);\n }\n return sheet;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DOCUMENT,\n ElementRef,\n inject,\n input,\n OnChanges,\n SimpleChanges,\n} from '@angular/core';\nimport type { NxrPageSize } from '../protocol/nxr-protocol.model';\nimport { adoptedSheet, scrubPageHtml } from './nxr-page-html.util';\n\n/** The viewer draws each page's frame and the space between pages, so the page CSS's own are cancelled. */\nconst PAGE_FRAME_CSS = '.nextera-page{margin:0;box-shadow:none;}';\n\n/**\n * One report page, in its own shadow root.\n *\n * The page's size comes from the report's page list, so the page holds its place before its HTML\n * arrives. The HTML is scrubbed by `scrubPageHtml` and placed beside the adopted page stylesheet, so the\n * report's styles and the application's never meet. `contain: paint` keeps even a fixed-position\n * element inside the page's box.\n */\n@Component({\n selector: 'nxr-report-page',\n standalone: true,\n template: '',\n styles: `\n :host {\n display: block;\n position: relative;\n box-sizing: content-box;\n contain: paint;\n background: #fff;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'nxr-report-page',\n '[attr.data-page]': 'page().pageNumber',\n '[style.width.pt]': 'page().widthPoints',\n '[style.height.pt]': 'page().heightPoints',\n },\n})\nexport class NxrReportPageComponent implements OnChanges {\n /** The page's number and size. */\n readonly page = input.required<NxrPageSize>();\n /** The page's HTML from the server, or null while it has not arrived. */\n readonly html = input<string | null>(null);\n /** The stylesheet every page of the report needs. */\n readonly css = input.required<string>();\n\n private readonly document = inject(DOCUMENT);\n private readonly root = (inject(ElementRef).nativeElement as HTMLElement).attachShadow({\n mode: 'open',\n });\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['css']) {\n this.root.adoptedStyleSheets = [adoptedSheet(this.css()), adoptedSheet(PAGE_FRAME_CSS)];\n }\n if (changes['html']) {\n const html = this.html();\n if (html === null) {\n this.root.replaceChildren();\n } else {\n this.root.replaceChildren(scrubPageHtml(html, this.document));\n }\n }\n }\n}\n","/**\n * Every caption and message the viewer shows, in its built-in English. A key in PascalCase is the name\n * Stimulsoft's viewer gives the same text, such as `PageOf`; a key in camelCase names a message only this\n * viewer has. The English is this package's own. A later plan lets a host's translation file replace any\n * of them, so code reads them from an `NxrViewerStrings` value wherever one is at hand.\n */\nexport const NXR_ENGLISH = {\n /** The label before the page-number box. */\n Page: 'Page',\n /** The label between the page-number box and the page count. */\n PageOf: 'of',\n FirstPage: 'First page',\n PrevPage: 'Previous page',\n NextPage: 'Next page',\n LastPage: 'Last page',\n errorUnreachable: 'The report server could not be reached.',\n errorStatus: 'The report server answered with HTTP status {0}.',\n errorTimeout: 'The report server did not answer within {0} seconds.',\n errorMalformed: \"The report server's answer to {0} is not one this viewer can read.\",\n errorProtocol:\n 'The report server speaks viewer protocol {0}, and this viewer speaks protocol {1}.',\n};\n\nexport type NxrViewerStrings = Readonly<Record<keyof typeof NXR_ENGLISH, string>>;\n\n/** Puts each value in place of its numbered placeholder: `{0}` is the first value. */\nexport function formatString(template: string, ...values: (string | number)[]): string {\n return template.replace(/\\{(\\d+)\\}/g, (placeholder, index: string) =>\n Number(index) < values.length ? String(values[Number(index)]) : placeholder,\n );\n}\n","import { HttpErrorResponse } from '@angular/common/http';\nimport { formatString, NXR_ENGLISH, NxrViewerStrings } from '../strings/nxr-viewer-strings.const';\nimport { NXR_VIEWER_PROTOCOL } from './nxr-protocol.const';\nimport type {\n NxrFindAnswer,\n NxrPagesAnswer,\n NxrReportAnswer,\n NxrUpdateCacheAnswer,\n NxrViewerAction,\n NxrViewerDataAnswer,\n NxrViewerFailure,\n} from './nxr-protocol.model';\n\n/**\n * A success answer that is not what the protocol says its action answers: the wrong shape, or an\n * AngularViewerData answer from another version of the protocol.\n */\nexport class NxrMalformedAnswerError extends Error {\n constructor(\n readonly action: NxrViewerAction,\n /** The version an AngularViewerData answer declared, when it declared another one. */\n readonly protocol: number = NXR_VIEWER_PROTOCOL,\n ) {\n super(`The ${action} answer is not what viewer protocol ${NXR_VIEWER_PROTOCOL} answers.`);\n this.name = 'NxrMalformedAnswerError';\n }\n}\n\n/** A request that got no answer within the server options' `requestTimeout`. */\nexport class NxrTimeoutError extends Error {\n constructor(readonly seconds: number) {\n super(`No answer within ${seconds} seconds.`);\n this.name = 'NxrTimeoutError';\n }\n}\n\ntype JsonObject = Record<string, unknown>;\n\nconst OPTION_GROUPS = ['actions', 'appearance', 'toolbar', 'exports', 'server'];\n\nfunction isObject(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isIndex(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 0;\n}\n\nfunction isNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\nfunction isBounds(value: unknown): boolean {\n return (\n isObject(value) &&\n isNumber(value['x']) &&\n isNumber(value['y']) &&\n isNumber(value['width']) &&\n isNumber(value['height'])\n );\n}\n\nfunction isPages(value: unknown): value is NxrPagesAnswer {\n if (!isObject(value)) return false;\n const pages = value['pages'];\n return (\n isIndex(value['startIndex']) &&\n Array.isArray(pages) &&\n pages.every((page) => typeof page === 'string')\n );\n}\n\nfunction isPageSize(value: unknown): boolean {\n return (\n isObject(value) &&\n isIndex(value['pageNumber']) &&\n isNumber(value['widthPoints']) &&\n isNumber(value['heightPoints'])\n );\n}\n\nfunction isLocated(value: unknown, textKey: 'title' | 'text'): boolean {\n return (\n isObject(value) &&\n typeof value[textKey] === 'string' &&\n isIndex(value['pageIndex']) &&\n isBounds(value['bounds'])\n );\n}\n\n/** Reads the answer to AngularViewerData: the token, the viewer options and the host's translation. */\nexport function readViewerData(body: unknown): NxrViewerDataAnswer {\n if (!isObject(body)) throw new NxrMalformedAnswerError('AngularViewerData');\n const { protocol, token, options, localization } = body;\n if (isNumber(protocol) && protocol !== NXR_VIEWER_PROTOCOL) {\n throw new NxrMalformedAnswerError('AngularViewerData', protocol);\n }\n const valid =\n protocol === NXR_VIEWER_PROTOCOL &&\n typeof token === 'string' &&\n token !== '' &&\n isObject(options) &&\n OPTION_GROUPS.every((group) => isObject(options[group])) &&\n (localization === null || isObject(localization));\n if (!valid) throw new NxrMalformedAnswerError('AngularViewerData');\n return body as unknown as NxrViewerDataAnswer;\n}\n\n/** Reads the answer to GetReport: the report's name, page count, page sizes, bookmarks and page stylesheet. */\nexport function readReport(body: unknown): NxrReportAnswer {\n if (!isObject(body)) throw new NxrMalformedAnswerError('GetReport');\n const { reportName, pageCount, pages, bookmarks, pageCss, pagesHtml } = body;\n const valid =\n typeof reportName === 'string' &&\n isIndex(pageCount) &&\n Array.isArray(pages) &&\n pages.length === pageCount &&\n pages.every(isPageSize) &&\n Array.isArray(bookmarks) &&\n bookmarks.every((bookmark) => isLocated(bookmark, 'title')) &&\n typeof pageCss === 'string' &&\n (pagesHtml === undefined || isPages(pagesHtml));\n if (!valid) throw new NxrMalformedAnswerError('GetReport');\n return {\n ...(body as unknown as NxrReportAnswer),\n pagesHtml: (pagesHtml as NxrPagesAnswer | undefined) ?? null,\n };\n}\n\n/** Reads the answer to GetPages. */\nexport function readPages(body: unknown): NxrPagesAnswer {\n if (!isPages(body)) throw new NxrMalformedAnswerError('GetPages');\n return body;\n}\n\n/** Reads the answer to Find. */\nexport function readFind(body: unknown): NxrFindAnswer {\n const hits = isObject(body) ? body['hits'] : undefined;\n if (!Array.isArray(hits) || !hits.every((hit) => isLocated(hit, 'text')))\n throw new NxrMalformedAnswerError('Find');\n return body as unknown as NxrFindAnswer;\n}\n\n/** Reads the answer to UpdateCache. */\nexport function readUpdateCache(body: unknown): NxrUpdateCacheAnswer {\n if (!isObject(body) || typeof body['updated'] !== 'boolean')\n throw new NxrMalformedAnswerError('UpdateCache');\n return body as unknown as NxrUpdateCacheAnswer;\n}\n\nfunction described(status: number, message: string): NxrViewerFailure {\n return { status, type: 'Error', message, retryable: false, traceId: null };\n}\n\n/**\n * What went wrong with a request, from whatever it failed with:\n * - the server's own error answer, kept as it is;\n * - an HTTP error answer without the protocol's shape (a host's, a framework's or a proxy's);\n * - no answer at all;\n * - a timeout;\n * - a success answer the viewer cannot read.\n */\nexport function readFailure(\n failure: unknown,\n action: NxrViewerAction,\n strings: NxrViewerStrings = NXR_ENGLISH,\n): NxrViewerFailure {\n if (failure instanceof HttpErrorResponse) {\n const body: unknown = failure.error;\n if (\n isObject(body) &&\n body['status'] === 'error' &&\n typeof body['type'] === 'string' &&\n typeof body['message'] === 'string' &&\n typeof body['retryable'] === 'boolean'\n ) {\n const traceId = typeof body['traceId'] === 'string' ? body['traceId'] : null;\n return {\n status: failure.status,\n type: body['type'],\n message: body['message'],\n retryable: body['retryable'],\n traceId,\n };\n }\n if (failure.status === 0) return described(0, strings.errorUnreachable);\n if (failure.status >= 200 && failure.status < 300)\n return described(0, formatString(strings.errorMalformed, action));\n return described(failure.status, formatString(strings.errorStatus, failure.status));\n }\n if (failure instanceof NxrTimeoutError) {\n return described(0, formatString(strings.errorTimeout, failure.seconds));\n }\n if (failure instanceof NxrMalformedAnswerError) {\n return failure.protocol !== NXR_VIEWER_PROTOCOL\n ? described(0, formatString(strings.errorProtocol, failure.protocol, NXR_VIEWER_PROTOCOL))\n : described(0, formatString(strings.errorMalformed, failure.action));\n }\n return described(0, failure instanceof Error ? failure.message : String(failure));\n}\n","import { HttpClient, HttpErrorResponse } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { catchError, defer, from, map, Observable, switchMap, throwError, timeout } from 'rxjs';\nimport type { NxrViewerStrings } from '../strings/nxr-viewer-strings.const';\nimport type {\n NxrExportAnswer,\n NxrFindAnswer,\n NxrPagesAnswer,\n NxrReportAnswer,\n NxrUpdateCacheAnswer,\n NxrViewerAction,\n NxrViewerDataAnswer,\n} from './nxr-protocol.model';\nimport {\n NxrTimeoutError,\n readFailure,\n readFind,\n readPages,\n readReport,\n readUpdateCache,\n readViewerData,\n} from './nxr-protocol-reader.util';\nimport type { NxrViewerOptions } from './nxr-viewer-options.model';\n\n/** What the component's `postParametersFunction` is called with: the request's action and its parameters. */\nexport interface NxrPostParametersData {\n action: NxrViewerAction;\n [parameter: string]: unknown;\n}\n\n/**\n * The component's `postParametersFunction` input. It runs for every request, the first one included.\n * Each key of an object it returns becomes a form field of the request, replacing a field of the same\n * name; anything else it returns adds nothing.\n */\nexport type NxrPostParametersFunction = (data: NxrPostParametersData) => unknown;\n\n/** What every request is built from. */\nexport interface NxrRequestContext {\n /** The component's `requestUrl`: each request's host action takes the place of `{action}`. */\n requestUrl: string;\n /** The component's `properties`, sent as JSON when truthy. */\n properties: unknown;\n /** The component's `postParametersFunction`. */\n postParametersFunction: NxrPostParametersFunction | null | undefined;\n /** The strings failures are described with. */\n strings: NxrViewerStrings;\n}\n\n/** The server's side of an open viewer: the token it issued and the options it sent. */\nexport interface NxrServerSession {\n token: string;\n options: NxrViewerOptions;\n}\n\n/** Consecutive pages, from a 0-based index. */\nexport interface NxrPageRange {\n startIndex: number;\n count: number;\n}\n\nexport interface NxrFindParameters {\n text: string;\n matchCase?: boolean;\n wholeWord?: boolean;\n}\n\n/**\n * The seconds a request may take when no positive `requestTimeout` applies. That includes the first\n * request, which is sent before the server's options are known. Stimulsoft's viewer uses the same value.\n */\nexport const NXR_UNSET_REQUEST_TIMEOUT_SECONDS = 1000;\n\n/**\n * The URL of a host action. The action's path takes the place of `{action}` in `requestUrl`, and a query\n * string on the action is appended to the URL's own.\n */\nexport function actionUrl(requestUrl: string, action: string): string {\n const queryAt = action.indexOf('?');\n const path = queryAt < 0 ? action : action.slice(0, queryAt);\n const url = requestUrl.replace('{action}', () => path);\n if (queryAt < 0) return url;\n return `${url}${url.includes('?') ? '&' : '?'}${action.slice(queryAt + 1)}`;\n}\n\n/**\n * The host action that answers a viewer action. GetReport goes to `getReport` (or `viewerEvent` when that\n * is empty). The other actions go to `viewerEvent`, or to `getReport` when the server keeps nothing.\n * ExportReport goes to `exportReport` when that is set.\n */\nexport function hostActionFor(options: NxrViewerOptions, action: NxrViewerAction): string {\n const { getReport, viewerEvent, exportReport } = options.actions;\n const reportAction = getReport || viewerEvent;\n const eventAction = options.server.cacheMode === 'None' ? reportAction : viewerEvent;\n if (action === 'GetReport') return reportAction;\n if (action === 'ExportReport') return exportReport || eventAction;\n return eventAction;\n}\n\n/** The file name in a Content-Disposition header, preferring its UTF-8 form. */\nexport function fileNameOf(disposition: string | null): string | null {\n if (!disposition) return null;\n const encoded = /filename\\*\\s*=\\s*UTF-8''([^;]+)/i.exec(disposition);\n if (encoded) {\n try {\n return decodeURIComponent(encoded[1].trim());\n } catch {\n // A malformed escape: the plain file name follows.\n }\n }\n const plain = /filename\\s*=\\s*(?:\"([^\"]*)\"|([^;]+))/i.exec(disposition);\n return plain ? (plain[1] ?? plain[2]).trim() : null;\n}\n\nfunction timeoutOf(session: NxrServerSession | null): number {\n const seconds = session?.options.server.requestTimeout ?? 0;\n return seconds > 0 ? seconds : NXR_UNSET_REQUEST_TIMEOUT_SECONDS;\n}\n\nfunction formOf(\n context: NxrRequestContext,\n action: NxrViewerAction,\n session: NxrServerSession | null,\n parameters: object | null,\n): FormData {\n const form = new FormData();\n form.set('nextera_action', action);\n if (session) {\n const { cacheMode, cacheTimeout, cacheItemPriority } = session.options.server;\n form.set('nextera_token', session.token);\n form.set(\n 'nextera_cache',\n JSON.stringify({ mode: cacheMode, timeout: cacheTimeout, priority: cacheItemPriority }),\n );\n }\n if (parameters) form.set('nextera_parameters', JSON.stringify(parameters));\n if (context.properties) form.set('properties', JSON.stringify(context.properties));\n const added = context.postParametersFunction?.({ ...parameters, action });\n if (typeof added === 'object' && added !== null) {\n for (const [name, value] of Object.entries(added)) {\n form.set(name, value instanceof Blob ? value : String(value));\n }\n }\n return form;\n}\n\n/** An error answer to a blob request carries its body as a blob. Read it, as JSON when it is JSON, so it can be classified. */\nasync function readableFailure(failure: unknown): Promise<unknown> {\n if (!(failure instanceof HttpErrorResponse) || !(failure.error instanceof Blob)) return failure;\n const text = await failure.error.text();\n let body: unknown = text;\n try {\n body = JSON.parse(text);\n } catch {\n // Not JSON: the failure is described by its status.\n }\n return new HttpErrorResponse({\n error: body,\n headers: failure.headers,\n status: failure.status,\n statusText: failure.statusText,\n url: failure.url ?? undefined,\n });\n}\n\n/**\n * Sends one viewer's protocol requests through the application's `HttpClient`, so the application's\n * interceptors apply, and reads each answer. Every observable fails with an `NxrViewerFailure`. A request's\n * form is built when the observable is subscribed.\n */\n@Injectable()\nexport class NxrViewerClientService {\n private readonly http = inject(HttpClient);\n\n /** AngularViewerData, sent to the component's `action`: the token and the options. */\n openViewer(context: NxrRequestContext, action: string): Observable<NxrViewerDataAnswer> {\n return this.post(context, 'AngularViewerData', action, null, null, readViewerData);\n }\n\n /** GetReport: renders the report, with the HTML of the pages in `range` when one is given. */\n getReport(\n context: NxrRequestContext,\n session: NxrServerSession,\n range?: NxrPageRange,\n ): Observable<NxrReportAnswer> {\n const hostAction = hostActionFor(session.options, 'GetReport');\n return this.post(context, 'GetReport', hostAction, session, range ?? null, readReport);\n }\n\n /** GetPages: the HTML of the pages in `range`. */\n getPages(\n context: NxrRequestContext,\n session: NxrServerSession,\n range: NxrPageRange,\n ): Observable<NxrPagesAnswer> {\n return this.post(\n context,\n 'GetPages',\n hostActionFor(session.options, 'GetPages'),\n session,\n range,\n readPages,\n );\n }\n\n /** Find: the text components that match. */\n find(\n context: NxrRequestContext,\n session: NxrServerSession,\n parameters: NxrFindParameters,\n ): Observable<NxrFindAnswer> {\n return this.post(\n context,\n 'Find',\n hostActionFor(session.options, 'Find'),\n session,\n parameters,\n readFind,\n );\n }\n\n /** UpdateCache: keeps the server's copy of the report. */\n updateCache(\n context: NxrRequestContext,\n session: NxrServerSession,\n ): Observable<NxrUpdateCacheAnswer> {\n const hostAction = hostActionFor(session.options, 'UpdateCache');\n return this.post(context, 'UpdateCache', hostAction, session, null, readUpdateCache);\n }\n\n /** ExportReport: the report as a file, in a format such as `Pdf` or `Html`. It never times out. */\n exportReport(\n context: NxrRequestContext,\n session: NxrServerSession,\n format: string,\n ): Observable<NxrExportAnswer> {\n const url = actionUrl(context.requestUrl, hostActionFor(session.options, 'ExportReport'));\n return defer(() =>\n this.http.post(url, formOf(context, 'ExportReport', session, { format }), {\n observe: 'response',\n responseType: 'blob',\n }),\n ).pipe(\n map((response) => ({\n blob: response.body ?? new Blob([]),\n fileName: fileNameOf(response.headers.get('Content-Disposition')) ?? '',\n contentType: response.headers.get('Content-Type') ?? '',\n })),\n catchError((failure: unknown) =>\n from(readableFailure(failure)).pipe(\n switchMap((readable) =>\n throwError(() => readFailure(readable, 'ExportReport', context.strings)),\n ),\n ),\n ),\n );\n }\n\n private post<T>(\n context: NxrRequestContext,\n action: NxrViewerAction,\n hostAction: string,\n session: NxrServerSession | null,\n parameters: object | null,\n read: (body: unknown) => T,\n ): Observable<T> {\n const seconds = timeoutOf(session);\n return defer(() =>\n this.http.post(\n actionUrl(context.requestUrl, hostAction),\n formOf(context, action, session, parameters),\n ),\n ).pipe(\n timeout({\n first: seconds * 1000,\n with: () => throwError(() => new NxrTimeoutError(seconds)),\n }),\n map((body) => read(body)),\n catchError((failure: unknown) =>\n throwError(() => readFailure(failure, action, context.strings)),\n ),\n );\n }\n}\n","import { computed, DestroyRef, inject, Injectable, signal } from '@angular/core';\nimport {\n catchError,\n EMPTY,\n exhaustMap,\n finalize,\n interval,\n Observable,\n Subject,\n Subscription,\n} from 'rxjs';\nimport type {\n NxrPagesAnswer,\n NxrPageSize,\n NxrReportAnswer,\n NxrViewerFailure,\n} from '../protocol/nxr-protocol.model';\nimport {\n NxrRequestContext,\n NxrServerSession,\n NxrViewerClientService,\n} from '../protocol/nxr-viewer-client.service';\nimport type { NxrViewerOptions } from '../protocol/nxr-viewer-options.model';\n\n/** How often an open viewer asks the server to keep its report: every 3 minutes, as Stimulsoft's viewer does. */\nexport const NXR_KEEP_ALIVE_MS = 180_000;\n\n/** The page on screen. */\nexport interface NxrShownPage {\n /** 0-based. */\n index: number;\n size: NxrPageSize;\n /** The page's HTML, or null while it has not arrived: while it is on its way, or after its request failed. */\n html: string | null;\n}\n\nfunction withPages(pages: Map<number, string>, answer: NxrPagesAnswer | null): Map<number, string> {\n answer?.pages.forEach((html, offset) => pages.set(answer.startIndex + offset, html));\n return pages;\n}\n\n/**\n * One viewer's conversation with the report server, and the state the viewer shows.\n *\n * Every signal changes only in this service's methods and in the answers they handle; nothing reacts to\n * a signal changing. Each viewer provides its own session, so viewers on one page never share state.\n */\n@Injectable()\nexport class NxrViewerSessionService {\n private readonly client = inject(NxrViewerClientService);\n\n private readonly optionsState = signal<NxrViewerOptions | null>(null);\n private readonly reportState = signal<NxrReportAnswer | null>(null);\n private readonly htmlState = signal<ReadonlyMap<number, string>>(new Map());\n private readonly pageIndexState = signal(0);\n private readonly pendingState = signal(0);\n private readonly failureState = signal<NxrViewerFailure | null>(null);\n\n /** The options from the last AngularViewerData answer. */\n readonly options = this.optionsState.asReadonly();\n /** The report from the last GetReport answer, or null before one. */\n readonly report = this.reportState.asReadonly();\n /** The 0-based index of the page on screen. */\n readonly pageIndex = this.pageIndexState.asReadonly();\n /** The failure on show, until it is dismissed. */\n readonly failure = this.failureState.asReadonly();\n /** How many pages the report has; 0 before one is loaded. */\n readonly pageCount = computed(() => this.reportState()?.pageCount ?? 0);\n /** Whether a request the user waits for is on its way. Keep-alive requests do not count. */\n readonly busy = computed(() => this.pendingState() > 0);\n /** The page on screen, or null before a report. */\n readonly shownPage = computed<NxrShownPage | null>(() => {\n const report = this.reportState();\n const index = this.pageIndexState();\n if (!report || index >= report.pageCount) return null;\n return { index, size: report.pages[index], html: this.htmlState().get(index) ?? null };\n });\n\n /** Emits after each successful GetReport answer. */\n readonly reportLoaded = new Subject<void>();\n /** Emits each failure put on show. */\n readonly failed = new Subject<NxrViewerFailure>();\n\n private context: NxrRequestContext | null = null;\n private session: NxrServerSession | null = null;\n /** Every request the user waits for. */\n private requests = new Subscription();\n /** The page requests among them, which a new rendering of the report makes obsolete. */\n private pageRequests = new Subscription();\n private keepAlive = Subscription.EMPTY;\n private readonly pagesOnTheWay = new Set<number>();\n /** True from the moment an expired report is sent to be rendered again until that rendering settles. */\n private recovering = false;\n private destroyed = false;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.destroyed = true;\n this.close();\n this.reportLoaded.complete();\n this.failed.complete();\n });\n }\n\n /** Opens the report the host action names, in place of whatever this viewer showed. */\n open(context: NxrRequestContext, action: string): void {\n if (this.destroyed) return;\n this.close();\n this.context = context;\n this.reportState.set(null);\n this.htmlState.set(new Map());\n this.pageIndexState.set(0);\n this.failureState.set(null);\n if (!context.requestUrl) return;\n this.track(this.client.openViewer(context, action), false, (answer) => {\n const session = { token: answer.token, options: answer.options };\n this.session = session;\n this.optionsState.set(answer.options);\n this.startKeepAlive(context, session);\n this.render();\n });\n }\n\n /**\n * Shows the page at a 0-based index; an index outside the report is ignored. Asking for the page already\n * on screen fetches it again when its HTML is missing, as it is after its request failed.\n */\n goToPage(index: number): void {\n const inReport = Number.isInteger(index) && index >= 0 && index < this.pageCount();\n if (this.destroyed || !inReport) return;\n this.pageIndexState.set(index);\n this.loadPage(index);\n }\n\n /** Takes the failure off show. */\n dismissFailure(): void {\n this.failureState.set(null);\n }\n\n /**\n * GetReport, asking for the page on screen, which stays on screen when it is still in the report. The new\n * rendering makes every page request still on its way obsolete. Its settling ends a recovery.\n */\n private render(): void {\n const { context, session } = this.connection();\n const range = { startIndex: this.pageIndexState(), count: 1 };\n const rendering = this.client\n .getReport(context, session, range)\n .pipe(finalize(() => (this.recovering = false)));\n this.track(rendering, false, (report) => {\n this.pageRequests.unsubscribe();\n this.pageRequests = new Subscription();\n this.htmlState.set(withPages(new Map(), report.pagesHtml));\n this.reportState.set(report);\n this.pageIndexState.update((index) => Math.max(0, Math.min(index, report.pageCount - 1)));\n this.reportLoaded.next();\n this.loadPage(this.pageIndexState());\n });\n }\n\n /** GetPages for one page, unless the page is already here or on its way. */\n private loadPage(index: number): void {\n if (index >= this.pageCount() || this.htmlState().has(index) || this.pagesOnTheWay.has(index))\n return;\n const { context, session } = this.connection();\n this.pagesOnTheWay.add(index);\n const request = this.client\n .getPages(context, session, { startIndex: index, count: 1 })\n .pipe(finalize(() => this.pagesOnTheWay.delete(index)));\n this.pageRequests.add(\n this.track(request, true, (answer) =>\n this.htmlState.set(withPages(new Map(this.htmlState()), answer)),\n ),\n );\n }\n\n /**\n * Sends a request the user waits for, and returns its subscription. A `recoverable` request that finds the\n * report gone renders it again; every other failure goes on show.\n */\n private track<T>(\n request: Observable<T>,\n recoverable: boolean,\n next: (value: T) => void,\n ): Subscription {\n this.pendingState.update((count) => count + 1);\n const subscription = request\n .pipe(finalize(() => this.pendingState.update((count) => count - 1)))\n .subscribe({\n next,\n error: (failure: NxrViewerFailure) => this.fail(failure, recoverable),\n });\n this.requests.add(subscription);\n return subscription;\n }\n\n /**\n * An expired report found by a recoverable request is rendered again, unless a rendering is already on its\n * way; every other failure goes on show. Only that rendering settling ends the recovery, so failures in the\n * meantime cannot start a second one.\n */\n private fail(failure: NxrViewerFailure, recoverable: boolean): void {\n if (failure.type === 'CacheExpired' && recoverable) {\n if (!this.recovering) {\n this.recovering = true;\n this.render();\n }\n return;\n }\n this.failureState.set(failure);\n this.failed.next(failure);\n }\n\n /** UpdateCache every three minutes while the server keeps the report. Its failures are not shown. */\n private startKeepAlive(context: NxrRequestContext, session: NxrServerSession): void {\n const { allowAutoUpdateCache, cacheMode } = session.options.server;\n if (!allowAutoUpdateCache || cacheMode === 'None') return;\n this.keepAlive = interval(NXR_KEEP_ALIVE_MS)\n .pipe(\n exhaustMap(() => this.client.updateCache(context, session).pipe(catchError(() => EMPTY))),\n )\n .subscribe();\n }\n\n /** Stops every request and the keep-alive. */\n private close(): void {\n this.requests.unsubscribe();\n this.requests = new Subscription();\n this.pageRequests = new Subscription();\n this.keepAlive.unsubscribe();\n this.session = null;\n this.pagesOnTheWay.clear();\n this.recovering = false;\n }\n\n private connection(): { context: NxrRequestContext; session: NxrServerSession } {\n if (!this.context || !this.session) throw new Error('The viewer has no report open.');\n return { context: this.context, session: this.session };\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';\nimport type { NxrViewerOptions } from '../protocol/nxr-viewer-options.model';\nimport { NXR_ENGLISH, type NxrViewerStrings } from '../strings/nxr-viewer-strings.const';\n\n/** The width of the page-number box, as Stimulsoft's page control sizes it. */\nconst PAGE_BOX_WIDTH_PX = 45;\n\n/**\n * The toolbar's page navigation.\n *\n * Stimulsoft's toolbar is a long list of groups; this is the navigation group of it, which is what\n * a report viewer cannot do without: first, previous, the page control, next, last. Each button\n * appears only when its `toolbar.show…Button` option is on, and the group is laid out where\n * `toolbar.alignment` says. The other groups — save, print, find, bookmarks, zoom, view mode —\n * arrive with the tasks that implement them.\n *\n * Navigation is disabled the way Stimulsoft disables it: in `MultiplePages`, and in `Continuous`\n * unless the report panel or the whole viewer scrolls. A button is disabled at the end of the\n * report it would move past, and everything is disabled while a request the user waits for is on\n * its way.\n */\n@Component({\n selector: 'nxr-viewer-toolbar',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'nxr-viewer-toolbar',\n role: 'toolbar',\n '[style.background-color]': 'backgroundColor()',\n '[style.border]': 'border()',\n '[style.color]': 'fontColor()',\n '[style.font-family]': 'fontFamily()',\n '[style.justify-content]': 'justifyContent()',\n '[class.nxr-busy]': 'busy()',\n },\n template: `\n @if (showFirstPage()) {\n <button\n type=\"button\"\n class=\"nxr-toolbar-button\"\n [disabled]=\"atStart()\"\n [attr.aria-label]=\"strings().FirstPage\"\n (click)=\"goTo(0)\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M12.5 3v10L6 8zM4.5 3h1.2v10H4.5z\" />\n </svg>\n </button>\n }\n @if (showPreviousPage()) {\n <button\n type=\"button\"\n class=\"nxr-toolbar-button\"\n [disabled]=\"atStart()\"\n [attr.aria-label]=\"strings().PrevPage\"\n (click)=\"goTo(pageIndex() - 1)\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M11 3v10L4.5 8z\" /></svg>\n </button>\n }\n @if (showCurrentPage()) {\n <span class=\"nxr-page-control\">\n <span class=\"nxr-page-label\">{{ strings().Page }}</span>\n <input\n type=\"text\"\n inputmode=\"numeric\"\n class=\"nxr-page-box\"\n [style.width.px]=\"pageBoxWidth\"\n [disabled]=\"pageControlDisabled()\"\n [value]=\"pageIndex() + 1\"\n [attr.aria-label]=\"strings().Page\"\n (keydown.enter)=\"enterPage($event)\"\n />\n <span class=\"nxr-page-label\">{{ strings().PageOf }} {{ pageCount() }}</span>\n </span>\n }\n @if (showNextPage()) {\n <button\n type=\"button\"\n class=\"nxr-toolbar-button\"\n [disabled]=\"atEnd()\"\n [attr.aria-label]=\"strings().NextPage\"\n (click)=\"goTo(pageIndex() + 1)\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M5 3v10l6.5-5z\" /></svg>\n </button>\n }\n @if (showLastPage()) {\n <button\n type=\"button\"\n class=\"nxr-toolbar-button\"\n [disabled]=\"atEnd()\"\n [attr.aria-label]=\"strings().LastPage\"\n (click)=\"goTo(pageCount() - 1)\"\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M3.5 3v10L10 8zM10.3 3h1.2v10h-1.2z\" />\n </svg>\n </button>\n }\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: 2px;\n box-sizing: border-box;\n padding: 3px 6px;\n min-height: 30px;\n position: relative;\n user-select: none;\n }\n\n /* Stimulsoft covers the toolbar with a disabled panel while a request is in flight. */\n :host(.nxr-busy)::after {\n content: '';\n position: absolute;\n inset: 0;\n cursor: default;\n }\n\n .nxr-toolbar-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n padding: 0;\n border: 0;\n border-radius: 2px;\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n\n .nxr-toolbar-button:hover:not(:disabled) {\n background: rgb(0 0 0 / 8%);\n }\n\n .nxr-toolbar-button:disabled {\n opacity: 0.5;\n cursor: default;\n }\n\n .nxr-toolbar-button svg {\n width: 16px;\n height: 16px;\n fill: currentColor;\n }\n\n .nxr-page-control {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 4px;\n white-space: nowrap;\n }\n\n .nxr-page-box {\n height: 21px;\n box-sizing: border-box;\n text-align: center;\n font: inherit;\n color: inherit;\n }\n\n .nxr-page-box:disabled {\n color: transparent;\n }\n `,\n})\nexport class NxrViewerToolbarComponent {\n /** The options from the server, or null before the first answer, when the toolbar shows nothing. */\n readonly options = input<NxrViewerOptions | null>(null);\n /** The 0-based index of the page on screen. */\n readonly pageIndex = input(0);\n /** How many pages the report has. */\n readonly pageCount = input(0);\n /** Whether a request the user waits for is on its way. */\n readonly busy = input(false);\n /** The captions to show. */\n readonly strings = input<NxrViewerStrings>(NXR_ENGLISH);\n\n /** The 0-based page the user asked for. */\n readonly goToPage = output<number>();\n\n protected readonly pageBoxWidth = PAGE_BOX_WIDTH_PX;\n\n private readonly toolbar = computed(() => this.options()?.toolbar ?? null);\n private readonly appearance = computed(() => this.options()?.appearance ?? null);\n\n /**\n * Stimulsoft's rule: navigation is off in `MultiplePages`, and in `Continuous` unless the report\n * panel scrolls or the viewer is full screen — in those cases the page is reached by scrolling.\n */\n private readonly navigationDisabled = computed(() => {\n const toolbar = this.toolbar();\n const appearance = this.appearance();\n if (!toolbar || !appearance) return true;\n if (toolbar.viewMode === 'MultiplePages') return true;\n return (\n toolbar.viewMode === 'Continuous' &&\n !appearance.scrollbarsMode &&\n !appearance.fullScreenMode\n );\n });\n\n protected readonly showFirstPage = computed(() => this.toolbar()?.showFirstPageButton === true);\n protected readonly showPreviousPage = computed(\n () => this.toolbar()?.showPreviousPageButton === true,\n );\n protected readonly showCurrentPage = computed(\n () => this.toolbar()?.showCurrentPageControl === true,\n );\n protected readonly showNextPage = computed(() => this.toolbar()?.showNextPageButton === true);\n protected readonly showLastPage = computed(() => this.toolbar()?.showLastPageButton === true);\n\n protected readonly atStart = computed(\n () => this.busy() || this.navigationDisabled() || this.pageIndex() <= 0,\n );\n protected readonly atEnd = computed(\n () => this.busy() || this.navigationDisabled() || this.pageIndex() >= this.pageCount() - 1,\n );\n protected readonly pageControlDisabled = computed(\n () => this.busy() || this.navigationDisabled() || this.pageCount() <= 1,\n );\n\n protected readonly backgroundColor = computed(() => this.toolbar()?.backgroundColor || null);\n protected readonly fontColor = computed(() => this.toolbar()?.fontColor || null);\n protected readonly fontFamily = computed(() => this.toolbar()?.fontFamily || null);\n\n /** A border only in `Simple`; `Separated` has none, as Stimulsoft's toolbar does. */\n protected readonly border = computed(() => {\n const toolbar = this.toolbar();\n if (!toolbar || toolbar.displayMode === 'Separated' || !toolbar.borderColor) return null;\n return `1px solid ${toolbar.borderColor}`;\n });\n\n protected readonly justifyContent = computed(() => {\n switch (this.toolbar()?.alignment) {\n case 'Center':\n return 'center';\n case 'Right':\n return 'flex-end';\n default:\n return 'flex-start';\n }\n });\n\n /**\n * Enter in the page box goes to the page typed, reading anything that is not a number as page 1\n * and clamping to the report, as Stimulsoft's page control does. Leaving the box does nothing.\n */\n protected enterPage(event: Event): void {\n const box = event.target as HTMLInputElement;\n const typed = Number.parseInt(box.value, 10);\n const page = Math.min(Math.max(Number.isNaN(typed) ? 1 : typed, 1), this.pageCount());\n box.value = String(page);\n this.goTo(page - 1);\n }\n\n protected goTo(index: number): void {\n if (this.busy() || index === this.pageIndex() || index < 0 || index >= this.pageCount()) return;\n this.goToPage.emit(index);\n }\n}\n","import { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n OnChanges,\n output,\n} from '@angular/core';\nimport { NxrReportPageComponent } from '../page/nxr-report-page.component';\nimport type { NxrViewerFailure } from '../protocol/nxr-protocol.model';\nimport {\n NxrViewerClientService,\n type NxrPostParametersFunction,\n type NxrRequestContext,\n} from '../protocol/nxr-viewer-client.service';\nimport { NxrViewerSessionService } from '../session/nxr-viewer-session.service';\nimport { NXR_ENGLISH } from '../strings/nxr-viewer-strings.const';\nimport { NxrViewerToolbarComponent } from '../toolbar/nxr-viewer-toolbar.component';\n\n/**\n * What a host reaches through the component's `api`, with Stimulsoft's names and meanings. The\n * members for zoom, view mode, export, print, email and find arrive with the tasks that implement\n * those; a host that only pages through a report needs these three.\n */\nexport interface NxrViewerApi {\n /** The 0-based page on screen. Setting it shows a page inside the report and ignores anything else. */\n currentPage: number;\n /** How many pages the report has; 0 before one is loaded. */\n readonly pagesCount: number;\n /** Always `Report`, as Stimulsoft's Angular viewer answers when it is not showing a dashboard. */\n readonly reportType: string;\n}\n\n/**\n * A report served by `Nextera.Reports.Angular.NetCore`, shown page by page.\n *\n * The inputs, outputs and `api` are Stimulsoft's `stimulsoft-viewer-angular`, so a host swaps the\n * component and keeps its bindings. As there, a change to any input reloads the report: the\n * component asks for the viewer's options again and opens the report the action names.\n *\n * Each viewer provides its own session, so several on a page never share a report or a token.\n */\n@Component({\n selector: 'nxr-report-viewer',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NxrReportPageComponent, NxrViewerToolbarComponent],\n providers: [NxrViewerClientService, NxrViewerSessionService],\n template: `\n <div\n class=\"nxr-viewer-root\"\n [style]=\"style()\"\n [style.background-color]=\"rootBackgroundColor()\"\n [style.width]=\"rootWidth()\"\n [style.height]=\"rootHeight()\"\n >\n @if (toolbarVisible()) {\n <nxr-viewer-toolbar\n [options]=\"session.options()\"\n [pageIndex]=\"session.pageIndex()\"\n [pageCount]=\"session.pageCount()\"\n [busy]=\"session.busy()\"\n (goToPage)=\"session.goToPage($event)\"\n />\n }\n\n <div\n class=\"nxr-viewer-pages\"\n [style.text-align]=\"pageAlignment()\"\n [style.overflow]=\"pagesOverflow()\"\n >\n @if (session.shownPage(); as page) {\n <nxr-report-page\n class=\"nxr-viewer-page\"\n [class.nxr-viewer-page-shadow]=\"showPageShadow()\"\n [style.border]=\"pageBorder()\"\n [page]=\"page.size\"\n [html]=\"page.html\"\n [css]=\"pageCss()\"\n />\n }\n </div>\n\n @if (session.failure(); as failure) {\n <div class=\"nxr-viewer-failure\" role=\"alert\">\n <span class=\"nxr-viewer-failure-text\">{{ failure.message }}</span>\n <button type=\"button\" class=\"nxr-viewer-failure-close\" (click)=\"session.dismissFailure()\">\n ×\n </button>\n </div>\n }\n </div>\n `,\n styles: `\n :host {\n display: inline-block;\n position: relative;\n }\n\n .nxr-viewer-root {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n position: relative;\n }\n\n .nxr-viewer-pages {\n flex: 1 1 auto;\n min-height: 0;\n padding: 10px;\n box-sizing: border-box;\n }\n\n .nxr-viewer-page {\n display: inline-block;\n vertical-align: top;\n }\n\n .nxr-viewer-page-shadow {\n box-shadow: 2px 2px 6px rgb(0 0 0 / 30%);\n }\n\n .nxr-viewer-failure {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: #fdecea;\n color: #611a15;\n font-size: 13px;\n }\n\n .nxr-viewer-failure-text {\n flex: 1 1 auto;\n }\n\n .nxr-viewer-failure-close {\n border: 0;\n background: transparent;\n color: inherit;\n font-size: 18px;\n line-height: 1;\n cursor: pointer;\n }\n `,\n})\nexport class NxrReportViewerComponent implements OnChanges {\n /** Each request's URL, with `{action}` in place of the host action it goes to. */\n readonly requestUrl = input('');\n /** The host action that answers the first request, and so names the report to open. */\n readonly action = input('');\n /** Sent to the host with every request, as JSON, when it is truthy. */\n readonly properties = input<unknown>(null);\n /** The viewer's width; `100%` when it is not given. */\n readonly width = input<string | null>(null);\n /** The viewer's height; 650px when the report panel scrolls, otherwise `100%`. */\n readonly height = input<string | null>(null);\n /** The viewer's background; `White` when it is not given. */\n readonly backgroundColor = input<string | null>('White');\n /** Styles for the viewer's root element. Width, height and background take precedence over it. */\n readonly style = input<string | null>(null);\n /** Called for every request; each key of an object it returns becomes a form field. */\n readonly postParametersFunction = input<NxrPostParametersFunction | null>(null);\n\n /** Emits after each report is loaded. */\n readonly loaded = output<void>();\n /** Emits every failure the viewer puts on show. */\n readonly error = output<NxrViewerFailure>();\n\n protected readonly session = inject(NxrViewerSessionService);\n\n /** Stimulsoft's `api` object: what a host calls to drive the viewer from outside. */\n readonly api: NxrViewerApi = this.buildApi();\n\n private readonly appearance = computed(() => this.session.options()?.appearance ?? null);\n\n protected readonly toolbarVisible = computed(\n () => this.session.options()?.toolbar.visible !== false,\n );\n protected readonly pageCss = computed(() => this.session.report()?.pageCss ?? '');\n protected readonly showPageShadow = computed(() => this.appearance()?.showPageShadow === true);\n protected readonly pageBorder = computed(() => {\n const color = this.appearance()?.pageBorderColor;\n return color ? `1px solid ${color}` : null;\n });\n\n /** Stimulsoft aligns the pages with the report panel's text alignment; `Default` means centred. */\n protected readonly pageAlignment = computed(() => {\n switch (this.appearance()?.pageAlignment) {\n case 'Left':\n return 'left';\n case 'Right':\n return 'right';\n default:\n return 'center';\n }\n });\n\n /** The report panel scrolls inside the viewer only when the server asks for scrollbars. */\n protected readonly pagesOverflow = computed(() =>\n this.appearance()?.scrollbarsMode ? 'auto' : 'hidden',\n );\n\n protected readonly rootWidth = computed(() => this.width() ?? '100%');\n protected readonly rootBackgroundColor = computed(() => this.backgroundColor() ?? 'White');\n protected readonly rootHeight = computed(() => {\n const given = this.height();\n if (given !== null) return given;\n return this.appearance()?.scrollbarsMode ? '650px' : '100%';\n });\n\n constructor() {\n this.session.reportLoaded\n .pipe(takeUntilDestroyed())\n .subscribe(() => this.loaded.emit());\n this.session.failed\n .pipe(takeUntilDestroyed())\n .subscribe((failure) => this.error.emit(failure));\n }\n\n /**\n * A change to any input reloads, as Stimulsoft's viewer does: its `ngOnChanges` never looks at\n * which input changed, so even a width change asks the server for the options and the report\n * again. Matching that keeps a host's reload behaviour the same across the swap.\n */\n ngOnChanges(): void {\n this.session.open(this.context(), this.action());\n }\n\n /**\n * The getters read the session's signals, so a host that asks between renders gets what is on\n * screen now. Built from a captured session rather than `this`, because `this` inside an object\n * literal's accessor is the literal.\n */\n private buildApi(): NxrViewerApi {\n const session = this.session;\n return {\n get currentPage(): number {\n return session.pageIndex();\n },\n set currentPage(value: number) {\n session.goToPage(value);\n },\n get pagesCount(): number {\n return session.pageCount();\n },\n get reportType(): string {\n return 'Report';\n },\n };\n }\n\n private context(): NxrRequestContext {\n return {\n requestUrl: this.requestUrl(),\n properties: this.properties(),\n postParametersFunction: this.postParametersFunction(),\n strings: NXR_ENGLISH,\n };\n }\n}\n","/*\n * Public API Surface of @nexterajs/report-viewer\n */\n\nexport { NXR_VIEWER_PROTOCOL } from './lib/protocol/nxr-protocol.const';\nexport {\n NxrReportViewerComponent,\n type NxrViewerApi,\n} from './lib/viewer/nxr-report-viewer.component';\nexport type { NxrViewerFailure } from './lib/protocol/nxr-protocol.model';\nexport type {\n NxrPostParametersData,\n NxrPostParametersFunction,\n} from './lib/protocol/nxr-viewer-client.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nexterajs/report-viewer",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/common": "^22.0.0",
|
|
6
|
+
"@angular/core": "^22.0.0",
|
|
7
|
+
"@angular/platform-browser": "^22.0.0",
|
|
8
|
+
"rxjs": "^7.8.0"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"tslib": "^2.3.0"
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"license": "Apache-2.0",
|
|
15
|
+
"author": "Nextera",
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": "^22.22.3 || ^24.15.0 || >=26.0.0"
|
|
21
|
+
},
|
|
22
|
+
"description": "Angular report viewer for reports served by Nextera.Report.AspNetCore: pages rendered on the server, shown in shadow roots, with a toolbar and a programmatic api.",
|
|
23
|
+
"keywords": [
|
|
24
|
+
"angular",
|
|
25
|
+
"report",
|
|
26
|
+
"viewer",
|
|
27
|
+
"nextera"
|
|
28
|
+
],
|
|
29
|
+
"module": "fesm2022/nexterajs-report-viewer.mjs",
|
|
30
|
+
"typings": "types/nexterajs-report-viewer.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
"./package.json": {
|
|
33
|
+
"default": "./package.json"
|
|
34
|
+
},
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./types/nexterajs-report-viewer.d.ts",
|
|
37
|
+
"default": "./fesm2022/nexterajs-report-viewer.mjs"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"type": "module"
|
|
41
|
+
}
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { OnChanges } from '@angular/core';
|
|
3
|
+
import { Subject } from 'rxjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The version of the viewer protocol this package speaks: the `protocol` member of every
|
|
7
|
+
* `AngularViewerData` answer from `Nextera.Report.AspNetCore`.
|
|
8
|
+
*/
|
|
9
|
+
declare const NXR_VIEWER_PROTOCOL = 1;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The viewer options as `Nextera.Report.AspNetCore` sends them in the AngularViewerData answer: every
|
|
13
|
+
* member of `NexteraAngularViewerOptions` in camelCase, enum values as member names, and colours as CSS
|
|
14
|
+
* colours, where `null` means the theme's colour.
|
|
15
|
+
*/
|
|
16
|
+
/** How pages are laid out. */
|
|
17
|
+
type NxrViewMode = 'SinglePage' | 'Continuous' | 'MultiplePages';
|
|
18
|
+
/** Horizontal placement; `Default` is the viewer's usual placement for the element. */
|
|
19
|
+
type NxrContentAlignment = 'Left' | 'Center' | 'Right' | 'Default';
|
|
20
|
+
/** One toolbar, or page navigation and zoom in a second bar. */
|
|
21
|
+
type NxrToolbarDisplayMode = 'Simple' | 'Separated';
|
|
22
|
+
/** What opens a toolbar menu. */
|
|
23
|
+
type NxrShowMenuMode = 'Click' | 'Hover';
|
|
24
|
+
/** Which input the controls are sized for. */
|
|
25
|
+
type NxrInterfaceType = 'Auto' | 'Mouse' | 'Touch' | 'Mobile';
|
|
26
|
+
/** Where the server keeps the rendered report between requests. */
|
|
27
|
+
type NxrCacheMode = 'None' | 'ObjectCache' | 'ObjectSession' | 'StringCache' | 'StringSession';
|
|
28
|
+
/** A kept report's priority when the server's memory cache compacts. */
|
|
29
|
+
type NxrCacheItemPriority = 'Low' | 'BelowNormal' | 'Normal' | 'AboveNormal' | 'High' | 'NotRemovable';
|
|
30
|
+
/** The host's action names, each put in place of `{action}` in the component's `requestUrl`. */
|
|
31
|
+
interface NxrViewerActions {
|
|
32
|
+
/** Answers GetReport. */
|
|
33
|
+
getReport: string;
|
|
34
|
+
/** Answers GetPages, Find and UpdateCache, unless the cache mode is `None`. */
|
|
35
|
+
viewerEvent: string;
|
|
36
|
+
/** Answers ExportReport; when empty, ExportReport goes where GetPages goes. */
|
|
37
|
+
exportReport: string;
|
|
38
|
+
}
|
|
39
|
+
interface NxrAppearanceOptions {
|
|
40
|
+
allowMobileMode: boolean;
|
|
41
|
+
allowTouchZoom: boolean;
|
|
42
|
+
backgroundColor: string | null;
|
|
43
|
+
bookmarksTreeWidth: number;
|
|
44
|
+
customCss: string;
|
|
45
|
+
fullScreenMode: boolean;
|
|
46
|
+
interfaceType: NxrInterfaceType;
|
|
47
|
+
openLinksWindow: string;
|
|
48
|
+
pageAlignment: NxrContentAlignment;
|
|
49
|
+
pageBorderColor: string | null;
|
|
50
|
+
rightToLeft: boolean;
|
|
51
|
+
scrollbarsMode: boolean;
|
|
52
|
+
showPageShadow: boolean;
|
|
53
|
+
showTooltips: boolean;
|
|
54
|
+
}
|
|
55
|
+
interface NxrToolbarOptions {
|
|
56
|
+
alignment: NxrContentAlignment;
|
|
57
|
+
autoHide: boolean;
|
|
58
|
+
backgroundColor: string | null;
|
|
59
|
+
borderColor: string | null;
|
|
60
|
+
displayMode: NxrToolbarDisplayMode;
|
|
61
|
+
fontColor: string | null;
|
|
62
|
+
fontFamily: string;
|
|
63
|
+
menuAnimation: boolean;
|
|
64
|
+
showAboutButton: boolean;
|
|
65
|
+
showBookmarksButton: boolean;
|
|
66
|
+
showButtonCaptions: boolean;
|
|
67
|
+
showCurrentPageControl: boolean;
|
|
68
|
+
showDesignButton: boolean;
|
|
69
|
+
showEditorButton: boolean;
|
|
70
|
+
showFindButton: boolean;
|
|
71
|
+
showFirstPageButton: boolean;
|
|
72
|
+
showFullScreenButton: boolean;
|
|
73
|
+
showLastPageButton: boolean;
|
|
74
|
+
showMenuMode: NxrShowMenuMode;
|
|
75
|
+
showNextPageButton: boolean;
|
|
76
|
+
showOpenButton: boolean;
|
|
77
|
+
showParametersButton: boolean;
|
|
78
|
+
showPinToolbarButton: boolean;
|
|
79
|
+
showPreviousPageButton: boolean;
|
|
80
|
+
showPrintButton: boolean;
|
|
81
|
+
showRefreshButton: boolean;
|
|
82
|
+
showResourcesButton: boolean;
|
|
83
|
+
showSaveButton: boolean;
|
|
84
|
+
showSendEmailButton: boolean;
|
|
85
|
+
showSignatureButton: boolean;
|
|
86
|
+
showViewModeButton: boolean;
|
|
87
|
+
showZoomButton: boolean;
|
|
88
|
+
viewMode: NxrViewMode;
|
|
89
|
+
visible: boolean;
|
|
90
|
+
/** The starting zoom, in percent. */
|
|
91
|
+
zoom: number;
|
|
92
|
+
}
|
|
93
|
+
interface NxrExportOptions {
|
|
94
|
+
showExportToHtml: boolean;
|
|
95
|
+
showExportToPdf: boolean;
|
|
96
|
+
}
|
|
97
|
+
interface NxrServerOptions {
|
|
98
|
+
allowAutoUpdateCache: boolean;
|
|
99
|
+
cacheItemPriority: NxrCacheItemPriority;
|
|
100
|
+
cacheMode: NxrCacheMode;
|
|
101
|
+
/** Minutes a kept report survives without a request about it. */
|
|
102
|
+
cacheTimeout: number;
|
|
103
|
+
/** Seconds the viewer waits for an answer. */
|
|
104
|
+
requestTimeout: number;
|
|
105
|
+
showServerErrorPage: boolean;
|
|
106
|
+
}
|
|
107
|
+
interface NxrViewerOptions {
|
|
108
|
+
/** A Stimulsoft viewer theme name, such as `Office2022WhiteBlue`. */
|
|
109
|
+
theme: string;
|
|
110
|
+
localization: string;
|
|
111
|
+
width: string;
|
|
112
|
+
height: string;
|
|
113
|
+
actions: NxrViewerActions;
|
|
114
|
+
appearance: NxrAppearanceOptions;
|
|
115
|
+
toolbar: NxrToolbarOptions;
|
|
116
|
+
exports: NxrExportOptions;
|
|
117
|
+
server: NxrServerOptions;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** The value of a request's `nextera_action` field. */
|
|
121
|
+
type NxrViewerAction = 'AngularViewerData' | 'GetReport' | 'GetPages' | 'Find' | 'ExportReport' | 'UpdateCache';
|
|
122
|
+
interface NxrPageSize {
|
|
123
|
+
/** 1-based. */
|
|
124
|
+
pageNumber: number;
|
|
125
|
+
widthPoints: number;
|
|
126
|
+
heightPoints: number;
|
|
127
|
+
}
|
|
128
|
+
/** A rectangle on a page, in points from its top left corner. */
|
|
129
|
+
interface NxrBounds {
|
|
130
|
+
x: number;
|
|
131
|
+
y: number;
|
|
132
|
+
width: number;
|
|
133
|
+
height: number;
|
|
134
|
+
}
|
|
135
|
+
interface NxrBookmark {
|
|
136
|
+
title: string;
|
|
137
|
+
/** 0-based. */
|
|
138
|
+
pageIndex: number;
|
|
139
|
+
bounds: NxrBounds;
|
|
140
|
+
}
|
|
141
|
+
/** The HTML of consecutive pages, starting at a 0-based index. */
|
|
142
|
+
interface NxrPagesAnswer {
|
|
143
|
+
startIndex: number;
|
|
144
|
+
pages: string[];
|
|
145
|
+
}
|
|
146
|
+
/** The answer to GetReport. */
|
|
147
|
+
interface NxrReportAnswer {
|
|
148
|
+
reportName: string;
|
|
149
|
+
pageCount: number;
|
|
150
|
+
/** Every page's size, in page order. */
|
|
151
|
+
pages: NxrPageSize[];
|
|
152
|
+
bookmarks: NxrBookmark[];
|
|
153
|
+
/** The stylesheet every page's HTML needs. */
|
|
154
|
+
pageCss: string;
|
|
155
|
+
/** The pages GetReport was asked for, or null when it was asked for none. */
|
|
156
|
+
pagesHtml: NxrPagesAnswer | null;
|
|
157
|
+
}
|
|
158
|
+
/** Why a request failed. */
|
|
159
|
+
interface NxrViewerFailure {
|
|
160
|
+
/** The HTTP status of the error answer; 0 when there was none: no answer, a timeout, or an unreadable success answer. */
|
|
161
|
+
status: number;
|
|
162
|
+
/**
|
|
163
|
+
* The protocol's error type for the server's own error answers: `BadRequest`, `Forbidden`,
|
|
164
|
+
* `CacheExpired`, `RenderError` or `Busy`. `Error` for every failure the viewer describes itself,
|
|
165
|
+
* the type Stimulsoft's viewer gives those.
|
|
166
|
+
*/
|
|
167
|
+
type: string;
|
|
168
|
+
/** What went wrong, as plain text: the server's message for its own error answers. */
|
|
169
|
+
message: string;
|
|
170
|
+
/** Whether the protocol says the request can succeed if it is made again (`CacheExpired`, `Busy`). */
|
|
171
|
+
retryable: boolean;
|
|
172
|
+
/** The server's trace id for its own error answers, else null. */
|
|
173
|
+
traceId: string | null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Every caption and message the viewer shows, in its built-in English. A key in PascalCase is the name
|
|
178
|
+
* Stimulsoft's viewer gives the same text, such as `PageOf`; a key in camelCase names a message only this
|
|
179
|
+
* viewer has. The English is this package's own. A later plan lets a host's translation file replace any
|
|
180
|
+
* of them, so code reads them from an `NxrViewerStrings` value wherever one is at hand.
|
|
181
|
+
*/
|
|
182
|
+
declare const NXR_ENGLISH: {
|
|
183
|
+
/** The label before the page-number box. */
|
|
184
|
+
Page: string;
|
|
185
|
+
/** The label between the page-number box and the page count. */
|
|
186
|
+
PageOf: string;
|
|
187
|
+
FirstPage: string;
|
|
188
|
+
PrevPage: string;
|
|
189
|
+
NextPage: string;
|
|
190
|
+
LastPage: string;
|
|
191
|
+
errorUnreachable: string;
|
|
192
|
+
errorStatus: string;
|
|
193
|
+
errorTimeout: string;
|
|
194
|
+
errorMalformed: string;
|
|
195
|
+
errorProtocol: string;
|
|
196
|
+
};
|
|
197
|
+
type NxrViewerStrings = Readonly<Record<keyof typeof NXR_ENGLISH, string>>;
|
|
198
|
+
|
|
199
|
+
/** What the component's `postParametersFunction` is called with: the request's action and its parameters. */
|
|
200
|
+
interface NxrPostParametersData {
|
|
201
|
+
action: NxrViewerAction;
|
|
202
|
+
[parameter: string]: unknown;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* The component's `postParametersFunction` input. It runs for every request, the first one included.
|
|
206
|
+
* Each key of an object it returns becomes a form field of the request, replacing a field of the same
|
|
207
|
+
* name; anything else it returns adds nothing.
|
|
208
|
+
*/
|
|
209
|
+
type NxrPostParametersFunction = (data: NxrPostParametersData) => unknown;
|
|
210
|
+
/** What every request is built from. */
|
|
211
|
+
interface NxrRequestContext {
|
|
212
|
+
/** The component's `requestUrl`: each request's host action takes the place of `{action}`. */
|
|
213
|
+
requestUrl: string;
|
|
214
|
+
/** The component's `properties`, sent as JSON when truthy. */
|
|
215
|
+
properties: unknown;
|
|
216
|
+
/** The component's `postParametersFunction`. */
|
|
217
|
+
postParametersFunction: NxrPostParametersFunction | null | undefined;
|
|
218
|
+
/** The strings failures are described with. */
|
|
219
|
+
strings: NxrViewerStrings;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** The page on screen. */
|
|
223
|
+
interface NxrShownPage {
|
|
224
|
+
/** 0-based. */
|
|
225
|
+
index: number;
|
|
226
|
+
size: NxrPageSize;
|
|
227
|
+
/** The page's HTML, or null while it has not arrived: while it is on its way, or after its request failed. */
|
|
228
|
+
html: string | null;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* One viewer's conversation with the report server, and the state the viewer shows.
|
|
232
|
+
*
|
|
233
|
+
* Every signal changes only in this service's methods and in the answers they handle; nothing reacts to
|
|
234
|
+
* a signal changing. Each viewer provides its own session, so viewers on one page never share state.
|
|
235
|
+
*/
|
|
236
|
+
declare class NxrViewerSessionService {
|
|
237
|
+
private readonly client;
|
|
238
|
+
private readonly optionsState;
|
|
239
|
+
private readonly reportState;
|
|
240
|
+
private readonly htmlState;
|
|
241
|
+
private readonly pageIndexState;
|
|
242
|
+
private readonly pendingState;
|
|
243
|
+
private readonly failureState;
|
|
244
|
+
/** The options from the last AngularViewerData answer. */
|
|
245
|
+
readonly options: _angular_core.Signal<NxrViewerOptions | null>;
|
|
246
|
+
/** The report from the last GetReport answer, or null before one. */
|
|
247
|
+
readonly report: _angular_core.Signal<NxrReportAnswer | null>;
|
|
248
|
+
/** The 0-based index of the page on screen. */
|
|
249
|
+
readonly pageIndex: _angular_core.Signal<number>;
|
|
250
|
+
/** The failure on show, until it is dismissed. */
|
|
251
|
+
readonly failure: _angular_core.Signal<NxrViewerFailure | null>;
|
|
252
|
+
/** How many pages the report has; 0 before one is loaded. */
|
|
253
|
+
readonly pageCount: _angular_core.Signal<number>;
|
|
254
|
+
/** Whether a request the user waits for is on its way. Keep-alive requests do not count. */
|
|
255
|
+
readonly busy: _angular_core.Signal<boolean>;
|
|
256
|
+
/** The page on screen, or null before a report. */
|
|
257
|
+
readonly shownPage: _angular_core.Signal<NxrShownPage | null>;
|
|
258
|
+
/** Emits after each successful GetReport answer. */
|
|
259
|
+
readonly reportLoaded: Subject<void>;
|
|
260
|
+
/** Emits each failure put on show. */
|
|
261
|
+
readonly failed: Subject<NxrViewerFailure>;
|
|
262
|
+
private context;
|
|
263
|
+
private session;
|
|
264
|
+
/** Every request the user waits for. */
|
|
265
|
+
private requests;
|
|
266
|
+
/** The page requests among them, which a new rendering of the report makes obsolete. */
|
|
267
|
+
private pageRequests;
|
|
268
|
+
private keepAlive;
|
|
269
|
+
private readonly pagesOnTheWay;
|
|
270
|
+
/** True from the moment an expired report is sent to be rendered again until that rendering settles. */
|
|
271
|
+
private recovering;
|
|
272
|
+
private destroyed;
|
|
273
|
+
constructor();
|
|
274
|
+
/** Opens the report the host action names, in place of whatever this viewer showed. */
|
|
275
|
+
open(context: NxrRequestContext, action: string): void;
|
|
276
|
+
/**
|
|
277
|
+
* Shows the page at a 0-based index; an index outside the report is ignored. Asking for the page already
|
|
278
|
+
* on screen fetches it again when its HTML is missing, as it is after its request failed.
|
|
279
|
+
*/
|
|
280
|
+
goToPage(index: number): void;
|
|
281
|
+
/** Takes the failure off show. */
|
|
282
|
+
dismissFailure(): void;
|
|
283
|
+
/**
|
|
284
|
+
* GetReport, asking for the page on screen, which stays on screen when it is still in the report. The new
|
|
285
|
+
* rendering makes every page request still on its way obsolete. Its settling ends a recovery.
|
|
286
|
+
*/
|
|
287
|
+
private render;
|
|
288
|
+
/** GetPages for one page, unless the page is already here or on its way. */
|
|
289
|
+
private loadPage;
|
|
290
|
+
/**
|
|
291
|
+
* Sends a request the user waits for, and returns its subscription. A `recoverable` request that finds the
|
|
292
|
+
* report gone renders it again; every other failure goes on show.
|
|
293
|
+
*/
|
|
294
|
+
private track;
|
|
295
|
+
/**
|
|
296
|
+
* An expired report found by a recoverable request is rendered again, unless a rendering is already on its
|
|
297
|
+
* way; every other failure goes on show. Only that rendering settling ends the recovery, so failures in the
|
|
298
|
+
* meantime cannot start a second one.
|
|
299
|
+
*/
|
|
300
|
+
private fail;
|
|
301
|
+
/** UpdateCache every three minutes while the server keeps the report. Its failures are not shown. */
|
|
302
|
+
private startKeepAlive;
|
|
303
|
+
/** Stops every request and the keep-alive. */
|
|
304
|
+
private close;
|
|
305
|
+
private connection;
|
|
306
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxrViewerSessionService, never>;
|
|
307
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<NxrViewerSessionService>;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* What a host reaches through the component's `api`, with Stimulsoft's names and meanings. The
|
|
312
|
+
* members for zoom, view mode, export, print, email and find arrive with the tasks that implement
|
|
313
|
+
* those; a host that only pages through a report needs these three.
|
|
314
|
+
*/
|
|
315
|
+
interface NxrViewerApi {
|
|
316
|
+
/** The 0-based page on screen. Setting it shows a page inside the report and ignores anything else. */
|
|
317
|
+
currentPage: number;
|
|
318
|
+
/** How many pages the report has; 0 before one is loaded. */
|
|
319
|
+
readonly pagesCount: number;
|
|
320
|
+
/** Always `Report`, as Stimulsoft's Angular viewer answers when it is not showing a dashboard. */
|
|
321
|
+
readonly reportType: string;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* A report served by `Nextera.Reports.Angular.NetCore`, shown page by page.
|
|
325
|
+
*
|
|
326
|
+
* The inputs, outputs and `api` are Stimulsoft's `stimulsoft-viewer-angular`, so a host swaps the
|
|
327
|
+
* component and keeps its bindings. As there, a change to any input reloads the report: the
|
|
328
|
+
* component asks for the viewer's options again and opens the report the action names.
|
|
329
|
+
*
|
|
330
|
+
* Each viewer provides its own session, so several on a page never share a report or a token.
|
|
331
|
+
*/
|
|
332
|
+
declare class NxrReportViewerComponent implements OnChanges {
|
|
333
|
+
/** Each request's URL, with `{action}` in place of the host action it goes to. */
|
|
334
|
+
readonly requestUrl: _angular_core.InputSignal<string>;
|
|
335
|
+
/** The host action that answers the first request, and so names the report to open. */
|
|
336
|
+
readonly action: _angular_core.InputSignal<string>;
|
|
337
|
+
/** Sent to the host with every request, as JSON, when it is truthy. */
|
|
338
|
+
readonly properties: _angular_core.InputSignal<unknown>;
|
|
339
|
+
/** The viewer's width; `100%` when it is not given. */
|
|
340
|
+
readonly width: _angular_core.InputSignal<string | null>;
|
|
341
|
+
/** The viewer's height; 650px when the report panel scrolls, otherwise `100%`. */
|
|
342
|
+
readonly height: _angular_core.InputSignal<string | null>;
|
|
343
|
+
/** The viewer's background; `White` when it is not given. */
|
|
344
|
+
readonly backgroundColor: _angular_core.InputSignal<string | null>;
|
|
345
|
+
/** Styles for the viewer's root element. Width, height and background take precedence over it. */
|
|
346
|
+
readonly style: _angular_core.InputSignal<string | null>;
|
|
347
|
+
/** Called for every request; each key of an object it returns becomes a form field. */
|
|
348
|
+
readonly postParametersFunction: _angular_core.InputSignal<NxrPostParametersFunction | null>;
|
|
349
|
+
/** Emits after each report is loaded. */
|
|
350
|
+
readonly loaded: _angular_core.OutputEmitterRef<void>;
|
|
351
|
+
/** Emits every failure the viewer puts on show. */
|
|
352
|
+
readonly error: _angular_core.OutputEmitterRef<NxrViewerFailure>;
|
|
353
|
+
protected readonly session: NxrViewerSessionService;
|
|
354
|
+
/** Stimulsoft's `api` object: what a host calls to drive the viewer from outside. */
|
|
355
|
+
readonly api: NxrViewerApi;
|
|
356
|
+
private readonly appearance;
|
|
357
|
+
protected readonly toolbarVisible: _angular_core.Signal<boolean>;
|
|
358
|
+
protected readonly pageCss: _angular_core.Signal<string>;
|
|
359
|
+
protected readonly showPageShadow: _angular_core.Signal<boolean>;
|
|
360
|
+
protected readonly pageBorder: _angular_core.Signal<string | null>;
|
|
361
|
+
/** Stimulsoft aligns the pages with the report panel's text alignment; `Default` means centred. */
|
|
362
|
+
protected readonly pageAlignment: _angular_core.Signal<"center" | "left" | "right">;
|
|
363
|
+
/** The report panel scrolls inside the viewer only when the server asks for scrollbars. */
|
|
364
|
+
protected readonly pagesOverflow: _angular_core.Signal<"auto" | "hidden">;
|
|
365
|
+
protected readonly rootWidth: _angular_core.Signal<string>;
|
|
366
|
+
protected readonly rootBackgroundColor: _angular_core.Signal<string>;
|
|
367
|
+
protected readonly rootHeight: _angular_core.Signal<string>;
|
|
368
|
+
constructor();
|
|
369
|
+
/**
|
|
370
|
+
* A change to any input reloads, as Stimulsoft's viewer does: its `ngOnChanges` never looks at
|
|
371
|
+
* which input changed, so even a width change asks the server for the options and the report
|
|
372
|
+
* again. Matching that keeps a host's reload behaviour the same across the swap.
|
|
373
|
+
*/
|
|
374
|
+
ngOnChanges(): void;
|
|
375
|
+
/**
|
|
376
|
+
* The getters read the session's signals, so a host that asks between renders gets what is on
|
|
377
|
+
* screen now. Built from a captured session rather than `this`, because `this` inside an object
|
|
378
|
+
* literal's accessor is the literal.
|
|
379
|
+
*/
|
|
380
|
+
private buildApi;
|
|
381
|
+
private context;
|
|
382
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxrReportViewerComponent, never>;
|
|
383
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxrReportViewerComponent, "nxr-report-viewer", never, { "requestUrl": { "alias": "requestUrl"; "required": false; "isSignal": true; }; "action": { "alias": "action"; "required": false; "isSignal": true; }; "properties": { "alias": "properties"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "backgroundColor": { "alias": "backgroundColor"; "required": false; "isSignal": true; }; "style": { "alias": "style"; "required": false; "isSignal": true; }; "postParametersFunction": { "alias": "postParametersFunction"; "required": false; "isSignal": true; }; }, { "loaded": "loaded"; "error": "error"; }, never, never, true, never>;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export { NXR_VIEWER_PROTOCOL, NxrReportViewerComponent };
|
|
387
|
+
export type { NxrPostParametersData, NxrPostParametersFunction, NxrViewerApi, NxrViewerFailure };
|