UNPKG

@noaestudio/forms

Version:

Dynamic forms extension for Covalent

1,481 lines (1,436 loc) 386 kB
import { Component, forwardRef, Inject, ViewChild, ChangeDetectorRef, Injectable, SkipSelf, Optional, Directive, Input, HostBinding, TemplateRef, ViewContainerRef, ComponentFactoryResolver, ChangeDetectionStrategy, ContentChildren, Output, EventEmitter, NgModule } from '@angular/core'; import { NG_VALUE_ACCESSOR, Validators, FormControl, FormBuilder, ReactiveFormsModule } from '@angular/forms'; import { TranslateService, TranslateModule } from '@ngx-translate/core'; import * as _isjson_ from 'is-json'; import * as moment from 'moment'; import { utc, fn } from 'moment'; import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatTreeModule, MatTableModule, MAT_DATE_FORMATS, DateAdapter } from '@angular/material'; import { __awaiter } from 'tslib'; import { SelectionModel } from '@angular/cdk/collections'; import { FlatTreeControl } from '@angular/cdk/tree'; import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree'; import { of, timer } from 'rxjs'; import { MatDialogRef as MatDialogRef$1, MAT_DIALOG_DATA as MAT_DIALOG_DATA$1 } from '@angular/material/dialog'; import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop'; import * as lodash_ from 'lodash'; import { TemplatePortalDirective } from '@angular/cdk/portal'; import { distinctUntilChanged } from 'rxjs/operators'; import { TREE_ACTIONS, TreeModule } from 'angular-tree-component'; import { TdLoadingService } from '@covalent/core/loading'; import { MomentDateAdapter, MatMomentDateModule } from '@angular/material-moment-adapter'; import { CommonModule } from '@angular/common'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatSliderModule } from '@angular/material/slider'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { MatIconModule } from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatTabsModule } from '@angular/material/tabs'; import { MatChipsModule } from '@angular/material/chips'; import { CovalentCommonModule } from '@covalent/core/common'; import { CovalentFileModule } from '@covalent/core/file'; import { NgxEditorModule } from 'ngx-editor'; import { AngularFontAwesomeModule } from 'angular-font-awesome'; import { MccColorPickerModule } from 'material-community-components'; import { NgSelectModule } from '@ng-select/ng-select'; import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ noop = () => { // empty method }; /** * @abstract */ class AbstractControlValueAccessor { constructor() { /** * Implemented as part of ControlValueAccessor. */ this._value = undefined; this.onChange = (_) => noop; this.onTouched = () => noop; } /** * @return {?} */ get value() { return this._value; } /** * @param {?} v * @return {?} */ set value(v) { if (v !== this._value) { this._value = v; this.onChange(v); } } /** * Implemented as part of ControlValueAccessor. * @param {?} value * @return {?} */ writeValue(value) { this.value = value; } /** * @param {?} fn * @return {?} */ registerOnChange(fn$$1) { this.onChange = fn$$1; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn$$1) { this.onTouched = fn$$1; } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ INPUT_INPUT_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TdDynamicInputComponent), multi: true, }; class TdDynamicInputComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.label = ''; this.type = undefined; this.required = undefined; this.min = undefined; this.max = undefined; this.minLength = undefined; this.maxLength = undefined; this.step = undefined; this.autocomplete = 'off'; } /** * @return {?} */ ngOnInit() { if (this.type == 'password') { this.autocomplete = 'new-password'; } else { this.autocomplete = 'off'; } } } TdDynamicInputComponent.decorators = [ { type: Component, args: [{ providers: [INPUT_INPUT_CONTROL_VALUE_ACCESSOR], selector: 'td-dynamic-input', styles: [`.td-dynamic-input-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-input-wrapper .td-dynamic-input-field{-ms-flex:1;flex:1;box-sizing:border-box}`], template: `<div class="td-dynamic-input-wrapper"> <mat-form-field class="td-dynamic-input-field"> <input #elementInput matInput [(ngModel)]="value" [formControl]="control" [placeholder]="label" [type]="type" [autocomplete]="autocomplete" [required]="required" [attr.min]="min" [attr.max]="max" [attr.minLength]="minLength" [attr.maxLength]="maxLength" [attr.step]="step" /> </mat-form-field> </div> `, },] }, ]; /** @nocollapse */ TdDynamicInputComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ UPLOAD_INPUT_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TdDynamicFileInputComponent), multi: true, }; class TdDynamicFileInputComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.required = undefined; this.label = ''; } } TdDynamicFileInputComponent.decorators = [ { type: Component, args: [{ providers: [UPLOAD_INPUT_CONTROL_VALUE_ACCESSOR], selector: 'td-dynamic-file-input', styles: [`.td-dynamic-file-input-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-file-input-wrapper .td-dynamic-file-input-field{-ms-flex:1;flex:1;box-sizing:border-box}.td-file-input{margin-left:10px}`], template: `<div class="td-dynamic-file-input-wrapper"> <mat-form-field tdFileDrop class="td-dynamic-file-input-field" floatLabel="never" [disabled]="control?.disabled" (fileDrop)="value = $event" (click)="!control?.disabled && fileInput.inputElement.click()" (keyup.enter)="!control?.disabled && fileInput.inputElement.click()" (keyup.delete)="fileInput.clear()" (keyup.backspace)="fileInput.clear()" > <input matInput [value]="value?.name" [placeholder]="label" [disabled]="control?.disabled" autocomplete="off" readonly /> </mat-form-field> <button mat-icon-button *ngIf="value" (click)="fileInput.clear()" (keyup.enter)="fileInput.clear()"> <mat-icon>cancel</mat-icon> </button> <td-file-input class="td-file-input" #fileInput [(ngModel)]="value"> <mat-icon>folder</mat-icon> <span>{{ label }}</span> </td-file-input> </div> `, },] }, ]; /** @nocollapse */ TdDynamicFileInputComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ TEXTAREA_INPUT_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TdDynamicTextareaComponent), multi: true, }; class TdDynamicTextareaComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.label = ''; this.required = undefined; } } TdDynamicTextareaComponent.decorators = [ { type: Component, args: [{ providers: [TEXTAREA_INPUT_CONTROL_VALUE_ACCESSOR], selector: 'td-dynamic-textarea', styles: [`.td-dynamic-textarea-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-textarea-wrapper .td-dynamic-textarea-field{-ms-flex:1;flex:1;box-sizing:border-box}`], template: `<div class="td-dynamic-textarea-wrapper"> <mat-form-field class="td-dynamic-textarea-field"> <textarea #elementInput matInput [(ngModel)]="value" [placeholder]="label" [required]="required" rows="4"> </textarea> </mat-form-field> </div>`, },] }, ]; /** @nocollapse */ TdDynamicTextareaComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ SLIDE_TOGGLE_INPUT_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TdDynamicSlideToggleComponent), multi: true, }; class TdDynamicSlideToggleComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.label = ''; this.required = false; } } TdDynamicSlideToggleComponent.decorators = [ { type: Component, args: [{ providers: [SLIDE_TOGGLE_INPUT_CONTROL_VALUE_ACCESSOR], selector: 'td-dynamic-slide-toggle', styles: [``], template: `<div class="td-dynamic-slide-toggle-wrapper"> <mat-slide-toggle [(ngModel)]="value" [required]="required"> {{label}} </mat-slide-toggle> </div>`, },] }, ]; /** @nocollapse */ TdDynamicSlideToggleComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ CHECKBOX_INPUT_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TdDynamicCheckboxComponent), multi: true, }; class TdDynamicCheckboxComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.label = ''; this.required = false; } } TdDynamicCheckboxComponent.decorators = [ { type: Component, args: [{ providers: [CHECKBOX_INPUT_CONTROL_VALUE_ACCESSOR], selector: 'td-dynamic-checkbox', styles: [``], template: `<div class="td-dynamic-checkbox-wrapper"> <mat-checkbox [(ngModel)]="value" [required]="required"> {{label}} </mat-checkbox> </div>`, },] }, ]; /** @nocollapse */ TdDynamicCheckboxComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ SLIDER_INPUT_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TdDynamicSliderComponent), multi: true, }; class TdDynamicSliderComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.label = ''; this.required = undefined; this.min = undefined; this.max = undefined; } } TdDynamicSliderComponent.decorators = [ { type: Component, args: [{ providers: [SLIDER_INPUT_CONTROL_VALUE_ACCESSOR], selector: 'td-dynamic-slider', styles: [`.td-dynamic-slider-field{position:relative;margin-top:8px;-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-slider-field .td-dynamic-slider{-ms-flex:1;flex:1}`], template: `<div class="td-dynamic-slider-wrapper"> <div class="mat-form-field-placeholder-wrapper mat-form-field-can-float mat-form-field-should-float" [class.mat-focused]="slider._isActive"> <label class="mat-form-field-placeholder mat-float mat-form-field-float td-slider-label"> {{label}} <span *ngIf="required" class="mat-placeholder-required">*</span></label> </div> <div class="td-dynamic-slider-field"> <mat-slider #slider class="td-dynamic-slider" [(ngModel)]="value" [min]="min" [max]="max" thumbLabel tickInterval="auto" [required]="required"> </mat-slider> </div> </div> `, },] }, ]; /** @nocollapse */ TdDynamicSliderComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ isJSON = _isjson_; const /** @type {?} */ SELECT_TOGGLE_INPUT_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TdDynamicSelectComponent), multi: true, }; class TdDynamicSelectComponent extends AbstractControlValueAccessor { /** * @param {?} translator */ constructor(translator) { super(); this.translator = translator; this.label = ''; this.required = undefined; this.selections = undefined; this.selectComplex = false; this.selectMultiple = false; this.flex = 100; this.flexPerc = this.flex / 100; } /** * @return {?} */ ngOnInit() { if (this.selections) { this.selections.forEach(sel => { if (sel.label) { sel.label = this.translateLabel(sel.label); } }); } } /** * @param {?} value * @return {?} */ translateLabel(value) { let /** @type {?} */ selectedLang = this.translator.currentLang; let /** @type {?} */ defaultLang = this.translator.defaultLang; if (isJSON(value)) { let /** @type {?} */ json = JSON.parse(value); if (json[selectedLang]) { return json[selectedLang]; } else if (json[defaultLang]) { return json[defaultLang]; } else { for (let /** @type {?} */ entry in json) { return json[entry]; } } } else { return this.translator.instant(value); } } } TdDynamicSelectComponent.decorators = [ { type: Component, args: [{ providers: [SELECT_TOGGLE_INPUT_CONTROL_VALUE_ACCESSOR], selector: 'td-dynamic-select', styles: [`.td-dynamic-select-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-select-wrapper .td-dynamic-select-field{-ms-flex:1;flex:1;box-sizing:border-box}`], template: `<div class="td-dynamic-select-wrapper"> <mat-form-field *ngIf="!selectComplex" class="td-dynamic-select-field"> <mat-select [(ngModel)]="value" [placeholder]="label" [required]="required"> <mat-option *ngFor="let selection of selections" [value]="selection.value || selection">{{selection.label || selection}}</mat-option> </mat-select> </mat-form-field> <ng-select style="padding-bottom: 2.25em;" *ngIf="selectComplex" [(ngModel)]="value" placeholder="{{label + (required ? ' *' : '')}}" [required]="required" [multiple]="selectMultiple" [items]="selections" [searchable]="true" bindLabel="label" bindValue="value" appendTo="body" [style.flex]="flexPerc"> </ng-select> </div> `, },] }, ]; /** @nocollapse */ TdDynamicSelectComponent.ctorParameters = () => [ { type: TranslateService, }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ DATEPICKER_INPUT_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TdDynamicDatepickerComponent), multi: true, }; class TdDynamicDatepickerComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.label = ''; this.type = undefined; this.required = undefined; this.min = undefined; this.max = undefined; } } TdDynamicDatepickerComponent.decorators = [ { type: Component, args: [{ providers: [DATEPICKER_INPUT_CONTROL_VALUE_ACCESSOR], selector: 'td-dynamic-datepicker', styles: [`.td-dynamic-datepicker-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-datepicker-wrapper .td-dynamic-datepicker-field{-ms-flex:1;flex:1;box-sizing:border-box}`], template: `<div class="td-dynamic-datepicker-wrapper"> <mat-form-field class="td-dynamic-datepicker-field"> <input #elementInput matInput [matDatepicker]="dynamicDatePicker" [(ngModel)]="value" [formControl]="control" autocomplete="off" [placeholder]="label" [required]="required" [min]="min" [max]="max"/> <mat-datepicker-toggle matSuffix [for]="dynamicDatePicker"></mat-datepicker-toggle> <mat-datepicker #dynamicDatePicker></mat-datepicker> </mat-form-field> </div> `, },] }, ]; /** @nocollapse */ TdDynamicDatepickerComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ INPUT_INPUT_CONTROL_VALUE_ACCESSOR$1 = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TextEditorComponent), multi: true, }; class TextEditorComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.label = ''; this.type = undefined; this.required = undefined; this.min = undefined; this.max = undefined; this.minLength = undefined; this.maxLength = undefined; this.height = "150px"; this.toolbarConfig = [ ['bold', 'italic', 'underline'], ['fontName', 'fontSize', 'color'], ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull', 'indent', 'outdent'], ['cut', 'copy', 'delete', 'removeFormat', 'undo', 'redo'], ['horizontalLine', 'orderedList', 'unorderedList'], ['link', 'unlink'] ]; } } TextEditorComponent.decorators = [ { type: Component, args: [{ providers: [INPUT_INPUT_CONTROL_VALUE_ACCESSOR$1], selector: 'text-editor', styles: [`.td-dynamic-input-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-input-wrapper .td-dynamic-input-field{-ms-flex:1;flex:1;box-sizing:border-box}.td-dynamic-input-wrapper .ngx-editor{margin-top:10px}`], template: `<style> .ngx-editor { margin-top: 10px; } </style> <div class="td-dynamic-input-wrapper" style="display: block;"> <label>{{label}} {{required ? '*' : ''}}</label> <app-ngx-editor [(ngModel)]="value" [height]="height" [minHeight]="height" [toolbar]="toolbarConfig" style="width:100%;"> </app-ngx-editor> </div> `, },] }, ]; /** @nocollapse */ TextEditorComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ INPUT_INPUT_CONTROL_VALUE_ACCESSOR$2 = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ColorPickerComponent), multi: true, }; class ColorPickerComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.label = ''; this.type = undefined; this.required = undefined; this.min = undefined; this.max = undefined; this.minLength = undefined; this.maxLength = undefined; this.hideUsedColors = true; } /** * @param {?} value * @return {?} */ selectColor(value) { this.control.setValue(value); } } ColorPickerComponent.decorators = [ { type: Component, args: [{ providers: [INPUT_INPUT_CONTROL_VALUE_ACCESSOR$2], selector: 'color-picker', styles: [`.td-dynamic-input-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-input-wrapper .td-dynamic-input-field{-ms-flex:1;flex:1;box-sizing:border-box}.td-dynamic-input-wrapper .ngx-editor{margin-top:10px}`], template: `<style> .ngx-editor { margin-top: 10px; } </style> <div class="td-dynamic-input-wrapper" style="display: block;"> <label style="display: block; margin-right: 10px;">{{label}} {{required ? '*' : ''}}</label> <mcc-color-picker [selectedColor]="value" (selected)="selectColor($event)" [hideUsedColors]="hideUsedColors"></mcc-color-picker> </div> `, },] }, ]; /** @nocollapse */ ColorPickerComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ DATEPICKER_INPUT_CONTROL_VALUE_ACCESSOR$1 = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TimePickerComponent), multi: true, }; class TimePickerComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.label = ''; this.type = undefined; this.required = undefined; this.min = undefined; this.max = undefined; this.format = 24; } /** * @param {?} value * @return {?} */ selectValue(value) { this.control.setValue(value); } } TimePickerComponent.decorators = [ { type: Component, args: [{ providers: [DATEPICKER_INPUT_CONTROL_VALUE_ACCESSOR$1], selector: 'td-time-picker', styles: [`.td-dynamic-timepicker-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-timepicker-wrapper .td-dynamic-timepicker-field{-ms-flex:1;flex:1;box-sizing:border-box}`], template: `<div class="td-time-picker"> <mat-form-field class="td-dynamic-timepicker-field"> <input matInput [(ngModel)]="value" (ngModelChange)="selectValue($event)" [format]="format" [ngxTimepicker]="pickerT" [placeholder]="label" [required]="required" [min]="min" [max]="max" autocomplete="off"/> <ngx-material-timepicker #pickerT></ngx-material-timepicker> </mat-form-field> </div> `, },] }, ]; /** @nocollapse */ TimePickerComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ moment$1 = moment; const /** @type {?} */ DATEPICKER_INPUT_CONTROL_VALUE_ACCESSOR$2 = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateTimePickerComponent), multi: true, }; class DateTimePickerComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.label = ''; this.type = undefined; this.required = undefined; this.min = undefined; this.max = undefined; this.format = 24; this.dateTime = moment$1.utc(); this.dateValue = null; this.timeValue = ''; } /** * @return {?} */ ngOnInit() { if (this.value) { this.dateTime = this.value; this.initValues(); } else { this.dateTime = moment$1.utc(); this.control.setValue(this.dateTime); } } /** * @return {?} */ initValues() { this.dateValue = moment$1.utc(this.dateTime.clone()); this.timeValue = this.dateTime.format('HH:mm'); } /** * @param {?} value * @return {?} */ selectDateValue(value) { if (this.dateTime == null) { this.dateTime = moment$1.utc(); } this.dateTime.year(value.year()).month(value.month()).date(value.date()); this.control.setValue(this.dateTime); } /** * @param {?} value * @return {?} */ selectTimeValue(value) { let /** @type {?} */ timeMoment = moment$1.utc(this.timeValue, 'HH:mm'); if (this.dateTime == null) { this.dateTime = moment$1.utc(); } this.dateTime.hour(timeMoment.hour()).minute(timeMoment.minute()).second(timeMoment.second()); this.control.setValue(this.dateTime); } } DateTimePickerComponent.decorators = [ { type: Component, args: [{ providers: [DATEPICKER_INPUT_CONTROL_VALUE_ACCESSOR$2], selector: 'td-date-time-picker', styles: [`.td-dynamic-timepicker-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-timepicker-wrapper .td-dynamic-timepicker-field{-ms-flex:1;flex:1;box-sizing:border-box}`], template: `<style> .timeLabel { display: block; margin-bottom: 5px; color: rgba(0, 0, 0, 0.54); font-size: 11px; } .timeInput { border: none; border-bottom: 1px solid rgba(0, 0, 0, 0.54); width: 201px; } .timeIcon { display: inline-flex; vertical-align: middle; } </style> <div class="td-dynamic-datepicker-wrapper"> <label>{{label}}</label> <br /> <br /> <mat-form-field class="td-dynamic-datepicker-field"> <input #elementInput matInput [matDatepicker]="dynamicDatePicker" autocomplete="off" [(ngModel)]="dateValue" (ngModelChange)="selectDateValue($event)" placeholder="Fecha" [required]="required" [min]="min" [max]="max" /> <mat-datepicker-toggle matSuffix [for]="dynamicDatePicker"></mat-datepicker-toggle> <mat-datepicker #dynamicDatePicker></mat-datepicker> </mat-form-field> <br /> <label class="timeLabel">Hora</label> <input class="timeInput" [ngxTimepicker]="pickerDT" [(ngModel)]="timeValue" (ngModelChange)="selectTimeValue($event)" [disableClick]="true" readonly [format]="format" [required]="required" autocomplete="off" /> <ngx-material-timepicker-toggle class="timeIcon" [for]="pickerDT"></ngx-material-timepicker-toggle> <ngx-material-timepicker #pickerDT></ngx-material-timepicker> </div> `, },] }, ]; /** @nocollapse */ DateTimePickerComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class TranslateDialogComponent { /** * @param {?} dialogRef * @param {?} data */ constructor(dialogRef, data) { this.dialogRef = dialogRef; this.data = data; this.remainingLangs = []; this.selectedLang = ''; if (this.data && this.data.langs) { this.remainingLangs = this.data.langs; } } /** * @return {?} */ ngOnInit() { } } TranslateDialogComponent.decorators = [ { type: Component, args: [{ selector: 'translate-dialog', template: `<h4 mat-dialog-title>{{'newLanguage' | translate}}</h4> <div mat-dialog-content> <mat-form-field> <mat-select placeholder="{{'language' | translate}}" [(ngModel)]="selectedLang"> <mat-option *ngFor="let lang of remainingLangs" [value]="lang"> {{lang | translate}} </mat-option> </mat-select> </mat-form-field> </div> <div mat-dialog-actions> <button mat-button style="float:right;" (click)="dialogRef.close(selectedLang)">OK</button> </div> ` },] }, ]; /** @nocollapse */ TranslateDialogComponent.ctorParameters = () => [ { type: MatDialogRef, }, { type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ INPUT_INPUT_CONTROL_VALUE_ACCESSOR$3 = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TranslateComponent), multi: true, }; class TranslateComponent extends AbstractControlValueAccessor { /** * @param {?} dialog * @param {?} changeDetector */ constructor(dialog, changeDetector) { super(); this.dialog = dialog; this.changeDetector = changeDetector; this.height = "150px"; this.toolbarConfig = [ ['bold', 'italic', 'underline'], ['fontName', 'fontSize', 'color'], ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull', 'indent', 'outdent'], ['cut', 'copy', 'delete', 'removeFormat', 'undo', 'redo'], ['horizontalLine', 'orderedList', 'unorderedList'], ['link', 'unlink'] ]; this.label = ''; this.type = undefined; this.required = undefined; this.min = undefined; this.max = undefined; this.minLength = undefined; this.maxLength = undefined; this.langs = ['es']; //TODO: Guachau... this.allLangs = ['es', 'en', 'fr', 'de']; this.selectedIndex = 0; this.selectedLang = ''; this.templateType = ''; } /** * @return {?} */ ngOnInit() { this.selectedLang = this.langs[0]; this.templateType = TranslateComponent.getTemplateType(this.type); this.initValue(this.value); } /** * @param {?} arr * @param {?} value * @return {?} */ inArray(arr, value) { return arr.indexOf(value) > -1; } /** * @param {?} value * @return {?} */ initValue(value) { this.valuesJSON = {}; if (value) { if (typeof value === 'string') { value = JSON.parse(value); } this.langs = []; for (let /** @type {?} */ lang in value) { if (this.inArray(this.allLangs, lang)) { this.langs.push(lang); } } } for (let /** @type {?} */ lang of this.langs) { if (value) { this.valuesJSON[lang] = (value[lang] || ''); } else { this.valuesJSON[lang] = ''; } } this.values = this.parseInit(this.valuesJSON); let /** @type {?} */ jsonValue = JSON.stringify(this.valuesJSON); this.control.setValue(jsonValue); } /** * @param {?} valuesJSON * @return {?} */ parseInit(valuesJSON) { let /** @type {?} */ values = {}; for (let /** @type {?} */ lang in valuesJSON) { values[lang] = this.parseValue(valuesJSON[lang]); } return values; } /** * @param {?} value * @return {?} */ parseValue(value) { if (this.templateType == 'file-input') { return undefined; } else { return value; } } /** * @param {?} type * @return {?} */ static getTemplateType(type) { switch (type) { case 'text': case 'input': return 'input'; case 'textarea': return 'area'; case 'text-editor': return 'editor'; case 'file-input': return 'file-input'; default: return ''; } } /** * @param {?} lang * @return {?} */ selectLang(lang) { let /** @type {?} */ index = this.langs.findIndex(row => { return row == lang; }); if (index != this.selectedIndex) { this.selectedIndex = index; } } /** * @return {?} */ addLang() { let /** @type {?} */ langs = this.langs; let /** @type {?} */ remLangs = this.allLangs.filter(x => { return !this.inArray(langs, x); }); this.openDialog(remLangs); } /** * @param {?} lang * @return {?} */ removeLang(lang) { if (this.langs.length <= 1) { return; } let /** @type {?} */ index = this.langs.findIndex(row => { return row == lang; }); if (index !== -1) { this.langs.splice(index, 1); delete this.values[lang]; delete this.valuesJSON[lang]; if (index == this.selectedIndex) { this.selectedIndex = 0; this.selectedLang = this.langs[0]; } else { this.selectLang(this.selectedLang); } let /** @type {?} */ jsonValue = JSON.stringify(this.valuesJSON); this.control.setValue(jsonValue); } } /** * @param {?} remLangs * @return {?} */ openDialog(remLangs) { let /** @type {?} */ data = { langs: remLangs }; let /** @type {?} */ dialogRef = this.dialog.open(TranslateDialogComponent, { data: data }); dialogRef.afterClosed().subscribe(lang => { if (lang) { this.valuesJSON[lang] = ''; this.values[lang] = this.parseValue(this.valuesJSON[lang]); this.langs.push(lang); this.changeDetector.detectChanges(); this.selectLang(lang); } }); } /** * @param {?} newValue * @param {?} lang * @return {?} */ changeValue(newValue, lang) { return __awaiter(this, void 0, void 0, function* () { if (newValue instanceof File) { this.valuesJSON[lang] = yield TranslateComponent.toBase64(newValue); } else if (newValue == undefined) { this.valuesJSON[lang] = ''; } else { this.valuesJSON[lang] = newValue; } let /** @type {?} */ jsonValue = JSON.stringify(this.valuesJSON); this.control.setValue(jsonValue); }); } /** * @param {?} value * @return {?} */ static toBase64(value) { return __awaiter(this, void 0, void 0, function* () { let /** @type {?} */ myReader = new FileReader(); let /** @type {?} */ image = ''; let /** @type {?} */ promise = new Promise(resolve => { myReader.onloadend = (e) => { image = myReader.result; resolve(image); }; myReader.readAsDataURL(value); }); return promise; }); } } TranslateComponent.decorators = [ { type: Component, args: [{ providers: [INPUT_INPUT_CONTROL_VALUE_ACCESSOR$3], selector: 'translate', styles: [`.td-dynamic-input-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-input-wrapper .td-dynamic-input-field{-ms-flex:1;flex:1;box-sizing:border-box}`], template: `<style> .ngx-editor { margin-top: 10px; } </style> <div class="td-translatable"> <label>{{label}}</label> <mat-tab-group #tabGroup class="tab-group" dynamicHeight [(selectedIndex)]="selectedIndex"> <mat-tab *ngFor="let lang of langs"> <ng-template matTabLabel> <span (click)="selectLang(lang)">{{lang | translate}}</span> <mat-icon (click)="removeLang(lang)" style="vertical-align: middle; margin-left: 10px;">close</mat-icon> </ng-template> <div style="width:100%;" [ngSwitch]="templateType"> <ng-template ngSwitchCase="input"> <div class="td-dynamic-input-wrapper"> <mat-form-field class="td-dynamic-input-field"> <input #elementInput matInput autocomplete="off" [(ngModel)]="values[lang]" (ngModelChange)="changeValue($event, lang)" [type]="type" [required]="required" [attr.min]="min" [attr.max]="max" [attr.minLength]="minLength" [attr.maxLength]="maxLength"/> </mat-form-field> </div> </ng-template> <ng-template ngSwitchCase="area"> <div class="td-dynamic-textarea-wrapper"> <mat-form-field class="td-dynamic-textarea-field" style="width:100%;"> <textarea #elementInput matInput [(ngModel)]="values[lang]" (ngModelChange)="changeValue($event, lang)" [required]="required" rows="4"> </textarea> </mat-form-field> </div> </ng-template> <ng-template ngSwitchCase="editor"> <div class="td-dynamic-input-wrapper" style="display: block;"> <app-ngx-editor [(ngModel)]="values[lang]" (ngModelChange)="changeValue($event, lang)" [height]="height" [minHeight]="height" [toolbar]="toolbarConfig" style="width:100%;"> </app-ngx-editor> </div> </ng-template> <ng-template ngSwitchCase="file-input"> <div class="td-dynamic-file-input-wrapper" style="display: flex;"> <mat-form-field tdFileDrop class="td-dynamic-file-input-field" floatLabel="never" (fileDrop)="values[lang] = $event" (click)="fileInput.inputElement.click()" (keyup.enter)="fileInput.inputElement.click()" (keyup.delete)="fileInput.clear()" (keyup.backspace)="fileInput.clear()"> <input matInput autocomplete="off" [value]="values[lang]?.name" [placeholder]="label" readonly /> </mat-form-field> <button style="align-self: center;" mat-icon-button *ngIf="values[lang]" (click)="fileInput.clear(); changeValue(undefined,lang);" (keyup.enter)="fileInput.clear()"> <mat-icon>cancel</mat-icon> </button> <td-file-input style="align-self:center; margin-left:10px;" class="td-file-input" #fileInput [(ngModel)]="values[lang]" (ngModelChange)="changeValue($event, lang)"> <mat-icon>folder</mat-icon> <span>{{ label }}</span> </td-file-input> </div> </ng-template> <ng-template ngSwitchDefault> <div class="td-dynamic-input-wrapper"> <mat-form-field class="td-dynamic-input-field"> <input #elementInput autocomplete="off" matInput [(ngModel)]="values[lang]" (ngModelChange)="changeValue($event, lang)" [type]="type" [required]="required" [attr.min]="min" [attr.max]="max" [attr.minLength]="minLength" [attr.maxLength]="maxLength"/> </mat-form-field> </div> </ng-template> </div> </mat-tab> <mat-tab [disabled]=true> <ng-template matTabLabel><mat-icon (click)="addLang()" style="color: #000000;">add</mat-icon></ng-template> </mat-tab> </mat-tab-group> </div> `, },] }, ]; /** @nocollapse */ TranslateComponent.ctorParameters = () => [ { type: MatDialog, }, { type: ChangeDetectorRef, }, ]; TranslateComponent.propDecorators = { "tabGroup": [{ type: ViewChild, args: ['tabGroup',] },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ INPUT_INPUT_CONTROL_VALUE_ACCESSOR$4 = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => FormOrganizationComponent), multi: true, }; class FormOrganizationComponent extends AbstractControlValueAccessor { constructor() { super(...arguments); this.label = ''; this.type = undefined; this.required = undefined; this.hasFilter = false; this.hasButtons = true; this.editable = true; this.multiple = false; this.saveable = false; this.expandible = true; this.collapsable = true; this.nodes = []; this.extraFields = []; } /** * @return {?} */ ngOnInit() { if (this.value) { this.nodes = this.value; } } /** * @param {?} nodes * @return {?} */ onUpdate(nodes) { if (nodes.length > 0) { this.control.setValue(nodes); } else { this.control.setValue(null); } } } FormOrganizationComponent.decorators = [ { type: Component, args: [{ providers: [INPUT_INPUT_CONTROL_VALUE_ACCESSOR$4], selector: 'form-organization', styles: [`.td-dynamic-input-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-input-wrapper .td-dynamic-input-field{-ms-flex:1;flex:1;box-sizing:border-box}.td-dynamic-input-wrapper .ngx-editor{margin-top:10px}`], template: `<style> </style> <div class="td-dynamic-input-wrapper" style="display: block;"> <label>{{label}} {{required ? '*' : ''}}</label> <covalent-organization [hasFilter]="hasFilter" [hasButtons]="hasButtons" [editable]="editable" [multiple]="multiple" [saveable]="saveable" [expandible]="expandible" [collapsable]="collapsable" [nodes]="nodes" [extraFields]="extraFields" (updater)="onUpdate($event)"> </covalent-organization> </div> `, },] }, ]; /** @nocollapse */ FormOrganizationComponent.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const /** @type {?} */ SELECT_TOGGLE_INPUT_CONTROL_VALUE_ACCESSOR$1 = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => GallerySelectorComponent), multi: true, }; class GallerySelectorComponent extends AbstractControlValueAccessor { /** * @param {?} changeDetector */ constructor(changeDetector) { super(); this.changeDetector = changeDetector; this.label = ''; this.required = undefined; this.flex = 100; this.flexPerc = this.flex / 100; this.id = ''; this.thumb = ''; } /** * @param {?} result * @return {?} */ assignValue(result) { this.value = result; this.control.setValue(this.value); if (result.id) { this.id = result.id; } if (result.thumb) { this.thumb = result.thumb; } } /** * @return {?} */ ngOnInit() { this.assignValue(this.value); } /** * @return {?} */ openGallery() { this.action(this.control.parent.value).then(result => { if (result != null && result != undefined && result != {}) { this.assignValue(result); } this.changeDetector.detectChanges(); }); } } GallerySelectorComponent.decorators = [ { type: Component, args: [{ providers: [SELECT_TOGGLE_INPUT_CONTROL_VALUE_ACCESSOR$1], selector: 'gallery-selector', styles: [`.td-dynamic-gallery-selector-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-gallery-selector-wrapper img{background:#ddd;width:36px;height:36px;border-radius:5px;margin-right:10px}`], template: `<div class="td-dynamic-gallery-selector-wrapper"> <img [src]="thumb" /> <button mat-raised-button color="primary" (click)="openGallery()"> {{label}} </button> </div>`, },] }, ]; /** @nocollapse */ GallerySelectorComponent.ctorParameters = () => [ { type: ChangeDetectorRef, }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Flat to-do item node with expandable and level information */ class ItemFlatNode { } const /** @type {?} */ INPUT_INPUT_CONTROL_VALUE_ACCESSOR$5 = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TreeSelectorComponent), multi: true, }; class TreeSelectorComponent extends AbstractControlValueAccessor { /** * @param {?} translator * @param {?} dialog * @param {?} changeDetector */ constructor(translator, dialog, changeDetector) { super(); this.translator = translator; this.dialog = dialog; this.changeDetector = changeDetector; /** * Map from flat node to nested node. This helps us finding the nested node to be modified */ this.flatNodeMap = new Map(); /** * Map from nested node to flattened node. This helps us to keep the same object for selection */ this.nestedNodeMap = new Map(); /** * A selected parent node to be inserted */ this.selectedParent = null; /** * The selection for checklist */ this.checklistSelection = new SelectionModel(true /* multiple */); this.selectMultiple = false; /** * Component Attributes */ this.label = ''; //Search attributes (not components) this.flattenedItems = []; //Nodo padre de todos this.masterNode = 0; //Elementos a devolver this.outputItems = []; //Preview Selected this.outputPreview = []; //Funcionamiento interno del arbol this.getLevel = (node) => node.level; this.isExpandable = (node) => node.expandable; this.getChildren = (node) => of(node.children); this.hasChild = (_, _nodeData) => _nodeData.expandable; this.hasNoContent = (_, _nodeData) => _nodeData.name === ''; /** * Transformer to convert nested node to flat node. Record the nodes in maps for later use. */ this.transformer = (node, level) => { const /** @type {?} */ existingNode = this.nestedNodeMap.get(node); const /** @type {?} */ flatNode = existingNode && existingNode.id === node.id ? existingNode : new ItemFlatNode(); flatNode.id = node.id; flatNode.name = node.name; flatNode.parent = node.parent; flatNode.checked = node.checked; flatNode.children = node.children; flatNode.level = level; flatNode.expandable = !!node.children; this.flatNodeMap.set(flatNode, node); this.nestedNodeMap.set(node, flatNode); return flatNode; }; this.treeFlattener = new MatTreeFlattener(this.transformer, this.getLevel, this.isExpandable, this.getChildren); this.treeControl = new FlatTreeControl(this.getLevel, this.isExpandable); this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); } /** * @return {?} */ ngOnInit() { if (this.treeItems != null && this.treeItems.length > 0) { //Generamos los nodos let /** @type {?} */ treeItems = this.generateTree(this.treeItems[0], null); this.dataSource.data = treeItems; //Cogemos el nodo padre de todos this.masterNode = this.treeItems[0].id; this.flattenedItems = this.flattenItems(this.treeItems); //Cargamos los nodos seleccionados if (this.control.value != null) { this.loadData(); } } } /** * @param {?} items * @return {?} */ flattenItems(items) { let /** @type {?} */ flattened = []; for (let /** @type {?} */ item of items) { flattened.push({ id: item.id, name: item.name }); let /** @type {?} */ childFlattened = this.flattenItems(item.children); flattened.push(...childFlattened); } return flattened; } /** * @return {?} */ get selectItems() { //TODO: Solo selectMultiple=false if (this.value) { return this.value[0]; } else { return []; } } /** * @param {?} value * @return {?} */ set selectItems(value) { //TODO: Solo selectMultiple=false if (value) { this.value = [value]; } else { this.value = []; } this.loadSearchData(); } /** * @return {?} */ loadSearchData() { let /** @type {?} */ checked = JSON.parse(JSON.stringify(this.value)); let /** @type {?} */ outputPreview = []; for (let /** @type {?} */ j = 0; j < this.treeControl.dataNodes.length; j++) { if (checked.includes(this.treeControl.dataNodes[j].id)) { this.treeControl.dataNodes[j].checked = true; outputPreview.push({ name: this.treeControl.dataNodes[j].name }); } else { this.treeControl.dataNodes[j].checked = false; } } this.outputPreview = outputPreview; } /** * @param {?} input * @param {?} parent * @return {?} */ generateTree(input, parent) { let /** @type {?} */ output = new ItemFlatNode(); output.id = input.id; output.name = input.name; output.parent = parent; output.checked = input.checked; output.children = input.children; if (input.children.length > 0) { output.children = []; } for (var /** @type {?} */ i in input.children) { output.children.push(...this.generateTree(input.children[i], input.id)); } return [output]; } /** * @param {?} node * @param {?} status * @return {?} */ refrescaPadre(node, status) { let /** @type {?} */ nodoPadre = null; if (status == true) { if (node != null) { for (let /** @type {?} */ i = 0; i < this.treeControl.dataNodes.length; i++) { if (this.treeControl.dataNodes