turbogui-angular
Version:
A library that tries to help with the most common user interface elements on several frameworks and platforms
849 lines (834 loc) • 174 kB
JavaScript
import * as i0 from '@angular/core';
import { EventEmitter, HostListener, Output, Directive, NgModule, inject, Injectable, Component, Inject, HostBinding, Input } from '@angular/core';
import { Subject, BehaviorSubject } from 'rxjs';
import { ArrayUtils, NumericUtils, HTTPManager, StringUtils, HTTPManagerGetRequest, HTTPManagerPostRequest, BrowserManager, ConversionUtils } from 'turbocommons-ts';
import * as i1 from '@angular/material/dialog';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import * as i3 from '@angular/material/button';
import { MatButtonModule } from '@angular/material/button';
import * as i2 from '@angular/common';
import { CommonModule } from '@angular/common';
import { take, filter } from 'rxjs/operators';
import { trigger, transition, style, animate } from '@angular/animations';
import { ComponentPortal, DomPortalOutlet } from '@angular/cdk/portal';
import * as i2$1 from '@angular/material/datepicker';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatNativeDateModule } from '@angular/material/core';
import * as i1$1 from '@angular/material/snack-bar';
import * as i1$2 from '@angular/router';
import { NavigationEnd } from '@angular/router';
import * as i2$2 from '@angular/platform-browser';
import { MatFormFieldModule } from '@angular/material/form-field';
import * as i4 from '@angular/material/input';
import { MatInputModule } from '@angular/material/input';
import * as i5 from '@angular/forms';
import { FormsModule, Validators, FormControl } from '@angular/forms';
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/** This directive is used to trigger an event when the user clicks outside of an element */
/**
* This directive is used to execute an action when the user clicks outside of an element.
* If we set the elementClickOutside tag to the html element and set the onClickOutside event to a function: <element elementClickOutside (onClickOutside)="onClickedOutside()" ...,
* this function will be executed when the user clicks outside of the element.
*/
class ElementClickOutsideDirective {
constructor(elementRef) {
this.elementRef = elementRef;
this.onClickOutside = new EventEmitter();
}
onClick(targetElement) {
const clickedInside = this.elementRef.nativeElement.contains(targetElement);
if (!clickedInside) {
this.onClickOutside.emit();
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ElementClickOutsideDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.5", type: ElementClickOutsideDirective, isStandalone: false, selector: "[elementClickOutside]", outputs: { onClickOutside: "onClickOutside" }, host: { listeners: { "document:click": "onClick($event.target)" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ElementClickOutsideDirective, decorators: [{
type: Directive,
args: [{
selector: '[elementClickOutside]',
standalone: false
}]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { onClickOutside: [{
type: Output
}], onClick: [{
type: HostListener,
args: ['document:click', ['$event.target']]
}] } });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/** This directive is used to listen for onInit events on raw html elements */
/**
* This directive is used to listen for onInit events on raw html elements
* If we place (elementCreated)="someMethod()" on the element at the html template part, when the element
* that uses this directive is visually created, someMethod() will be called.
*/
class ElementCreatedDirective {
constructor() {
/**
* Event that will be dispatched once element is created
*/
this.elementCreated = new EventEmitter();
}
/**
* Listen for the on init event
*/
ngOnInit() {
this.elementCreated.next(this);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ElementCreatedDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.5", type: ElementCreatedDirective, isStandalone: false, selector: "[elementCreated]", outputs: { elementCreated: "elementCreated" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ElementCreatedDirective, decorators: [{
type: Directive,
args: [{
selector: '[elementCreated]',
standalone: false
}]
}], propDecorators: { elementCreated: [{
type: Output,
args: ['elementCreated']
}] } });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/** This directive is used to listen for onDestroy events on raw html elements */
/**
* This directive is used to listen for onDestroy events on raw html elements
* If we place (elementDestroyed)="someMethod()" on the element at the html template part, when the element
* that uses this directive is visually destroyed from the screen, someMethod() will be called.
*/
class ElementDestroyedDirective {
constructor() {
/**
* Event that will be dispatched once element is destroyed
*/
this.elementDestroyed = new EventEmitter();
}
/**
* Listen for the on destroy event
*/
ngOnDestroy() {
this.elementDestroyed.next(this);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ElementDestroyedDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.5", type: ElementDestroyedDirective, isStandalone: false, selector: "[elementDestroyed]", outputs: { elementDestroyed: "elementDestroyed" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ElementDestroyedDirective, decorators: [{
type: Directive,
args: [{
selector: '[elementDestroyed]',
standalone: false
}]
}], propDecorators: { elementDestroyed: [{
type: Output,
args: ['elementDestroyed']
}] } });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/** This directive is used to perform an autofocus on an element every time it is displayed */
/**
* This directive is used to perform an autofocus on an element every time it is displayed
* If we set the autoFocusOnDisplay tag to the html element, it will be automatically focused after it is shown.
*/
class AutoFocusOnDisplayDirective {
constructor(el, zone, renderer) {
this.el = el;
this.zone = zone;
this.renderer = renderer;
if (!el.nativeElement['focus']) {
throw new Error('Element does not accept focus');
}
}
ngAfterContentInit() {
this.zone.runOutsideAngular(() => setTimeout(() => {
this.renderer.selectRootElement(this.el.nativeElement).focus();
}, 0));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AutoFocusOnDisplayDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.5", type: AutoFocusOnDisplayDirective, isStandalone: false, selector: "[autoFocusOnDisplay]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AutoFocusOnDisplayDirective, decorators: [{
type: Directive,
args: [{
selector: '[autoFocusOnDisplay]',
standalone: false
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }] });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/** This directive is used to perform an automatic select all text on an element every time it is focused */
/**
* This directive is used to perform an an automatic select all text on an element every time it is focused.
* If we set the autoSelectTextOnFocus tag to the html element, its text will be automatically selected after it gets the focus.
*/
class AutoSelectTextOnFocusDirective {
constructor(el, renderer) {
this.el = el;
this.renderer = renderer;
if (!el.nativeElement['select']) {
throw new Error('Element does not accept select');
}
}
onFocus() {
this.renderer.selectRootElement(this.el.nativeElement).select();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AutoSelectTextOnFocusDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.5", type: AutoSelectTextOnFocusDirective, isStandalone: false, selector: "[autoSelectTextOnFocus]", host: { listeners: { "focus": "onFocus($event)" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AutoSelectTextOnFocusDirective, decorators: [{
type: Directive,
args: [{
selector: '[autoSelectTextOnFocus]',
standalone: false
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { onFocus: [{
type: HostListener,
args: ['focus', ['$event']]
}] } });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/**
* This file contains the root module that contains all the library declarations and exports.
*/
class TurboGuiAngularModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: TurboGuiAngularModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.5", ngImport: i0, type: TurboGuiAngularModule, declarations: [ElementClickOutsideDirective,
ElementCreatedDirective,
ElementDestroyedDirective,
AutoFocusOnDisplayDirective,
AutoSelectTextOnFocusDirective], exports: [ElementClickOutsideDirective,
ElementCreatedDirective,
ElementDestroyedDirective,
AutoFocusOnDisplayDirective,
AutoSelectTextOnFocusDirective] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: TurboGuiAngularModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: TurboGuiAngularModule, decorators: [{
type: NgModule,
args: [{
imports: [],
declarations: [
ElementClickOutsideDirective,
ElementCreatedDirective,
ElementDestroyedDirective,
AutoFocusOnDisplayDirective,
AutoSelectTextOnFocusDirective
],
providers: [],
exports: [
ElementClickOutsideDirective,
ElementCreatedDirective,
ElementDestroyedDirective,
AutoFocusOnDisplayDirective,
AutoSelectTextOnFocusDirective
]
}]
}] });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/**
* Defines a base class that can be used to create singleton services which cannot be instantiated more than one time
* during the whole application lifetime.
*
* To use it, simply extend this class and pass the parent class type to this constructor via super()
*/
class SingletoneStrictClass {
constructor(classType) {
const parent = inject(classType, { skipSelf: true, optional: true });
if (parent) {
throw Error(`[${classType.name}]: Can not create more than one instance`);
}
}
}
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/**
* This is the main application event bus.
* All global events that happen on the application are broadcasted by this service, and
* can be listened by any application element who previously subscribed
*/
class NotificationService extends SingletoneStrictClass {
constructor() {
super(NotificationService);
/**
* The Observable instance that handles subscriptions and notifications
*/
this._notifications = new Subject();
}
/**
* used by other services or components to subscribe to all notifications that are generated by this service
*
* @param notificationHandler A method that will be used to receive each notification as a GUINotification instance
*
* @returns The new subscription object. Make sure to unsubscribe when not required anymore
*/
subscribe(notificationHandler) {
return this._notifications.subscribe(notificationHandler);
}
/**
* Launch a notification to anyone who may be listening
*
* @param notification A notification instance to launch
*/
send(notification) {
this._notifications.next(notification);
}
/**
* End a previously initiated subscription
*
* @param subscription A previously created subscription instance from which we want to unsubscribe
*/
unsubscribe(subscription) {
return subscription.unsubscribe();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: NotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: NotificationService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: NotificationService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: () => [] });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/**
* Captures all the application exceptions and performs any required action.
* It also contains multiple general error management features.
*
* To define this class as your application error handler, you must add the following to your
* Application providers:
* {
* provide: ErrorHandler,
* useClass: GlobalErrorService
* },
* GlobalErrorService
*
* You cannot access the error handler at runtime. If you need to modify any of the behaviours
* or implement your custom ones, you must extend this class and set your new one as the error
* handler provider.
*/
class GlobalErrorService extends SingletoneStrictClass {
constructor() {
super(GlobalErrorService);
/**
* Enables or disables the error notification to user via an alert box
* Extend this class and override this value on your custom error handle to change it
*/
this.showExceptionsToUser = true;
/**
* Enables or disables the error notification to user via an alert box
* Extend this class and override this value on your custom error handle to change it
*/
this.showExceptionsOnConsole = true;
/**
* Defines the text that will be used for the alert that is shown to the user when an exception happens
* and showExceptionsToUser is true
* Extend this class and override this value on your custom error handle to change it
*/
this.errorAlertMessage = 'Application exception:\n\n';
}
/**
* Show an alert with the received error detail and also log it to the js console.
*
* Angular expects at least this method to be implemented on any class that is used as a global exception handler.
*
* @param error An error instance
*/
handleError(error) {
if (this.showExceptionsToUser) {
alert(this.errorAlertMessage + error);
}
if (this.showExceptionsOnConsole) {
console.log(error);
}
throw error;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: GlobalErrorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: GlobalErrorService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: GlobalErrorService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: () => [] });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/**
* This is the base class for all the dialog components that can be loaded by the dialog service class
*/
class DialogBaseComponent {
/*
* The name of the superclass must be set into this constant as it is required by the dialog service to identify dialogs as different.
*
* When you extend the dialog base class, simply declare this static constant with the exact same name as your class and you're done.
* If this value is not set on the extended dialog component, a runtime exception will happen when trying to show the dialog.
*
* The root cause of this requirement is that when apps are compiled for production, class names are minified and this causes problems
* when creating a dialog hash to uniquely identify a dialog instance. Therefore, a hardcoded class name is necesary.
*/
static { this.DIALOG_CLASS_NAME = ''; }
constructor(elementRef, dialogRef) {
this.elementRef = elementRef;
this.dialogRef = dialogRef;
}
ngAfterViewInit() {
// Assign the component HTML identifier if it is specifically assigned to the dialogref instance
if (this.dialogRef.id !== undefined && this.dialogRef.id !== '') {
this.elementRef.nativeElement.id = this.dialogRef.id;
}
}
/**
* Method to be called by the dialogs that extend this base component when they want to close themselves.
* It will perform the close of that dialog and also send an object to the addDialog() callback with the index and value
* that the user may have selected.
*
* @param index The numeric index of the user option selection. It will be specific for each dialog and it's different available options
* @param value Any value that may be provided to the callback regarding the user selected option.
*
* @return void
*/
closeDialog(index, value = null) {
this.dialogRef.close({ index: index, value: value });
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DialogBaseComponent, deps: [{ token: i0.ElementRef }, { token: i1.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: DialogBaseComponent, isStandalone: false, selector: "ng-component", ngImport: i0, template: '', isInline: true }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DialogBaseComponent, decorators: [{
type: Component,
args: [{
template: '',
standalone: false
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.MatDialogRef }] });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/**
* A dialog component with a single option button, to be used for error notifications
*/
class DialogErrorComponent extends DialogBaseComponent {
static { this.DIALOG_CLASS_NAME = 'DialogErrorComponent'; }
constructor(elementRef, dialogRef, data) {
super(elementRef, dialogRef);
this.elementRef = elementRef;
this.dialogRef = dialogRef;
this.data = data;
if (data.texts.length < 1) {
throw new Error('DialogErrorComponent expects 2 texts: The title and optionally a description');
}
if (data.options.length !== 1) {
throw new Error('DialogErrorComponent expects only one option');
}
if (data.texts.length > 1) {
data.texts[1] = data.texts[1].replace(/\n/g, "<br/>");
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DialogErrorComponent, deps: [{ token: i0.ElementRef }, { token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: DialogErrorComponent, isStandalone: true, selector: "tg-dialog-error", providers: [], usesInheritance: true, ngImport: i0, template: "<div class=\"titleAndIconContainer\">\r\n <h3>\r\n {{data.texts[0]}}\r\n </h3>\r\n \r\n <!-- error icon -->\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\">\r\n <path d=\"M0 0h24v24H0z\" fill=\"none\"/>\r\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\" fill=\"#ff0000\" />\r\n </svg>\r\n \r\n</div>\r\n\r\n<div class=\"textContainer\">\r\n <p *ngIf=\"data.texts.length > 1\" [innerHTML]=\"data.texts[1]\">\r\n </p>\r\n</div>\r\n\r\n<button mat-raised-button color=\"warn\"\r\n (click)=\"closeDialog(0)\">\r\n \r\n {{data.options[0]}}\r\n \r\n</button>", styles: [":host{position:relative;min-height:300px}.titleAndIconContainer{display:flex;flex-direction:row;align-items:center;justify-content:space-between}svg{height:10vh;width:auto}.textContainer{margin-top:5px;max-height:70vh;overflow:auto}p{-webkit-user-select:text;user-select:text}h3{margin-top:0;margin-bottom:25px;width:82%}button{width:100%;margin-top:5px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DialogErrorComponent, decorators: [{
type: Component,
args: [{ selector: 'tg-dialog-error', imports: [CommonModule, MatButtonModule], providers: [], template: "<div class=\"titleAndIconContainer\">\r\n <h3>\r\n {{data.texts[0]}}\r\n </h3>\r\n \r\n <!-- error icon -->\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\">\r\n <path d=\"M0 0h24v24H0z\" fill=\"none\"/>\r\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\" fill=\"#ff0000\" />\r\n </svg>\r\n \r\n</div>\r\n\r\n<div class=\"textContainer\">\r\n <p *ngIf=\"data.texts.length > 1\" [innerHTML]=\"data.texts[1]\">\r\n </p>\r\n</div>\r\n\r\n<button mat-raised-button color=\"warn\"\r\n (click)=\"closeDialog(0)\">\r\n \r\n {{data.options[0]}}\r\n \r\n</button>", styles: [":host{position:relative;min-height:300px}.titleAndIconContainer{display:flex;flex-direction:row;align-items:center;justify-content:space-between}svg{height:10vh;width:auto}.textContainer{margin-top:5px;max-height:70vh;overflow:auto}p{-webkit-user-select:text;user-select:text}h3{margin-top:0;margin-bottom:25px;width:82%}button{width:100%;margin-top:5px}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.MatDialogRef }, { type: undefined, decorators: [{
type: Inject,
args: [MAT_DIALOG_DATA]
}] }] });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/**
* Fade animations
*/
class FadeAnimationClass {
/**
* Get a custom trigger to create fade animations when components are added or removed from the application
*
* @param triggerName The name for the trigger we want to create
* @param enter The time and easing that we want to use for the enter state
* @param leave The time and easing that we want to use for the leave state
*/
static getTrigger(triggerName, enter = '1s ease', leave = '300ms ease') {
return trigger(triggerName, [
transition('void => *', [style({ opacity: 0 }), animate(enter, style({ opacity: 1 }))]),
transition('* => void', [animate(leave, style({ opacity: 0 }))])
]);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: FadeAnimationClass, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: FadeAnimationClass }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: FadeAnimationClass, decorators: [{
type: Injectable
}] });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/**
* This component is used by turboGUI angular library to show the busy state to the user.
* It is used to block all the user input and progressively shows a busy cursor to notify that the application
* is waiting for something.
*
* We can (should) override this component with our own one to adapt its visual appearance to our application.
* We can then set dialogService.busyStateComponentClass to our component class at the application start to to
* override the default one.
*/
class BusyStateBaseComponent {
constructor() {
/**
* This is used to attach the fade animation directly to this component so it fades in and out when created and removed from the app
*/
this.busyStateBaseFade = true;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: BusyStateBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: BusyStateBaseComponent, isStandalone: true, selector: "tg-busy-state-base", host: { properties: { "@busyStateBaseFade": "this.busyStateBaseFade" } }, providers: [], ngImport: i0, template: "<div class=\"darkBg\">\r\n\r\n</div>\r\n\r\n<svg width=\"38\" height=\"38\" viewBox=\"0 0 38 38\" xmlns=\"http://www.w3.org/2000/svg\" stroke=\"#fff\">\r\n <g fill=\"none\" fill-rule=\"evenodd\">\r\n <g transform=\"translate(1 1)\" stroke-width=\"1\">\r\n <circle stroke-opacity=\".2\" cx=\"18\" cy=\"18\" r=\"18\"/>\r\n <path d=\"M36 18c0-9.94-8.06-18-18-18\">\r\n <animateTransform\r\n attributeName=\"transform\"\r\n type=\"rotate\"\r\n from=\"0 18 18\"\r\n to=\"360 18 18\"\r\n dur=\"1s\"\r\n repeatCount=\"indefinite\"/>\r\n </path>\r\n </g>\r\n </g>\r\n</svg>\r\n", styles: [":host{position:fixed;inset:0;display:flex;justify-content:center;align-items:center;z-index:999999999}.darkBg{position:absolute;cursor:progress;width:100%;height:100%;display:flex;justify-content:center;align-items:center;background-color:#00000096;animation-name:bgfadein;animation-duration:30s;animation-timing-function:ease}svg{z-index:5000;width:40%;height:40%;max-width:130px;max-height:130px;animation-name:loadingfadein;animation-duration:3s;animation-timing-function:ease-in}@keyframes loadingfadein{0%{opacity:0}25%{opacity:0}to{opacity:1}}@keyframes bgfadein{0%{opacity:0}4%{opacity:0}14%{opacity:.2}35%{opacity:.5}to{opacity:1}}\n"], animations: [FadeAnimationClass.getTrigger('busyStateBaseFade', '1s ease', '400ms ease')] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: BusyStateBaseComponent, decorators: [{
type: Component,
args: [{ selector: 'tg-busy-state-base', imports: [], providers: [], animations: [FadeAnimationClass.getTrigger('busyStateBaseFade', '1s ease', '400ms ease')], template: "<div class=\"darkBg\">\r\n\r\n</div>\r\n\r\n<svg width=\"38\" height=\"38\" viewBox=\"0 0 38 38\" xmlns=\"http://www.w3.org/2000/svg\" stroke=\"#fff\">\r\n <g fill=\"none\" fill-rule=\"evenodd\">\r\n <g transform=\"translate(1 1)\" stroke-width=\"1\">\r\n <circle stroke-opacity=\".2\" cx=\"18\" cy=\"18\" r=\"18\"/>\r\n <path d=\"M36 18c0-9.94-8.06-18-18-18\">\r\n <animateTransform\r\n attributeName=\"transform\"\r\n type=\"rotate\"\r\n from=\"0 18 18\"\r\n to=\"360 18 18\"\r\n dur=\"1s\"\r\n repeatCount=\"indefinite\"/>\r\n </path>\r\n </g>\r\n </g>\r\n</svg>\r\n", styles: [":host{position:fixed;inset:0;display:flex;justify-content:center;align-items:center;z-index:999999999}.darkBg{position:absolute;cursor:progress;width:100%;height:100%;display:flex;justify-content:center;align-items:center;background-color:#00000096;animation-name:bgfadein;animation-duration:30s;animation-timing-function:ease}svg{z-index:5000;width:40%;height:40%;max-width:130px;max-height:130px;animation-name:loadingfadein;animation-duration:3s;animation-timing-function:ease-in}@keyframes loadingfadein{0%{opacity:0}25%{opacity:0}to{opacity:1}}@keyframes bgfadein{0%{opacity:0}4%{opacity:0}14%{opacity:.2}35%{opacity:.5}to{opacity:1}}\n"] }]
}], propDecorators: { busyStateBaseFade: [{
type: HostBinding,
args: ['@busyStateBaseFade']
}] } });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/**
* A dialog component with a calendar that allows us to select a single date value
*/
class DialogDateSelectionComponent extends DialogBaseComponent {
static { this.DIALOG_CLASS_NAME = 'DialogDateSelectionComponent'; }
constructor(elementRef, dialogRef, data) {
super(elementRef, dialogRef);
this.elementRef = elementRef;
this.dialogRef = dialogRef;
this.data = data;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DialogDateSelectionComponent, deps: [{ token: i0.ElementRef }, { token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: DialogDateSelectionComponent, isStandalone: true, selector: "tg-dialog-date-selection", providers: [], usesInheritance: true, ngImport: i0, template: "<h2>{{data.texts[0]}}</h2>\r\n\r\n<mat-calendar #calendar\r\n (selectedChange)=\"closeDialog(0, $event)\">\r\n</mat-calendar>", styles: [":host{position:relative;min-height:300px}h1{margin-top:0;margin-bottom:25px;width:82%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i2$1.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "ngmodule", type: MatNativeDateModule }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DialogDateSelectionComponent, decorators: [{
type: Component,
args: [{ selector: 'tg-dialog-date-selection', imports: [CommonModule, MatDatepickerModule, MatNativeDateModule], providers: [], template: "<h2>{{data.texts[0]}}</h2>\r\n\r\n<mat-calendar #calendar\r\n (selectedChange)=\"closeDialog(0, $event)\">\r\n</mat-calendar>", styles: [":host{position:relative;min-height:300px}h1{margin-top:0;margin-bottom:25px;width:82%}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.MatDialogRef }, { type: undefined, decorators: [{
type: Inject,
args: [MAT_DIALOG_DATA]
}] }] });
/**
* TurboGUI is A library that helps with the most common and generic UI elements and functionalities
*
* Website : -> http://www.turbogui.org
* License : -> Licensed under the Apache License, Version 2.0. You may not use this file except in compliance with the License.
* License Url : -> http://www.apache.org/licenses/LICENSE-2.0
* CopyRight : -> Copyright 2018 Edertone Advanded Solutions. https://www.edertone.com
*/
/**
* Manages the application modal and non modal floating elements
*/
class DialogService extends SingletoneStrictClass {
constructor(rendererFactory, matSnackBar, matDialog, injector, applicationRef, environmentInjector) {
super(DialogService);
this.matSnackBar = matSnackBar;
this.matDialog = matDialog;
this.injector = injector;
this.applicationRef = applicationRef;
this.environmentInjector = environmentInjector;
/**
* Used to modify the busy state component that is shown by default by the addModalBusyState() method.
*
* @see this.addModalBusyState()
*/
this.customBusyStateComponentClass = BusyStateBaseComponent;
/**
* Check public getter for docs
*/
this._isEnabled = true;
/**
* Tells if the main application is currently showing a busy state that blocks all user interaction
*/
this._isShowingBusyState = false;
/**
* A reference to the modal busy state component that is initialized only the first time it is called.
*
* (To append the busy state dynamically, we use the Portal concept from the angular material library)
*/
this._componentPortal = null;
/**
* A reference to the modal busy state container where the component will be added
*/
this._modalBusyStateHost = null;
/**
* Tells if the manager is currently showing a snackbar element or not
*/
this._isShowingSnackBar = false;
/**
* Contains a list of the dialogs (MODAL AND NON MODAL) that are currently visible to the user.
* Each item in this list is a hash that is computed when dialog is created to uniquely identify it.
*
* Empty list means no dialogs are currently visible
*/
this._activeDialogs = [];
/**
* Contains a list with all the MatDialog instances that are currently visible to the user.
* The list uses the same order as the list of _activeDialogs hash values
*/
this._activeDialogInstances = [];
/**
* Counts the number of dialogs that are currently open and that can be closed by the user by navigating with the browser
*/
this._activeCloseableDialogs = 0;
/**
* Method that is used to delete the window beforeunload event listener once not used anymore
*/
this._windowBeforeUnloadUnListen = null;
/**
* Method that is used to delete the document keydown event listener once not used anymore
*/
this._documentKeydownUnlisten = null;
/**
* Method that is used to delete the document mousedown event listener once not used anymore
*/
this._documentMousedownUnlisten = null;
/**
* Method that is used to delete the document pointerdown event listener once not used anymore
*/
this._documentPointerdownUnlisten = null;
this._renderer = rendererFactory.createRenderer(null, null);
}
/**
* Tells if this dialog service is enabled or not. If dialog service is disabled, none of it's features will work
* This is used to block all dialog features normally when shutting down the application
*
* Use with caution. When this is set to false, dialog service stops working.
*/
set isEnabled(v) {
if (v === this._isEnabled) {
return;
}
this._isEnabled = v;
}
/**
* Enables a warning that will be shown to the user when he/she tries to close the application.
* This warning will prompt the user to continue with the exit process or cancel it.
* The specific texts of this message are a generic ones and cannot be changed.
*
* IMPORTANT: This method must be called after the main application has been initialized in order to work,
* otherwise it will do nothing.
*/
addCloseApplicationWarning() {
this._windowBeforeUnloadUnListen ??= this._renderer.listen('window', 'beforeunload', (event) => event.returnValue = true);
}
/**
* Remove the close application warning message if previously assigned
*/
removeCloseApplicationWarning() {
if (this._windowBeforeUnloadUnListen !== null) {
this._windowBeforeUnloadUnListen();
this._windowBeforeUnloadUnListen = null;
}
}
/**
* Change the application visual appearance so the user perceives that the application is
* currently busy. While modal busy state is enabled, no user input is possible neither via
* keyboard, mouse or touch. Use this state when performing server requests or operations that
* must block the user interaction with the application. To allow user interaction again, you must
* call removeModalBusyState()
*
* Notice: We can modify the busy state visual component that is shown by this method. To do it, we must
* set this.customBusyStateComponentClass property with our own custom busy state component class. (We can do it at
* our main application component constructor for example). Our custom component must extend the
* BusyStateBaseComponent one to add its own visual appearance.
*
* @see this.customBusyStateComponentClass
*/
addModalBusyState() {
if (!this._isEnabled || this._isShowingBusyState) {
return;
}
this._disableUserInteraction();
// Dynamically create the busy state component reference if this is the first time
if (this._componentPortal === null) {
this._componentPortal = new ComponentPortal(this.customBusyStateComponentClass);
// Create a PortalHost with document.body as its anchor element
this._modalBusyStateHost = new DomPortalOutlet(document.body, this.environmentInjector, this.applicationRef, this.injector);
}
this._modalBusyStateHost.attach(this._componentPortal);
this._isShowingBusyState = true;
}
/**
* Tells if the application is currently locked in a modal busy state (caused by an addModalBusyState() call)
*/
get isShowingBusyState() {
return this._isShowingBusyState;
}
/**
* Cancel the application busy state and restore it back to normal so user interaction is allowed again
*/
removeModalBusyState() {
if (!this._isEnabled || !this._isShowingBusyState) {
return;
}
if (this._componentPortal !== null) {
this._modalBusyStateHost.detach();
}
this._enableUserInteraction();
this._isShowingBusyState = false;
}
/**
* TODO - adapt from TS version
*/
addToolTip() {
// TODO - adapt from TS version
}
/**
* Show a non modal snackbar notification to the user (Only one snack-bar can ever be opened at the same time).
*
* Snackbars inform users of a process that an app has performed or will perform. They appear temporarily, towards the bottom or top of the screen.
* They shouldn’t interrupt the user experience, and they don’t require user input to disappear.
*
* @param config A MatSnackBarConfig instance with the customizations we want for this snackbar
* @param message The message to show on the snackbar
* @param action If not empty, the text to place on the snackbar confirmation button
* @param actionCallback A method to execute once the user clicks into the action button.
*
* @return A promise that will be resolved once the snackbar is closed.
*/
addSnackBar(config, message, action = '') {
if (!this._isEnabled) {
return Promise.reject(new Error('Dialog service is disabled'));
}
if (this._isShowingSnackBar) {
throw new Error('Trying to show a snackbar while another one is still visible');
}
this._isShowingSnackBar = true;
return new Promise((resolve) => {
const snackBarRef = this.matSnackBar.open(message, action === '' ? undefined : action, config);
// Handle action button click
snackBarRef.onAction().pipe(take(1)).subscribe(() => {
this._isShowingSnackBar = false;
resolve(true);
});
// Handle dismiss
snackBarRef.afterDismissed().pipe(take(1)).subscribe(() => {
this._isShowingSnackBar = false;
resolve(false);
});
});
}
/**
* Tells if the application is currently showing a snackbar or not
*/
get isShowingSnackBar() {
return this._isShowingSnackBar;
}
/**
* Force the removal of the snack bar dialog if it exists.
*
* If no snackbar is currently visible, this method will do nothing
*/
removeSnackBar() {
if (!this._isEnabled || !this._isShowingSnackBar) {
return;
}
this.matSnackBar.dismiss();
this._isShowingSnackBar = false;
}
/**
* Show a dialog with one or more options that can be used to close it. We can use any of the predefined dialog types that are bundled with
* this library or extend DialogBaseComponent to create our own custom ones.
*
* @param dialogComponentClass A class for a component that extends DialogBaseComponent, which will be the dialog that is shown to the user.
* @param properties An object containing the different visual and textual options that this dialog allows.
* IMPORTANT: texts, options and data values need to be read at the dialog component by declaring "@Inject(MAT_DIALOG_DATA) public data: any"
* at the dialog component constructor. This data object will contain the texts, options and data properties
*
* - id: The html unique identifier that the dialog will have once created. If not specified, no id will be explicitly set
* - width: 50% by default. Specify the css value for the default dialog width. As the dialog is responsive, the value will be automatically
* reduced if the available screen is not enough, and will reach the desired value otherwise. We can set any css unit like pixels,
* %, vh, vw, or any other. For example: '400px', '50%', etc.
* - maxWidth: Defines the maximum width that the dialog will have. We can specify it in % or vw, just like is done in
* css. By default it is defined as 96vw, which will fit 96% of the viewport on small devices
* - height: Unset by default. Specify the css value for the dialog height.
* - maxHeig