@rero/ng-core
Version:
RERO angular core library.
1,156 lines (1,136 loc) • 753 kB
JavaScript
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 */