@noaestudio/forms
Version:
Dynamic forms extension for Covalent
1,481 lines (1,436 loc) • 386 kB
JavaScript
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