UNPKG

@rero/ng-core

Version:

RERO angular core library.

1,156 lines (1,136 loc) 753 kB
import * as i0 from '@angular/core'; import { Injectable, inject, HostListener, Component, Pipe, Input, NgModule, input, output, effect, ViewChild, ElementRef, Directive, linkedSignal, computed, provideAppInitializer, ViewContainerRef, signal, EventEmitter, Output, LOCALE_ID, model, ChangeDetectionStrategy, ChangeDetectorRef, viewChild } from '@angular/core'; import * as i1$2 from '@angular/common'; import { DatePipe, registerLocaleData, CommonModule, Location } from '@angular/common'; import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http'; import * as i2$8 from '@angular/router'; import { TitleStrategy, RouterModule, Router, ActivatedRoute } from '@angular/router'; import * as i5 from '@ngx-translate/core'; import { TranslateService, _, TranslateModule, TranslateLoader as TranslateLoader$1 } from '@ngx-translate/core'; import { NgxSpinnerModule, NgxSpinnerService } from 'ngx-spinner'; import { ConfirmationService, MessageService } from 'primeng/api'; import { of, forkJoin, throwError, Subject, BehaviorSubject, catchError as catchError$1, tap as tap$1, isObservable, map as map$5, Subscription, combineLatest, switchMap as switchMap$1, merge } from 'rxjs'; import { DynamicDialogConfig, DynamicDialogRef, DialogService, DynamicDialogModule } from 'primeng/dynamicdialog'; import * as i1 from 'primeng/button'; import { ButtonModule } from 'primeng/button'; import { DomSanitizer, Title } from '@angular/platform-browser'; import { marked } from 'marked'; import * as i1$3 from 'primeng/autocomplete'; import { AutoCompleteModule } from 'primeng/autocomplete'; import * as i1$1 from 'primeng/autofocus'; import { AutoFocusModule } from 'primeng/autofocus'; import { BadgeModule } from 'primeng/badge'; import { CardModule } from 'primeng/card'; import * as i2$5 from 'primeng/checkbox'; import { CheckboxModule } from 'primeng/checkbox'; import { ConfirmDialogModule } from 'primeng/confirmdialog'; import * as i2$4 from 'primeng/datepicker'; import { DatePickerModule } from 'primeng/datepicker'; import * as i2$3 from 'primeng/divider'; import { DividerModule } from 'primeng/divider'; import * as i1$7 from 'primeng/fieldset'; import { FieldsetModule } from 'primeng/fieldset'; import * as i4 from 'primeng/inputgroup'; import { InputGroupModule } from 'primeng/inputgroup'; import * as i3 from 'primeng/inputgroupaddon'; import { InputGroupAddonModule } from 'primeng/inputgroupaddon'; import * as i3$6 from 'primeng/inputnumber'; import { InputNumberModule } from 'primeng/inputnumber'; import * as i3$1 from 'primeng/inputtext'; import { InputTextModule } from 'primeng/inputtext'; import * as i2$2 from 'primeng/listbox'; import { ListboxModule } from 'primeng/listbox'; import * as i2$7 from 'primeng/menu'; import { MenuModule } from 'primeng/menu'; import * as i2$1 from 'primeng/message'; import { MessageModule } from 'primeng/message'; import * as i1$8 from 'primeng/paginator'; import { PaginatorModule } from 'primeng/paginator'; import { PanelModule } from 'primeng/panel'; import * as i1$6 from 'primeng/radiobutton'; import { RadioButtonModule } from 'primeng/radiobutton'; import { RippleModule } from 'primeng/ripple'; import { ScrollPanelModule } from 'primeng/scrollpanel'; import * as i4$2 from 'primeng/select'; import { SelectModule } from 'primeng/select'; import * as i3$3 from 'primeng/splitbutton'; import { SplitButtonModule } from 'primeng/splitbutton'; import * as i1$9 from 'primeng/tabs'; import { TabsModule } from 'primeng/tabs'; import * as i1$5 from 'primeng/textarea'; import { TextareaModule } from 'primeng/textarea'; import * as i2$6 from 'primeng/tieredmenu'; import { TieredMenuModule } from 'primeng/tieredmenu'; import { ToastModule } from 'primeng/toast'; import * as i1$4 from 'primeng/toggleswitch'; import { ToggleSwitchModule } from 'primeng/toggleswitch'; import * as i2 from 'primeng/tooltip'; import { TooltipModule } from 'primeng/tooltip'; import { FluidModule } from 'primeng/fluid'; import { catchError, map as map$4, tap, debounceTime, first, switchMap, finalize, distinctUntilChanged } from 'rxjs/operators'; import localeDe from '@angular/common/locales/de'; import localeEn from '@angular/common/locales/en-GB'; import localeFr from '@angular/common/locales/fr'; import localeIt from '@angular/common/locales/it'; import { DateTime } from 'luxon'; import de$6 from 'primelocale/de.json'; import en$6 from 'primelocale/en.json'; import fr$6 from 'primelocale/fr.json'; import it$6 from 'primelocale/it.json'; import { PrimeNG } from 'primeng/config'; import renderMathInElement from 'katex/contrib/auto-render'; import { definePreset } from '@primeng/themes'; import Aura from '@primeng/themes/aura'; import * as i3$2 from '@angular/forms'; import { UntypedFormGroup, FormsModule, ReactiveFormsModule, FormControl } from '@angular/forms'; import { FormlyJsonschema } from '@ngx-formly/core/json-schema'; import { cloneDeep } from 'lodash-es'; import * as i4$1 from '@ngx-formly/core'; import { FieldType, FormlyModule, FieldArrayType, FieldWrapper, FORMLY_CONFIG } from '@ngx-formly/core'; import { FormlyFormFieldModule } from '@ngx-formly/primeng/form-field'; import { FormlySelectModule } from '@ngx-formly/core/select'; import * as i3$4 from 'primeng/multiselect'; import { MultiSelectModule } from 'primeng/multiselect'; import { toSignal } from '@angular/core/rxjs-interop'; import { FormlySelectModule as FormlySelectModule$1 } from '@ngx-formly/primeng/select'; import * as i3$5 from 'primeng/treeselect'; import { TreeSelectModule } from 'primeng/treeselect'; import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard'; import { GeneratePassword } from 'generate-password-lite'; import { FormlyPrimeNGModule } from '@ngx-formly/primeng'; import * as i8 from 'primeng/dataview'; import { DataViewModule } from 'primeng/dataview'; import EasyMDE from 'easymde'; import { DomHandler } from 'primeng/dom'; import * as CryptoJS from 'crypto-js'; /* * RERO angular core * Copyright (C) 2020-2025 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * Service for managing configuration of the application. */ class CoreConfigService { constructor() { this.production = false; this.apiBaseUrl = ''; this.apiEndpointPrefix = '/api'; this.schemaFormEndpoint = '/api/schemaform'; this.languages = ['en']; this.defaultLanguage = 'en'; this.secretPassphrase = 'ShERWIN53SnAggIng48rELAtiVes'; this.translationsURLs = []; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CoreConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CoreConfigService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CoreConfigService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); /* * RERO angular core * Copyright (C) 2020-2025 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * Service giving information about API. */ class ApiService { constructor() { this.configService = inject(CoreConfigService); // API base URL. Ex: https://localhost:5000. this.baseUrl = ''; // API prefix. Ex: /api this.endpointPrefix = '/'; } /** * Returns Invenio API Endpoint corresponding to type. * * @param type Type of the resource. * @param absolute If absolute or relative url must be returned. * @return Endpoint as string. */ getEndpointByType(type, absolute = false) { let endpoint = this.configService.apiEndpointPrefix + '/' + type; if (absolute === true) { endpoint = this.configService.apiBaseUrl + endpoint; } return endpoint; } /** * Returns Invenio-RERO-base API export endpoint corresponding to type. * * @param type Type of the resource. * @param absolute If absolute or relative url must be returned. * @return Endpoint as string. */ getExportEndpointByType(type, absolute = false) { let endpoint = this.configService.apiEndpointPrefix + '/export/' + type; if (absolute === true) { endpoint = this.configService.apiBaseUrl + endpoint; } return endpoint; } /** * Returns $ref endpoint to resource. * * @param type Type of resource. * @param id Id of the record. * @return Ref endpoint as string. */ getRefEndpoint(type, id) { let prefix = ''; if (this.configService.$refPrefix) { prefix += this.configService.$refPrefix; } return `${prefix}${this.configService.apiEndpointPrefix}/${type}/${id}`; } /** * Returns invenio API FormOption Endpoint corresponding to type. * * @param type Type of the resource * @param absolute If absolute or relative url must be returned. * @return Schema form endpoint. */ getSchemaFormEndpoint(type, absolute = false) { let endpoint = this.configService.schemaFormEndpoint + '/' + type; if (absolute === true) { endpoint = this.configService.apiBaseUrl + endpoint; } return endpoint; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApiService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApiService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); /* * RERO angular core * Copyright (C) 2023 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * Doc: https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event * * The beforeunload event is fired when the window, the document and its resources * are about to be unloaded. The document is still visible and the event is still * cancelable at this point. */ class AbstractCanDeactivateComponent { unloadNotification($event) { if (!this.canDeactivate) { $event.returnValue = true; } } /** * Can deactivate changed on editor * @param activate - boolean */ canDeactivateChanged(activate) { this.canDeactivate = activate; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AbstractCanDeactivateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: AbstractCanDeactivateComponent, isStandalone: false, selector: "ng-component", host: { listeners: { "window:beforeunload": "unloadNotification($event)" } }, ngImport: i0, template: '', isInline: true }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AbstractCanDeactivateComponent, decorators: [{ type: Component, args: [{ template: '', standalone: false }] }], propDecorators: { unloadNotification: [{ type: HostListener, args: ['window:beforeunload', ['$event']] }] } }); /* * RERO angular core * Copyright (C) 2020-2025 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * Pipe for converting carriage returns to <br> html entities. */ class Nl2brPipe { constructor() { this.sanitizer = inject(DomSanitizer); } /** * Returns transformed value containing <br> entities. * * @param value Value to transform. * @return Transformed value. */ transform(value) { if (!value) { return this.sanitizer.bypassSecurityTrustHtml(''); } return this.sanitizer.bypassSecurityTrustHtml(value.replace(/\r\n?|\n/g, '<br>\n')); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: Nl2brPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: Nl2brPipe, isStandalone: false, name: "nl2br" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: Nl2brPipe, decorators: [{ type: Pipe, args: [{ name: 'nl2br', standalone: false }] }] }); /* * RERO angular core * Copyright (C) 2020-2025 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ class DialogComponent { constructor() { this.config = inject(DynamicDialogConfig); this.ref = inject(DynamicDialogRef); } confirm() { this.ref.close(true); } cancel() { this.ref.close(false); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: DialogComponent, isStandalone: false, selector: "ng-core-dialog", ngImport: i0, template: ` <div class="core:flex core:flex-col core:gap-2"> <div class="core:flex" [innerHtml]="config.data.body|nl2br"></div> <div class="core:flex core:justify-end core:gap-1"> <p-button [label]="config.data.cancelTitleButton || 'Cancel'|translate" severity="danger" [outlined]="true" (onClick)="cancel()" /> @if (config.data.confirmButton) { <p-button [label]="config.data.confirmTitleButton || 'OK'|translate" (onClick)="confirm()" /> } </div> </div> `, isInline: true, dependencies: [{ kind: "component", type: i1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: Nl2brPipe, name: "nl2br" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DialogComponent, decorators: [{ type: Component, args: [{ selector: 'ng-core-dialog', template: ` <div class="core:flex core:flex-col core:gap-2"> <div class="core:flex" [innerHtml]="config.data.body|nl2br"></div> <div class="core:flex core:justify-end core:gap-1"> <p-button [label]="config.data.cancelTitleButton || 'Cancel'|translate" severity="danger" [outlined]="true" (onClick)="cancel()" /> @if (config.data.confirmButton) { <p-button [label]="config.data.confirmTitleButton || 'OK'|translate" (onClick)="confirm()" /> } </div> </div> `, standalone: false }] }] }); /* * RERO angular core * Copyright (C) 2020 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * Pipe for returning a default value if the given value is null or undefined. */ class DefaultPipe { /** * Returns a default value. * * @param value Value to check. * @param defaultValue Value to return if value is null. * @return Value or default value. */ transform(value, defaultValue) { return value || defaultValue; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DefaultPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: DefaultPipe, isStandalone: false, name: "default" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DefaultPipe, decorators: [{ type: Pipe, args: [{ name: 'default', pure: true, standalone: false }] }] }); /* * RERO angular core * Copyright (C) 2020 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * Component for displaying errors. */ class ErrorComponent { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: ErrorComponent, isStandalone: false, selector: "ng-core-error", inputs: { error: "error" }, ngImport: i0, template: "<!--\n RERO angular core\n Copyright (C) 2020 RERO\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published by\n the Free Software Foundation, version 3 of the License.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n-->\n<div class=\"core:text-center core:my-8\">\n <p class=\"core:text-4xl\">\n <i class=\"fa fa-flash core:mr-4\"></i>\n <span class=\"core:text-muted-color\">{{ error.status }}</span>\n {{ error.title }}\n </p>\n <h5 class=\"core:mt-8\">{{ error.message | default: ('You cannot access this page.' | translate) }}</h5>\n</div>\n", dependencies: [{ kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: DefaultPipe, name: "default" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ErrorComponent, decorators: [{ type: Component, args: [{ selector: 'ng-core-error', standalone: false, template: "<!--\n RERO angular core\n Copyright (C) 2020 RERO\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published by\n the Free Software Foundation, version 3 of the License.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n-->\n<div class=\"core:text-center core:my-8\">\n <p class=\"core:text-4xl\">\n <i class=\"fa fa-flash core:mr-4\"></i>\n <span class=\"core:text-muted-color\">{{ error.status }}</span>\n {{ error.title }}\n </p>\n <h5 class=\"core:mt-8\">{{ error.message | default: ('You cannot access this page.' | translate) }}</h5>\n</div>\n" }] }], propDecorators: { error: [{ type: Input }] } }); /* * RERO angular core * Copyright (C) 2023-2024 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * When this guard is configured, it intercepts the form output without * saving or undoing changes. * * Route definition configuration * { path: 'foo/bar', canDeactivate: [ ComponentCanDeactivateGuard ] }, * * Custom editor component configuration * class FooComponent AbstractCanDeactivateComponent { * canDeactivate: boolean = false; * ... * } * * Template configuration (add output canDeactivateChange) * <ng-core-editor * (canDeactivateChange)="canDeactivateChanged($event)" * ... * ></ng-core-editor> */ class ComponentCanDeactivateGuard { constructor() { this.translateService = inject(TranslateService); this.dialogService = inject(DialogService); } /** * Displays a confirmation modal if the user leaves the form without * saving or canceling * @param component - AbstractCanDeactivateComponent * @returns Observable<boolean> or boolean */ canDeactivate(component) { if (!component.canDeactivate) { this.ref = this.dialogService.open(DialogComponent, { header: this.translateService.instant('Quit the page'), data: { body: this.translateService.instant('Do you want to quit the page? The changes made so far will be lost.'), confirmButton: true, confirmTitleButton: this.translateService.instant('Quit'), cancelTitleButton: this.translateService.instant('Stay'), }, dismissableMask: true, modal: true, style: { width: '25rem' } }); return this.ref.onClose; } return true; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ComponentCanDeactivateGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ComponentCanDeactivateGuard }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ComponentCanDeactivateGuard, decorators: [{ type: Injectable }] }); /* * RERO angular core * Copyright (C) 2020 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * Pipe for applying a callback function to filter array items. */ class CallbackArrayFilterPipe { /** * Filter array items with the given callback function. * * @param items List of items. * @param callback Callback function to apply. * @return List of filtered values. */ transform(items, callback) { if (!items && !callback) { return []; } if (items && !callback) { return items; } return items.filter(item => callback(item)); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CallbackArrayFilterPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: CallbackArrayFilterPipe, isStandalone: false, name: "callbackArrayFilter" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CallbackArrayFilterPipe, decorators: [{ type: Pipe, args: [{ name: 'callbackArrayFilter', standalone: false }] }] }); /* * RERO angular core * Copyright (C) 2020 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * Get human readable file size. */ class FilesizePipe { /** * Transform size to a human readable size. * * @param size Size of file. * @param precision Number of decimals. * @return Human readable file size. */ transform(size, precision = 2) { let i = -1; const byteUnits = ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; do { size /= 1024; i++; } while (size > 1024); return [Math.max(size, 0.1).toFixed(precision), byteUnits[i]].join(' '); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FilesizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: FilesizePipe, isStandalone: false, name: "filesize" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FilesizePipe, decorators: [{ type: Pipe, args: [{ name: 'filesize', standalone: false }] }] }); /* * RERO angular core * Copyright (C) 2021-2024 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * Pipe to transform markdown to html. */ class MarkdownPipe { constructor() { this.sanitizer = inject(DomSanitizer); } /** * Transform markdown to HTML. * * @param value Markdown initial value. * @returns HTML corresponding to markdown. */ transform(value) { const markValue = marked.parse(value, { gfm: true, breaks: false, async: false }); return this.sanitizer.bypassSecurityTrustHtml(markValue); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MarkdownPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: MarkdownPipe, isStandalone: false, name: "markdown" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MarkdownPipe, decorators: [{ type: Pipe, args: [{ name: 'markdown', standalone: false }] }] }); /* * RERO angular core * Copyright (C) 2025 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ class SanitizePipe { transform(value, regex = '<[^>]*>', replace = '', flag = 'g') { const re = new RegExp(regex, flag); return value.replace(re, replace); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SanitizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: SanitizePipe, isStandalone: false, name: "sanitize" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SanitizePipe, decorators: [{ type: Pipe, args: [{ name: 'sanitize', standalone: false }] }] }); /* * RERO angular core * Copyright (C) 2020 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Source code: https://dev.to/codephobia/using-typescricore:pt-to-sort-by-keys-35ob */ /** * Error messages */ const ERROR_REQUIRES_AT_LEAST_ONE_KEY = 'provide at least one key to sort by'; const ERROR_KEY_LENGTH_INVALID = 'a key was provided as an empty string'; const ERROR_DESC_KEY_LENGTH_INVALID = 'a descending key was missing the key name'; const ERROR_OBJECT_DOESNT_CONTAIN_KEY = 'a key you are attempting to sort by is not on all objects'; /** * Recursive function to sort values by their keys. */ const sortByKey = (a, b, ...keys) => { // Get first key in array. let key = keys.shift(); // Make sure we have a valid key name. if (!key.length) { throw new Error(ERROR_KEY_LENGTH_INVALID); } // Default to ascending order. let desc = false; // Check for descending sort. if (key.charAt(0) === '-') { // Make sure key has a name as well as the minus sign. if (key.length < 2) { throw new Error(ERROR_DESC_KEY_LENGTH_INVALID); } // Remove minus from key name. key = key.substr(1); // Flag as descending order. desc = true; } // Make sure the objects both have the key. We make sure // to check this after we have removed the minus sign. if (!Object.prototype.hasOwnProperty.call(a, key) || !Object.prototype.hasOwnProperty.call(b, key)) { throw new Error(ERROR_OBJECT_DOESNT_CONTAIN_KEY); } // Determine checks based on asc / desc. const direction = (desc) ? -1 : 1; // Perform bubble sort based on the values. const authorizedSort = [-1, 1]; if (authorizedSort.includes(a[key].localeCompare(b[key]))) { return a[key].localeCompare(b[key]) * direction; } // The values of the current key are equal, so if we still // have keys to check recursively, check the next key. if (keys.length) { return sortByKey(a, b, ...keys); } // All keys returned and no more sorting needed. return 0; }; /** * Wrapper sort function for the recursive one. */ const sortByKeys = (data, ...keys) => { // Make sure we have at least one key to sort by. if (!keys.length) { throw new Error(ERROR_REQUIRES_AT_LEAST_ONE_KEY); } // Sort data. data.sort((a, b) => { return sortByKey(a, b, ...keys); }); // Return sorted data. return data; }; /* * RERO angular core * Copyright (C) 2020 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Source code: https://dev.to/codephobia/using-typescript-to-sort-by-keys-35ob */ /** * Pipe for the sorting function. */ class SortByKeysPipe { /** * Order elements by sort key(s) * @param value - array of values * @param keys - string, sort key */ transform(value, ...keys) { return sortByKeys(value, ...keys); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SortByKeysPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: SortByKeysPipe, isStandalone: false, name: "sortByKeys" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SortByKeysPipe, decorators: [{ type: Pipe, args: [{ name: 'sortByKeys', pure: true, standalone: false }] }] }); /* * RERO angular core * Copyright (C) 2020 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * Pipe for truncating text. */ class TruncateTextPipe { /** * Truncate text. * * @param value Text to truncate. * @param limit Limit after which the text is truncated. * @param trail Trailing chars * @param type Word or Char type * @return Truncated string */ transform(value, limit = 40, trail = '…', type = 'word') { let result = value || ''; if (type === 'char' && value) { if (value.length < limit) { return value; } else { return value.substring(0, limit) + trail; } } if (type === 'word' && value) { const words = value.split(/\s+/); if (words.length > Math.abs(limit)) { if (limit < 0) { limit *= -1; result = trail + words.slice(words.length - limit).join(' '); } else { result = words.slice(0, limit).join(' ') + trail; } } } return result; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TruncateTextPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: TruncateTextPipe, isStandalone: false, name: "truncateText" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TruncateTextPipe, decorators: [{ type: Pipe, args: [{ name: 'truncateText', standalone: false }] }] }); /* * RERO angular core * Copyright (C) 2020-2025 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ function extractIdOnRef(ref) { if (ref != null) { const pidRegExp = new RegExp('.*/(.*)$'); return pidRegExp.exec(ref)[1]; } return null; } function cleanDictKeys(data) { // let data = _.cloneDeep(data); for (const key in data) { if (data[key] === null || data[key] === undefined || data[key].length === 0) { delete data[key]; } } return data; } function capitalize(value) { return value.charAt(0).toUpperCase() + value.slice(1); } function removeChars(value, chars = ['"']) { const re = new RegExp('[' + chars.join('') + ']', 'gi'); return value.replace(re, ''); } /* * RERO angular core * Copyright (C) 2020-2025 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * Uppercase the first letter of the string. */ class UpperCaseFirstPipe { /** * Uppercase the first letter of the given value. * * @param value Value to transform. * @return Transformed value. */ transform(value) { if (!value) { return value; } return capitalize(value); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UpperCaseFirstPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: UpperCaseFirstPipe, isStandalone: false, name: "ucfirst" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UpperCaseFirstPipe, decorators: [{ type: Pipe, args: [{ name: 'ucfirst', standalone: false }] }] }); /* * RERO angular core * Copyright (C) 2020-2024 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ class PrimeNgCoreModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PrimeNgCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: PrimeNgCoreModule, exports: [AutoCompleteModule, AutoFocusModule, BadgeModule, ButtonModule, CardModule, CheckboxModule, ConfirmDialogModule, DatePickerModule, DividerModule, DynamicDialogModule, FieldsetModule, FluidModule, InputGroupAddonModule, InputGroupModule, InputNumberModule, InputTextModule, ListboxModule, MenuModule, MessageModule, PaginatorModule, PanelModule, RadioButtonModule, RippleModule, ScrollPanelModule, SelectModule, SplitButtonModule, TabsModule, TextareaModule, TieredMenuModule, ToastModule, ToggleSwitchModule, TooltipModule] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PrimeNgCoreModule, providers: [ ConfirmationService, DialogService, MessageService ], imports: [AutoCompleteModule, AutoFocusModule, BadgeModule, ButtonModule, CardModule, CheckboxModule, ConfirmDialogModule, DatePickerModule, DividerModule, DynamicDialogModule, FieldsetModule, FluidModule, InputGroupAddonModule, InputGroupModule, InputNumberModule, InputTextModule, ListboxModule, MenuModule, MessageModule, PaginatorModule, PanelModule, RadioButtonModule, RippleModule, ScrollPanelModule, SelectModule, SplitButtonModule, TabsModule, TextareaModule, TieredMenuModule, ToastModule, ToggleSwitchModule, TooltipModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PrimeNgCoreModule, decorators: [{ type: NgModule, args: [{ providers: [ ConfirmationService, DialogService, MessageService ], exports: [ AutoCompleteModule, AutoFocusModule, BadgeModule, ButtonModule, CardModule, CheckboxModule, ConfirmDialogModule, DatePickerModule, DividerModule, DynamicDialogModule, FieldsetModule, FluidModule, InputGroupAddonModule, InputGroupModule, InputNumberModule, InputTextModule, ListboxModule, MenuModule, MessageModule, PaginatorModule, PanelModule, RadioButtonModule, RippleModule, ScrollPanelModule, SelectModule, SplitButtonModule, TabsModule, TextareaModule, TieredMenuModule, ToastModule, ToggleSwitchModule, TooltipModule, ], }] }] }); /* * RERO angular core * Copyright (C) 2020-2024 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ class SearchInputComponent { constructor() { /** Input Id */ this.inputId = input('search'); /** Display label */ this.displayLabel = input(false); /** Placeholder */ this.placeholder = input('search'); /** Value to search */ this.searchText = input(''); /** Remove trailing and leading spaces if true */ this.trimQueryString = input(true); /** Disabled attribute of search input */ this.disabled = input(false); /** Make the focus on field */ this.focus = input(false); /** Search value event */