UNPKG

@recursyve/forms-frontend

Version:
813 lines (790 loc) 54.7 kB
import { __decorate, __awaiter } from 'tslib'; import { Overlay, OverlayModule } from '@angular/cdk/overlay'; import { CdkColumnDef } from '@angular/cdk/table'; import { CommonModule } from '@angular/common'; import { EventEmitter, Input, Output, Component, ViewEncapsulation, Injectable, ViewChild, HostBinding, Directive, Pipe, NgModule } from '@angular/core'; import { FlexModule } from '@angular/flex-layout'; import { FormsModule } from '@angular/forms'; import { MatButtonModule, MatCardModule, MatCheckboxModule, MatDatepickerModule, MatFormFieldModule, MatIconModule, MatInputModule, MatLineModule, MatNativeDateModule, MatProgressSpinnerModule, MatSelectModule, MatTableModule, MatTooltipModule, MatBadgeModule } from '@angular/material'; import { MatCarouselComponent, MatCarouselModule } from '@ngmodule/material-carousel'; import { TranslateModule } from '@ngx-translate/core'; import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker'; import { v4 } from 'uuid'; import { isNullOrUndefined as isNullOrUndefined$1 } from 'util'; import idx from 'idx'; import { ComponentPortal } from '@angular/cdk/portal'; import { BehaviorSubject } from 'rxjs'; import { DomSanitizer } from '@angular/platform-browser'; class FormViewBase { constructor() { this.editable = false; this.onValueChange = new EventEmitter(); } onModelChange(value) { if (this.config) { if (!isNullOrUndefined$1(value)) { if (!this.model) { this.model = { value }; } else { this.model.value = value; } } this.onValueChange.emit({ key: this.config.keyName, viewModel: this.model }); } } } __decorate([ Input() ], FormViewBase.prototype, "config", void 0); __decorate([ Input() ], FormViewBase.prototype, "model", void 0); __decorate([ Input() ], FormViewBase.prototype, "editable", void 0); __decorate([ Output() ], FormViewBase.prototype, "onValueChange", void 0); let CheckboxComponent = class CheckboxComponent extends FormViewBase { constructor() { super(); this.id = v4(); } ngOnInit() { if (!this.model) { this.model = { value: null }; } if (this.config.typeConfig.multi && (this.model.value === null || this.model.value === undefined)) { this.model.value = []; } if (this.config.typeConfig.multi && typeof this.model.value === "number") { this.model.value = [this.model.value]; } } onCheck(optionValue) { if (this.config.typeConfig.multi) { if (this.model.value.includes(optionValue)) { const valueIndex = this.model.value.indexOf(optionValue); if (valueIndex >= 0) { this.model.value.splice(valueIndex, 1); } } else { this.model.value.push(optionValue); } } else { if (this.model.value === optionValue) { this.model.value = null; } else { this.model.value = optionValue; } } this.onModelChange(); } isChecked(optionValue) { if (this.config.typeConfig.multi) { return this.model.value.indexOf(optionValue) >= 0; } else { return this.model.value === optionValue; } } }; CheckboxComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-checkbox", template: "<div class=\"form-view\" mat-line fxLayout=\"column\" fxLayoutAlign=\"start start\">\n <div class=\"form-view-title\">\n <h4>\n <strong [innerHTML]=\"config?.title | trust: 'html'\"></strong>\n </h4>\n </div>\n <div fxLayout=\"row wrap\" fxLayoutAlign=\"start center\" fxLayoutGap=\"5px\" class=\"form-view-content\">\n <ng-container *ngFor=\"let option of config?.typeConfig?.options\">\n <div class=\"checkbox-line\" fxFlex=\"1 1 calc(50% - 5px)\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <mat-checkbox\n fxFlex=\"0 1 auto\"\n id=\"{{id}}{{option.value}}\"\n [checked]=\"isChecked(option.value)\"\n (change)=\"onCheck(option.value)\"\n [disabled]=\"!editable\">\n <div [innerHTML]=\"option.text | trust: 'html'\"></div>\n </mat-checkbox>\n <tooltip fxFlex=\"1 0 auto\" [tooltipContent]=\"option.description\"></tooltip>\n </div>\n </ng-container>\n </div>\n</div>\n", styles: [".mat-checkbox span{word-break:normal;white-space:normal}.checkbox-line{min-height:40px;min-width:200px!important}"] }) ], CheckboxComponent); let GeolocationService = class GeolocationService { getCurrentGeolocation(options) { return new Promise((resolve, reject) => { navigator.geolocation.getCurrentPosition(position => { resolve(position); }, positionError => { reject(positionError); }, options); }); } }; GeolocationService = __decorate([ Injectable() ], GeolocationService); let CoordComponent = class CoordComponent extends FormViewBase { constructor(geolocationService) { super(); this.geolocationService = geolocationService; } ngOnInit() { this.initModel(); } initModel() { if (!this.model) { this.model = { value: {} }; } else if (!this.model.value) { this.model.value = {}; } return true; } onLatitudeChange(value) { this.model.value.latitude = value; this.onModelChange(); } onLongitudeChange(value) { this.model.value.longitude = value; this.onModelChange(); } setCoordWithDevice() { this.geolocationService.getCurrentGeolocation().then(position => { this.model.value.latitude = position.coords.latitude; this.model.value.longitude = position.coords.longitude; this.onModelChange(); }); } }; CoordComponent.ctorParameters = () => [ { type: GeolocationService } ]; CoordComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-coord", template: "<div mat-line fxLayout=\"column\" fxLayoutAlign=\"start start\" class=\"form-view\">\n <div class=\"form-view-title\">\n <h4>\n <strong [innerHTML]=\"config?.title | trust: 'html'\"></strong>s\n </h4>\n </div>\n <div fxLayout=\"column\" fxLayoutAlign=\"start start\" fxLayoutGap=\"5px\" class=\"form-view-content coord-content\">\n <ng-container *ngIf=\"editable\">\n <div fxLayout=\"row wrap\" fxLayoutAlign=\"start center\" fxLayoutGap=\"5px\" class=\"fullWidth\">\n <mat-form-field fxFlex=\"calc(50% - 5px)\">\n <input\n matInput\n [placeholder]=\"'recursyve_forms.components.coord.latitude' | translate\"\n [ngModel]=\"model?.value?.latitude\"\n (ngModelChange)=\"onLatitudeChange($event)\"\n />\n </mat-form-field>\n <mat-form-field fxFlex=\"50%\">\n <input\n matInput\n [placeholder]=\"'recursyve_forms.components.coord.longitude' | translate\"\n [ngModel]=\"model?.value?.longitude\"\n (ngModelChange)=\"onLongitudeChange($event)\"\n />\n </mat-form-field>\n </div>\n <button mat-raised-button color=\"accent\" (click)=\"setCoordWithDevice()\">\n {{ \"recursyve_forms.components.coord.update_with_user_location\" | translate }}\n <mat-icon class=\"material-icons\">my_location</mat-icon>\n </button>\n </ng-container>\n <ng-container *ngIf=\"!editable\">\n <div fxLayout=\"row wrap\" fxLayoutAlign=\"start center\" fxLayoutGap=\"5px\" class=\"fullWidth\">\n <div fxFlex=\"calc(50% - 5px)\">\n <span>\n {{ \"recursyve_forms.components.coord.latitude\" | translate | titlecase }}: {{\n model.value.latitude || (\"recursyve_forms.general.not_available\" | translate) }}\n </span>\n </div>\n <div fxFlex=\"50%\">\n <span>\n {{ \"recursyve_forms.components.coord.longitude\" | translate | titlecase }}: {{\n model.value.longitude || (\"recursyve_forms.general.not_available\" | translate) }}\n </span>\n </div>\n </div>\n </ng-container>\n </div>\n</div>\n", styles: [".coord-content mat-form-field{min-width:100px!important}"] }) ], CoordComponent); let DateComponent = class DateComponent extends FormViewBase { constructor() { super(); } ngOnInit() { if (!this.model) { this.model = { value: new Date() }; } else if (!this.model.value) { this.model.value = new Date(); } } }; DateComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-date", template: "<div mat-line fxLayout=\"column\" fxLayoutAlign=\"start start\" class=\"form-view\">\n <div class=\"form-view-title\">\n <h4>\n <strong>\n <strong [innerHTML]=\"config?.title | trust: 'html'\"></strong>\n </strong>\n </h4>\n </div>\n <div class=\"form-view-content date-content\">\n <ng-container *ngIf=\"editable\">\n <mat-form-field>\n <input\n matInput\n #date_picker_input\n [value]=\"model.value\"\n (dateChange)=\"onModelChange($event.value)\"\n [matDatepicker]=\"date_picker\"\n (focus)=\"date_picker.open()\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"date_picker\"></mat-datepicker-toggle>\n <mat-datepicker #date_picker (closed)=\"date_picker_input.blur()\"></mat-datepicker>\n </mat-form-field>\n </ng-container>\n <ng-container *ngIf=\"!editable\">\n <span>\n {{ (model.value | date: 'fullDate') || (\"recursyve_forms.general.not_available\" | translate) }}\n </span>\n </ng-container>\n </div>\n</div>\n", styles: [".date-content mat-form-field{width:100%}"] }) ], DateComponent); let DropdownComponent = class DropdownComponent extends FormViewBase { constructor() { super(); } ngOnInit() { if (!this.model) { this.model = {}; } } onSelectOption(matSelectChange) { const option = matSelectChange.value; if (this.config) { if (!this.model) { this.model = { value: option.value }; } else { this.model.value = option.value; } this.onModelChange(); } } getSelectedOption() { return this.config.typeConfig.options.find(option => option.value === this.model.value); } }; DropdownComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-dropdown", template: "<div mat-line fxLayout=\"column\" fxLayoutAlign=\"start start\" class=\"form-view\">\n <div class=\"form-view-title\">\n <h4>\n <strong>\n <strong [innerHTML]=\"config?.title | trust: 'html'\"></strong>\n </strong>\n </h4>\n </div>\n <div class=\"form-view-content dropdown-content\">\n <ng-container *ngIf=\"editable\">\n <div class=\"checkbox-line\" fxFlex=\"1 1 calc(50% - 5px)\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <mat-form-field>\n <mat-select [value]=\"getSelectedOption()\" (selectionChange)=\"onSelectOption($event)\">\n <mat-option *ngFor=\"let option of config?.typeConfig?.options\" [value]=\"option\">\n <div [innerHTML]=\"option?.text | trust: 'html'\"></div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n <tooltip fxFlex=\"1 0 auto\" [tooltipContent]=\"getSelectedOption()?.description\"></tooltip>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!editable\">\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <div fxFlex=\"0 1 auto\" class=\"text-justify\">\n <span *ngIf=\"getSelectedOption()?.text; else noValue\"\n [innerHTML]=\"getSelectedOption().text | trust: 'html'\"\n ></span>\n <ng-template #noValue>\n <span>{{ \"recursyve_forms.general.not_available\" | translate }}</span>\n </ng-template>\n </div>\n <tooltip fxFlex=\"1 0 auto\" [tooltipContent]=\"getSelectedOption()?.description\"></tooltip>\n </div>\n </ng-container>\n </div>\n</div>\n", styles: [".dropdown-content mat-form-field{width:100%}"] }) ], DropdownComponent); var ViewType; (function (ViewType) { ViewType["DATE"] = "date"; ViewType["LONG_TEXT"] = "long_text"; ViewType["SHORT_TEXT"] = "short_text"; ViewType["CHECKBOX"] = "checkbox"; ViewType["PICTURE"] = "picture"; ViewType["TIME"] = "time"; ViewType["GROUP"] = "group"; ViewType["TABLE"] = "table"; ViewType["COORD"] = "coord"; ViewType["DROPDOWN"] = "dropdown"; ViewType["TEXT"] = "text"; })(ViewType || (ViewType = {})); function isNullOrUndefined(value) { return value === null || value === undefined; } let FormViewComponent = class FormViewComponent { constructor() { this.editable = false; this.depth = 0; this.onValueChange = new EventEmitter(); this.types = ViewType; } isTypeOf(type) { return this.config.type === type; } onModelChange(valueChangeEvent) { this.onValueChange.emit(valueChangeEvent); } onAppendableChange(valueChangeEvent) { this.model[valueChangeEvent.key] = valueChangeEvent.viewModel; this.onModelChange({ key: this.config.keyName, viewModel: this.model }); } showAppendable(appendable) { if (appendable.expectedParentValue === null || appendable.expectedParentValue === undefined) { return true; } if (this.config.type === ViewType.CHECKBOX) { const value = idx(this.model, _ => _.value); if (isNullOrUndefined(value)) { return false; } if (this.config.typeConfig.multi) { return value.some(v => v === appendable.expectedParentValue); } return value === appendable.expectedParentValue; } else { return this.model.value === appendable.expectedParentValue; } } }; __decorate([ Input() ], FormViewComponent.prototype, "config", void 0); __decorate([ Input() ], FormViewComponent.prototype, "model", void 0); __decorate([ Input() ], FormViewComponent.prototype, "editable", void 0); __decorate([ Input() ], FormViewComponent.prototype, "depth", void 0); __decorate([ Output() ], FormViewComponent.prototype, "onValueChange", void 0); FormViewComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-view", template: "<ng-container *ngIf=\"config\">\n <form-date\n *ngIf=\"isTypeOf(types.DATE)\"\n [model]=\"model\"\n [config]=\"config\"\n [editable]=\"editable\"\n (onValueChange)=\"onModelChange($event)\"\n ></form-date>\n <form-long-text\n *ngIf=\"isTypeOf(types.LONG_TEXT)\"\n [model]=\"model\"\n [config]=\"config\"\n [editable]=\"editable\"\n (onValueChange)=\"onModelChange($event)\"\n ></form-long-text>\n <form-short-text\n *ngIf=\"isTypeOf(types.SHORT_TEXT)\"\n [model]=\"model\"\n [config]=\"config\"\n [editable]=\"editable\"\n (onValueChange)=\"onModelChange($event)\"\n ></form-short-text>\n <form-checkbox\n *ngIf=\"isTypeOf(types.CHECKBOX)\"\n [model]=\"model\"\n [config]=\"config\"\n [editable]=\"editable\"\n (onValueChange)=\"onModelChange($event)\"\n ></form-checkbox>\n <form-picture\n *ngIf=\"isTypeOf(types.PICTURE)\"\n [model]=\"model\"\n [config]=\"config\"\n [editable]=\"editable\"\n (onValueChange)=\"onModelChange($event)\"\n ></form-picture>\n <form-time\n *ngIf=\"isTypeOf(types.TIME)\"\n [model]=\"model\"\n [config]=\"config\"\n [editable]=\"editable\"\n (onValueChange)=\"onModelChange($event)\"\n ></form-time>\n <form-group\n *ngIf=\"isTypeOf(types.GROUP)\"\n [config]=\"config\"\n [model]=\"model\"\n [editable]=\"editable\"\n [depth]=\"depth + 1\"\n (onValueChange)=\"onModelChange($event)\"\n ></form-group>\n <form-table\n *ngIf=\"isTypeOf(types.TABLE)\"\n [model]=\"model\"\n [config]=\"config\"\n [editable]=\"editable\"\n (onValueChange)=\"onModelChange($event)\"\n ></form-table>\n <form-coord\n *ngIf=\"isTypeOf(types.COORD)\"\n [model]=\"model\"\n [config]=\"config\"\n [editable]=\"editable\"\n (onValueChange)=\"onModelChange($event)\"\n ></form-coord>\n <form-dropdown\n *ngIf=\"isTypeOf(types.DROPDOWN)\"\n [model]=\"model\"\n [config]=\"config\"\n [editable]=\"editable\"\n (onValueChange)=\"onModelChange($event)\"\n ></form-dropdown>\n <form-text *ngIf=\"isTypeOf(types.TEXT)\" [config]=\"config\"></form-text>\n <ng-container *ngIf=\"config?.appendables?.length > 0\">\n <ng-container *ngFor=\"let appendable of config?.appendables\">\n <ng-container *ngIf=\"showAppendable(appendable)\">\n <form-view\n [config]=\"appendable.viewConfig\"\n [model]=\"model[appendable.viewConfig.keyName]\"\n [editable]=\"editable\"\n (onValueChange)=\"onAppendableChange($event)\"\n >\n </form-view>\n </ng-container>\n </ng-container>\n </ng-container>\n</ng-container>\n", styles: [""] }) ], FormViewComponent); let GroupComponent = class GroupComponent extends FormViewBase { constructor() { super(...arguments); this.depth = 0; } getModel(key) { if (!this.model) { this.model = {}; } if (!this.model[key]) { this.onChildModelChange({ key, viewModel: {} }); } return this.model[key]; } onChildModelChange(valueChangeEvent) { if (this.config) { if (!this.model) { this.model = {}; } this.model[valueChangeEvent.key] = valueChangeEvent.viewModel; this.onModelChange(); } } }; __decorate([ Input() ], GroupComponent.prototype, "depth", void 0); GroupComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-group", template: "<ng-container *ngIf=\"config?.typeConfig?.viewConfigs?.length > 0\">\n <ng-container *ngIf=\"depth <= 1\">\n <mat-card>\n <mat-card-header *ngIf=\"config?.title\">\n <mat-card-title>\n <ng-container [ngTemplateOutlet]=\"title\"></ng-container>\n </mat-card-title>\n </mat-card-header>\n <mat-card-content>\n <ng-container [ngTemplateOutlet]=\"content\"></ng-container>\n </mat-card-content>\n </mat-card>\n </ng-container>\n <ng-container *ngIf=\"depth > 1\">\n <div fxLayout=\"column\" fxLayoutAlign=\"start start\">\n <ng-container *ngIf=\"config?.title\" [ngTemplateOutlet]=\"title\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"content\"></ng-container>\n </div>\n </ng-container>\n</ng-container>\n\n<ng-template #title>\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <span *ngIf=\"config?.title\" [innerHTML]=\"config?.title | trust: 'html'\"></span>\n <tooltip [tooltipContent]=\"config.description\"></tooltip>\n </div>\n</ng-template>\n\n<ng-template #content>\n <div display [displayConfig]=\"config?.displayConfig\" [isFlexGroup]=\"true\">\n <ng-container *ngFor=\"let subViewConfig of config?.typeConfig?.viewConfigs\">\n <div display [displayConfig]=\"subViewConfig?.displayConfig\" [isFlexGroupItem]=\"true\">\n <form-view\n [config]=\"subViewConfig\"\n [model]=\"getModel(subViewConfig.keyName)\"\n [editable]=\"editable\"\n [depth]=\"depth\"\n (onValueChange)=\"onChildModelChange($event)\"\n ></form-view>\n </div>\n </ng-container>\n </div>\n</ng-template>\n", styles: [""] }) ], GroupComponent); let LongTextComponent = class LongTextComponent extends FormViewBase { constructor() { super(); } ngOnInit() { if (!this.model) { this.model = { value: "" }; } else if (!this.model.value) { this.model.value = ""; } } }; LongTextComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-long-text", template: "<div mat-line fxLayout=\"column\" fxLayoutAlign=\"start start\" class=\"form-view\">\n <div class=\"form-view-title\">\n <h4>\n <strong [innerHTML]=\"config?.title | trust: 'html'\"></strong>\n </h4>\n </div>\n <div class=\"form-view-content long-text-content\">\n <ng-container *ngIf=\"editable\">\n <mat-form-field>\n <textarea\n matInput\n type=\"text\"\n [ngModel]=\"model.value\"\n (ngModelChange)=\"onModelChange($event)\"\n ></textarea>\n </mat-form-field>\n </ng-container>\n <ng-container *ngIf=\"!editable\">\n <div class=\"text-justify\">\n <span>\n {{ model.value || (\"recursyve_forms.general.not_available\" | translate) }}\n </span>\n </div>\n </ng-container>\n </div>\n</div>\n", styles: [".long-text-content mat-form-field{width:100%}"] }) ], LongTextComponent); let PictureModalComponent = class PictureModalComponent { constructor() { this.selectedPictureIndex = 0; this.editable = false; this.close = new EventEmitter(); } changePicture(newSelectedIndex) { this.selectedPictureIndex = newSelectedIndex; } clickClose() { this.close.emit(); } }; __decorate([ Output() ], PictureModalComponent.prototype, "close", void 0); __decorate([ ViewChild(MatCarouselComponent, { static: true }) ], PictureModalComponent.prototype, "matCarousel", void 0); PictureModalComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-picture-modal", template: "<mat-card>\n <mat-card-content>\n <div fxLayout=\"column\" fxLayoutAlign=\"start center\" fxLayoutGap=\"10px\" class=\"picture-modal-inner-container\">\n <div fxFlex=\"90%\" fxLayoutAlign=\"center center\" class=\"carousel-container\">\n <mat-carousel\n timings=\"250ms ease-in\"\n [autoplay]=\"false\"\n interval=\"5000\"\n color=\"accent\"\n maxWidth=\"auto\"\n proportion=\"88\"\n [slides]=\"pictures.length\"\n [loop]=\"true\"\n [hideArrows]=\"false\"\n [hideIndicators]=\"false\"\n [useKeyboard]=\"true\"\n [useMouseWheel]=\"true\"\n orientation=\"ltr\"\n (change)=\"changePicture($event)\"\n >\n <mat-carousel-slide\n #matCarouselSlide\n *ngFor=\"let picture of pictures\"\n [image]=\"picture\"\n overlayColor=\"#00000000\"\n [hideOverlay]=\"false\"\n ></mat-carousel-slide>\n </mat-carousel>\n </div>\n <div fxFlex=\"10%\" fxLayoutAlign=\"center center\" class=\"action-container\">\n <button mat-raised-button color=\"accent\" (click)=\"clickClose()\">\n {{ \"recursyve_forms.general.close\" | translate }}\n </button>\n </div>\n </div>\n </mat-card-content>\n</mat-card>\n", styles: ["form-picture-modal{height:100%;max-width:750px;margin:auto;width:100%}form-picture-modal mat-card{box-sizing:border-box;height:100%;width:100%}form-picture-modal mat-card mat-card-content{height:100%}form-picture-modal mat-card mat-card-content .picture-modal-inner-container{height:100%;width:100%}form-picture-modal mat-card mat-card-content .picture-modal-inner-container .action-container,form-picture-modal mat-card mat-card-content .picture-modal-inner-container .carousel-container{width:100%}form-picture-modal mat-card mat-card-content .picture-modal-inner-container .carousel-container mat-carousel{height:100%;width:100%}form-picture-modal mat-card mat-card-content .picture-modal-inner-container .carousel-container mat-carousel .carousel .carousel-list>li>div{background-size:contain}"] }) ], PictureModalComponent); let PictureModalService = class PictureModalService { constructor(overlay) { this.overlay = overlay; } open(config) { const positionStrategy = this.overlay .position() .global() .centerHorizontally() .centerVertically(); const overlayRef = this.overlay.create({ backdropClass: "cdk-overlay-dark-backdrop", hasBackdrop: true, positionStrategy, scrollStrategy: this.overlay.scrollStrategies.block(), width: "70%" }); const pictureModalPortal = new ComponentPortal(PictureModalComponent); const pictureModalRef = overlayRef.attach(pictureModalPortal); pictureModalRef.instance.close.subscribe(() => { overlayRef.dispose(); }); pictureModalRef.instance.editable = config.editable; pictureModalRef.instance.pictures = config.pictures; pictureModalRef.instance.selectedPictureIndex = config.selectedIndex; overlayRef.backdropClick().subscribe(() => overlayRef.dispose()); } }; PictureModalService.ctorParameters = () => [ { type: Overlay } ]; PictureModalService = __decorate([ Injectable() ], PictureModalService); class FormStorageInterface { } let PictureComponent = class PictureComponent extends FormViewBase { constructor(pictureModalService, storageService) { super(); this.pictureModalService = pictureModalService; this.storageService = storageService; this.id = v4(); this.pictureUrls = []; this.uploading = false; } ngOnInit() { return __awaiter(this, void 0, void 0, function* () { if (!this.model) { this.model = { value: [] }; } else if (!this.model.value) { this.model.value = []; } if (typeof this.model.value === "string") { this.model.value = [this.model.value]; } for (const storageId of this.model.value) { const url = yield this.storageService.getDownloadUrl(storageId); this.pictureUrls.push(url); } }); } ngAfterViewInit() { const input = document.getElementById(`input-${this.id}`); const button = document.getElementById(`button-${this.id}`); button.addEventListener("click", () => { input.click(); }); } handleFile(fileList) { if (fileList.length <= 0) { return; } this.uploading = true; let uploadCount = 0; const uploaded = () => { uploadCount++; if (uploadCount >= fileList.length) { this.uploading = false; } }; const files = []; for (let i = 0; i < fileList.length; ++i) { files.push(fileList[i]); } files.forEach((file) => __awaiter(this, void 0, void 0, function* () { const storageId = (yield this.storageService.upload(file, "files/work-orders/"))[0]; this.model.value.push(storageId); const url = yield this.storageService.getDownloadUrl(storageId); this.pictureUrls.push(url); this.onModelChange(); uploaded(); })); } clickView(i) { if (this.uploading) { return; } this.pictureModalService.open({ closeIfAllRemoved: true, editable: this.editable, pictures: this.pictureUrls, selectedIndex: i }); } removeImage(i) { this.model.value.splice(i, 1); this.pictureUrls.splice(i, 1); this.onModelChange(); } onModelChange() { this.onValueChange.emit({ key: this.config.keyName, viewModel: this.model }); } }; PictureComponent.ctorParameters = () => [ { type: PictureModalService }, { type: FormStorageInterface } ]; PictureComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-picture", template: "<div mat-line fxLayout=\"column\" fxLayoutAlign=\"start start\" class=\"form-view\">\n <div class=\"form-view-title\">\n <h4>\n <strong [innerHTML]=\"config?.title | trust: 'html'\"></strong>\n </h4>\n </div>\n <div class=\"form-view-content scrolling-carousel\" fxLayout=\"row wrap\" fxLayoutGap=\"10px\">\n <ng-container *ngIf=\"this.pictureUrls && this.pictureUrls.length > 0\">\n <div *ngFor=\"let imageUrl of this.pictureUrls; let i = index;\" fxLayout=\"row\">\n <div class=\"scrolling-carousel-image-container\">\n <img\n class=\"scrolling-carousel-image\"\n [src]=\"imageUrl\"\n (click)=\"clickView(i)\"\n [alt]=\"imageUrl\"\n />\n </div>\n <div class=\"remove-button\" (click)=\"removeImage(i)\" *ngIf=\"editable\">\n <mat-icon class=\"close-icon\">close</mat-icon>\n </div>\n </div>\n </ng-container>\n <div *ngIf=\"!this.pictureUrls || this.pictureUrls.length <= 0\">\n {{ \"recursyve_forms.components.picture.no_picture\" | translate }}\n </div>\n </div>\n <div [hidden]=\"!editable\">\n <input\n id=\"input-{{id}}\"\n (change)=\"handleFile($event.target.files)\"\n type=\"file\"\n accept=\"image/*\"\n multiple\n [disabled]=\"uploading\"\n />\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\" fxLayoutGap=\"5px\">\n <button mat-raised-button id=\"button-{{id}}\" color=\"accent\" [disabled]=\"uploading\">\n {{ (\"recursyve_forms.components.picture.add_picture\" | translate) }}\n </button>\n <mat-spinner [diameter]=\"22\" *ngIf=\"uploading\" color=\"accent\" [mode]=\"'indeterminate'\"></mat-spinner>\n </div>\n </div>\n</div>\n", styles: [".scrolling-carousel{display:block;padding-bottom:1.25em}.scrolling-carousel-image-container{border:1px solid #d3d3d3;border-radius:5px;background-color:#f5f5f5;max-width:300px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;margin-right:auto;margin-top:10px}.scrolling-carousel-image{height:100px;margin:2px 4px}.scrolling-carousel-add{font-size:30px;margin:auto 0 auto 10px}.input-container{margin:1em auto}input[type=file]{display:none;position:absolute}.remove-button{width:24px;height:24px;border-radius:50%;background-color:#f44336;position:relative;top:3px;right:12px;cursor:pointer;box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.close-icon{font-size:15px!important;position:relative;left:5px;top:4px;color:#fff;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}"] }) ], PictureComponent); let ShortTextComponent = class ShortTextComponent extends FormViewBase { constructor() { super(); } ngOnInit() { if (!this.model) { this.model = { value: "" }; } else if (!this.model.value) { this.model.value = ""; } } }; ShortTextComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-short-text", template: "<div mat-line fxLayout=\"column\" fxLayoutAlign=\"start start\" class=\"form-view\">\n <div class=\"form-view-title\">\n <h4>\n <strong [innerHTML]=\"config?.title | trust: 'html'\"></strong>\n </h4>\n </div>\n <div class=\"form-view-content short-text-content\">\n <ng-container *ngIf=\"editable\">\n <mat-form-field>\n <input matInput type=\"text\" [ngModel]=\"model.value\" (ngModelChange)=\"onModelChange($event)\" />\n </mat-form-field>\n </ng-container>\n <ng-container *ngIf=\"!editable\">\n <div class=\"text-justify\">\n <span>\n {{ model.value || (\"recursyve_forms.general.not_available\" | translate) }}\n </span>\n </div>\n </ng-container>\n </div>\n</div>\n", styles: [".short-text-content mat-form-field{width:100%}"] }) ], ShortTextComponent); let TableComponent = class TableComponent extends FormViewBase { constructor() { super(); this.dataSource = new BehaviorSubject([]); } getColHeaders(withDelete = false) { if (withDelete && this.editable) { return this.config.typeConfig.colHeaders.concat(["delete"]); } return this.config.typeConfig.colHeaders; } ngOnInit() { if (!this.model || !this.model.value) { this.model = { value: [Array(this.config.typeConfig.colHeaders.length)] }; this.dataSource.next(this.model.value); this.onModelChange(); } else { this.dataSource.next(this.model.value); } } addRow() { if (!this.model) { this.model = { value: [] }; } this.model.value.push(Array(this.config.typeConfig.colHeaders.length)); this.dataSource.next(this.model.value); this.onModelChange(); } removeRow(index) { if (!this.model) { this.model = { value: [] }; } else { this.model.value.splice(index, 1); } this.dataSource.next(this.model.value); this.onModelChange(); } trackByFn(item) { return item; } }; TableComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-table", template: "<div mat-line fxLayout=\"column\" fxLayoutAlign=\"start start\" class=\"form-view\">\n <div class=\"form-view-title\">\n <h4>\n <strong [innerHTML]=\"config?.title | trust: 'html'\"></strong>\n </h4>\n </div>\n <div fxLayout=\"column\" fxLayoutAlign=\"start start\" fxLayoutGap=\"15px\" class=\"form-view-content\">\n <div class=\"table-container mat-elevation-z4\">\n <table\n mat-table\n [dataSource]=\"dataSource\"\n [trackBy]=\"trackByFn\"\n [class.sticky-column-left-padding]=\"editable\"\n >\n <ng-container [matColumnDef]=\"colDef\" *ngFor=\"let colDef of getColHeaders(); let col = index\">\n <th mat-header-cell *matHeaderCellDef>\n <span [innerHTML]=\"colDef | trust: 'html'\"></span>\n </th>\n <td mat-cell *matCellDef=\"let element; let row = index\">\n <ng-container *ngIf=\"editable\">\n <mat-form-field>\n <input\n matInput\n [disabled]=\"!editable\"\n type=\"text\"\n [(ngModel)]=\"model.value[row][col]\"\n (ngModelChange)=\"this.onModelChange()\"\n />\n </mat-form-field>\n </ng-container>\n <ng-container *ngIf=\"!editable\">\n <div>\n <span>\n {{ model.value[row][col] || (\"recursyve_forms.general.not_available\" | translate) }}\n </span>\n </div>\n </ng-container>\n </td>\n </ng-container>\n\n <ng-container *ngIf=\"editable\">\n <ng-container matColumnDef=\"delete\" stickyEnd>\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let element; let i = index\">\n <button\n mat-icon-button\n color=\"accent\"\n (click)=\"removeRow(i)\"\n [matTooltip]=\"'recursyve_forms.general.delete' | translate\"\n [matTooltipPosition]=\"'above'\"\n >\n <mat-icon color=\"warn\" class=\"material-icons\">close</mat-icon>\n </button>\n </td>\n </ng-container>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"getColHeaders(true); sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: getColHeaders(true);\"></tr>\n </table>\n </div>\n <ng-container *ngIf=\"editable\">\n <button mat-raised-button color=\"accent\" class=\"add-row-button\" (click)=\"addRow()\" *ngIf=\"editable\">\n {{ \"recursyve_forms.components.table.add_row\" | translate }}\n </button>\n </ng-container>\n </div>\n</div>\n", styles: [".table-container{width:100%;max-height:400px;overflow:auto}.table-container .sticky-column-left-padding td:last-of-type{padding-left:.75rem}.table-container table{width:100%}.table-container table th{font-weight:600!important}.table-container table th span{margin-right:.75rem}.table-container table td>*{width:calc(100% - .75rem)}.add-row-button{margin-left:auto}"] }) ], TableComponent); let TextComponent = class TextComponent extends FormViewBase { constructor() { super(); } ngOnInit() { if (!this.model) { this.model = { value: "" }; } else if (!this.model.value) { this.model.value = ""; } } }; TextComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-text", template: "<div *ngIf=\"config?.typeConfig?.text?.length > 0\" [innerHTML]=\"config.typeConfig.text | trust: 'html'\"></div>\n", styles: [""] }) ], TextComponent); let TimeComponent = class TimeComponent extends FormViewBase { constructor() { super(); } ngOnInit() { if (!this.model) { this.model = { value: "00:00" }; } else if (!this.model.value) { this.model.value = "00:00"; } } }; TimeComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "form-time", template: "<div mat-line fxLayout=\"column\" fxLayoutAlign=\"start start\" class=\"form-view\">\n <div class=\"form-view-title\">\n <h4>\n <strong [innerHTML]=\"config?.title | trust: 'html'\"></strong>\n </h4>\n </div>\n <div class=\"form-view-content time-content\">\n <ng-container *ngIf=\"editable\">\n <mat-form-field>\n <input\n matInput\n [(ngModel)]=\"model.value\"\n (ngModelChange)=\"onModelChange()\"\n [ngxTimepicker]=\"toggleTimepicker\"\n [value]=\"model.value\"\n readonly\n />\n <ngx-material-timepicker-toggle matSuffix [for]=\"toggleTimepicker\"></ngx-material-timepicker-toggle>\n <ngx-material-timepicker\n (timeSet)=\"onModelChange($event)\"\n [ESC]=\"true\"\n [enableKeyboardInput]=\"true\"\n #toggleTimepicker\n ></ngx-material-timepicker>\n </mat-form-field>\n </ng-container>\n <ng-container *ngIf=\"!editable\">\n <span>\n {{ model.value || (\"recursyve_forms.general.not_available\" | translate) }}\n </span>\n </ng-container>\n </div>\n</div>\n", styles: [".time-content mat-form-field{width:100%}.time-content mat-form-field .mat-form-field-suffix{height:21px}.time-content mat-form-field ngx-material-timepicker-toggle .ngx-material-timepicker-toggle{padding:0!important;height:100%}.time-content mat-form-field ngx-material-timepicker-toggle .ngx-material-timepicker-toggle svg{height:14px!important;width:14px!important}"] }) ], TimeComponent); let TooltipComponent = class TooltipComponent { toggle(matTooltip) { matTooltip.toggle(); } onHoverIn(matTooltip) { matTooltip.show(); } onHoverOut(matTooltip) { matTooltip.hide(); } }; __decorate([ Input() ], TooltipComponent.prototype, "tooltipContent", void 0); TooltipComponent = __decorate([ Component({ encapsulation: ViewEncapsulation.None, selector: "tooltip", template: "<ng-container *ngIf=\"tooltipContent && tooltipContent.length > 0\">\n <button\n mat-icon-button\n (click)=\"toggle(tooltip)\"\n (mouseenter)=\"onHoverIn(tooltip)\"\n (mouseleave)=\"onHoverOut(tooltip)\"\n #tooltip=\"matTooltip\"\n [matTooltip]=\"tooltipContent\"\n matTooltipPosition=\"right\"\n >\n <mat-icon color=\"accent\" class=\"material-icons\">help_outline</mat-icon>\n </button>\n</ng-container>\n", styles: [".mat-tooltip{font-size:14px}.checkbox-line{min-height:40px}mat-icon{margin-bottom:4px}"] }) ], TooltipComponent); let DisplayDirective = class DisplayDirective { constructor() { this.isFlexGroup = false; this.isFlexGroupItem = false; this.applyBasicStyling = true; } ngOnInit() { this.updateStyle(); } updateStyle() { this.updateBasicStyling(); this.updateFlexGroupStyling(); this.updateFlexGroupItemStyling(); } updateBasicStyling() { if (!this.applyBasicStyling) { return; } this.display = this.safeGet(_ => _.display, "block"); this.width = this.safeGet(_ => _.width.width, "auto"); this.minWidth = this.safeGet(_ => _.width.minWidth, "0"); this.maxWidth = this.safeGet(_ => _.width.maxWidth, "none"); this.height = this.safeGet(_ => _.height.height, "auto"); this.minHeight = this.safeGet(_ => _.height.minHeight, "0"); this.maxHeight = this.safeGet(_ => _.height.maxHeight, "none"); this.marginTop = this.safeGet(_ => _.margin.top, this.safeGet(_ => _.margin.margin, "0")); this.marginRight = this.safeGet(_ => _.margin.right, this.safeGet(_ => _.margin.margin, "0")); this.marginBottom = this.safeGet(_ => _.margin.bottom, this.safeGet(_ => _.margin.margin, "0")); this.marginLeft = this.safeGet(_ => _.margin.left, this.safeGet(_ => _.margin.margin, "0")); } updateFlexGroupStyling() { if (!this.isFlexGroup || !this.safeGet(_ => _.fxConfig.flexGroup, null)) { return; } this.display = "flex"; this.flexDirection = this.safeGet(_ => _.fxConfig.flexGroup.layout.direction, "row"); this.flexWrap = this.safeGet(_ => _.fxConfig.flexGroup.layout.wrap, "nowrap"); this.justifyContent = this.safeGet(_ => _.fxConfig.flexGroup.alignment.mainAxis, "flex-start"); this.alignItems = this.safeGet(_ => _.fxConfig.flexGroup.alignment.crossAxis, "stretch"); this.alignContent = this.safeGet(_ => _.fxConfig.flexGroup.alignment.crossAxis, "stretch"); } updateFlexGroupItemStyling() { if (!this.isFlexGroupItem || !this.safeGet(_ => _.fxConfig.flexGroupItem, null)) { return; } this.flexGrow = this.safeGet(_ => _.fxConfig.flexGroupItem.flex.grow, "1"); this.flexShrink = this.safeGet(_ => _.fxConfig.flexGroupItem.flex.shrink, "1"); this.flexBasis = this.safeGet(_ => _.fxConfig.flexGroupItem.flex.basis, "0%"); } safeGet(getter, defaultValue) { const style = idx(this.displayConfig, getter); return isNullOrUndefined(style) ? defaultValue : style; } }; __decorate([ Input() ], DisplayDirective.prototype, "displayConfig", void 0); __decorate([ Input() ], DisplayDirective.prototype, "isFlexGroup", void 0); __decorate([ Input() ], DisplayDirective.prototype, "isFlexGroupItem", void 0); __decorate([ Input() ], DisplayDirective.prototype, "applyBasicStyling", void 0); __decorate([ HostBinding("style.display") ], DisplayDirective.prototype, "display", void 0); __decorate([ HostBinding("style.width") ], DisplayDirective.prototype, "width", void 0); __decorate([ HostBinding("style.min-width") ], DisplayDirective.prototype, "minWidth", void 0); __decorate([ HostBinding("style.max-width") ], DisplayDirective.prototype, "maxWidth", void 0); __decorate([ HostBinding("style.height") ], DisplayDirective.prototype, "height", void 0); __decorate([ HostBinding("style.min-height") ], DisplayDirective.prototype, "minHeight", void 0); __decorate([ HostBinding("style.max-height") ], DisplayDirective.prototype, "maxHeight", void 0); __decorate([ HostBinding("style.margin-top") ], DisplayDirective.prototype, "marginTop", void 0); __decorate([ HostBinding("style.margin-right") ], DisplayDirective.prototype, "marginRight", void 0); __decorate([ HostBinding("style.margin-bottom") ], DisplayDirective.prototype, "marginBottom", void 0); __decorate([ HostBinding("style.margin-left") ], DisplayDirective.prototype, "marginLeft", void 0); __decorate([ HostBinding("style.justify-content") ], DisplayDirective.prototype, "justifyContent", void 0); __decorate([ HostBinding("style.align-items") ], DisplayDirective.prototype, "alignItems", void 0); __decorate([ HostBinding("style.align-content") ], DisplayDirective.prototype, "alignContent", void 0); __decorate([ HostBinding("style.flex-direction") ], DisplayDirective.prototype, "flexDirection", void 0); __decorate([ HostBinding("style.flex-wrap") ], DisplayDirective.prototype, "flexWrap", void 0); __decorate([ HostBinding("style.flex-grow") ], DisplayDirective.prototype, "flexGrow", void 0); __decorate([ HostBinding("style.flex-shrink") ], DisplayDirective.prototype, "flexShrink", void 0); __decorate([ HostBinding("style.flex-basis") ], DisplayDirective.prototype, "flexBasis", void 0); DisplayDirective = __decorate([ Directive({ selector: "[display]" }) ], DisplayDirective); let TrustPipe = class TrustPipe { constructor(sanitizer) { this.sanitizer = sanitizer; } transform(value, type) { if (!value || value.length === 0) { return ""; } switch (type) { case "html": return this.sanitizer.bypassSecurityTrustHtml(value); case "style": return this.sanitizer.bypassSecurityTrustStyle(value); } return value; } }; TrustPipe.ctorParameters = () => [ { type: DomSanitizer } ]; TrustPipe = __decorate([ Pipe({ name: "trust" }) ], TrustPipe); let RecursyveFormComponent = class RecursyveFormComponent { constructor() { this.editable = fals