@vendasta/store
Version:
Components and data for Store
182 lines • 69.3 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';
import { BUSINESS_USER, CHECK_BOX, DROP_DOWN, FILES, TEXT_AREA, TEXT_BOX } from '../field-base';
import * as i0 from "@angular/core";
import * as i1 from "@angular/material/checkbox";
import * as i2 from "@angular/material/form-field";
import * as i3 from "@angular/material/select";
import * as i4 from "@angular/material/core";
import * as i5 from "@angular/material/button";
import * as i6 from "@angular/material/icon";
import * as i7 from "@angular/forms";
import * as i8 from "@angular/material/tooltip";
import * as i9 from "@angular/common";
import * as i10 from "@angular/material/input";
import * as i11 from "@ngx-translate/core";
export class FieldBuilderComponent {
constructor() {
this.removeField = new EventEmitter(null);
}
static createDropDownOption(option, required) {
return new FormGroup({
label: new FormControl(option.label || option.value, required ? [Validators.required] : []),
value: new FormControl(option.value),
useValue: new FormControl(!!option.value),
});
}
static createDropDownOptions(options) {
if (options === null || options === undefined) {
options = [];
}
const orderFormFieldsGroupArray = options.map((option) => FieldBuilderComponent.createDropDownOption(option, false));
return new FormArray(orderFormFieldsGroupArray);
}
static createOrderFormFieldGroup(orderFormField) {
const orderFormFieldGroup = new FormGroup({
descriptionControl: new FormControl(orderFormField.description, []),
labelControl: new FormControl(orderFormField.label, [Validators.required]),
idControl: new FormControl(orderFormField.id, [Validators.required]),
requiredControl: new FormControl(orderFormField.required || false, []),
uploadUrlControl: new FormControl(orderFormField.uploadUrl, []),
prefixControl: new FormControl(orderFormField.prefix, []),
suffixControl: new FormControl(orderFormField.suffix, []),
regexValidatorControl: new FormControl(orderFormField.regexValidator, regexValidator()),
regexErrorMessageControl: new FormControl(orderFormField.regexErrorMessage, []),
typeControl: new FormControl(getFieldInterface(orderFormField.type), [Validators.required]),
allowMultiples: new FormControl(orderFormField.allowMultiples || false, []),
allowDuplicates: new FormControl(orderFormField.allowDuplicates || false, []),
maxChoices: new FormControl(orderFormField.maxChoices ? orderFormField.maxChoices : 1, [
Validators.min(1),
numberValidator(),
]),
forOfficeUseOnly: new FormControl(orderFormField.forOfficeUseOnly || false, []),
officeEditableOnly: new FormControl(orderFormField.officeEditableOnly || false, []),
});
if (orderFormField.optionsWithLabels) {
const optionsArray = FieldBuilderComponent.createDropDownOptions(orderFormField.optionsWithLabels);
orderFormFieldGroup.addControl('optionsFormArray', optionsArray);
}
else if (orderFormField.options) {
const optionsArray = FieldBuilderComponent.createDropDownOptions(orderFormField.options.map((option) => ({ label: option })));
orderFormFieldGroup.addControl('optionsFormArray', optionsArray);
}
else {
orderFormFieldGroup.addControl('optionsFormArray', new FormArray([]));
}
return orderFormFieldGroup;
}
ngOnInit() {
if (!this.supportedFieldTypes || this.supportedFieldTypes.length < 1) {
this.supportedFieldTypes = FORM_FIELDS;
}
this.initForm();
}
initForm() {
// Check to see if form has been initiated
if (!this.orderFormFieldGroup.get('labelControl')) {
this.orderFormFieldGroup = FieldBuilderComponent.createOrderFormFieldGroup({});
}
}
getOptionsArray() {
return this.orderFormFieldGroup.get('optionsFormArray');
}
getCurrentFieldInterface() {
const formFieldTypeInterface = this.orderFormFieldGroup.get('typeControl').value;
return formFieldTypeInterface ? formFieldTypeInterface.id : null;
}
createIdFromLabel() {
const idControlValue = this.orderFormFieldGroup.get('idControl').value;
if (!idControlValue || idControlValue === '') {
const newId = convertLabelInputIntoId(this.orderFormFieldGroup.get('labelControl').value);
this.orderFormFieldGroup.get('idControl').setValue(newId);
}
}
removeOption(index) {
const formArray = this.getOptionsArray();
formArray.removeAt(index);
}
addOption() {
const fieldArray = this.getOptionsArray();
fieldArray.push(FieldBuilderComponent.createDropDownOption({ label: '' }, true));
}
getFormValues() {
const obj = {};
obj.label = this.orderFormFieldGroup.get('labelControl').value;
obj.id = this.orderFormFieldGroup.get('idControl').value;
const formFieldType = this.orderFormFieldGroup.get('typeControl').value; // use the id instead of the whole object
obj.type = formFieldType ? formFieldType.id : null;
// Options will be nested under their own form control in the larger Orderformfield array
const optionsArray = this.orderFormFieldGroup.get('optionsFormArray');
if (optionsArray && optionsArray.value) {
obj.options = optionsArray.value.map((option) => option.value || option.label);
obj.optionsWithLabels = optionsArray.value.map((option) => ({ label: option.label, value: option.value }));
}
obj.description = this.orderFormFieldGroup.get('descriptionControl').value;
obj.required = this.orderFormFieldGroup.get('requiredControl').value || false;
obj.uploadUrl = this.orderFormFieldGroup.get('uploadUrlControl').value;
obj.prefix = this.orderFormFieldGroup.get('prefixControl').value;
obj.suffix = this.orderFormFieldGroup.get('suffixControl').value;
obj.regexValidator = this.orderFormFieldGroup.get('regexValidatorControl').value;
obj.regexErrorMessage = this.orderFormFieldGroup.get('regexErrorMessageControl').value;
obj.allowMultiples = this.orderFormFieldGroup.get('allowMultiples').value || false;
obj.allowDuplicates = this.orderFormFieldGroup.get('allowDuplicates').value || false;
obj.maxChoices = this.orderFormFieldGroup.get('maxChoices').value || 1;
obj.forOfficeUseOnly = this.orderFormFieldGroup.get('forOfficeUseOnly').value || false;
obj.officeEditableOnly = this.orderFormFieldGroup.get('officeEditableOnly').value || false;
return obj;
}
}
FieldBuilderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: FieldBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
FieldBuilderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.2", type: FieldBuilderComponent, selector: "app-field-builder", inputs: { orderFormFieldGroup: "orderFormFieldGroup", supportedFieldTypes: "supportedFieldTypes" }, outputs: { removeField: "removeField" }, ngImport: i0, template: "<div\n class=\"color-primary grab-mask order-form-field-form-container\"\n [formGroup]=\"orderFormFieldGroup\"\n>\n <div class=\"options\">\n <mat-checkbox color=\"primary\" [formControlName]=\"'requiredControl'\">\n {{ 'FRONTEND.STORE.REQUIRED' | translate }}\n </mat-checkbox>\n <mat-checkbox\n color=\"primary\"\n [formControlName]=\"'forOfficeUseOnly'\"\n [disabled]=\"orderFormFieldGroup.get('officeEditableOnly').value\"\n [matTooltip]=\"\n 'FRONTEND.STORE.ORDER_FORM.FOR_OFFICE_USE_ONLY_TOOLTIP' | translate\n \"\n >\n <span class=\"underlined\">\n {{ 'FRONTEND.STORE.ORDER_FORM.HIDDEN_FROM_END_USERS' | translate }}\n </span>\n </mat-checkbox>\n <mat-checkbox\n color=\"primary\"\n [formControlName]=\"'officeEditableOnly'\"\n [disabled]=\"orderFormFieldGroup.get('forOfficeUseOnly').value\"\n [matTooltip]=\"\n 'FRONTEND.STORE.ORDER_FORM.OFFICE_EDITABLE_ONLY_TOOLTIP' | translate\n \"\n >\n <span class=\"underlined\">\n {{ 'FRONTEND.STORE.ORDER_FORM.OFFICE_EDITABLE_ONLY' | translate }}\n </span>\n </mat-checkbox>\n </div>\n <mat-form-field class=\"order-form-mat-form-field\">\n <mat-select\n matInput\n formControlName=\"typeControl\"\n placeholder=\"Type\"\n required\n novalidate\n >\n <mat-option *ngFor=\"let field of supportedFieldTypes\" [value]=\"field\">\n {{ field.name | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"'typeControl.invalid'\">\n {{ 'FRONTEND.STORE.ORDER_FORM.FIELD_TYPE_REQUIRED' | translate }}\n </mat-error>\n </mat-form-field>\n <!-- Options if drop down type is selected -->\n <ng-container\n *ngIf=\"\n getCurrentFieldInterface() && getCurrentFieldInterface() === 'dropdown'\n \"\n >\n <div\n formArrayName=\"optionsFormArray\"\n *ngFor=\"let option of getOptionsArray().controls; let i = index\"\n >\n <div class=\"removable-form-field dropdown-option\">\n <mat-form-field class=\"dropdown-option-label\">\n <input\n matInput\n [formControl]=\"option.get('label')\"\n placeholder=\"{{ 'FRONTEND.STORE.ORDER_FORM.OPTION' | translate }}\"\n />\n </mat-form-field>\n <mat-form-field\n class=\"dropdown-option-value\"\n *ngIf=\"option.get('useValue').value\"\n >\n <input\n matInput\n [formControl]=\"option.get('value')\"\n placeholder=\"{{ 'FRONTEND.STORE.ORDER_FORM.VALUE' | translate }}\"\n />\n </mat-form-field>\n <a\n class=\"dropdown-option-value\"\n (click)=\"option.get('useValue').setValue(true)\"\n *ngIf=\"!option.get('useValue').value\"\n >\n + {{ 'FRONTEND.STORE.ORDER_FORM.ASSIGN_VALUE' | translate }}\n </a>\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n (click)=\"removeOption(i)\"\n >\n <mat-icon\n attr.aria-label=\"{{\n 'FRONTEND.STORE.ORDER_FORM.CLEAR_BUTTON' | translate\n }}\"\n >\n clear\n </mat-icon>\n </button>\n </div>\n </div>\n <div class=\"order-form-mat-form-field\">\n <a (click)=\"addOption()\">\n + {{ 'FRONTEND.STORE.ORDER_FORM.OPTION' | translate }}\n </a>\n </div>\n <div class=\"dropdown-config\">\n <mat-checkbox color=\"primary\" [formControlName]=\"'allowMultiples'\">\n {{ 'FRONTEND.STORE.ORDER_FORM.ALLOW_MULTIPLES' | translate }}\n </mat-checkbox>\n <ng-container *ngIf=\"orderFormFieldGroup.controls.allowMultiples.value\">\n <mat-checkbox\n class=\"required-checkbox\"\n color=\"primary\"\n [formControlName]=\"'allowDuplicates'\"\n >\n {{ 'FRONTEND.STORE.ORDER_FORM.ALLOW_DUPLICATES' | translate }}\n </mat-checkbox>\n <div>\n <mat-form-field class=\"order-form-mat-form-field\">\n <input\n matInput\n formControlName=\"maxChoices\"\n placeholder=\"{{\n 'FRONTEND.STORE.ORDER_FORM.MAX_NUM_CHOICES' | translate\n }}\"\n required\n type=\"number\"\n />\n <mat-hint>\n {{\n 'FRONTEND.STORE.ORDER_FORM.CHOICES_HINT'\n | translate: { minChoices: 0 }\n }}\n </mat-hint>\n <mat-error *ngIf=\"'maxChoices.invalid'\">\n {{\n 'FRONTEND.STORE.ORDER_FORM.CHOICES_ERROR'\n | translate: { minChoices: 0 }\n }}\n </mat-error>\n </mat-form-field>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <div>\n <mat-form-field class=\"order-form-mat-form-field\">\n <input\n matInput\n formControlName=\"labelControl\"\n placeholder=\"Label\"\n required\n novalidate\n (change)=\"createIdFromLabel()\"\n />\n <mat-hint>\n {{\n 'FRONTEND.STORE.ORDER_FORM.LABEL_HINT'\n | translate: { maxCharacters: 140 }\n }}\n </mat-hint>\n <mat-error *ngIf=\"'idControl.invalid'\">\n {{ 'FRONTEND.STORE.ORDER_FORM.LABEL_ERROR' | translate }}\n </mat-error>\n </mat-form-field>\n </div>\n <!-- Prefix/suffix if textbox type is selected -->\n <ng-container\n *ngIf=\"\n getCurrentFieldInterface() && getCurrentFieldInterface() === 'textbox'\n \"\n >\n <ng-container *ngIf=\"showSuffixes\">\n <mat-form-field>\n <input matInput formControlName=\"prefixControl\" placeholder=\"Prefix\" />\n </mat-form-field>\n <mat-form-field>\n <input matInput formControlName=\"suffixControl\" placeholder=\"Suffix\" />\n </mat-form-field>\n <div class=\"show-hide-text-button\">\n <a (click)=\"showSuffixes = !showSuffixes\">\n {{ 'FRONTEND.STORE.ORDER_FORM.HIDE_PREFIX_SUFFIX' | translate }}\n </a>\n </div>\n </ng-container>\n <div *ngIf=\"!showSuffixes\" class=\"show-hide-text-button\">\n <a (click)=\"showSuffixes = !showSuffixes\">\n + {{ 'FRONTEND.STORE.ORDER_FORM.PREFIX_SUFFIX' | translate }}\n </a>\n <div class=\"hidden-note\">\n - {{ 'FRONTEND.STORE.ORDER_FORM.HIDDEN_NOTE' | translate }}\n </div>\n </div>\n </ng-container>\n\n <div>\n <mat-form-field class=\"order-form-mat-form-field\">\n <input matInput formControlName=\"idControl\" placeholder=\"ID\" required />\n <mat-hint>{{ 'FRONTEND.STORE.ORDER_FORM.ID_HINT' | translate }}</mat-hint>\n <mat-error *ngIf=\"'idControl.invalid'\">\n {{ 'FRONTEND.STORE.ORDER_FORM.ID_ERROR' | translate }}\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- Upload url if file type is selected -->\n <ng-container\n *ngIf=\"getCurrentFieldInterface() && getCurrentFieldInterface() === 'file'\"\n >\n <mat-form-field>\n <input\n matInput\n formControlName=\"uploadUrlControl\"\n placeholder=\"{{ 'FRONTEND.STORE.ORDER_FORM.UPLOAD_URL' | translate }}\"\n />\n <mat-hint>\n {{ 'FRONTEND.STORE.ORDER_FORM.UPLOAD_URL_HINT' | translate }}\n </mat-hint>\n </mat-form-field>\n </ng-container>\n\n <!-- Prefix/suffix if textbox type is selected -->\n <ng-container\n *ngIf=\"\n getCurrentFieldInterface() && getCurrentFieldInterface() === 'textbox'\n \"\n >\n <!-- RegexValidator/RegexErrorMessage if textbox type is selected -->\n <ng-container *ngIf=\"showValidators\">\n <mat-form-field>\n <input\n matInput\n formControlName=\"regexValidatorControl\"\n placeholder=\"{{\n 'FRONTEND.STORE.ORDER_FORM.REGEX_VALIDATOR' | translate\n }}\"\n />\n <mat-error *ngIf=\"'regexValidatorControl.invalid'\">\n {{ 'FRONTEND.STORE.ORDER_FORM.REGEX_VALIDATOR_ERROR' | translate }}\n </mat-error>\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n formControlName=\"regexErrorMessageControl\"\n placeholder=\"{{\n 'FRONTEND.STORE.ORDER_FORM.REGEX_ERROR_MESSAGE' | translate\n }}\"\n />\n <mat-hint>\n {{ 'FRONTEND.STORE.ORDER_FORM.REGEX_ERROR_MESSAGE_HINT' | translate }}\n </mat-hint>\n </mat-form-field>\n <div class=\"show-hide-text-button\">\n <a (click)=\"showValidators = !showValidators\">\n {{ 'FRONTEND.STORE.ORDER_FORM.HIDE_VALIDATION' | translate }}\n </a>\n </div>\n </ng-container>\n <div *ngIf=\"!showValidators\" class=\"show-hide-text-button\">\n <a (click)=\"showValidators = !showValidators\">\n + {{ 'FRONTEND.STORE.ORDER_FORM.VALIDATION' | translate }}\n </a>\n <div class=\"hidden-note\">\n - {{ 'FRONTEND.STORE.ORDER_FORM.HIDDEN_NOTE' | translate }}\n </div>\n </div>\n </ng-container>\n\n <!-- Optional description -->\n <div class=\"removable-form-field\">\n <mat-form-field>\n <input\n matInput\n formControlName=\"descriptionControl\"\n placeholder=\"{{ 'FRONTEND.STORE.ORDER_FORM.HINT_TEXT' | translate }}\"\n />\n <mat-hint>\n {{ 'FRONTEND.STORE.ORDER_FORM.HINT_TEXT_HINT' | translate }}\n </mat-hint>\n </mat-form-field>\n </div>\n\n <div class=\"delete-field-section\">\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n (click)=\"removeField.emit()\"\n >\n {{ 'FRONTEND.STORE.ORDER_FORM.DELETE_FIELD' | translate }}\n <!-- <mat-icon attr.aria-label=\"{{ 'FRONTEND.STORE.ORDER_FORM.CLEAR_BUTTON' | translate }}\">clear</mat-icon> -->\n </button>\n </div>\n</div>\n", styles: [".show-hide-text-button{margin-bottom:2em;display:flex}.show-hide-text-button .hidden-note{font-size:10px;margin-left:7px;color:#9e9e9e;align-self:center}.options{margin-bottom:12px}.options mat-checkbox{margin-right:12px}mat-form-field,.dropdown-option{width:100%}.delete-field-section{text-align:right}.mat-icon-button{width:auto;color:rgba(0,0,0,.54)!important}.mat-icon-button:hover{color:#c62828!important}.dropdown-config{margin-top:17px}.dropdown-config mat-checkbox{margin-right:16px}.dropdown-option{display:flex;align-items:center}.dropdown-option-label{flex:1 1 auto;margin-right:16px}.dropdown-option-value{flex:0 1 33%}.underlined{border-bottom:1px dotted}\n"], components: [{ type: i1.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i2.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i4.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i7.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i8.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.MatError, selector: "mat-error", inputs: ["id"] }, { type: i7.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { type: i10.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i7.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i7.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }], pipes: { "translate": i11.TranslatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: FieldBuilderComponent, decorators: [{
type: Component,
args: [{ selector: 'app-field-builder', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"color-primary grab-mask order-form-field-form-container\"\n [formGroup]=\"orderFormFieldGroup\"\n>\n <div class=\"options\">\n <mat-checkbox color=\"primary\" [formControlName]=\"'requiredControl'\">\n {{ 'FRONTEND.STORE.REQUIRED' | translate }}\n </mat-checkbox>\n <mat-checkbox\n color=\"primary\"\n [formControlName]=\"'forOfficeUseOnly'\"\n [disabled]=\"orderFormFieldGroup.get('officeEditableOnly').value\"\n [matTooltip]=\"\n 'FRONTEND.STORE.ORDER_FORM.FOR_OFFICE_USE_ONLY_TOOLTIP' | translate\n \"\n >\n <span class=\"underlined\">\n {{ 'FRONTEND.STORE.ORDER_FORM.HIDDEN_FROM_END_USERS' | translate }}\n </span>\n </mat-checkbox>\n <mat-checkbox\n color=\"primary\"\n [formControlName]=\"'officeEditableOnly'\"\n [disabled]=\"orderFormFieldGroup.get('forOfficeUseOnly').value\"\n [matTooltip]=\"\n 'FRONTEND.STORE.ORDER_FORM.OFFICE_EDITABLE_ONLY_TOOLTIP' | translate\n \"\n >\n <span class=\"underlined\">\n {{ 'FRONTEND.STORE.ORDER_FORM.OFFICE_EDITABLE_ONLY' | translate }}\n </span>\n </mat-checkbox>\n </div>\n <mat-form-field class=\"order-form-mat-form-field\">\n <mat-select\n matInput\n formControlName=\"typeControl\"\n placeholder=\"Type\"\n required\n novalidate\n >\n <mat-option *ngFor=\"let field of supportedFieldTypes\" [value]=\"field\">\n {{ field.name | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"'typeControl.invalid'\">\n {{ 'FRONTEND.STORE.ORDER_FORM.FIELD_TYPE_REQUIRED' | translate }}\n </mat-error>\n </mat-form-field>\n <!-- Options if drop down type is selected -->\n <ng-container\n *ngIf=\"\n getCurrentFieldInterface() && getCurrentFieldInterface() === 'dropdown'\n \"\n >\n <div\n formArrayName=\"optionsFormArray\"\n *ngFor=\"let option of getOptionsArray().controls; let i = index\"\n >\n <div class=\"removable-form-field dropdown-option\">\n <mat-form-field class=\"dropdown-option-label\">\n <input\n matInput\n [formControl]=\"option.get('label')\"\n placeholder=\"{{ 'FRONTEND.STORE.ORDER_FORM.OPTION' | translate }}\"\n />\n </mat-form-field>\n <mat-form-field\n class=\"dropdown-option-value\"\n *ngIf=\"option.get('useValue').value\"\n >\n <input\n matInput\n [formControl]=\"option.get('value')\"\n placeholder=\"{{ 'FRONTEND.STORE.ORDER_FORM.VALUE' | translate }}\"\n />\n </mat-form-field>\n <a\n class=\"dropdown-option-value\"\n (click)=\"option.get('useValue').setValue(true)\"\n *ngIf=\"!option.get('useValue').value\"\n >\n + {{ 'FRONTEND.STORE.ORDER_FORM.ASSIGN_VALUE' | translate }}\n </a>\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n (click)=\"removeOption(i)\"\n >\n <mat-icon\n attr.aria-label=\"{{\n 'FRONTEND.STORE.ORDER_FORM.CLEAR_BUTTON' | translate\n }}\"\n >\n clear\n </mat-icon>\n </button>\n </div>\n </div>\n <div class=\"order-form-mat-form-field\">\n <a (click)=\"addOption()\">\n + {{ 'FRONTEND.STORE.ORDER_FORM.OPTION' | translate }}\n </a>\n </div>\n <div class=\"dropdown-config\">\n <mat-checkbox color=\"primary\" [formControlName]=\"'allowMultiples'\">\n {{ 'FRONTEND.STORE.ORDER_FORM.ALLOW_MULTIPLES' | translate }}\n </mat-checkbox>\n <ng-container *ngIf=\"orderFormFieldGroup.controls.allowMultiples.value\">\n <mat-checkbox\n class=\"required-checkbox\"\n color=\"primary\"\n [formControlName]=\"'allowDuplicates'\"\n >\n {{ 'FRONTEND.STORE.ORDER_FORM.ALLOW_DUPLICATES' | translate }}\n </mat-checkbox>\n <div>\n <mat-form-field class=\"order-form-mat-form-field\">\n <input\n matInput\n formControlName=\"maxChoices\"\n placeholder=\"{{\n 'FRONTEND.STORE.ORDER_FORM.MAX_NUM_CHOICES' | translate\n }}\"\n required\n type=\"number\"\n />\n <mat-hint>\n {{\n 'FRONTEND.STORE.ORDER_FORM.CHOICES_HINT'\n | translate: { minChoices: 0 }\n }}\n </mat-hint>\n <mat-error *ngIf=\"'maxChoices.invalid'\">\n {{\n 'FRONTEND.STORE.ORDER_FORM.CHOICES_ERROR'\n | translate: { minChoices: 0 }\n }}\n </mat-error>\n </mat-form-field>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <div>\n <mat-form-field class=\"order-form-mat-form-field\">\n <input\n matInput\n formControlName=\"labelControl\"\n placeholder=\"Label\"\n required\n novalidate\n (change)=\"createIdFromLabel()\"\n />\n <mat-hint>\n {{\n 'FRONTEND.STORE.ORDER_FORM.LABEL_HINT'\n | translate: { maxCharacters: 140 }\n }}\n </mat-hint>\n <mat-error *ngIf=\"'idControl.invalid'\">\n {{ 'FRONTEND.STORE.ORDER_FORM.LABEL_ERROR' | translate }}\n </mat-error>\n </mat-form-field>\n </div>\n <!-- Prefix/suffix if textbox type is selected -->\n <ng-container\n *ngIf=\"\n getCurrentFieldInterface() && getCurrentFieldInterface() === 'textbox'\n \"\n >\n <ng-container *ngIf=\"showSuffixes\">\n <mat-form-field>\n <input matInput formControlName=\"prefixControl\" placeholder=\"Prefix\" />\n </mat-form-field>\n <mat-form-field>\n <input matInput formControlName=\"suffixControl\" placeholder=\"Suffix\" />\n </mat-form-field>\n <div class=\"show-hide-text-button\">\n <a (click)=\"showSuffixes = !showSuffixes\">\n {{ 'FRONTEND.STORE.ORDER_FORM.HIDE_PREFIX_SUFFIX' | translate }}\n </a>\n </div>\n </ng-container>\n <div *ngIf=\"!showSuffixes\" class=\"show-hide-text-button\">\n <a (click)=\"showSuffixes = !showSuffixes\">\n + {{ 'FRONTEND.STORE.ORDER_FORM.PREFIX_SUFFIX' | translate }}\n </a>\n <div class=\"hidden-note\">\n - {{ 'FRONTEND.STORE.ORDER_FORM.HIDDEN_NOTE' | translate }}\n </div>\n </div>\n </ng-container>\n\n <div>\n <mat-form-field class=\"order-form-mat-form-field\">\n <input matInput formControlName=\"idControl\" placeholder=\"ID\" required />\n <mat-hint>{{ 'FRONTEND.STORE.ORDER_FORM.ID_HINT' | translate }}</mat-hint>\n <mat-error *ngIf=\"'idControl.invalid'\">\n {{ 'FRONTEND.STORE.ORDER_FORM.ID_ERROR' | translate }}\n </mat-error>\n </mat-form-field>\n </div>\n\n <!-- Upload url if file type is selected -->\n <ng-container\n *ngIf=\"getCurrentFieldInterface() && getCurrentFieldInterface() === 'file'\"\n >\n <mat-form-field>\n <input\n matInput\n formControlName=\"uploadUrlControl\"\n placeholder=\"{{ 'FRONTEND.STORE.ORDER_FORM.UPLOAD_URL' | translate }}\"\n />\n <mat-hint>\n {{ 'FRONTEND.STORE.ORDER_FORM.UPLOAD_URL_HINT' | translate }}\n </mat-hint>\n </mat-form-field>\n </ng-container>\n\n <!-- Prefix/suffix if textbox type is selected -->\n <ng-container\n *ngIf=\"\n getCurrentFieldInterface() && getCurrentFieldInterface() === 'textbox'\n \"\n >\n <!-- RegexValidator/RegexErrorMessage if textbox type is selected -->\n <ng-container *ngIf=\"showValidators\">\n <mat-form-field>\n <input\n matInput\n formControlName=\"regexValidatorControl\"\n placeholder=\"{{\n 'FRONTEND.STORE.ORDER_FORM.REGEX_VALIDATOR' | translate\n }}\"\n />\n <mat-error *ngIf=\"'regexValidatorControl.invalid'\">\n {{ 'FRONTEND.STORE.ORDER_FORM.REGEX_VALIDATOR_ERROR' | translate }}\n </mat-error>\n </mat-form-field>\n <mat-form-field>\n <input\n matInput\n formControlName=\"regexErrorMessageControl\"\n placeholder=\"{{\n 'FRONTEND.STORE.ORDER_FORM.REGEX_ERROR_MESSAGE' | translate\n }}\"\n />\n <mat-hint>\n {{ 'FRONTEND.STORE.ORDER_FORM.REGEX_ERROR_MESSAGE_HINT' | translate }}\n </mat-hint>\n </mat-form-field>\n <div class=\"show-hide-text-button\">\n <a (click)=\"showValidators = !showValidators\">\n {{ 'FRONTEND.STORE.ORDER_FORM.HIDE_VALIDATION' | translate }}\n </a>\n </div>\n </ng-container>\n <div *ngIf=\"!showValidators\" class=\"show-hide-text-button\">\n <a (click)=\"showValidators = !showValidators\">\n + {{ 'FRONTEND.STORE.ORDER_FORM.VALIDATION' | translate }}\n </a>\n <div class=\"hidden-note\">\n - {{ 'FRONTEND.STORE.ORDER_FORM.HIDDEN_NOTE' | translate }}\n </div>\n </div>\n </ng-container>\n\n <!-- Optional description -->\n <div class=\"removable-form-field\">\n <mat-form-field>\n <input\n matInput\n formControlName=\"descriptionControl\"\n placeholder=\"{{ 'FRONTEND.STORE.ORDER_FORM.HINT_TEXT' | translate }}\"\n />\n <mat-hint>\n {{ 'FRONTEND.STORE.ORDER_FORM.HINT_TEXT_HINT' | translate }}\n </mat-hint>\n </mat-form-field>\n </div>\n\n <div class=\"delete-field-section\">\n <button\n mat-icon-button\n type=\"button\"\n color=\"primary\"\n (click)=\"removeField.emit()\"\n >\n {{ 'FRONTEND.STORE.ORDER_FORM.DELETE_FIELD' | translate }}\n <!-- <mat-icon attr.aria-label=\"{{ 'FRONTEND.STORE.ORDER_FORM.CLEAR_BUTTON' | translate }}\">clear</mat-icon> -->\n </button>\n </div>\n</div>\n", styles: [".show-hide-text-button{margin-bottom:2em;display:flex}.show-hide-text-button .hidden-note{font-size:10px;margin-left:7px;color:#9e9e9e;align-self:center}.options{margin-bottom:12px}.options mat-checkbox{margin-right:12px}mat-form-field,.dropdown-option{width:100%}.delete-field-section{text-align:right}.mat-icon-button{width:auto;color:rgba(0,0,0,.54)!important}.mat-icon-button:hover{color:#c62828!important}.dropdown-config{margin-top:17px}.dropdown-config mat-checkbox{margin-right:16px}.dropdown-option{display:flex;align-items:center}.dropdown-option-label{flex:1 1 auto;margin-right:16px}.dropdown-option-value{flex:0 1 33%}.underlined{border-bottom:1px dotted}\n"] }]
}], propDecorators: { orderFormFieldGroup: [{
type: Input
}], supportedFieldTypes: [{
type: Input
}], removeField: [{
type: Output
}] } });
// Validation to ensure supplied regex is valid
export function regexValidator() {
return (control) => {
try {
const _ = new RegExp(control.value || '');
}
catch (e) {
return { regex: true };
}
return null;
};
}
export function numberValidator() {
return (control) => {
const isNumber = /^\d+$/;
if (isNumber.test(control.value)) {
return null;
}
return { number: true };
};
}
export const FORM_FIELDS = [
{ id: FILES, name: 'FRONTEND.STORE.ORDER_FORM.FIELD_TYPES.FILES' },
{ id: DROP_DOWN, name: 'FRONTEND.STORE.ORDER_FORM.FIELD_TYPES.DROP_DOWN' },
{ id: CHECK_BOX, name: 'FRONTEND.STORE.ORDER_FORM.FIELD_TYPES.CHECK_BOX' },
{ id: TEXT_AREA, name: 'FRONTEND.STORE.ORDER_FORM.FIELD_TYPES.TEXT_AREA' },
{ id: TEXT_BOX, name: 'FRONTEND.STORE.ORDER_FORM.FIELD_TYPES.TEXT_BOX' },
{ id: BUSINESS_USER, name: 'FRONTEND.STORE.ORDER_FORM.FIELD_TYPES.END_USER' },
];
export function getFieldInterface(formFieldId) {
return getFormFieldInterfaceFromId(formFieldId);
}
export function getFormFieldInterfaceFromId(id) {
return FORM_FIELDS.find((obj) => obj.id === id);
}
export function convertLabelInputIntoId(labelValue) {
let newId = labelValue.toLowerCase();
newId = newId.replace(/[ -]/g, '_');
newId = newId.replace(/[^0-9a-z_]/g, '');
return newId;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGQtYnVpbGRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL3N0b3JlL3NyYy9saWIvb3JkZXItZm9ybS9maWVsZHMvZmllbGQtYnVpbGRlci9maWVsZC1idWlsZGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvc3RvcmUvc3JjL2xpYi9vcmRlci1mb3JtL2ZpZWxkcy9maWVsZC1idWlsZGVyL2ZpZWxkLWJ1aWxkZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RyxPQUFPLEVBQW1CLFNBQVMsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFlLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTdHLE9BQU8sRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFlLFNBQVMsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7Ozs7OztBQVE3RyxNQUFNLE9BQU8scUJBQXFCO0lBTmxDO1FBU1ksZ0JBQVcsR0FBeUIsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7S0FpSXRFO0lBNUhDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxNQUFxQyxFQUFFLFFBQWlCO1FBQ2xGLE9BQU8sSUFBSSxTQUFTLENBQUM7WUFDbkIsS0FBSyxFQUFFLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDM0YsS0FBSyxFQUFFLElBQUksV0FBVyxDQUFDLE1BQU0s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YSxFQUFFLElBQUksRUFBRSxnREFBZ0QsRUFBRTtDQUM5RSxDQUFDO0FBRUYsTUFBTSxVQUFVLGlCQUFpQixDQUFDLFdBQW1CO0lBQ25ELE9BQU8sMkJBQTJCLENBQUMsV0FBMEIsQ0FBQyxDQUFDO0FBQ2pFLENBQUM7QUFFRCxNQUFNLFVBQVUsMkJBQTJCLENBQUMsRUFBZTtJQUN6RCxPQUFPLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUF1QixFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0FBQ3RFLENBQUM7QUFFRCxNQUFNLFVBQVUsdUJBQXVCLENBQUMsVUFBa0I7SUFDeEQsSUFBSSxLQUFLLEdBQUcsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JDLEtBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNwQyxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDekMsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgRm9ybUFycmF5LCBGb3JtQ29udHJvbCwgRm9ybUdyb3VwLCBWYWxpZGF0b3JGbiwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE9yZGVyRm9ybUZpZWxkSW50ZXJmYWNlLCBPcmRlckZvcm1GaWVsZE9wdGlvbkludGVyZmFjZSB9IGZyb20gJ0B2ZW5kYXN0YS9tYXJrZXRwbGFjZS1hcHBzL3YxJztcbmltcG9ydCB7IEJVU0lORVNTX1VTRVIsIENIRUNLX0JPWCwgQ29udHJvbFR5cGUsIERST1BfRE9XTiwgRklMRVMsIFRFWFRfQVJFQSwgVEVYVF9CT1ggfSBmcm9tICcuLi9maWVsZC1iYXNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWZpZWxkLWJ1aWxkZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vZmllbGQtYnVpbGRlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2ZpZWxkLWJ1aWxkZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIEZpZWxkQnVpbGRlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIEBJbnB1dCgpIG9yZGVyRm9ybUZpZWxkR3JvdXA6IEZvcm1Hcm91cDtcbiAgQElucHV0KCkgc3VwcG9ydGVkRmllbGRUeXBlczogRm9ybUZpZWxkSW50ZXJmYWNlW107XG4gIEBPdXRwdXQoKSByZW1vdmVGaWVsZDogRXZlbnRFbWl0dGVyPHN0cmluZz4gPSBuZXcgRXZlbnRFbWl0dGVyKG51bGwpO1xuXG4gIHNob3dWYWxpZGF0b3JzOiBib29sZWFuO1xuICBzaG93U3VmZml4ZXM6IGJvb2xlYW47XG5cbiAgc3RhdGljIGNyZWF0ZURyb3BEb3duT3B0aW9uKG9wdGlvbjogT3JkZXJGb3JtRmllbGRPcHRpb25JbnRlcmZhY2UsIHJlcXVpcmVkOiBib29sZWFuKTogRm9ybUdyb3VwIHtcbiAgICByZXR1cm4gbmV3IEZvcm1Hcm91cCh7XG4gICAgICBsYWJlbDogbmV3IEZvcm1Db250cm9sKG9wdGlvbi5sYWJlbCB8fCBvcHRpb24udmFsdWUsIHJlcXVpcmVkID8gW1ZhbGlkYXRvcnMucmVxdWlyZWRdIDogW10pLFxuICAgICAgdmFsdWU6IG5ldyBGb3JtQ29udHJvbChvcHRpb24udmFsdWUpLFxuICAgICAgdXNlVmFsdWU6IG5ldyBGb3JtQ29udHJvbCghIW9wdGlvbi52YWx1ZSksXG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRHJvcERvd25PcHRpb25zKG9wdGlvbnM6IE9yZGVyRm9ybUZpZWxkT3B0aW9uSW50ZXJmYWNlW10pOiBGb3JtQXJyYXkge1xuICAgIGlmIChvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0aW9ucyA9IFtdO1xuICAgIH1cbiAgICBjb25zdCBvcmRlckZvcm1GaWVsZHNHcm91cEFycmF5OiBGb3JtR3JvdXBbXSA9IG9wdGlvbnMubWFwKChvcHRpb24pID0+XG4gICAgICBGaWVsZEJ1aWxkZXJDb21wb25lbnQuY3JlYXRlRHJvcERvd25PcHRpb24ob3B0aW9uLCBmYWxzZSksXG4gICAgKTtcbiAgICByZXR1cm4gbmV3IEZvcm1BcnJheShvcmRlckZvcm1GaWVsZHNHcm91cEFycmF5KTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVPcmRlckZvcm1GaWVsZEdyb3VwKG9yZGVyRm9ybUZpZWxkOiBPcmRlckZvcm1GaWVsZEludGVyZmFjZSk6IEZvcm1Hcm91cCB7XG4gICAgY29uc3Qgb3JkZXJGb3JtRmllbGRHcm91cCA9IG5ldyBGb3JtR3JvdXAoe1xuICAgICAgZGVzY3JpcHRpb25Db250cm9sOiBuZXcgRm9ybUNvbnRyb2wob3JkZXJGb3JtRmllbGQuZGVzY3JpcHRpb24sIFtdKSxcbiAgICAgIGxhYmVsQ29udHJvbDogbmV3IEZvcm1Db250cm9sKG9yZGVyRm9ybUZpZWxkLmxhYmVsLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF0pLFxuICAgICAgaWRDb250cm9sOiBuZXcgRm9ybUNvbnRyb2wob3JkZXJGb3JtRmllbGQuaWQsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXSksXG4gICAgICByZXF1aXJlZENvbnRyb2w6IG5ldyBGb3JtQ29udHJvbChvcmRlckZvcm1GaWVsZC5yZXF1aXJlZCB8fCBmYWxzZSwgW10pLFxuICAgICAgdXBsb2FkVXJsQ29udHJvbDogbmV3IEZvcm1Db250cm9sKG9yZGVyRm9ybUZpZWxkLnVwbG9hZFVybCwgW10pLFxuICAgICAgcHJlZml4Q29udHJvbDogbmV3IEZvcm1Db250cm9sKG9yZGVyRm9ybUZpZWxkLnByZWZpeCwgW10pLFxuICAgICAgc3VmZml4Q29udHJvbDogbmV3IEZvcm1Db250cm9sKG9yZGVyRm9ybUZpZWxkLnN1ZmZpeCwgW10pLFxuICAgICAgcmVnZXhWYWxpZGF0b3JDb250cm9sOiBuZXcgRm9ybUNvbnRyb2wob3JkZXJGb3JtRmllbGQucmVnZXhWYWxpZGF0b3IsIHJlZ2V4VmFsaWRhdG9yKCkpLFxuICAgICAgcmVnZXhFcnJvck1lc3NhZ2VDb250cm9sOiBuZXcgRm9ybUNvbnRyb2wob3JkZXJGb3JtRmllbGQucmVnZXhFcnJvck1lc3NhZ2UsIFtdKSxcbiAgICAgIHR5cGVDb250cm9sOiBuZXcgRm9ybUNvbnRyb2woZ2V0RmllbGRJbnRlcmZhY2Uob3JkZXJGb3JtRmllbGQudHlwZSksIFtWYWxpZGF0b3JzLnJlcXVpcmVkXSksXG4gICAgICBhbGxvd011bHRpcGxlczogbmV3IEZvcm1Db250cm9sKG9yZGVyRm9ybUZpZWxkLmFsbG93TXVsdGlwbGVzIHx8IGZhbHNlLCBbXSksXG4gICAgICBhbGxvd0R1cGxpY2F0ZXM6IG5ldyBGb3JtQ29udHJvbChvcmRlckZvcm1GaWVsZC5hbGxvd0R1cGxpY2F0ZXMgfHwgZmFsc2UsIFtdKSxcbiAgICAgIG1heENob2ljZXM6IG5ldyBGb3JtQ29udHJvbChvcmRlckZvcm1GaWVsZC5tYXhDaG9pY2VzID8gb3JkZXJGb3JtRmllbGQubWF4Q2hvaWNlcyA6IDEsIFtcbiAgICAgICAgVmFsaWRhdG9ycy5taW4oMSksXG4gICAgICAgIG51bWJlclZhbGlkYXRvcigpLFxuICAgICAgXSksXG4gICAgICBmb3JPZmZpY2VVc2VPbmx5OiBuZXcgRm9ybUNvbnRyb2wob3JkZXJGb3JtRmllbGQuZm9yT2ZmaWNlVXNlT25seSB8fCBmYWxzZSwgW10pLFxuICAgICAgb2ZmaWNlRWRpdGFibGVPbmx5OiBuZXcgRm9ybUNvbnRyb2wob3JkZXJGb3JtRmllbGQub2ZmaWNlRWRpdGFibGVPbmx5IHx8IGZhbHNlLCBbXSksXG4gICAgfSk7XG4gICAgaWYgKG9yZGVyRm9ybUZpZWxkLm9wdGlvbnNXaXRoTGFiZWxzKSB7XG4gICAgICBjb25zdCBvcHRpb25zQXJyYXkgPSBGaWVsZEJ1aWxkZXJDb21wb25lbnQuY3JlYXRlRHJvcERvd25PcHRpb25zKG9yZGVyRm9ybUZpZWxkLm9wdGlvbnNXaXRoTGFiZWxzKTtcbiAgICAgIG9yZGVyRm9ybUZpZWxkR3JvdXAuYWRkQ29udHJvbCgnb3B0aW9uc0Zvcm1BcnJheScsIG9wdGlvbnNBcnJheSk7XG4gICAgfSBlbHNlIGlmIChvcmRlckZvcm1GaWVsZC5vcHRpb25zKSB7XG4gICAgICBjb25zdCBvcHRpb25zQXJyYXkgPSBGaWVsZEJ1aWxkZXJDb21wb25lbnQuY3JlYXRlRHJvcERvd25PcHRpb25zKFxuICAgICAgICBvcmRlckZvcm1GaWVsZC5vcHRpb25zLm1hcCgob3B0aW9uKSA9PiAoeyBsYWJlbDogb3B0aW9uIH0pKSxcbiAgICAgICk7XG4gICAgICBvcmRlckZvcm1GaWVsZEdyb3VwLmFkZENvbnRyb2woJ29wdGlvbnNGb3JtQXJyYXknLCBvcHRpb25zQXJyYXkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcmRlckZvcm1GaWVsZEdyb3VwLmFkZENvbnRyb2woJ29wdGlvbnNGb3JtQXJyYXknLCBuZXcgRm9ybUFycmF5KFtdKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9yZGVyRm9ybUZpZWxkR3JvdXA7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc3VwcG9ydGVkRmllbGRUeXBlcyB8fCB0aGlzLnN1cHBvcnRlZEZpZWxkVHlwZXMubGVuZ3RoIDwgMSkge1xuICAgICAgdGhpcy5zdXBwb3J0ZWRGaWVsZFR5cGVzID0gRk9STV9GSUVMRFM7XG4gICAgfVxuICAgIHRoaXMuaW5pdEZvcm0oKTtcbiAgfVxuXG4gIGluaXRGb3JtKCk6IHZvaWQge1xuICAgIC8vIENoZWNrIHRvIHNlZSBpZiBmb3JtIGhhcyBiZWVuIGluaXRpYXRlZFxuICAgIGlmICghdGhpcy5vcmRlckZvcm1GaWVsZEdyb3VwLmdldCgnbGFiZWxDb250cm9sJykpIHtcbiAgICAgIHRoaXMub3JkZXJGb3JtRmllbGRHcm91cCA9IEZpZWxkQnVpbGRlckNvbXBvbmVudC5jcmVhdGVPcmRlckZvcm1GaWVsZEdyb3VwKHt9KTtcbiAgICB9XG4gIH1cblxuICBnZXRPcHRpb25zQXJyYXkoKTogRm9ybUFycmF5IHtcbiAgICByZXR1cm4gdGhpcy5vcmRlckZvcm1GaWVsZEdyb3VwLmdldCgnb3B0aW9uc0Zvcm