@arsedizioni/ars-utils 22.5.17 → 22.5.18

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.
@@ -1 +1 @@
1
- {"version":3,"file":"arsedizioni-ars-utils-ui.notifications.mjs","sources":["../../../projects/ars-utils/ui.notifications/notifications-browser/notification/notification.component.ts","../../../projects/ars-utils/ui.notifications/notifications-browser/notification/notification.component.html","../../../projects/ars-utils/ui.notifications/notifications-browser/notifications-browser.component.ts","../../../projects/ars-utils/ui.notifications/notifications-browser/notifications-browser.component.html","../../../projects/ars-utils/ui.notifications/public_api.ts","../../../projects/ars-utils/ui.notifications/arsedizioni-ars-utils-ui.notifications.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n inject,\n signal\n} from '@angular/core';\nimport { MAT_DIALOG_DATA, MatDialogTitle, MatDialogClose, MatDialogContent, MatDialogActions } from '@angular/material/dialog';\nimport { BroadcastService, ScreenService, SystemUtils } from '@arsedizioni/ars-utils/core';\nimport { SupportDocumentInfo, SupportMessages, SupportNotificationInfo, SupportService } from '@arsedizioni/ars-utils/support.common';\nimport { DialogService } from '@arsedizioni/ars-utils/ui.dialogs';\nimport { FlexLayoutModule } from '@arsedizioni/ars-utils/ui';\nimport { saveAs } from 'file-saver';\nimport { SafeHtmlPipe } from '@arsedizioni/ars-utils/core';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { MatButtonModule } from '@angular/material/button';\nimport { finalize } from 'rxjs';\n\nexport interface SupportNotificationData {\n id?: number;\n}\n\n\n@Component({\n host: { 'Bind': SystemUtils.generateUUID() },\n templateUrl: './notification.component.html',\n styleUrls: ['./notification.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FlexLayoutModule, MatDialogTitle, MatButtonModule, MatTooltipModule, MatDialogClose, MatIconModule, MatDialogContent,\n MatDialogActions, MatMenuModule, SafeHtmlPipe]\n})\nexport class SupportNotificationComponent {\n\n protected readonly screenService = inject(ScreenService);\n private readonly supportService = inject(SupportService);\n private readonly broadcastService = inject(BroadcastService);\n private readonly dialogService = inject(DialogService);\n private readonly dialogData: SupportNotificationData = inject(MAT_DIALOG_DATA);\n\n /** Id of the notification to display, resolved from dialog data. */\n protected readonly id: number = this.dialogData?.id ?? -1;\n\n /** The loaded notification; `undefined` until the fetch completes. */\n protected readonly item = signal<SupportNotificationInfo | undefined>(undefined);\n\n constructor() {\n this.fetch();\n }\n\n /**\n * Fetches the notification from the server and populates the `item` signal.\n */\n private fetch(): void {\n this.dialogService.busy('Caricamento in corso...');\n this.supportService.notifications.getNotification(this.id)\n .pipe(finalize(() => this.dialogService.clearBusy()))\n .subscribe(r => {\n if (!r.success) {\n this.dialogService.error(r.message);\n } else {\n this.item.set(r.value);\n this.broadcastService.sendMessage(SupportMessages.NOTIFICATION_READ, r.value.id);\n }\n });\n }\n\n /**\n * Downloads a binary attachment using FileSaver, or opens a URL document in a new tab.\n * @param doc - The notification document to open or download.\n */\n protected downloadDocument(doc: SupportDocumentInfo): void {\n if (doc.isBinary) {\n if (doc.id === undefined) return;\n this.supportService.notifications.downloadNotificationDocument(doc.id).subscribe(blob => {\n saveAs(blob);\n });\n } else if (doc.url) {\n window.open(doc.url, '_blank');\n }\n }\n\n}\n","<div class=\"support-notification-fixed\">\r\n <div class=\"support-notification-header\">\r\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\" fxLayoutGap=\"10px\" fxFill >\r\n <div fxFlex=\"*\">\r\n <div mat-dialog-title>{{item()?.title}}</div>\r\n </div>\r\n <div fxLayoutAlign=\"end\">\r\n <button fxFlexAlign=\"start\" type=\"button\" mat-icon-button matTooltip=\"Chiudi\"\r\n aria-label=\"Chiudi\" [mat-dialog-close]=\"true\" class=\"dialog-close\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n<mat-dialog-content id=\"notification-scrollable\">\r\n <div id=\"notification-scroller\">\r\n <div [innerHtml]=\"(item()?.text ?? 'Caricamento in corso...') | safeHtml\"></div>\r\n </div>\r\n</mat-dialog-content>\r\n@if (item()?.documents && item()!.documents!.length > 0) {\r\n<mat-dialog-actions class=\"notification-fixed\">\r\n <div style=\"padding: 10px 0\">\r\n <button type=\"button\" mat-button [attr.aria-label]=\"'Documenti scaricabili'\" [matMenuTriggerFor]=\"documentsMenu\">\r\n {{item()!.documents!.length}}\r\n @if (item()!.documents!.length === 1) {\r\n <span>Documento scaricabile</span>\r\n } @else {\r\n <span>Documenti scaricabili</span>\r\n }\r\n <mat-icon class=\"icon-menu-drop-down\">arrow_drop_down</mat-icon>\r\n </button>\r\n <mat-menu #documentsMenu=\"matMenu\">\r\n <ng-template matMenuContent>\r\n @for (doc of item()!.documents; track doc.id) {\r\n <button mat-menu-item (click)=\"downloadDocument(doc)\">\r\n @if (doc.isBinary) {\r\n <mat-icon>attach_file</mat-icon>\r\n } @else {\r\n <mat-icon>link</mat-icon>\r\n }\r\n {{doc.name}}\r\n </button>\r\n }\r\n </ng-template>\r\n </mat-menu>\r\n </div>\r\n</mat-dialog-actions>\r\n}","import {\n ChangeDetectionStrategy,\n Component, DestroyRef,\n afterNextRender,\n inject,\n signal,\n viewChild\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormsModule } from '@angular/forms';\nimport { MatBadgeModule } from '@angular/material/badge';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatDialogActions, MatDialogClose, MatDialogContent, MatDialogTitle } from '@angular/material/dialog';\nimport { MatDividerModule } from '@angular/material/divider';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatPaginator, MatPaginatorModule, PageEvent } from '@angular/material/paginator';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { BroadcastService, FormatPipe, ScreenService, SelectableModel, SystemUtils } from '@arsedizioni/ars-utils/core';\nimport { SupportMessages, SupportNotificationInfo, SupportNotificationsSearchParams, SupportService } from '@arsedizioni/ars-utils/support.common';\nimport { DialogService } from '@arsedizioni/ars-utils/ui.dialogs';\nimport { FlexLayoutModule } from '@arsedizioni/ars-utils/ui';\nimport { finalize } from 'rxjs';\nimport { SupportNotificationComponent } from './notification/notification.component';\n\n@Component({\n host: { 'Bind': SystemUtils.generateUUID() },\n templateUrl: './notifications-browser.component.html',\n styleUrls: ['./notifications-browser.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FlexLayoutModule, MatDialogTitle, MatButtonModule, MatTooltipModule, MatDialogClose,\n MatIconModule, MatFormFieldModule, MatInputModule, FormsModule, MatMenuModule, MatBadgeModule, MatDividerModule, MatDialogContent,\n MatCheckboxModule, MatDialogActions, MatPaginatorModule, FormatPipe]\n})\nexport class SupportNotificationsBrowserComponent {\n\n readonly paginator = viewChild.required<MatPaginator>('paginator');\n protected readonly screenService = inject(ScreenService);\n private readonly supportService = inject(SupportService);\n private readonly broadcastService = inject(BroadcastService);\n private readonly dialogService = inject(DialogService);\n private readonly destroyRef = inject(DestroyRef);\n protected selection = new SelectableModel<SupportNotificationInfo, number>(true, 'id');\n protected searchParams: SupportNotificationsSearchParams = {\n first: 0,\n count: 25\n };\n protected total = signal<number>(-1);\n protected items = signal<SupportNotificationInfo[]>([]);\n\n constructor() {\n // React to message broadcasting\n this.broadcastService.getMessage()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(message => {\n if (message.id === SupportMessages.NOTIFICATION_READ) {\n this.items.update(list =>\n list.map(n => n.id === message.data ? { ...n, isRead: true } : n)\n );\n }\n });\n\n afterNextRender(() => this.find());\n }\n\n /**\n * Scrolls the notifications list back to the top.\n */\n private updateScroll(): void {\n const elem = document.getElementById('notifications-browser-scroller');\n if (elem?.parentElement) {\n elem.parentElement.scrollTop = 0;\n }\n }\n\n /**\n * Resets the `isMenuOpen` flag on all items after a context menu is closed.\n */\n protected updateMenuButtonsVisibility(): void {\n this.items.update(list => list.map(n => ({ ...n, isMenuOpen: false })));\n }\n\n /**\n * Returns the ids of the currently selected items.\n * Shows an error and returns `undefined` when the selection exceeds 50 items.\n * @returns An array of selected notification ids, or `undefined` on validation failure.\n */\n private getSelectedIds(): number[] | undefined {\n if ((this.selection.all?.length ?? 0) > 50) {\n this.dialogService.error('La selezione non può contenere più di 50 elementi.');\n return undefined;\n }\n return this.selection.all?.map(n => n.id) ?? [];\n }\n\n /**\n * Returns the CSS class to apply to the read-state indicator stripe.\n * @param item - The notification to evaluate.\n * @returns `'unread-bg'` when the notification has not been read, otherwise `undefined`.\n */\n protected getItemStateCssClass(item: SupportNotificationInfo): string | undefined {\n return !item.isRead ? 'unread-bg' : undefined;\n }\n\n /**\n * Returns the tooltip text for the read-state indicator stripe.\n * @param item - The notification to evaluate.\n * @returns `'Non letto'` when unread, otherwise an empty string.\n */\n protected getItemStateTooltip(item: SupportNotificationInfo): string {\n return !item.isRead ? 'Non letto' : '';\n }\n\n /**\n * Resets pagination to page 0 and fetches a fresh result set.\n */\n protected find(): void {\n this.searchParams.first = 0;\n const paginator = this.paginator();\n if (paginator) {\n paginator.pageIndex = 0;\n }\n this.fetch();\n }\n\n /**\n * Fetches the current page of notifications from the server.\n */\n private fetch(): void {\n this.dialogService.busy('Caricamento in corso...');\n this.supportService.notifications.queryNotifications(this.searchParams)\n .pipe(finalize(() => this.dialogService.clearBusy()))\n .subscribe(r => {\n if (!r.success) {\n this.dialogService.error(r.message);\n } else {\n this.items.set(r.value?.items ?? []);\n this.total.set(r.value?.total ?? 0);\n this.updateScroll();\n }\n });\n }\n\n /**\n * Handles paginator page changes and loads the corresponding result page.\n * @param e - The `PageEvent` emitted by `MatPaginator`.\n */\n protected fetchMore(e: PageEvent): void {\n const first = e.pageIndex * (this.searchParams.count ?? 25);\n this.searchParams.first = first;\n this.fetch();\n }\n\n\n /**\n * Marks one or more notifications as read or unread.\n * When no specific item is supplied, acts on the current selection.\n * @param item - A single notification to mark, or `undefined` to use the selection.\n * @param unmark - `true` to mark as unread; `false` (default) to mark as read.\n */\n protected mark(item?: SupportNotificationInfo, unmark: boolean = false): void {\n if (!item && !this.selection.all?.length) return;\n const ids: number[] | undefined = item ? [item.id] : this.getSelectedIds();\n if (!ids) return;\n this.dialogService.busy('Aggiornamento in corso...');\n this.supportService.notifications.markNotifications({ ids, unmark })\n .pipe(finalize(() => this.dialogService.clearBusy()))\n .subscribe(r => {\n if (!r.success) {\n this.dialogService.error(r.message);\n } else {\n const idSet = new Set(ids);\n this.items.update(list =>\n list.map(n => idSet.has(n.id) ? { ...n, isRead: !unmark } : n)\n );\n this.selection.clear();\n this.supportService.notifications.countUnreadNotifications();\n }\n });\n }\n\n /**\n * Opens the notification detail dialog for the given item.\n * @param item - The notification to display.\n */\n protected show(item: SupportNotificationInfo): void {\n this.dialogService.open(SupportNotificationComponent, {\n ariaLabel: 'visualizza notifica',\n autoFocus: 'dialog',\n restoreFocus: false,\n disableClose: true,\n data: { id: item.id },\n minWidth: '375px',\n maxWidth: '900px',\n width: '99%',\n height: '99%'\n });\n }\n\n}\n","<div class=\"notifications-browser-fixed\">\r\n <div class=\"notifications-browser-header\">\r\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\" fxLayoutGap=\"10px\" fxFill>\r\n <div fxFlex=\"*\">\r\n <div mat-dialog-title>Novità e informazioni</div>\r\n </div>\r\n <div fxLayoutAlign=\"end\">\r\n <button fxFlexAlign=\"start\" type=\"button\" mat-icon-button matTooltip=\"Chiudi\" aria-label=\"Chiudi\"\r\n [mat-dialog-close]=\"true\" class=\"dialog-close\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <div style=\"padding-left: 24px; padding-right: 24px; padding-bottom: 10px;\">\r\n <div fxLayout=\"row wrap\" fxFill fxLayoutAlign=\"space-between\">\r\n <div fxFlex=\"200px\" fxFlexAlign=\"end\">\r\n <mat-form-field style=\"width:200px\" subscriptSizing=\"dynamic\" appearance=\"outline\">\r\n <mat-label>Cerca</mat-label>\r\n <input matInput #searchInput=\"matInput\" type=\"text\" [(ngModel)]=\"searchParams.any\" maxlength=\"200\"\r\n (keyup.Enter)=\"find()\" autofocus placeholder=\"Inserisci testo + INVIO...\" />\r\n @if (searchParams.any) {\r\n <button type=\"button\" tabindex=\"-1\" matSuffix mat-icon-button aria-label=\"Pulisci\"\r\n (click)=\"searchParams.any = ''\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n }\r\n </mat-form-field>\r\n </div>\r\n <div fxFlex=\"*\" fxLayoutAlign=\"end\">\r\n <div fxFlexAlign=\"center\">\r\n @if (selection.hasValue()) {\r\n <button type=\"button\" mat-icon-button matTooltip=\"Azioni da eseguire sugli elementi selezionati\"\r\n [attr.aria-label]=\"'Menu opzioni per elementi selezionati'\" [matMenuTriggerFor]=\"menuSelections\">\r\n <mat-icon aria-hidden=\"false\" [matBadge]=\"selection.all.length\">checklist</mat-icon>\r\n </button>\r\n }\r\n <mat-menu #menuSelections=\"matMenu\">\r\n <button mat-menu-item (click)=\"selection.clear()\" [attr.aria-label]=\"'Deseleziona tutti'\">\r\n <mat-icon>clear</mat-icon>Deseleziona tutti\r\n </button>\r\n <mat-divider></mat-divider>\r\n <button mat-menu-item [attr.aria-label]=\"'Segna come da leggere'\" (click)=\"mark(undefined, true)\">\r\n <mat-icon>outlined_flag</mat-icon>Segna come da leggere\r\n </button>\r\n <button mat-menu-item [attr.aria-label]=\"'Segna come già letto'\" (click)=\"mark(undefined)\">\r\n <mat-icon>flag</mat-icon>Segna come già letto\r\n </button>\r\n </mat-menu>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n<mat-dialog-content id=\"notifications-browser-scrollable\">\r\n <div id=\"notifications-browser-scroller\">\r\n @if (total() === 0) {\r\n <div>\r\n <p class=\"message\"><i>Nessun elemento da visualizzare.</i></p>\r\n </div>\r\n } @else {\r\n <div>\r\n @for (item of items(); track item.id; let i = $index) {\r\n <div (mouseenter)=\"item.isOver = true;\" (mouseleave)=\"item.isOver = false\"\r\n [matContextMenuTriggerFor]=\"contextMenu\" [matContextMenuTriggerData]=\"{item: item}\">\r\n <div class=\"news\" fxLayout=\"row\" fxLayoutGap=\"6px\" fxFill [class.news-selected]=\"selection.isSelected(item.id)\"\r\n [class.news-read]=\"item.isRead\">\r\n <div fxFlex=\"6px\" [class]=\"getItemStateCssClass(item)\" [matTooltip]=\"getItemStateTooltip(item)\">\r\n </div>\r\n <div fxFlex=\"48px\" fxFlexAlign=\"center\" fxLayoutAlign=\"center\">\r\n @if (screenService.isTouchable || item.isOver || selection.isSelected(item.id)) {\r\n <mat-checkbox (change)=\"$event ? selection.toggle(item, item.id) : null\"\r\n [checked]=\"selection.isSelected(item.id)\">\r\n </mat-checkbox>\r\n }\r\n </div>\r\n <div fxFlex=\"*\" fxFlexAlign=\"center\" (click)=\"show(item); $event.stopPropagation()\">\r\n <div class=\"info-1 uppercase\">\r\n {{ (item.publishingDate ?? item.created) | format:'D':'dd/MM/yyyy'}}</div>\r\n <div>{{item.title}}</div>\r\n <div class=\"info-2 uppercase\">\r\n {{item.productNames}}\r\n @if (item.productModuleNames) {\r\n <span> | {{item.productModuleNames}}</span>\r\n }\r\n </div>\r\n </div>\r\n <div fxFlex=\"50px\" fxFlexAlign=\"center\">\r\n <button type=\"button\" mat-icon-button matTooltip=\"Menu\" [attr.aria-label]=\"'Menu opzioni'\"\r\n [matMenuTriggerFor]=\"contextMenu\" [matMenuTriggerData]=\"{item: item}\" (click)=\"item.isMenuOpen = true\"\r\n [hidden]=\"!(item.isOver || item.isMenuOpen || selection.isSelected(item.id))\">\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n <mat-menu #contextMenu=\"matMenu\" (closed)=\"updateMenuButtonsVisibility()\">\r\n <ng-template matMenuContent let-item=\"item\">\r\n @if (item.isRead) {\r\n <button mat-menu-item [attr.aria-label]=\"'Segna come da leggere'\" (click)=\"mark(item, true)\">\r\n <mat-icon>flag</mat-icon>Segna come da leggere\r\n </button>\r\n } @else {\r\n <button mat-menu-item [attr.aria-label]=\"'Segna come da già letto'\" (click)=\"mark(item)\">\r\n <mat-icon>outlined_flag</mat-icon>Segna come già letto\r\n </button>\r\n }\r\n </ng-template>\r\n </mat-menu>\r\n </div>\r\n }\r\n </div>\r\n</mat-dialog-content>\r\n<mat-dialog-actions class=\"notifications-browser-fixed\">\r\n <div fxLayout=\"row wrap\" fxLayoutGap=\"10px\" fxLayoutAlign=\"space-between\" fxFill>\r\n <!-- legend -->\r\n <div fxFlex.lt-md=\"100\" class=\"legend-container\">\r\n <div class=\"legend unread-bg\"></div>\r\n da leggere\r\n </div>\r\n <div fxFlex.lt-md=\"100\" fxLayoutAlign=\"end\">\r\n <mat-paginator #paginator [hidePageSize]=\"true\" [length]=\"total()\" [pageSize]=\"searchParams.count\"\r\n [showFirstLastButtons]=\"true\" (page)=\"fetchMore($event)\"></mat-paginator>\r\n </div>\r\n </div>\r\n</mat-dialog-actions>","/*\n * Public API Surface of @arsedizioni/ars-utils/ui.notifications\n */\nexport * from './notifications-browser/notifications-browser.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["i5"],"mappings":"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"}
1
+ {"version":3,"file":"arsedizioni-ars-utils-ui.notifications.mjs","sources":["../../../projects/ars-utils/ui.notifications/notifications-browser/notification/notification.component.ts","../../../projects/ars-utils/ui.notifications/notifications-browser/notification/notification.component.html","../../../projects/ars-utils/ui.notifications/notifications-browser/notifications-browser.component.ts","../../../projects/ars-utils/ui.notifications/notifications-browser/notifications-browser.component.html","../../../projects/ars-utils/ui.notifications/public_api.ts","../../../projects/ars-utils/ui.notifications/arsedizioni-ars-utils-ui.notifications.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n inject,\n signal\n} from '@angular/core';\nimport { MAT_DIALOG_DATA, MatDialogTitle, MatDialogClose, MatDialogContent, MatDialogActions } from '@angular/material/dialog';\nimport { BroadcastService, ScreenService, SystemUtils } from '@arsedizioni/ars-utils/core';\nimport { SupportDocumentInfo, SupportMessages, SupportNotificationInfo, SupportService } from '@arsedizioni/ars-utils/support.common';\nimport { DialogService } from '@arsedizioni/ars-utils/ui.dialogs';\nimport { FlexLayoutModule } from '@arsedizioni/ars-utils/ui';\nimport { saveAs } from 'file-saver';\nimport { SafeHtmlPipe } from '@arsedizioni/ars-utils/core';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { MatButtonModule } from '@angular/material/button';\nimport { finalize } from 'rxjs';\n\nexport interface SupportNotificationData {\n id?: number;\n}\n\n\n@Component({\n host: { 'Bind': SystemUtils.generateUUID() },\n templateUrl: './notification.component.html',\n styleUrls: ['./notification.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FlexLayoutModule, MatDialogTitle, MatButtonModule, MatTooltipModule, MatDialogClose, MatIconModule, MatDialogContent,\n MatDialogActions, MatMenuModule, SafeHtmlPipe]\n})\nexport class SupportNotificationComponent {\n\n protected readonly screenService = inject(ScreenService);\n private readonly supportService = inject(SupportService);\n private readonly broadcastService = inject(BroadcastService);\n private readonly dialogService = inject(DialogService);\n private readonly dialogData: SupportNotificationData = inject(MAT_DIALOG_DATA);\n\n /** Id of the notification to display, resolved from dialog data. */\n protected readonly id: number = this.dialogData?.id ?? -1;\n\n /** The loaded notification; `undefined` until the fetch completes. */\n protected readonly item = signal<SupportNotificationInfo | undefined>(undefined);\n\n constructor() {\n this.fetch();\n }\n\n /**\n * Fetches the notification from the server and populates the `item` signal.\n */\n private fetch(): void {\n this.dialogService.busy('Caricamento in corso...');\n this.supportService.notifications.getNotification(this.id)\n .pipe(finalize(() => this.dialogService.clearBusy()))\n .subscribe(r => {\n if (!r.success) {\n this.dialogService.error(r.message);\n } else {\n this.item.set(r.value);\n this.broadcastService.sendMessage(SupportMessages.NOTIFICATION_READ, r.value.id);\n }\n });\n }\n\n /**\n * Downloads a binary attachment using FileSaver, or opens a URL document in a new tab.\n * @param doc - The notification document to open or download.\n */\n protected downloadDocument(doc: SupportDocumentInfo): void {\n if (doc.isBinary) {\n if (doc.id === undefined) return;\n this.supportService.notifications.downloadNotificationDocument(doc.id).subscribe(blob => {\n saveAs(blob);\n });\n } else if (doc.url) {\n window.open(doc.url, '_blank');\n }\n }\n\n}\n","<div class=\"support-notification-fixed\">\r\n <div class=\"support-notification-header\">\r\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\" fxLayoutGap=\"10px\" fxFill >\r\n <div fxFlex=\"*\">\r\n <div mat-dialog-title>{{item()?.title}}</div>\r\n </div>\r\n <div fxLayoutAlign=\"end\">\r\n <button fxFlexAlign=\"start\" type=\"button\" mat-icon-button matTooltip=\"Chiudi\"\r\n aria-label=\"Chiudi\" [mat-dialog-close]=\"true\" class=\"dialog-close\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n<mat-dialog-content id=\"notification-scrollable\">\r\n <div id=\"notification-scroller\">\r\n <div [innerHtml]=\"(item()?.text ?? 'Caricamento in corso...') | safeHtml\"></div>\r\n </div>\r\n</mat-dialog-content>\r\n@if (item()?.documents && item()!.documents!.length > 0) {\r\n<mat-dialog-actions class=\"notification-fixed\">\r\n <div style=\"padding: 10px 0\">\r\n <button type=\"button\" mat-button [attr.aria-label]=\"'Documenti scaricabili'\" [matMenuTriggerFor]=\"documentsMenu\">\r\n {{item()!.documents!.length}}\r\n @if (item()!.documents!.length === 1) {\r\n <span>Documento scaricabile</span>\r\n } @else {\r\n <span>Documenti scaricabili</span>\r\n }\r\n <mat-icon class=\"icon-menu-drop-down\">arrow_drop_down</mat-icon>\r\n </button>\r\n <mat-menu #documentsMenu=\"matMenu\">\r\n <ng-template matMenuContent>\r\n @for (doc of item()!.documents; track doc.id) {\r\n <button mat-menu-item (click)=\"downloadDocument(doc)\">\r\n @if (doc.isBinary) {\r\n <mat-icon>attach_file</mat-icon>\r\n } @else {\r\n <mat-icon>link</mat-icon>\r\n }\r\n {{doc.name}}\r\n </button>\r\n }\r\n </ng-template>\r\n </mat-menu>\r\n </div>\r\n</mat-dialog-actions>\r\n}","import {\n ChangeDetectionStrategy,\n Component, DestroyRef,\n afterNextRender,\n inject,\n signal,\n viewChild\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormField, form, maxLength } from '@angular/forms/signals';\nimport { MatBadgeModule } from '@angular/material/badge';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatDialogActions, MatDialogClose, MatDialogContent, MatDialogTitle } from '@angular/material/dialog';\nimport { MatDividerModule } from '@angular/material/divider';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatPaginator, MatPaginatorModule, PageEvent } from '@angular/material/paginator';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { BroadcastService, FormatPipe, ScreenService, SelectableModel, SystemUtils } from '@arsedizioni/ars-utils/core';\nimport { SupportMessages, SupportNotificationInfo, SupportNotificationsSearchParams, SupportService } from '@arsedizioni/ars-utils/support.common';\nimport { DialogService } from '@arsedizioni/ars-utils/ui.dialogs';\nimport { FlexLayoutModule } from '@arsedizioni/ars-utils/ui';\nimport { finalize } from 'rxjs';\nimport { SupportNotificationComponent } from './notification/notification.component';\n\n@Component({\n host: { 'Bind': SystemUtils.generateUUID() },\n templateUrl: './notifications-browser.component.html',\n styleUrls: ['./notifications-browser.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FlexLayoutModule, MatDialogTitle, MatButtonModule, MatTooltipModule, MatDialogClose,\n MatIconModule, MatFormFieldModule, MatInputModule, FormField, MatMenuModule, MatBadgeModule, MatDividerModule, MatDialogContent,\n MatCheckboxModule, MatDialogActions, MatPaginatorModule, FormatPipe]\n})\nexport class SupportNotificationsBrowserComponent {\n\n readonly paginator = viewChild.required<MatPaginator>('paginator');\n protected readonly screenService = inject(ScreenService);\n private readonly supportService = inject(SupportService);\n private readonly broadcastService = inject(BroadcastService);\n private readonly dialogService = inject(DialogService);\n private readonly destroyRef = inject(DestroyRef);\n protected selection = new SelectableModel<SupportNotificationInfo, number>(true, 'id');\n protected searchParams: SupportNotificationsSearchParams = {\n first: 0,\n count: 25\n };\n\n /** Current free-text search value, bound to the search input. */\n protected readonly searchText = signal<string>('');\n\n /** Signal form for the search box (max 200 characters). */\n protected readonly searchForm = form(this.searchText, p => {\n maxLength(p, 200);\n });\n protected total = signal<number>(-1);\n protected items = signal<SupportNotificationInfo[]>([]);\n\n constructor() {\n // React to message broadcasting\n this.broadcastService.getMessage()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(message => {\n if (message.id === SupportMessages.NOTIFICATION_READ) {\n this.items.update(list =>\n list.map(n => n.id === message.data ? { ...n, isRead: true } : n)\n );\n }\n });\n\n afterNextRender(() => this.find());\n }\n\n /**\n * Scrolls the notifications list back to the top.\n */\n private updateScroll(): void {\n const elem = document.getElementById('notifications-browser-scroller');\n if (elem?.parentElement) {\n elem.parentElement.scrollTop = 0;\n }\n }\n\n /**\n * Resets the `isMenuOpen` flag on all items after a context menu is closed.\n */\n protected updateMenuButtonsVisibility(): void {\n this.items.update(list => list.map(n => ({ ...n, isMenuOpen: false })));\n }\n\n /**\n * Returns the ids of the currently selected items.\n * Shows an error and returns `undefined` when the selection exceeds 50 items.\n * @returns An array of selected notification ids, or `undefined` on validation failure.\n */\n private getSelectedIds(): number[] | undefined {\n if ((this.selection.all?.length ?? 0) > 50) {\n this.dialogService.error('La selezione non può contenere più di 50 elementi.');\n return undefined;\n }\n return this.selection.all?.map(n => n.id) ?? [];\n }\n\n /**\n * Returns the CSS class to apply to the read-state indicator stripe.\n * @param item - The notification to evaluate.\n * @returns `'unread-bg'` when the notification has not been read, otherwise `undefined`.\n */\n protected getItemStateCssClass(item: SupportNotificationInfo): string | undefined {\n return !item.isRead ? 'unread-bg' : undefined;\n }\n\n /**\n * Returns the tooltip text for the read-state indicator stripe.\n * @param item - The notification to evaluate.\n * @returns `'Non letto'` when unread, otherwise an empty string.\n */\n protected getItemStateTooltip(item: SupportNotificationInfo): string {\n return !item.isRead ? 'Non letto' : '';\n }\n\n /**\n * Resets pagination to page 0 and fetches a fresh result set.\n */\n protected find(): void {\n this.searchParams.first = 0;\n const paginator = this.paginator();\n if (paginator) {\n paginator.pageIndex = 0;\n }\n this.fetch();\n }\n\n /**\n * Fetches the current page of notifications from the server.\n */\n private fetch(): void {\n // Commit the live search text to the query parameters at fetch time.\n this.searchParams.any = this.searchText() || undefined;\n this.dialogService.busy('Caricamento in corso...');\n this.supportService.notifications.queryNotifications(this.searchParams)\n .pipe(finalize(() => this.dialogService.clearBusy()))\n .subscribe(r => {\n if (!r.success) {\n this.dialogService.error(r.message);\n } else {\n this.items.set(r.value?.items ?? []);\n this.total.set(r.value?.total ?? 0);\n this.updateScroll();\n }\n });\n }\n\n /**\n * Handles paginator page changes and loads the corresponding result page.\n * @param e - The `PageEvent` emitted by `MatPaginator`.\n */\n protected fetchMore(e: PageEvent): void {\n const first = e.pageIndex * (this.searchParams.count ?? 25);\n this.searchParams.first = first;\n this.fetch();\n }\n\n\n /**\n * Marks one or more notifications as read or unread.\n * When no specific item is supplied, acts on the current selection.\n * @param item - A single notification to mark, or `undefined` to use the selection.\n * @param unmark - `true` to mark as unread; `false` (default) to mark as read.\n */\n protected mark(item?: SupportNotificationInfo, unmark: boolean = false): void {\n if (!item && !this.selection.all?.length) return;\n const ids: number[] | undefined = item ? [item.id] : this.getSelectedIds();\n if (!ids) return;\n this.dialogService.busy('Aggiornamento in corso...');\n this.supportService.notifications.markNotifications({ ids, unmark })\n .pipe(finalize(() => this.dialogService.clearBusy()))\n .subscribe(r => {\n if (!r.success) {\n this.dialogService.error(r.message);\n } else {\n const idSet = new Set(ids);\n this.items.update(list =>\n list.map(n => idSet.has(n.id) ? { ...n, isRead: !unmark } : n)\n );\n this.selection.clear();\n this.supportService.notifications.countUnreadNotifications();\n }\n });\n }\n\n /**\n * Opens the notification detail dialog for the given item.\n * @param item - The notification to display.\n */\n protected show(item: SupportNotificationInfo): void {\n this.dialogService.open(SupportNotificationComponent, {\n ariaLabel: 'visualizza notifica',\n autoFocus: 'dialog',\n restoreFocus: false,\n disableClose: true,\n data: { id: item.id },\n minWidth: '375px',\n maxWidth: '900px',\n width: '99%',\n height: '99%'\n });\n }\n\n}\n","<div class=\"notifications-browser-fixed\">\n <div class=\"notifications-browser-header\">\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\" fxLayoutGap=\"10px\" fxFill>\n <div fxFlex=\"*\">\n <div mat-dialog-title>Novità e informazioni</div>\n </div>\n <div fxLayoutAlign=\"end\">\n <button fxFlexAlign=\"start\" type=\"button\" mat-icon-button matTooltip=\"Chiudi\" aria-label=\"Chiudi\"\n [mat-dialog-close]=\"true\" class=\"dialog-close\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <div style=\"padding-left: 24px; padding-right: 24px; padding-bottom: 10px;\">\n <div fxLayout=\"row wrap\" fxFill fxLayoutAlign=\"space-between\">\n <div fxFlex=\"200px\" fxFlexAlign=\"end\">\n <mat-form-field style=\"width:200px\" subscriptSizing=\"dynamic\" appearance=\"outline\">\n <mat-label>Cerca</mat-label>\n <input matInput #searchInput=\"matInput\" type=\"text\" [formField]=\"searchForm\"\n (keyup.enter)=\"find()\" autofocus placeholder=\"Inserisci testo + INVIO...\" />\n @if (searchText()) {\n <button type=\"button\" tabindex=\"-1\" matSuffix mat-icon-button aria-label=\"Pulisci\"\n (click)=\"searchText.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </mat-form-field>\n </div>\n <div fxFlex=\"*\" fxLayoutAlign=\"end\">\n <div fxFlexAlign=\"center\">\n @if (selection.hasValue()) {\n <button type=\"button\" mat-icon-button matTooltip=\"Azioni da eseguire sugli elementi selezionati\"\n [attr.aria-label]=\"'Menu opzioni per elementi selezionati'\" [matMenuTriggerFor]=\"menuSelections\">\n <mat-icon aria-hidden=\"false\" [matBadge]=\"selection.all.length\">checklist</mat-icon>\n </button>\n }\n <mat-menu #menuSelections=\"matMenu\">\n <button mat-menu-item (click)=\"selection.clear()\" [attr.aria-label]=\"'Deseleziona tutti'\">\n <mat-icon>clear</mat-icon>Deseleziona tutti\n </button>\n <mat-divider></mat-divider>\n <button mat-menu-item [attr.aria-label]=\"'Segna come da leggere'\" (click)=\"mark(undefined, true)\">\n <mat-icon>outlined_flag</mat-icon>Segna come da leggere\n </button>\n <button mat-menu-item [attr.aria-label]=\"'Segna come già letto'\" (click)=\"mark(undefined)\">\n <mat-icon>flag</mat-icon>Segna come già letto\n </button>\n </mat-menu>\n </div>\n </div>\n </div>\n </div>\n</div>\n<mat-dialog-content id=\"notifications-browser-scrollable\">\n <div id=\"notifications-browser-scroller\">\n @if (total() === 0) {\n <div>\n <p class=\"message\"><i>Nessun elemento da visualizzare.</i></p>\n </div>\n } @else {\n <div>\n @for (item of items(); track item.id; let i = $index) {\n <div (mouseenter)=\"item.isOver = true;\" (mouseleave)=\"item.isOver = false\"\n [matContextMenuTriggerFor]=\"contextMenu\" [matContextMenuTriggerData]=\"{item: item}\">\n <div class=\"news\" fxLayout=\"row\" fxLayoutGap=\"6px\" fxFill [class.news-selected]=\"selection.isSelected(item.id)\"\n [class.news-read]=\"item.isRead\">\n <div fxFlex=\"6px\" [class]=\"getItemStateCssClass(item)\" [matTooltip]=\"getItemStateTooltip(item)\">\n </div>\n <div fxFlex=\"48px\" fxFlexAlign=\"center\" fxLayoutAlign=\"center\">\n @if (screenService.isTouchable || item.isOver || selection.isSelected(item.id)) {\n <mat-checkbox (change)=\"$event ? selection.toggle(item, item.id) : null\"\n [checked]=\"selection.isSelected(item.id)\">\n </mat-checkbox>\n }\n </div>\n <div fxFlex=\"*\" fxFlexAlign=\"center\" (click)=\"show(item); $event.stopPropagation()\">\n <div class=\"info-1 uppercase\">\n {{ (item.publishingDate ?? item.created) | format:'D':'dd/MM/yyyy'}}</div>\n <div>{{item.title}}</div>\n <div class=\"info-2 uppercase\">\n {{item.productNames}}\n @if (item.productModuleNames) {\n <span> | {{item.productModuleNames}}</span>\n }\n </div>\n </div>\n <div fxFlex=\"50px\" fxFlexAlign=\"center\">\n <button type=\"button\" mat-icon-button matTooltip=\"Menu\" [attr.aria-label]=\"'Menu opzioni'\"\n [matMenuTriggerFor]=\"contextMenu\" [matMenuTriggerData]=\"{item: item}\" (click)=\"item.isMenuOpen = true\"\n [hidden]=\"!(item.isOver || item.isMenuOpen || selection.isSelected(item.id))\">\n <mat-icon>more_vert</mat-icon>\n </button>\n </div>\n </div>\n </div>\n }\n <mat-menu #contextMenu=\"matMenu\" (closed)=\"updateMenuButtonsVisibility()\">\n <ng-template matMenuContent let-item=\"item\">\n @if (item.isRead) {\n <button mat-menu-item [attr.aria-label]=\"'Segna come da leggere'\" (click)=\"mark(item, true)\">\n <mat-icon>flag</mat-icon>Segna come da leggere\n </button>\n } @else {\n <button mat-menu-item [attr.aria-label]=\"'Segna come da già letto'\" (click)=\"mark(item)\">\n <mat-icon>outlined_flag</mat-icon>Segna come già letto\n </button>\n }\n </ng-template>\n </mat-menu>\n </div>\n }\n </div>\n</mat-dialog-content>\n<mat-dialog-actions class=\"notifications-browser-fixed\">\n <div fxLayout=\"row wrap\" fxLayoutGap=\"10px\" fxLayoutAlign=\"space-between\" fxFill>\n <!-- legend -->\n <div fxFlex.lt-md=\"100\" class=\"legend-container\">\n <div class=\"legend unread-bg\"></div>\n da leggere\n </div>\n <div fxFlex.lt-md=\"100\" fxLayoutAlign=\"end\">\n <mat-paginator #paginator [hidePageSize]=\"true\" [length]=\"total()\" [pageSize]=\"searchParams.count\"\n [showFirstLastButtons]=\"true\" (page)=\"fetchMore($event)\"></mat-paginator>\n </div>\n </div>\n</mat-dialog-actions>","/*\n * Public API Surface of @arsedizioni/ars-utils/ui.notifications\n */\nexport * from './notifications-browser/notifications-browser.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["i5"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAiCa,4BAA4B,CAAA;AAcvC,IAAA,WAAA,GAAA;AAZmB,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;AACvC,QAAA,IAAA,CAAA,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;AACvC,QAAA,IAAA,CAAA,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAC3C,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;AACrC,QAAA,IAAA,CAAA,UAAU,GAA4B,MAAM,CAAC,eAAe,CAAC;;QAG3D,IAAA,CAAA,EAAE,GAAW,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,CAAC;;QAGtC,IAAA,CAAA,IAAI,GAAG,MAAM,CAAsC,SAAS;iFAAC;QAG9E,IAAI,CAAC,KAAK,EAAE;IACd;AAEA;;AAEG;IACK,KAAK,GAAA;AACX,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,yBAAyB,CAAC;QAClD,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE;AACtD,aAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;aACnD,SAAS,CAAC,CAAC,IAAG;AACb,YAAA,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE;gBACd,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;YACrC;iBAAO;gBACL,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AACtB,gBAAA,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAClF;AACF,QAAA,CAAC,CAAC;IACN;AAEA;;;AAGG;AACO,IAAA,gBAAgB,CAAC,GAAwB,EAAA;AACjD,QAAA,IAAI,GAAG,CAAC,QAAQ,EAAE;AAChB,YAAA,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS;gBAAE;AAC1B,YAAA,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,4BAA4B,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,IAAG;gBACtF,MAAM,CAAC,IAAI,CAAC;AACd,YAAA,CAAC,CAAC;QACJ;AAAO,aAAA,IAAI,GAAG,CAAC,GAAG,EAAE;YAClB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC;QAChC;IACF;8GAhDW,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAA5B,4BAA4B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,MAAA,EARvB,WAAW,CAAC,YAAY,EAAE,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECzB5C,i6DAgDC,EAAA,MAAA,EAAA,CAAA,usJAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDlBW,gBAAgB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,oRAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,aAAA,EAAA,aAAA,EAAA,aAAA,EAAA,aAAA,EAAA,aAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,wPAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,WAAA,EAAA,WAAA,EAAA,WAAA,EAAA,WAAA,EAAA,WAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,0VAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8TAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8TAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,6TAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,QAAA,EAAA,eAAA,EAAA,eAAA,EAAA,eAAA,EAAA,eAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,cAAc,EAAA,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,IAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,eAAe,0iBAAE,gBAAgB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,cAAc,EAAA,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,MAAA,EAAA,kBAAA,EAAA,gBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,QAAA,EAAA,8DAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAC5H,gBAAgB,EAAA,QAAA,EAAA,8DAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,WAAA,EAAA,WAAA,EAAA,gBAAA,EAAA,aAAA,EAAA,OAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,OAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,WAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,6CAAA,EAAA,MAAA,EAAA,CAAA,sBAAA,EAAA,mBAAA,EAAA,oBAAA,EAAA,4BAAA,CAAA,EAAA,OAAA,EAAA,CAAA,YAAA,EAAA,YAAA,EAAA,YAAA,EAAA,aAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAE,YAAY,EAAA,IAAA,EAAA,UAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAEpC,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBATxC,SAAS;2BACF,EAAE,MAAM,EAAE,WAAW,CAAC,YAAY,EAAE,EAAE,EAAA,UAAA,EAGhC,IAAI,EAAA,eAAA,EACC,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB;AAC5H,wBAAA,gBAAgB,EAAE,aAAa,EAAE,YAAY,CAAC,EAAA,QAAA,EAAA,i6DAAA,EAAA,MAAA,EAAA,CAAA,usJAAA,CAAA,EAAA;;;MEOrC,oCAAoC,CAAA;AAwB/C,IAAA,WAAA,GAAA;AAtBS,QAAA,IAAA,CAAA,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAe,WAAW;sFAAC;AAC/C,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;AACvC,QAAA,IAAA,CAAA,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;AACvC,QAAA,IAAA,CAAA,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAC3C,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;AACrC,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACtC,IAAA,CAAA,SAAS,GAAG,IAAI,eAAe,CAAkC,IAAI,EAAE,IAAI,CAAC;AAC5E,QAAA,IAAA,CAAA,YAAY,GAAqC;AACzD,YAAA,KAAK,EAAE,CAAC;AACR,YAAA,KAAK,EAAE;SACR;;QAGkB,IAAA,CAAA,UAAU,GAAG,MAAM,CAAS,EAAE;uFAAC;;QAG/B,IAAA,CAAA,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,IAAG;AACxD,YAAA,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC;AACnB,QAAA,CAAC,CAAC;AACQ,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAS,CAAC,CAAC;kFAAC;QAC1B,IAAA,CAAA,KAAK,GAAG,MAAM,CAA4B,EAAE;kFAAC;;AAIrD,QAAA,IAAI,CAAC,gBAAgB,CAAC,UAAU;AAC7B,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;aACxC,SAAS,CAAC,OAAO,IAAG;YACnB,IAAI,OAAO,CAAC,EAAE,KAAK,eAAe,CAAC,iBAAiB,EAAE;AACpD,gBAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,IACpB,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAClE;YACH;AACF,QAAA,CAAC,CAAC;QAEJ,eAAe,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACpC;AAEA;;AAEG;IACK,YAAY,GAAA;QAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,gCAAgC,CAAC;AACtE,QAAA,IAAI,IAAI,EAAE,aAAa,EAAE;AACvB,YAAA,IAAI,CAAC,aAAa,CAAC,SAAS,GAAG,CAAC;QAClC;IACF;AAEA;;AAEG;IACO,2BAA2B,GAAA;AACnC,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACzE;AAEA;;;;AAIG;IACK,cAAc,GAAA;AACpB,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE;AAC1C,YAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,oDAAoD,CAAC;AAC9E,YAAA,OAAO,SAAS;QAClB;AACA,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE;IACjD;AAEA;;;;AAIG;AACO,IAAA,oBAAoB,CAAC,IAA6B,EAAA;AAC1D,QAAA,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,WAAW,GAAG,SAAS;IAC/C;AAEA;;;;AAIG;AACO,IAAA,mBAAmB,CAAC,IAA6B,EAAA;AACzD,QAAA,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,WAAW,GAAG,EAAE;IACxC;AAEA;;AAEG;IACO,IAAI,GAAA;AACZ,QAAA,IAAI,CAAC,YAAY,CAAC,KAAK,GAAG,CAAC;AAC3B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;QAClC,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,SAAS,GAAG,CAAC;QACzB;QACA,IAAI,CAAC,KAAK,EAAE;IACd;AAEA;;AAEG;IACK,KAAK,GAAA;;QAEX,IAAI,CAAC,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,SAAS;AACtD,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,yBAAyB,CAAC;QAClD,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY;AACnE,aAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;aACnD,SAAS,CAAC,CAAC,IAAG;AACb,YAAA,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE;gBACd,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;YACrC;iBAAO;AACL,gBAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC;AACpC,gBAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,IAAI,CAAC,CAAC;gBACnC,IAAI,CAAC,YAAY,EAAE;YACrB;AACF,QAAA,CAAC,CAAC;IACN;AAEA;;;AAGG;AACO,IAAA,SAAS,CAAC,CAAY,EAAA;AAC9B,QAAA,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC;AAC3D,QAAA,IAAI,CAAC,YAAY,CAAC,KAAK,GAAG,KAAK;QAC/B,IAAI,CAAC,KAAK,EAAE;IACd;AAGA;;;;;AAKG;AACO,IAAA,IAAI,CAAC,IAA8B,EAAE,MAAA,GAAkB,KAAK,EAAA;QACpE,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM;YAAE;AAC1C,QAAA,MAAM,GAAG,GAAyB,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE;AAC1E,QAAA,IAAI,CAAC,GAAG;YAAE;AACV,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,2BAA2B,CAAC;AACpD,QAAA,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE;AAChE,aAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;aACnD,SAAS,CAAC,CAAC,IAAG;AACb,YAAA,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE;gBACd,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;YACrC;iBAAO;AACL,gBAAA,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC;AAC1B,gBAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,IACpB,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAC/D;AACD,gBAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;AACtB,gBAAA,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,wBAAwB,EAAE;YAC9D;AACF,QAAA,CAAC,CAAC;IACN;AAEA;;;AAGG;AACO,IAAA,IAAI,CAAC,IAA6B,EAAA;AAC1C,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,4BAA4B,EAAE;AACpD,YAAA,SAAS,EAAE,qBAAqB;AAChC,YAAA,SAAS,EAAE,QAAQ;AACnB,YAAA,YAAY,EAAE,KAAK;AACnB,YAAA,YAAY,EAAE,IAAI;AAClB,YAAA,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;AACrB,YAAA,QAAQ,EAAE,OAAO;AACjB,YAAA,QAAQ,EAAE,OAAO;AACjB,YAAA,KAAK,EAAE,KAAK;AACZ,YAAA,MAAM,EAAE;AACT,SAAA,CAAC;IACJ;8GA7KW,oCAAoC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApC,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oCAAoC,8EAT/B,WAAW,CAAC,YAAY,EAAE,EAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,WAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,WAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC7B5C,kkMA8HqB,EAAA,MAAA,EAAA,CAAA,+6KAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED5FT,gBAAgB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,oRAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,aAAA,EAAA,aAAA,EAAA,aAAA,EAAA,aAAA,EAAA,aAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,wPAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,WAAA,EAAA,WAAA,EAAA,WAAA,EAAA,WAAA,EAAA,WAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,EAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,0VAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,qBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8TAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8TAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,EAAA,mBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,6TAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,QAAA,EAAA,eAAA,EAAA,eAAA,EAAA,eAAA,EAAA,eAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,cAAc,8HAAE,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,sFAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,cAAc,oLAC3F,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,kBAAkB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,YAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,OAAA,EAAA,YAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,QAAA,EAAA,QAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,+CAAA,EAAA,MAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,cAAc,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,QAAA,EAAA,QAAA,EAAA,yHAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,IAAA,EAAA,aAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,mBAAA,EAAA,kBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,qBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,SAAS,uGAAE,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,WAAA,EAAA,WAAA,EAAA,gBAAA,EAAA,aAAA,EAAA,OAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,OAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,WAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,6CAAA,EAAA,MAAA,EAAA,CAAA,sBAAA,EAAA,mBAAA,EAAA,oBAAA,EAAA,4BAAA,CAAA,EAAA,OAAA,EAAA,CAAA,YAAA,EAAA,YAAA,EAAA,YAAA,EAAA,aAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,MAAA,EAAA,CAAA,0BAAA,EAAA,2BAAA,EAAA,mCAAA,EAAA,+BAAA,CAAA,EAAA,OAAA,EAAA,CAAA,YAAA,EAAA,YAAA,CAAA,EAAA,QAAA,EAAA,CAAA,uBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,cAAc,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,QAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,cAAA,EAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,gBAAgB,wGAC/H,iBAAiB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,GAAA,CAAA,WAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,eAAA,EAAA,WAAA,EAAA,IAAA,EAAA,UAAA,EAAA,eAAA,EAAA,MAAA,EAAA,OAAA,EAAA,eAAA,EAAA,UAAA,EAAA,OAAA,EAAA,qBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,qBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,QAAA,EAAA,8DAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,kBAAkB,gSAAE,UAAU,EAAA,IAAA,EAAA,QAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAE1D,oCAAoC,EAAA,UAAA,EAAA,CAAA;kBAVhD,SAAS;2BACF,EAAE,MAAM,EAAE,WAAW,CAAC,YAAY,EAAE,EAAE,EAAA,UAAA,EAGhC,IAAI,EAAA,eAAA,EACC,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc;AAC3F,wBAAA,aAAa,EAAE,kBAAkB,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB;AAC/H,wBAAA,iBAAiB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,CAAC,EAAA,QAAA,EAAA,kkMAAA,EAAA,MAAA,EAAA,CAAA,+6KAAA,CAAA,EAAA;iGAIhB,WAAW,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AExCnE;;AAEG;;ACFH;;AAEG;;;;"}
@@ -1,12 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Service, input, output, inject, ElementRef, ChangeDetectorRef, forwardRef, Directive, signal, ChangeDetectionStrategy, Component } from '@angular/core';
3
- import * as i1 from '@angular/forms';
4
- import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
3
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
5
4
  import { ThemeService } from '@arsedizioni/ars-utils/core';
6
- import * as i3 from '@angular/material/button';
5
+ import { form, disabled, FormField } from '@angular/forms/signals';
6
+ import * as i2 from '@angular/material/button';
7
7
  import { MatButtonModule } from '@angular/material/button';
8
8
  import { MatDialogRef, MAT_DIALOG_DATA, MatDialogContent, MatDialogActions, MatDialogClose } from '@angular/material/dialog';
9
- import * as i2 from '@arsedizioni/ars-utils/ui';
9
+ import * as i1 from '@arsedizioni/ars-utils/ui';
10
10
  import { FlexLayoutModule } from '@arsedizioni/ars-utils/ui';
11
11
 
12
12
  /**
@@ -568,12 +568,20 @@ class TinyMceEditorComponent {
568
568
  /** Whether the editor is in read-only mode. */
569
569
  this.disabled = signal(false, /* @ts-ignore */
570
570
  ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
571
- /** Current editor content, kept as a plain field for [(ngModel)] two-way binding. */
572
- this.text = '';
571
+ /** Current editor content. */
572
+ this.text = signal('', /* @ts-ignore */
573
+ ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
574
+ /**
575
+ * Signal form bound to the editor textarea. The disabled state is pushed to the
576
+ * TinymceEditorDirective through the ControlValueAccessor interop.
577
+ */
578
+ this.textForm = form(this.text, p => {
579
+ disabled(p, () => this.disabled());
580
+ });
573
581
  /** The profile handed to the editor directive, merged over its defaults. */
574
582
  this.tinymceConfig = {};
575
583
  const data = this.dialogData();
576
- this.text = data.text;
584
+ this.text.set(data.text);
577
585
  // The accessor already returns a private copy, so the toolbar override below cannot leak
578
586
  // into the preset shared with the rest of the application.
579
587
  this.tinymceConfig = data.configuration
@@ -587,18 +595,18 @@ class TinyMceEditorComponent {
587
595
  * Save the current editor content and close the dialog.
588
596
  */
589
597
  ok() {
590
- this.saving.emit(this.text ?? '');
598
+ this.saving.emit(this.text() ?? '');
591
599
  setTimeout(() => {
592
600
  this.dialogRef.close();
593
601
  }, 500);
594
602
  }
595
603
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TinyMceEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
596
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: TinyMceEditorComponent, isStandalone: true, selector: "ng-component", outputs: { saving: "saving" }, ngImport: i0, template: "<mat-dialog-content style=\"padding: 10px 10px 0 10px\">\r\n <textarea tinymceEditor class=\"full-screen-editor\" name=\"text\" [tinymceConfig]=\"tinymceConfig\"\r\n [disabled]=\"disabled()\" [(ngModel)]=\"text\"></textarea>\r\n</mat-dialog-content>\r\n<mat-dialog-actions>\r\n <div fxLayout=\"row\" fxLayoutGap=\"10px\" fxLayoutAlign=\"start center\" fxFill>\r\n <div fxFlex=\"50\">\r\n @if(dialogData().onShowInfo) {\r\n <button mat-stroked-button (click)=\"dialogData().onShowInfo()\">{{dialogData().infoButtonLabel ?? 'Informazioni'}}\r\n </button>\r\n }\r\n </div>\r\n <div fxFlex=\"50\" fxLayoutAlign=\"end\">\r\n @if (disabled()) {\r\n <button mat-stroked-button [mat-dialog-close]=\"true\">Chiudi</button>\r\n } @else {\r\n <button mat-flat-button (click)=\"ok()\">Salva</button>\r\n <button mat-stroked-button [mat-dialog-close]=\"true\">Annulla</button>\r\n }\r\n </div>\r\n </div>\r\n</mat-dialog-actions>\r\n", styles: [".mat-mdc-dialog-content{height:calc(100% - 52px)!important;max-height:calc(100% - 52px)!important}::ng-deep .full-screen-editor+.tox-tinymce{height:100%!important}\n"], dependencies: [{ kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: TinymceEditorDirective, selector: "textarea[tinymceEditor], div[tinymceEditor]", inputs: ["tinymceConfig", "tinymceToolbarMode", "tinymceImageUploader"], outputs: ["ready", "failed"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "ngmodule", type: FlexLayoutModule }, { kind: "directive", type: i2.FxLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg] ", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i2.FxFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg] ", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i2.FxLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg] ", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i2.FxLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg] ", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i2.FxFlexFillDirective, selector: " [fxFlexFill], [fxFill], [fxFlexFill.xs], [fxFlexFill.sm], [fxFlexFill.md], [fxFlexFill.lg], [fxFlexFill.xl], [fxFlexFill.lt-sm], [fxFlexFill.lt-md], [fxFlexFill.lt-lg], [fxFlexFill.lt-xl], [fxFlexFill.gt-xs], [fxFlexFill.gt-sm], [fxFlexFill.gt-md], [fxFlexFill.gt-lg] ", inputs: ["fxFlexFill", "fxFill", "fxFlexFill.xs", "fxFlexFill.sm", "fxFlexFill.md", "fxFlexFill.lg", "fxFlexFill.xl", "fxFlexFill.lt-sm", "fxFlexFill.lt-md", "fxFlexFill.lt-lg", "fxFlexFill.lt-xl", "fxFlexFill.gt-xs", "fxFlexFill.gt-sm", "fxFlexFill.gt-md", "fxFlexFill.gt-lg"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
604
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: TinyMceEditorComponent, isStandalone: true, selector: "ng-component", outputs: { saving: "saving" }, ngImport: i0, template: "<mat-dialog-content style=\"padding: 10px 10px 0 10px\">\n <textarea tinymceEditor class=\"full-screen-editor\" [tinymceConfig]=\"tinymceConfig\"\n [formField]=\"textForm\"></textarea>\n</mat-dialog-content>\n<mat-dialog-actions>\n <div fxLayout=\"row\" fxLayoutGap=\"10px\" fxLayoutAlign=\"start center\" fxFill>\n <div fxFlex=\"50\">\n @if(dialogData().onShowInfo) {\n <button mat-stroked-button (click)=\"dialogData().onShowInfo()\">{{dialogData().infoButtonLabel ?? 'Informazioni'}}\n </button>\n }\n </div>\n <div fxFlex=\"50\" fxLayoutAlign=\"end\">\n @if (disabled()) {\n <button mat-stroked-button [mat-dialog-close]=\"true\">Chiudi</button>\n } @else {\n <button mat-flat-button (click)=\"ok()\">Salva</button>\n <button mat-stroked-button [mat-dialog-close]=\"true\">Annulla</button>\n }\n </div>\n </div>\n</mat-dialog-actions>\n", styles: [".mat-mdc-dialog-content{height:calc(100% - 52px)!important;max-height:calc(100% - 52px)!important}::ng-deep .full-screen-editor+.tox-tinymce{height:100%!important}\n"], dependencies: [{ kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: TinymceEditorDirective, selector: "textarea[tinymceEditor], div[tinymceEditor]", inputs: ["tinymceConfig", "tinymceToolbarMode", "tinymceImageUploader"], outputs: ["ready", "failed"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "ngmodule", type: FlexLayoutModule }, { kind: "directive", type: i1.FxLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg] ", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i1.FxFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg] ", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i1.FxLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg] ", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i1.FxLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg] ", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i1.FxFlexFillDirective, selector: " [fxFlexFill], [fxFill], [fxFlexFill.xs], [fxFlexFill.sm], [fxFlexFill.md], [fxFlexFill.lg], [fxFlexFill.xl], [fxFlexFill.lt-sm], [fxFlexFill.lt-md], [fxFlexFill.lt-lg], [fxFlexFill.lt-xl], [fxFlexFill.gt-xs], [fxFlexFill.gt-sm], [fxFlexFill.gt-md], [fxFlexFill.gt-lg] ", inputs: ["fxFlexFill", "fxFill", "fxFlexFill.xs", "fxFlexFill.sm", "fxFlexFill.md", "fxFlexFill.lg", "fxFlexFill.xl", "fxFlexFill.lt-sm", "fxFlexFill.lt-md", "fxFlexFill.lt-lg", "fxFlexFill.lt-xl", "fxFlexFill.gt-xs", "fxFlexFill.gt-sm", "fxFlexFill.gt-md", "fxFlexFill.gt-lg"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
597
605
  }
598
606
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: TinyMceEditorComponent, decorators: [{
599
607
  type: Component,
600
- args: [{ standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatDialogContent, TinymceEditorDirective, FormsModule, MatDialogActions, FlexLayoutModule,
601
- MatButtonModule, MatDialogClose], template: "<mat-dialog-content style=\"padding: 10px 10px 0 10px\">\r\n <textarea tinymceEditor class=\"full-screen-editor\" name=\"text\" [tinymceConfig]=\"tinymceConfig\"\r\n [disabled]=\"disabled()\" [(ngModel)]=\"text\"></textarea>\r\n</mat-dialog-content>\r\n<mat-dialog-actions>\r\n <div fxLayout=\"row\" fxLayoutGap=\"10px\" fxLayoutAlign=\"start center\" fxFill>\r\n <div fxFlex=\"50\">\r\n @if(dialogData().onShowInfo) {\r\n <button mat-stroked-button (click)=\"dialogData().onShowInfo()\">{{dialogData().infoButtonLabel ?? 'Informazioni'}}\r\n </button>\r\n }\r\n </div>\r\n <div fxFlex=\"50\" fxLayoutAlign=\"end\">\r\n @if (disabled()) {\r\n <button mat-stroked-button [mat-dialog-close]=\"true\">Chiudi</button>\r\n } @else {\r\n <button mat-flat-button (click)=\"ok()\">Salva</button>\r\n <button mat-stroked-button [mat-dialog-close]=\"true\">Annulla</button>\r\n }\r\n </div>\r\n </div>\r\n</mat-dialog-actions>\r\n", styles: [".mat-mdc-dialog-content{height:calc(100% - 52px)!important;max-height:calc(100% - 52px)!important}::ng-deep .full-screen-editor+.tox-tinymce{height:100%!important}\n"] }]
608
+ args: [{ standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatDialogContent, TinymceEditorDirective, FormField, MatDialogActions, FlexLayoutModule,
609
+ MatButtonModule, MatDialogClose], template: "<mat-dialog-content style=\"padding: 10px 10px 0 10px\">\n <textarea tinymceEditor class=\"full-screen-editor\" [tinymceConfig]=\"tinymceConfig\"\n [formField]=\"textForm\"></textarea>\n</mat-dialog-content>\n<mat-dialog-actions>\n <div fxLayout=\"row\" fxLayoutGap=\"10px\" fxLayoutAlign=\"start center\" fxFill>\n <div fxFlex=\"50\">\n @if(dialogData().onShowInfo) {\n <button mat-stroked-button (click)=\"dialogData().onShowInfo()\">{{dialogData().infoButtonLabel ?? 'Informazioni'}}\n </button>\n }\n </div>\n <div fxFlex=\"50\" fxLayoutAlign=\"end\">\n @if (disabled()) {\n <button mat-stroked-button [mat-dialog-close]=\"true\">Chiudi</button>\n } @else {\n <button mat-flat-button (click)=\"ok()\">Salva</button>\n <button mat-stroked-button [mat-dialog-close]=\"true\">Annulla</button>\n }\n </div>\n </div>\n</mat-dialog-actions>\n", styles: [".mat-mdc-dialog-content{height:calc(100% - 52px)!important;max-height:calc(100% - 52px)!important}::ng-deep .full-screen-editor+.tox-tinymce{height:100%!important}\n"] }]
602
610
  }], ctorParameters: () => [], propDecorators: { saving: [{ type: i0.Output, args: ["saving"] }] } });
603
611
 
604
612
  /*
@@ -1 +1 @@
1
- {"version":3,"file":"arsedizioni-ars-utils-ui.tinymce.mjs","sources":["../../../projects/ars-utils/ui.tinymce/utils.ts","../../../projects/ars-utils/ui.tinymce/tinymce-loader.service.ts","../../../projects/ars-utils/ui.tinymce/tinymce-editor.directive.ts","../../../projects/ars-utils/ui.tinymce/editor/editor.component.ts","../../../projects/ars-utils/ui.tinymce/editor/editor.component.html","../../../projects/ars-utils/ui.tinymce/public_api.ts","../../../projects/ars-utils/ui.tinymce/arsedizioni-ars-utils-ui.tinymce.ts"],"sourcesContent":["import type { RawEditorOptions } from 'tinymce';\n\n/**\n * The editor profiles the applications ask for, ready to be handed to\n * `[tinymceConfig]` on {@link TinymceEditorDirective}.\n *\n * They describe **what the editor offers** — plugins, toolbar, formats, link and image\n * behaviour — and nothing else. Everything about *loading* TinyMCE (`base_url`, `suffix`,\n * `language`, `language_url`, `license_key`) and about the *theme* (`skin`, `content_css`)\n * belongs to `TinymceLoaderService` and to the directive, which resolve them against the\n * document base href and against `ThemeService`: a preset repeating them could only get them\n * wrong, and used to — the old ones pinned a relative `assets/tinymce` that broke under a\n * sub-path, and read the skin from `prefers-color-scheme` instead of the theme the user chose.\n *\n * Uploads are the same story: `automatic_uploads`, `paste_data_images` and `file_picker_types`\n * follow the `tinymceImageUploader` input, so an editor without a handler cannot end up\n * offering an upload tab that leads nowhere.\n *\n * Each accessor returns a **fresh deep copy**: a caller that tweaks a returned object — as the\n * editor dialog does with its toolbar — cannot corrupt the preset for everyone else.\n */\nexport class TinymceUtils {\n\n /**\n * Everything TinyMCE 8 open source has to offer, for a full-page editor.\n *\n * Adapted from the TinyMCE 5 profile the library used to ship: `paste`, `print`, `hr`,\n * `textpattern` and the `fullpage_*` options no longer exist (paste and text patterns moved\n * into the core, `fullpage` and `print` were dropped in v6), and `checklist`,\n * `openCodeMirrorButton` and `insertMediaButton` are premium or application-specific buttons\n * that a self-hosted GPL build has no way to render.\n */\n private static readonly FULL: RawEditorOptions = {\n height: 500,\n width: '100%',\n min_height: 250,\n onboarding: false,\n browser_spellcheck: true,\n custom_undo_redo_levels: 50,\n // Three &nbsp; per TAB, and no wrapping of the inserted spaces.\n nonbreaking_force_tab: true,\n nonbreaking_wrap: false,\n help_tabs: ['shortcuts', 'keyboardnav', 'versions'],\n menubar: false,\n plugins: 'advlist anchor autolink autosave charmap code fullscreen help image insertdatetime'\n + ' link lists media nonbreaking pagebreak preview quickbars searchreplace table'\n + ' visualblocks visualchars',\n toolbar: [\n 'fullscreen | undo redo searchreplace | code preview | link image media charmap nonbreaking | table tableprops tabledelete',\n 'bold italic superscript subscript forecolor backcolor | alignleft aligncenter alignright alignjustify | removeformat | bullist numlist'\n ],\n quickbars_insert_toolbar: false,\n quickbars_selection_toolbar: 'removeformat | bold italic | superscript subscript | quicklink h2 h3 blockquote',\n style_formats: [\n {\n title: 'Immagini float', items: [\n { title: 'Immagine a SX', selector: 'img', styles: { float: 'left', margin: '0 10px 0 10px' } },\n { title: 'Immagine a DX', selector: 'img', styles: { float: 'right', margin: '0 10px 0 10px' } }\n ]\n },\n {\n title: 'Formati', items: [\n { title: 'Grassetto', format: 'bold' },\n { title: 'Corsivo', format: 'italic' },\n { title: 'Sottolineato', format: 'underline' },\n { title: 'Barrato', format: 'strikethrough' },\n { title: 'Superscript', format: 'superscript' },\n { title: 'Subscript', format: 'subscript' },\n { title: 'Codice', format: 'code' }\n ]\n }\n ],\n // Spans with an inline style rather than <u>/<strike>: the content travels by e-mail, where\n // the presentational tags are the first thing a client strips.\n formats: {\n underline: { inline: 'span', styles: { 'text-decoration': 'underline' }, exact: true },\n strikethrough: { inline: 'span', styles: { 'text-decoration': 'line-through' }, exact: true }\n },\n insertdatetime_formats: ['%d/%m/%Y', '%d %b %Y', '%A, %d %B %Y'],\n link_default_target: '_blank',\n link_title: true,\n link_assume_external_targets: 'https',\n link_class_list: [\n { title: 'Nessuno', value: '' },\n { title: 'Rilevante', value: 'relevant' },\n ],\n link_context_toolbar: true,\n link_quicklink: true,\n image_advtab: true,\n image_caption: true,\n image_title: true,\n };\n\n /**\n * The one for a field inside a form: it grows with the text instead of owning the page, the\n * toolbar sits under it and collapses into groups, and there is no status bar or context menu\n * to compete with the form around it.\n */\n private static readonly COMPACT: RawEditorOptions = {\n ...TinymceUtils.FULL,\n height: 200,\n min_height: 200,\n max_height: 500,\n statusbar: false,\n contextmenu: false,\n toolbar_location: 'bottom',\n plugins: 'advlist anchor autolink autoresize autosave charmap code image insertdatetime'\n + ' link lists media nonbreaking preview quickbars searchreplace table'\n + ' visualblocks visualchars',\n toolbar: ['undo redo | quickimage | formatgroup paragraphgroup'],\n toolbar_groups: {\n formatgroup: {\n icon: 'format',\n tooltip: 'Formattazione',\n items: 'bold italic underline superscript subscript | forecolor backcolor | removeformat'\n },\n paragraphgroup: {\n icon: 'paragraph',\n tooltip: 'Formato paragrafo',\n items: 'h1 h2 h3 | bullist numlist | alignleft aligncenter alignright alignjustify | indent outdent'\n },\n insertgroup: {\n icon: 'plus',\n tooltip: 'Inserisci',\n items: 'quickimage media | link charmap nonbreaking | table tableprops tabledelete'\n }\n },\n quickbars_insert_toolbar: 'quickimage',\n link_class_list: [],\n };\n\n /** The compact one plus full screen, the insert group and the source view. */\n private static readonly COMPACT_EXTENDED: RawEditorOptions = {\n ...TinymceUtils.COMPACT,\n plugins: 'advlist anchor autolink autoresize autosave charmap code fullscreen image'\n + ' insertdatetime link lists media nonbreaking preview quickbars searchreplace table'\n + ' visualblocks visualchars',\n toolbar: ['undo redo | quickimage insertgroup | formatgroup paragraphgroup | code | fullscreen'],\n };\n\n /**\n * The full-page profile.\n * @returns A fresh copy of the configuration, safe to modify.\n */\n static get TinymceConfig(): RawEditorOptions {\n return structuredClone(TinymceUtils.FULL);\n }\n\n /**\n * The in-form profile.\n * @returns A fresh copy of the configuration, safe to modify.\n */\n static get TinymceCompactConfig(): RawEditorOptions {\n return structuredClone(TinymceUtils.COMPACT);\n }\n\n /**\n * The in-form profile with full screen and source view.\n * @returns A fresh copy of the configuration, safe to modify.\n */\n static get TinymceCompactExtendedConfig(): RawEditorOptions {\n return structuredClone(TinymceUtils.COMPACT_EXTENDED);\n }\n}\n","import { Service } from '@angular/core';\nimport type { TinyMCE } from 'tinymce';\n\ndeclare global {\n interface Window {\n tinymce?: TinyMCE;\n }\n}\n\n/**\n * Loads the self-hosted TinyMCE bundle on demand.\n *\n * TinyMCE is deliberately NOT imported by any module: a static import would pull ~500 kB into\n * whichever chunk referenced it, and the editor is needed by exactly one dialog. The library is\n * copied to `assets/tinymce` by the build (see `angular.json`) and injected here as a plain\n * `<script>` the first time an editor is created, so it costs nothing until then and is served\n * from the browser cache afterwards. Loading it this way also lets TinyMCE resolve its own theme,\n * model, plugins and skin relative to `base_url`, which is how the self-hosted distribution\n * expects to work.\n */\n@Service()\nexport class TinymceLoaderService {\n\n /** The in-flight (or completed) load, so concurrent editors share a single script tag. */\n private pending?: Promise<TinyMCE>;\n\n /**\n * The absolute URL of the TinyMCE asset folder, resolved against the document base href so the\n * app keeps working when it is served from a sub-path.\n * @returns The base URL, without a trailing slash.\n */\n get baseUrl(): string {\n return new URL('assets/tinymce', document.baseURI).href.replace(/\\/$/, '');\n }\n\n /**\n * Loads TinyMCE, reusing the script already injected by a previous call.\n * @returns A promise resolving with the global TinyMCE instance.\n */\n load(): Promise<TinyMCE> {\n if (window.tinymce) return Promise.resolve(window.tinymce);\n\n // A failed load clears `pending`, so a later attempt can retry instead of being stuck on the\n // rejected promise forever (e.g. the first open happened while the network was down).\n this.pending ??= new Promise<TinyMCE>((resolve, reject) => {\n const script = document.createElement('script');\n script.src = `${this.baseUrl}/tinymce.min.js`;\n script.async = true;\n script.referrerPolicy = 'origin';\n script.onload = () => {\n if (window.tinymce) {\n resolve(window.tinymce);\n } else {\n this.pending = undefined;\n reject(new Error('TinyMCE caricato ma non disponibile.'));\n }\n };\n script.onerror = () => {\n this.pending = undefined;\n script.remove();\n reject(new Error('Impossibile caricare l\\'editor.'));\n };\n document.head.appendChild(script);\n });\n\n return this.pending;\n }\n}\n","import {\n ChangeDetectorRef,\n Directive,\n ElementRef,\n OnDestroy,\n OnInit,\n forwardRef,\n inject,\n input,\n output\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { ThemeService } from '@arsedizioni/ars-utils/core';\nimport type { Editor, RawEditorOptions } from 'tinymce';\nimport { TinymceLoaderService } from './tinymce-loader.service';\n\n/** Uploads one image and resolves with the URL to reference it by. */\nexport type TinymceImageUploader = (file: File) => Promise<string>;\n\n/**\n * How the editor presents itself.\n *\n * `fixed` is the classic editor: the content lives in an iframe and the toolbar sits above it,\n * pinned so it stays reachable while the surrounding container scrolls.\n *\n * `inline` edits the host element in place, with no iframe and no chrome until the user focuses\n * it, at which point the toolbar floats over the content. It needs an ordinary element to edit —\n * a `<div>` — because there is nothing to render inside a `<textarea>`.\n */\nexport type TinymceToolbarMode = 'fixed' | 'inline';\n\n/**\n * Turns a `<textarea>` into a rich text editor backed by the self-hosted TinyMCE bundle, and wires\n * it to Angular forms as a `ControlValueAccessor`, so `[(ngModel)]`, `required` and the\n * pristine/dirty state keep working exactly as they do on a plain control.\n *\n * The library itself is fetched on demand by <see cref=\"TinymceLoaderService\"/>: nothing about\n * TinyMCE reaches the bundle until an editor is actually created.\n *\n * Usage: `<textarea tinymceEditor [(ngModel)]=\"item.text\" name=\"text\" required></textarea>`\n *\n */\n@Directive({\n // Both hosts are accepted because the two modes need different ones: the classic editor\n // replaces a textarea, the inline editor edits a div in place.\n selector: 'textarea[tinymceEditor], div[tinymceEditor]',\n providers: [{\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => TinymceEditorDirective),\n multi: true\n }]\n})\nexport class TinymceEditorDirective implements ControlValueAccessor, OnInit, OnDestroy {\n\n /** Extra TinyMCE options, merged over (and able to override) the defaults below. */\n readonly tinymceConfig = input<RawEditorOptions>({});\n\n /** Whether the toolbar is pinned above the content (`fixed`) or floats on focus (`inline`). */\n readonly tinymceToolbarMode = input<TinymceToolbarMode>('fixed');\n\n /**\n * Handler invoked for every image dropped, pasted or picked in the editor. When not provided\n * the upload tab is hidden and only images referenced by URL can be inserted.\n */\n readonly tinymceImageUploader = input<TinymceImageUploader | undefined>(undefined);\n\n /** Emitted once the editor is up, for callers that want to enable UI only when it is usable. */\n readonly ready = output<Editor>();\n\n /** Emitted when the editor could not be loaded or initialised. */\n readonly failed = output<Error>();\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly loader = inject(TinymceLoaderService);\n private readonly themeService = inject(ThemeService);\n private readonly changeDetector = inject(ChangeDetectorRef);\n\n private editor?: Editor;\n /** True while the editor is showing itself full screen. */\n private fullscreen = false;\n /** True once the directive has been destroyed, so a late init resolves into a no-op. */\n private destroyed = false;\n /**\n * True while the directive itself is pushing a value into the editor. TinyMCE raises the same\n * content events for a programmatic `setContent` as for a keystroke, so without this flag\n * `writeValue` would immediately echo back through `onChange` and mark a freshly loaded form\n * as dirty.\n */\n private writingValue = false;\n /** The value received before the editor existed, applied as soon as it does. */\n private value = '';\n private disabled = false;\n\n private onChange: (value: string) => void = () => { /* set by Angular forms */ };\n private onTouched: () => void = () => { /* set by Angular forms */ };\n\n /**\n * Leaves full screen on Escape, for the keystrokes that happen outside the content: with the\n * classic editor the content is an iframe, and a keydown in there never reaches this document.\n * Bound on the capture phase and stopped, so a dialog hosting the editor does not take the\n * Escape and close, throwing the edit away when the user only meant to leave full screen.\n */\n private readonly onDocumentKeydown = (event: KeyboardEvent): void => {\n if (!this.shouldEscapeLeaveFullscreen(event)) return;\n event.preventDefault();\n event.stopPropagation();\n this.exitFullscreen();\n };\n\n /**\n * Loads TinyMCE and initialises the editor over the host textarea.\n * @returns A promise that completes once the editor is ready (or has failed).\n */\n async ngOnInit(): Promise<void> {\n try {\n const tinymce = await this.loader.load();\n if (this.destroyed) return;\n\n const dark = this.themeService.getTheme() === 'dark';\n const uploader = this.tinymceImageUploader();\n const inline = this.tinymceToolbarMode() === 'inline';\n\n // Caught here rather than left to TinyMCE, which would fail deep inside its own setup\n // with a message that says nothing about the actual mistake.\n if (inline && this.host.nativeElement.tagName === 'TEXTAREA') {\n throw new Error('La modalità inline richiede un <div>, non un <textarea>.');\n }\n\n // TinyMCE ships its language packs outside the npm package, so `it.js` is committed\n // under `src/assets/tinymce/langs/`: the existing `src/assets` build rule publishes it\n // exactly where TinyMCE looks for it, relative to `base_url`.\n const defaults: RawEditorOptions = {\n // Self-hosting TinyMCE 8 requires an explicit license key: without one the editor\n // refuses to start. 'gpl' selects the GPLv2+ terms.\n license_key: 'gpl',\n language: 'it',\n branding: false,\n promotion: false,\n menubar: false,\n statusbar: false,\n resize: false,\n // Pins the toolbar while the container scrolls. In inline mode it is what keeps\n // the floating toolbar attached to the text instead of drifting off with it.\n toolbar_sticky: true,\n // An inline editor takes the size of the element it edits; only the classic one\n // has a box of its own to dimension.\n ...(inline ? {} : { height: 360 }),\n // The dialog body scrolls, and 'split' is what keeps the toolbar menus anchored\n // to the editor while it does: the popup sink is attached next to the editor, so\n // it shares its scrolling ancestry. It does NOT affect the modal dialogs — those\n // always go to <body> — which is why the CDK overlay has to be kept out of the\n // top layer (see OVERLAY_DEFAULT_CONFIG in app.config.ts).\n ui_mode: 'split',\n skin: dark ? 'oxide-dark' : 'oxide',\n content_css: dark ? 'dark' : 'default',\n // Absolute URLs must survive untouched: the content ends up in an e-mail, where a\n // relative image path resolves against nothing.\n convert_urls: false,\n plugins: 'advlist autolink lists link image table charmap searchreplace code fullscreen',\n toolbar: 'undo redo | blocks | bold italic underline | forecolor backcolor'\n + ' | bullist numlist | link image table | removeformat code fullscreen',\n content_style: 'body { font-family: Arial, Helvetica, sans-serif; font-size: 14px; }',\n // Pasted and dropped images go through the same upload path as the image dialog.\n automatic_uploads: !!uploader,\n paste_data_images: !!uploader,\n images_file_types: 'jpeg,jpg,png,gif,webp',\n file_picker_types: uploader ? 'image' : '',\n images_upload_handler: uploader\n ? (blobInfo) => uploader(new File([blobInfo.blob()], blobInfo.filename(), { type: blobInfo.blob().type }))\n : undefined,\n };\n\n await tinymce.init({\n ...defaults,\n // The caller's profile wins over every default above: that is what the presets in\n // `TinymceUtils` are for.\n ...this.tinymceConfig(),\n // Not negotiable, whatever the profile says. `target` and `base_url` are resolved\n // here and nowhere else, `inline` is the input's job, and replacing `setup` would\n // unhook the editor from the form and leave a ControlValueAccessor that never\n // reports a change.\n target: this.host.nativeElement,\n base_url: this.loader.baseUrl,\n inline,\n setup: (editor: Editor) => {\n // Typing, toolbar commands, undo/redo and programmatic inserts all have to\n // reach the form; the guard keeps our own writes from bouncing back.\n editor.on('change input undo redo SetContent', () => {\n if (this.writingValue) return;\n this.value = editor.getContent();\n this.onChange(this.value);\n this.changeDetector.markForCheck();\n });\n editor.on('blur', () => {\n this.onTouched();\n this.changeDetector.markForCheck();\n });\n editor.on('FullscreenStateChanged', (event) => {\n this.handleFullscreenChanged((event as unknown as { state?: boolean }).state === true);\n });\n // The content of a classic editor lives in an iframe, so its keystrokes are\n // only visible from the editor itself.\n editor.on('keydown', (event) => {\n if (!this.shouldEscapeLeaveFullscreen(event)) return;\n event.preventDefault();\n event.stopPropagation();\n this.exitFullscreen();\n });\n editor.on('init', () => {\n this.editor = editor;\n this.applyValue(this.value);\n this.applyDisabled(this.disabled);\n this.ready.emit(editor);\n this.changeDetector.markForCheck();\n });\n },\n });\n } catch (error) {\n if (this.destroyed) return;\n this.failed.emit(error instanceof Error ? error : new Error(String(error)));\n this.changeDetector.markForCheck();\n }\n }\n\n /**\n * Tears the editor down. TinyMCE keeps global state per instance, so leaving it behind when a\n * dialog closes leaks both DOM and editor registrations.\n * @returns void\n */\n ngOnDestroy(): void {\n this.destroyed = true;\n // Removing the editor does not raise the full-screen event, so the session is closed by\n // hand here: the Escape listener would otherwise stay attached to the document forever.\n this.releaseFullscreen();\n this.editor?.remove();\n this.editor = undefined;\n }\n\n /**\n * Decides whether an Escape press means \"leave full screen\": it does whenever the editor is\n * full screen, full stop. While full screen the editor owns Escape, and the press is stopped\n * here so it can never reach the dialog hosting it — leaving full screen must not also throw\n * away what is being written.\n * @param event The keyboard event, from the document or from the editor's content.\n * @returns True when full screen should be left.\n */\n private shouldEscapeLeaveFullscreen(event: KeyboardEvent): boolean {\n return event.key === 'Escape' && this.fullscreen;\n }\n\n /**\n * Asks the editor to leave full screen. Safe to call when it is not in full screen.\n * @returns void\n */\n private exitFullscreen(): void {\n if (!this.fullscreen) return;\n this.editor?.execCommand('mceFullScreen');\n }\n\n /**\n * Attaches or detaches everything that only makes sense while the editor is full screen.\n * @param state True when the editor has just entered full screen.\n * @returns void\n */\n private handleFullscreenChanged(state: boolean): void {\n if (state === this.fullscreen) return;\n this.fullscreen = state;\n\n if (state) {\n document.addEventListener('keydown', this.onDocumentKeydown, true);\n } else {\n this.releaseFullscreen();\n }\n\n this.changeDetector.markForCheck();\n }\n\n /**\n * Detaches the listener that only makes sense while the editor is full screen.\n * @returns void\n */\n private releaseFullscreen(): void {\n document.removeEventListener('keydown', this.onDocumentKeydown, true);\n this.fullscreen = false;\n }\n\n /**\n * Pushes a value coming from the form into the editor.\n * @param value The new content, or null/undefined for an empty editor.\n * @returns void\n */\n writeValue(value: string | null | undefined): void {\n this.value = value ?? '';\n this.applyValue(this.value);\n }\n\n /**\n * Registers the callback used to report content changes to the form.\n * @param fn The callback supplied by Angular forms.\n * @returns void\n */\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n /**\n * Registers the callback used to report the first blur to the form.\n * @param fn The callback supplied by Angular forms.\n * @returns void\n */\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n /**\n * Enables or disables editing.\n * @param isDisabled True to switch the editor to read-only.\n * @returns void\n */\n setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled;\n this.applyDisabled(isDisabled);\n }\n\n /**\n * Writes content into the editor when it exists, guarding against the echo described on\n * <see cref=\"writingValue\"/>.\n * @param value The content to write.\n * @returns void\n */\n private applyValue(value: string): void {\n const editor = this.editor;\n if (!editor) return;\n // Comparing with the serialized content avoids resetting the caret on every form patch\n // that did not actually change anything.\n if (editor.getContent() === value) return;\n this.writingValue = true;\n try {\n editor.setContent(value);\n } finally {\n this.writingValue = false;\n }\n }\n\n /**\n * Applies the disabled state to the editor when it exists.\n * @param isDisabled True to switch the editor to read-only.\n * @returns void\n */\n private applyDisabled(isDisabled: boolean): void {\n this.editor?.mode.set(isDisabled ? 'readonly' : 'design');\n }\n}\n","import { ChangeDetectionStrategy, Component, inject, output, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef } from '@angular/material/dialog';\nimport { FlexLayoutModule } from '@arsedizioni/ars-utils/ui';\nimport type { RawEditorOptions } from 'tinymce';\nimport { TinymceEditorDirective } from '../tinymce-editor.directive';\nimport { TinymceUtils } from '../utils';\n\nexport interface TinyMceEditorDialogData {\n text: string;\n configuration: RawEditorOptions;\n infoButtonLabel?: string;\n onShowInfo?: Function,\n disabled?: boolean;\n}\n\n/**\n * A dialog that is nothing but an editor: the caller hands it a text and gets the edited one\n * back through {@link saving}.\n *\n * The editor is {@link TinymceEditorDirective} on a plain `<textarea>`, so this dialog costs\n * exactly what any other editor in the application costs — the TinyMCE bundle is fetched on\n * first use and nothing about it reaches the initial chunk.\n */\n@Component({\n templateUrl: './editor.component.html',\n styleUrls: ['./editor.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MatDialogContent, TinymceEditorDirective, FormsModule, MatDialogActions, FlexLayoutModule,\n MatButtonModule, MatDialogClose]\n})\nexport class TinyMceEditorComponent {\n\n /** Emitted with the edited text when the user saves. */\n readonly saving = output<string>();\n private readonly dialogRef = inject(MatDialogRef<TinyMceEditorComponent>);\n /** Dialog configuration, injected and exposed as a signal. */\n protected readonly dialogData = signal<TinyMceEditorDialogData>((() => {\n const data: TinyMceEditorDialogData = inject(MAT_DIALOG_DATA) ?? {};\n return { ...data, text: data.text ?? '' };\n })());\n /** Whether the editor is in read-only mode. */\n protected readonly disabled = signal<boolean>(false);\n /** Current editor content, kept as a plain field for [(ngModel)] two-way binding. */\n protected text = '';\n /** The profile handed to the editor directive, merged over its defaults. */\n protected tinymceConfig: RawEditorOptions = {};\n\n constructor() {\n const data = this.dialogData();\n this.text = data.text;\n // The accessor already returns a private copy, so the toolbar override below cannot leak\n // into the preset shared with the rest of the application.\n this.tinymceConfig = data.configuration\n ? { ...data.configuration }\n : TinymceUtils.TinymceCompactExtendedConfig;\n // No full screen: the editor already owns the whole dialog.\n this.tinymceConfig.toolbar = ['undo redo | quickimage insertgroup | formatgroup paragraphgroup | code'];\n this.disabled.set(data.disabled ?? false);\n }\n\n\n /**\n * Save the current editor content and close the dialog.\n */\n protected ok(): void {\n this.saving.emit(this.text ?? '');\n setTimeout(() => {\n this.dialogRef.close();\n }, 500);\n }\n}\n","<mat-dialog-content style=\"padding: 10px 10px 0 10px\">\r\n <textarea tinymceEditor class=\"full-screen-editor\" name=\"text\" [tinymceConfig]=\"tinymceConfig\"\r\n [disabled]=\"disabled()\" [(ngModel)]=\"text\"></textarea>\r\n</mat-dialog-content>\r\n<mat-dialog-actions>\r\n <div fxLayout=\"row\" fxLayoutGap=\"10px\" fxLayoutAlign=\"start center\" fxFill>\r\n <div fxFlex=\"50\">\r\n @if(dialogData().onShowInfo) {\r\n <button mat-stroked-button (click)=\"dialogData().onShowInfo()\">{{dialogData().infoButtonLabel ?? 'Informazioni'}}\r\n </button>\r\n }\r\n </div>\r\n <div fxFlex=\"50\" fxLayoutAlign=\"end\">\r\n @if (disabled()) {\r\n <button mat-stroked-button [mat-dialog-close]=\"true\">Chiudi</button>\r\n } @else {\r\n <button mat-flat-button (click)=\"ok()\">Salva</button>\r\n <button mat-stroked-button [mat-dialog-close]=\"true\">Annulla</button>\r\n }\r\n </div>\r\n </div>\r\n</mat-dialog-actions>\r\n","/*\n * Public API Surface of @arsedizioni/ars-utils/ui.tinymce\n */\nexport * from './utils';\nexport * from './tinymce-loader.service';\nexport * from './tinymce-editor.directive';\nexport * from './editor/editor.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"arsedizioni-ars-utils-ui.tinymce.mjs","sources":["../../../projects/ars-utils/ui.tinymce/utils.ts","../../../projects/ars-utils/ui.tinymce/tinymce-loader.service.ts","../../../projects/ars-utils/ui.tinymce/tinymce-editor.directive.ts","../../../projects/ars-utils/ui.tinymce/editor/editor.component.ts","../../../projects/ars-utils/ui.tinymce/editor/editor.component.html","../../../projects/ars-utils/ui.tinymce/public_api.ts","../../../projects/ars-utils/ui.tinymce/arsedizioni-ars-utils-ui.tinymce.ts"],"sourcesContent":["import type { RawEditorOptions } from 'tinymce';\n\n/**\n * The editor profiles the applications ask for, ready to be handed to\n * `[tinymceConfig]` on {@link TinymceEditorDirective}.\n *\n * They describe **what the editor offers** — plugins, toolbar, formats, link and image\n * behaviour — and nothing else. Everything about *loading* TinyMCE (`base_url`, `suffix`,\n * `language`, `language_url`, `license_key`) and about the *theme* (`skin`, `content_css`)\n * belongs to `TinymceLoaderService` and to the directive, which resolve them against the\n * document base href and against `ThemeService`: a preset repeating them could only get them\n * wrong, and used to — the old ones pinned a relative `assets/tinymce` that broke under a\n * sub-path, and read the skin from `prefers-color-scheme` instead of the theme the user chose.\n *\n * Uploads are the same story: `automatic_uploads`, `paste_data_images` and `file_picker_types`\n * follow the `tinymceImageUploader` input, so an editor without a handler cannot end up\n * offering an upload tab that leads nowhere.\n *\n * Each accessor returns a **fresh deep copy**: a caller that tweaks a returned object — as the\n * editor dialog does with its toolbar — cannot corrupt the preset for everyone else.\n */\nexport class TinymceUtils {\n\n /**\n * Everything TinyMCE 8 open source has to offer, for a full-page editor.\n *\n * Adapted from the TinyMCE 5 profile the library used to ship: `paste`, `print`, `hr`,\n * `textpattern` and the `fullpage_*` options no longer exist (paste and text patterns moved\n * into the core, `fullpage` and `print` were dropped in v6), and `checklist`,\n * `openCodeMirrorButton` and `insertMediaButton` are premium or application-specific buttons\n * that a self-hosted GPL build has no way to render.\n */\n private static readonly FULL: RawEditorOptions = {\n height: 500,\n width: '100%',\n min_height: 250,\n onboarding: false,\n browser_spellcheck: true,\n custom_undo_redo_levels: 50,\n // Three &nbsp; per TAB, and no wrapping of the inserted spaces.\n nonbreaking_force_tab: true,\n nonbreaking_wrap: false,\n help_tabs: ['shortcuts', 'keyboardnav', 'versions'],\n menubar: false,\n plugins: 'advlist anchor autolink autosave charmap code fullscreen help image insertdatetime'\n + ' link lists media nonbreaking pagebreak preview quickbars searchreplace table'\n + ' visualblocks visualchars',\n toolbar: [\n 'fullscreen | undo redo searchreplace | code preview | link image media charmap nonbreaking | table tableprops tabledelete',\n 'bold italic superscript subscript forecolor backcolor | alignleft aligncenter alignright alignjustify | removeformat | bullist numlist'\n ],\n quickbars_insert_toolbar: false,\n quickbars_selection_toolbar: 'removeformat | bold italic | superscript subscript | quicklink h2 h3 blockquote',\n style_formats: [\n {\n title: 'Immagini float', items: [\n { title: 'Immagine a SX', selector: 'img', styles: { float: 'left', margin: '0 10px 0 10px' } },\n { title: 'Immagine a DX', selector: 'img', styles: { float: 'right', margin: '0 10px 0 10px' } }\n ]\n },\n {\n title: 'Formati', items: [\n { title: 'Grassetto', format: 'bold' },\n { title: 'Corsivo', format: 'italic' },\n { title: 'Sottolineato', format: 'underline' },\n { title: 'Barrato', format: 'strikethrough' },\n { title: 'Superscript', format: 'superscript' },\n { title: 'Subscript', format: 'subscript' },\n { title: 'Codice', format: 'code' }\n ]\n }\n ],\n // Spans with an inline style rather than <u>/<strike>: the content travels by e-mail, where\n // the presentational tags are the first thing a client strips.\n formats: {\n underline: { inline: 'span', styles: { 'text-decoration': 'underline' }, exact: true },\n strikethrough: { inline: 'span', styles: { 'text-decoration': 'line-through' }, exact: true }\n },\n insertdatetime_formats: ['%d/%m/%Y', '%d %b %Y', '%A, %d %B %Y'],\n link_default_target: '_blank',\n link_title: true,\n link_assume_external_targets: 'https',\n link_class_list: [\n { title: 'Nessuno', value: '' },\n { title: 'Rilevante', value: 'relevant' },\n ],\n link_context_toolbar: true,\n link_quicklink: true,\n image_advtab: true,\n image_caption: true,\n image_title: true,\n };\n\n /**\n * The one for a field inside a form: it grows with the text instead of owning the page, the\n * toolbar sits under it and collapses into groups, and there is no status bar or context menu\n * to compete with the form around it.\n */\n private static readonly COMPACT: RawEditorOptions = {\n ...TinymceUtils.FULL,\n height: 200,\n min_height: 200,\n max_height: 500,\n statusbar: false,\n contextmenu: false,\n toolbar_location: 'bottom',\n plugins: 'advlist anchor autolink autoresize autosave charmap code image insertdatetime'\n + ' link lists media nonbreaking preview quickbars searchreplace table'\n + ' visualblocks visualchars',\n toolbar: ['undo redo | quickimage | formatgroup paragraphgroup'],\n toolbar_groups: {\n formatgroup: {\n icon: 'format',\n tooltip: 'Formattazione',\n items: 'bold italic underline superscript subscript | forecolor backcolor | removeformat'\n },\n paragraphgroup: {\n icon: 'paragraph',\n tooltip: 'Formato paragrafo',\n items: 'h1 h2 h3 | bullist numlist | alignleft aligncenter alignright alignjustify | indent outdent'\n },\n insertgroup: {\n icon: 'plus',\n tooltip: 'Inserisci',\n items: 'quickimage media | link charmap nonbreaking | table tableprops tabledelete'\n }\n },\n quickbars_insert_toolbar: 'quickimage',\n link_class_list: [],\n };\n\n /** The compact one plus full screen, the insert group and the source view. */\n private static readonly COMPACT_EXTENDED: RawEditorOptions = {\n ...TinymceUtils.COMPACT,\n plugins: 'advlist anchor autolink autoresize autosave charmap code fullscreen image'\n + ' insertdatetime link lists media nonbreaking preview quickbars searchreplace table'\n + ' visualblocks visualchars',\n toolbar: ['undo redo | quickimage insertgroup | formatgroup paragraphgroup | code | fullscreen'],\n };\n\n /**\n * The full-page profile.\n * @returns A fresh copy of the configuration, safe to modify.\n */\n static get TinymceConfig(): RawEditorOptions {\n return structuredClone(TinymceUtils.FULL);\n }\n\n /**\n * The in-form profile.\n * @returns A fresh copy of the configuration, safe to modify.\n */\n static get TinymceCompactConfig(): RawEditorOptions {\n return structuredClone(TinymceUtils.COMPACT);\n }\n\n /**\n * The in-form profile with full screen and source view.\n * @returns A fresh copy of the configuration, safe to modify.\n */\n static get TinymceCompactExtendedConfig(): RawEditorOptions {\n return structuredClone(TinymceUtils.COMPACT_EXTENDED);\n }\n}\n","import { Service } from '@angular/core';\nimport type { TinyMCE } from 'tinymce';\n\ndeclare global {\n interface Window {\n tinymce?: TinyMCE;\n }\n}\n\n/**\n * Loads the self-hosted TinyMCE bundle on demand.\n *\n * TinyMCE is deliberately NOT imported by any module: a static import would pull ~500 kB into\n * whichever chunk referenced it, and the editor is needed by exactly one dialog. The library is\n * copied to `assets/tinymce` by the build (see `angular.json`) and injected here as a plain\n * `<script>` the first time an editor is created, so it costs nothing until then and is served\n * from the browser cache afterwards. Loading it this way also lets TinyMCE resolve its own theme,\n * model, plugins and skin relative to `base_url`, which is how the self-hosted distribution\n * expects to work.\n */\n@Service()\nexport class TinymceLoaderService {\n\n /** The in-flight (or completed) load, so concurrent editors share a single script tag. */\n private pending?: Promise<TinyMCE>;\n\n /**\n * The absolute URL of the TinyMCE asset folder, resolved against the document base href so the\n * app keeps working when it is served from a sub-path.\n * @returns The base URL, without a trailing slash.\n */\n get baseUrl(): string {\n return new URL('assets/tinymce', document.baseURI).href.replace(/\\/$/, '');\n }\n\n /**\n * Loads TinyMCE, reusing the script already injected by a previous call.\n * @returns A promise resolving with the global TinyMCE instance.\n */\n load(): Promise<TinyMCE> {\n if (window.tinymce) return Promise.resolve(window.tinymce);\n\n // A failed load clears `pending`, so a later attempt can retry instead of being stuck on the\n // rejected promise forever (e.g. the first open happened while the network was down).\n this.pending ??= new Promise<TinyMCE>((resolve, reject) => {\n const script = document.createElement('script');\n script.src = `${this.baseUrl}/tinymce.min.js`;\n script.async = true;\n script.referrerPolicy = 'origin';\n script.onload = () => {\n if (window.tinymce) {\n resolve(window.tinymce);\n } else {\n this.pending = undefined;\n reject(new Error('TinyMCE caricato ma non disponibile.'));\n }\n };\n script.onerror = () => {\n this.pending = undefined;\n script.remove();\n reject(new Error('Impossibile caricare l\\'editor.'));\n };\n document.head.appendChild(script);\n });\n\n return this.pending;\n }\n}\n","import {\n ChangeDetectorRef,\n Directive,\n ElementRef,\n OnDestroy,\n OnInit,\n forwardRef,\n inject,\n input,\n output\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { ThemeService } from '@arsedizioni/ars-utils/core';\nimport type { Editor, RawEditorOptions } from 'tinymce';\nimport { TinymceLoaderService } from './tinymce-loader.service';\n\n/** Uploads one image and resolves with the URL to reference it by. */\nexport type TinymceImageUploader = (file: File) => Promise<string>;\n\n/**\n * How the editor presents itself.\n *\n * `fixed` is the classic editor: the content lives in an iframe and the toolbar sits above it,\n * pinned so it stays reachable while the surrounding container scrolls.\n *\n * `inline` edits the host element in place, with no iframe and no chrome until the user focuses\n * it, at which point the toolbar floats over the content. It needs an ordinary element to edit —\n * a `<div>` — because there is nothing to render inside a `<textarea>`.\n */\nexport type TinymceToolbarMode = 'fixed' | 'inline';\n\n/**\n * Turns a `<textarea>` into a rich text editor backed by the self-hosted TinyMCE bundle, and wires\n * it to Angular forms as a `ControlValueAccessor`, so `[(ngModel)]`, `required` and the\n * pristine/dirty state keep working exactly as they do on a plain control.\n *\n * The library itself is fetched on demand by <see cref=\"TinymceLoaderService\"/>: nothing about\n * TinyMCE reaches the bundle until an editor is actually created.\n *\n * Usage: `<textarea tinymceEditor [(ngModel)]=\"item.text\" name=\"text\" required></textarea>`\n *\n */\n@Directive({\n // Both hosts are accepted because the two modes need different ones: the classic editor\n // replaces a textarea, the inline editor edits a div in place.\n selector: 'textarea[tinymceEditor], div[tinymceEditor]',\n providers: [{\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => TinymceEditorDirective),\n multi: true\n }]\n})\nexport class TinymceEditorDirective implements ControlValueAccessor, OnInit, OnDestroy {\n\n /** Extra TinyMCE options, merged over (and able to override) the defaults below. */\n readonly tinymceConfig = input<RawEditorOptions>({});\n\n /** Whether the toolbar is pinned above the content (`fixed`) or floats on focus (`inline`). */\n readonly tinymceToolbarMode = input<TinymceToolbarMode>('fixed');\n\n /**\n * Handler invoked for every image dropped, pasted or picked in the editor. When not provided\n * the upload tab is hidden and only images referenced by URL can be inserted.\n */\n readonly tinymceImageUploader = input<TinymceImageUploader | undefined>(undefined);\n\n /** Emitted once the editor is up, for callers that want to enable UI only when it is usable. */\n readonly ready = output<Editor>();\n\n /** Emitted when the editor could not be loaded or initialised. */\n readonly failed = output<Error>();\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly loader = inject(TinymceLoaderService);\n private readonly themeService = inject(ThemeService);\n private readonly changeDetector = inject(ChangeDetectorRef);\n\n private editor?: Editor;\n /** True while the editor is showing itself full screen. */\n private fullscreen = false;\n /** True once the directive has been destroyed, so a late init resolves into a no-op. */\n private destroyed = false;\n /**\n * True while the directive itself is pushing a value into the editor. TinyMCE raises the same\n * content events for a programmatic `setContent` as for a keystroke, so without this flag\n * `writeValue` would immediately echo back through `onChange` and mark a freshly loaded form\n * as dirty.\n */\n private writingValue = false;\n /** The value received before the editor existed, applied as soon as it does. */\n private value = '';\n private disabled = false;\n\n private onChange: (value: string) => void = () => { /* set by Angular forms */ };\n private onTouched: () => void = () => { /* set by Angular forms */ };\n\n /**\n * Leaves full screen on Escape, for the keystrokes that happen outside the content: with the\n * classic editor the content is an iframe, and a keydown in there never reaches this document.\n * Bound on the capture phase and stopped, so a dialog hosting the editor does not take the\n * Escape and close, throwing the edit away when the user only meant to leave full screen.\n */\n private readonly onDocumentKeydown = (event: KeyboardEvent): void => {\n if (!this.shouldEscapeLeaveFullscreen(event)) return;\n event.preventDefault();\n event.stopPropagation();\n this.exitFullscreen();\n };\n\n /**\n * Loads TinyMCE and initialises the editor over the host textarea.\n * @returns A promise that completes once the editor is ready (or has failed).\n */\n async ngOnInit(): Promise<void> {\n try {\n const tinymce = await this.loader.load();\n if (this.destroyed) return;\n\n const dark = this.themeService.getTheme() === 'dark';\n const uploader = this.tinymceImageUploader();\n const inline = this.tinymceToolbarMode() === 'inline';\n\n // Caught here rather than left to TinyMCE, which would fail deep inside its own setup\n // with a message that says nothing about the actual mistake.\n if (inline && this.host.nativeElement.tagName === 'TEXTAREA') {\n throw new Error('La modalità inline richiede un <div>, non un <textarea>.');\n }\n\n // TinyMCE ships its language packs outside the npm package, so `it.js` is committed\n // under `src/assets/tinymce/langs/`: the existing `src/assets` build rule publishes it\n // exactly where TinyMCE looks for it, relative to `base_url`.\n const defaults: RawEditorOptions = {\n // Self-hosting TinyMCE 8 requires an explicit license key: without one the editor\n // refuses to start. 'gpl' selects the GPLv2+ terms.\n license_key: 'gpl',\n language: 'it',\n branding: false,\n promotion: false,\n menubar: false,\n statusbar: false,\n resize: false,\n // Pins the toolbar while the container scrolls. In inline mode it is what keeps\n // the floating toolbar attached to the text instead of drifting off with it.\n toolbar_sticky: true,\n // An inline editor takes the size of the element it edits; only the classic one\n // has a box of its own to dimension.\n ...(inline ? {} : { height: 360 }),\n // The dialog body scrolls, and 'split' is what keeps the toolbar menus anchored\n // to the editor while it does: the popup sink is attached next to the editor, so\n // it shares its scrolling ancestry. It does NOT affect the modal dialogs — those\n // always go to <body> — which is why the CDK overlay has to be kept out of the\n // top layer (see OVERLAY_DEFAULT_CONFIG in app.config.ts).\n ui_mode: 'split',\n skin: dark ? 'oxide-dark' : 'oxide',\n content_css: dark ? 'dark' : 'default',\n // Absolute URLs must survive untouched: the content ends up in an e-mail, where a\n // relative image path resolves against nothing.\n convert_urls: false,\n plugins: 'advlist autolink lists link image table charmap searchreplace code fullscreen',\n toolbar: 'undo redo | blocks | bold italic underline | forecolor backcolor'\n + ' | bullist numlist | link image table | removeformat code fullscreen',\n content_style: 'body { font-family: Arial, Helvetica, sans-serif; font-size: 14px; }',\n // Pasted and dropped images go through the same upload path as the image dialog.\n automatic_uploads: !!uploader,\n paste_data_images: !!uploader,\n images_file_types: 'jpeg,jpg,png,gif,webp',\n file_picker_types: uploader ? 'image' : '',\n images_upload_handler: uploader\n ? (blobInfo) => uploader(new File([blobInfo.blob()], blobInfo.filename(), { type: blobInfo.blob().type }))\n : undefined,\n };\n\n await tinymce.init({\n ...defaults,\n // The caller's profile wins over every default above: that is what the presets in\n // `TinymceUtils` are for.\n ...this.tinymceConfig(),\n // Not negotiable, whatever the profile says. `target` and `base_url` are resolved\n // here and nowhere else, `inline` is the input's job, and replacing `setup` would\n // unhook the editor from the form and leave a ControlValueAccessor that never\n // reports a change.\n target: this.host.nativeElement,\n base_url: this.loader.baseUrl,\n inline,\n setup: (editor: Editor) => {\n // Typing, toolbar commands, undo/redo and programmatic inserts all have to\n // reach the form; the guard keeps our own writes from bouncing back.\n editor.on('change input undo redo SetContent', () => {\n if (this.writingValue) return;\n this.value = editor.getContent();\n this.onChange(this.value);\n this.changeDetector.markForCheck();\n });\n editor.on('blur', () => {\n this.onTouched();\n this.changeDetector.markForCheck();\n });\n editor.on('FullscreenStateChanged', (event) => {\n this.handleFullscreenChanged((event as unknown as { state?: boolean }).state === true);\n });\n // The content of a classic editor lives in an iframe, so its keystrokes are\n // only visible from the editor itself.\n editor.on('keydown', (event) => {\n if (!this.shouldEscapeLeaveFullscreen(event)) return;\n event.preventDefault();\n event.stopPropagation();\n this.exitFullscreen();\n });\n editor.on('init', () => {\n this.editor = editor;\n this.applyValue(this.value);\n this.applyDisabled(this.disabled);\n this.ready.emit(editor);\n this.changeDetector.markForCheck();\n });\n },\n });\n } catch (error) {\n if (this.destroyed) return;\n this.failed.emit(error instanceof Error ? error : new Error(String(error)));\n this.changeDetector.markForCheck();\n }\n }\n\n /**\n * Tears the editor down. TinyMCE keeps global state per instance, so leaving it behind when a\n * dialog closes leaks both DOM and editor registrations.\n * @returns void\n */\n ngOnDestroy(): void {\n this.destroyed = true;\n // Removing the editor does not raise the full-screen event, so the session is closed by\n // hand here: the Escape listener would otherwise stay attached to the document forever.\n this.releaseFullscreen();\n this.editor?.remove();\n this.editor = undefined;\n }\n\n /**\n * Decides whether an Escape press means \"leave full screen\": it does whenever the editor is\n * full screen, full stop. While full screen the editor owns Escape, and the press is stopped\n * here so it can never reach the dialog hosting it — leaving full screen must not also throw\n * away what is being written.\n * @param event The keyboard event, from the document or from the editor's content.\n * @returns True when full screen should be left.\n */\n private shouldEscapeLeaveFullscreen(event: KeyboardEvent): boolean {\n return event.key === 'Escape' && this.fullscreen;\n }\n\n /**\n * Asks the editor to leave full screen. Safe to call when it is not in full screen.\n * @returns void\n */\n private exitFullscreen(): void {\n if (!this.fullscreen) return;\n this.editor?.execCommand('mceFullScreen');\n }\n\n /**\n * Attaches or detaches everything that only makes sense while the editor is full screen.\n * @param state True when the editor has just entered full screen.\n * @returns void\n */\n private handleFullscreenChanged(state: boolean): void {\n if (state === this.fullscreen) return;\n this.fullscreen = state;\n\n if (state) {\n document.addEventListener('keydown', this.onDocumentKeydown, true);\n } else {\n this.releaseFullscreen();\n }\n\n this.changeDetector.markForCheck();\n }\n\n /**\n * Detaches the listener that only makes sense while the editor is full screen.\n * @returns void\n */\n private releaseFullscreen(): void {\n document.removeEventListener('keydown', this.onDocumentKeydown, true);\n this.fullscreen = false;\n }\n\n /**\n * Pushes a value coming from the form into the editor.\n * @param value The new content, or null/undefined for an empty editor.\n * @returns void\n */\n writeValue(value: string | null | undefined): void {\n this.value = value ?? '';\n this.applyValue(this.value);\n }\n\n /**\n * Registers the callback used to report content changes to the form.\n * @param fn The callback supplied by Angular forms.\n * @returns void\n */\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n /**\n * Registers the callback used to report the first blur to the form.\n * @param fn The callback supplied by Angular forms.\n * @returns void\n */\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n /**\n * Enables or disables editing.\n * @param isDisabled True to switch the editor to read-only.\n * @returns void\n */\n setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled;\n this.applyDisabled(isDisabled);\n }\n\n /**\n * Writes content into the editor when it exists, guarding against the echo described on\n * <see cref=\"writingValue\"/>.\n * @param value The content to write.\n * @returns void\n */\n private applyValue(value: string): void {\n const editor = this.editor;\n if (!editor) return;\n // Comparing with the serialized content avoids resetting the caret on every form patch\n // that did not actually change anything.\n if (editor.getContent() === value) return;\n this.writingValue = true;\n try {\n editor.setContent(value);\n } finally {\n this.writingValue = false;\n }\n }\n\n /**\n * Applies the disabled state to the editor when it exists.\n * @param isDisabled True to switch the editor to read-only.\n * @returns void\n */\n private applyDisabled(isDisabled: boolean): void {\n this.editor?.mode.set(isDisabled ? 'readonly' : 'design');\n }\n}\n","import { ChangeDetectionStrategy, Component, inject, output, signal } from '@angular/core';\nimport { FormField, disabled as fieldDisabled, form } from '@angular/forms/signals';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef } from '@angular/material/dialog';\nimport { FlexLayoutModule } from '@arsedizioni/ars-utils/ui';\nimport type { RawEditorOptions } from 'tinymce';\nimport { TinymceEditorDirective } from '../tinymce-editor.directive';\nimport { TinymceUtils } from '../utils';\n\nexport interface TinyMceEditorDialogData {\n text: string;\n configuration: RawEditorOptions;\n infoButtonLabel?: string;\n onShowInfo?: Function,\n disabled?: boolean;\n}\n\n/**\n * A dialog that is nothing but an editor: the caller hands it a text and gets the edited one\n * back through {@link saving}.\n *\n * The editor is {@link TinymceEditorDirective} on a plain `<textarea>`, so this dialog costs\n * exactly what any other editor in the application costs — the TinyMCE bundle is fetched on\n * first use and nothing about it reaches the initial chunk.\n */\n@Component({\n templateUrl: './editor.component.html',\n styleUrls: ['./editor.component.scss'],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MatDialogContent, TinymceEditorDirective, FormField, MatDialogActions, FlexLayoutModule,\n MatButtonModule, MatDialogClose]\n})\nexport class TinyMceEditorComponent {\n\n /** Emitted with the edited text when the user saves. */\n readonly saving = output<string>();\n private readonly dialogRef = inject(MatDialogRef<TinyMceEditorComponent>);\n /** Dialog configuration, injected and exposed as a signal. */\n protected readonly dialogData = signal<TinyMceEditorDialogData>((() => {\n const data: TinyMceEditorDialogData = inject(MAT_DIALOG_DATA) ?? {};\n return { ...data, text: data.text ?? '' };\n })());\n /** Whether the editor is in read-only mode. */\n protected readonly disabled = signal<boolean>(false);\n /** Current editor content. */\n protected readonly text = signal<string>('');\n\n /**\n * Signal form bound to the editor textarea. The disabled state is pushed to the\n * TinymceEditorDirective through the ControlValueAccessor interop.\n */\n protected readonly textForm = form(this.text, p => {\n fieldDisabled(p, () => this.disabled());\n });\n /** The profile handed to the editor directive, merged over its defaults. */\n protected tinymceConfig: RawEditorOptions = {};\n\n constructor() {\n const data = this.dialogData();\n this.text.set(data.text);\n // The accessor already returns a private copy, so the toolbar override below cannot leak\n // into the preset shared with the rest of the application.\n this.tinymceConfig = data.configuration\n ? { ...data.configuration }\n : TinymceUtils.TinymceCompactExtendedConfig;\n // No full screen: the editor already owns the whole dialog.\n this.tinymceConfig.toolbar = ['undo redo | quickimage insertgroup | formatgroup paragraphgroup | code'];\n this.disabled.set(data.disabled ?? false);\n }\n\n\n /**\n * Save the current editor content and close the dialog.\n */\n protected ok(): void {\n this.saving.emit(this.text() ?? '');\n setTimeout(() => {\n this.dialogRef.close();\n }, 500);\n }\n}\n","<mat-dialog-content style=\"padding: 10px 10px 0 10px\">\n <textarea tinymceEditor class=\"full-screen-editor\" [tinymceConfig]=\"tinymceConfig\"\n [formField]=\"textForm\"></textarea>\n</mat-dialog-content>\n<mat-dialog-actions>\n <div fxLayout=\"row\" fxLayoutGap=\"10px\" fxLayoutAlign=\"start center\" fxFill>\n <div fxFlex=\"50\">\n @if(dialogData().onShowInfo) {\n <button mat-stroked-button (click)=\"dialogData().onShowInfo()\">{{dialogData().infoButtonLabel ?? 'Informazioni'}}\n </button>\n }\n </div>\n <div fxFlex=\"50\" fxLayoutAlign=\"end\">\n @if (disabled()) {\n <button mat-stroked-button [mat-dialog-close]=\"true\">Chiudi</button>\n } @else {\n <button mat-flat-button (click)=\"ok()\">Salva</button>\n <button mat-stroked-button [mat-dialog-close]=\"true\">Annulla</button>\n }\n </div>\n </div>\n</mat-dialog-actions>\n","/*\n * Public API Surface of @arsedizioni/ars-utils/ui.tinymce\n */\nexport * from './utils';\nexport * from './tinymce-loader.service';\nexport * from './tinymce-editor.directive';\nexport * from './editor/editor.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["fieldDisabled"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arsedizioni/ars-utils",
3
- "version": "22.5.17",
3
+ "version": "22.5.18",
4
4
  "author": {
5
5
  "email": "software@arsedizioni.it",
6
6
  "name": "Fabio Buscaroli, Alberto Doria"