diff options
author | Ittay Stern <ittay.stern@att.com> | 2018-08-29 17:01:32 +0300 |
---|---|---|
committer | Ittay Stern <ittay.stern@att.com> | 2019-02-18 18:35:30 +0200 |
commit | 6f900cc45d7dd7f97430812b86b5c1d1693c8ae3 (patch) | |
tree | 936005c364dc5a7264d6304d4777c3d83494db22 /vid-webpack-master/src/app/shared/components/dynamic-inputs | |
parent | 67d99f816cc583643c35193197594cf78d8ce60a (diff) |
merge from ecomp a88f0072 - Modern UI
Issue-ID: VID-378
Change-Id: Ibcb23dd27f550cf32ce2fe0239f0f496ae014ff6
Signed-off-by: Ittay Stern <ittay.stern@att.com>
Diffstat (limited to 'vid-webpack-master/src/app/shared/components/dynamic-inputs')
4 files changed, 317 insertions, 0 deletions
diff --git a/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.component.spec.ts b/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.component.spec.ts new file mode 100644 index 000000000..6194aad5e --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.component.spec.ts @@ -0,0 +1,157 @@ +import {HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing"; +import {DynamicInputsComponent} from "./dynamic-inputs.component"; +import {async, ComponentFixture, getTestBed, TestBed} from "@angular/core/testing"; +import {CUSTOM_ELEMENTS_SCHEMA} from "@angular/core"; +import {FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, ValidatorFn} from "@angular/forms"; +import {BrowserModule} from "@angular/platform-browser"; +import {CommonModule} from "@angular/common"; +import {RouterTestingModule} from "@angular/router/testing"; +import {DynamicInputLabelPipe} from "../../pipes/dynamicInputLabel/dynamic-input-label.pipe"; +import {DynamicNumber} from "../../models/dynamicInput"; + + +describe('DynamicInputs Component', () => { + let component: DynamicInputsComponent; + let fixture: ComponentFixture<DynamicInputsComponent>; + + beforeAll(done => (async () => { + TestBed.configureTestingModule({ + imports: [BrowserModule, CommonModule, FormsModule, HttpClientTestingModule, RouterTestingModule, ReactiveFormsModule], + declarations: [DynamicInputsComponent, DynamicInputLabelPipe], + providers : [FormBuilder], + schemas: [ CUSTOM_ELEMENTS_SCHEMA ] + }); + await TestBed.compileComponents(); + + fixture = TestBed.createComponent(DynamicInputsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })().then(done).catch(done.fail)); + + test('should be defined', () => { + expect(component).toBeDefined(); + }); + + test('isDynamicNumber should return item', () => { + let options = { + minLength : 10, + maxLength : 10 + }; + + let dynamicNumber : DynamicNumber = new DynamicNumber(<any>options); + expect(component.isDynamicNumber(dynamicNumber)).toBeDefined(); + }); + + test('buildValidators should return validator', () => { + let options = { + minLength : 10, + maxLength : 10, + max : 10, + min : 1 + }; + + let dynamicNumber : DynamicNumber = new DynamicNumber(<any>options); + let validator : ValidatorFn = component.buildValidators(dynamicNumber); + expect(validator).toBeDefined(); + }); + + + test('ngOnInit', ()=>{ + component.group = new FormGroup({ + + }); + component.list = [ + { + type : 'select', + value : 'optionName', + name : 'multiSelectControl', + optionList : [{ + isDataLoading : true, + name : 'optionName', + id : 'id' + }] + }, + { + type : 'select', + value : 'optionName', + name : 'multiSelectControl', + optionList : [{ + isDataLoading : true, + name : 'optionName', + id : 'id' + }] + }, + { + type : 'multi_select', + value : 'optionName', + name : 'selectControl', + optionList : [{ + isDataLoading : true, + name : 'optionName', + id : 'id' + }] + }, + { + type : 'multi_select', + value : 'optionName', + name : 'selectControl', + optionList : [{ + isDataLoading : true, + name : 'optionName' + }] + }, + { + type : 'boolean', + value : true, + name : 'booleanControl' + }, + { + type : 'boolean', + name : 'booleanControl2' + }, + { + type : 'number', + value : 100, + name : 'numberControl' + }, + { + type : 'file', + value : 'someValue', + name : 'fileControl' + }, + { + type : 'checkbox', + value : true, + name : 'checkboxControl' + }, + { + type : 'map', + value : true, + name : 'mapControl' + }, + { + type : 'list', + value : true, + name : 'listControl' + }, + { + type : 'default', + value : true, + name : 'defaultControl' + } + ]; + + component.ngOnInit(); + expect(component.group.controls['multiSelectControl'].value).toEqual('id'); + expect(component.group.controls['selectControl'].value).toEqual('optionName'); + expect(component.group.controls['booleanControl'].value).toEqual(true); + expect(component.group.controls['booleanControl2'].value).toEqual(false); + expect(component.group.controls['numberControl'].value).toEqual(100); + expect(component.group.controls['fileControl'].value).toEqual('someValue'); + expect(component.group.controls['checkboxControl'].value).toEqual(true); + expect(component.group.controls['mapControl'].value).toEqual(true); + expect(component.group.controls['listControl'].value).toEqual(true); + expect(component.group.controls['defaultControl'].value).toEqual(true); + }) + +}); diff --git a/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.component.ts b/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.component.ts new file mode 100644 index 000000000..096a51eb7 --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.component.ts @@ -0,0 +1,80 @@ +import {Component, Input, OnInit} from '@angular/core'; +import {FormControl, FormGroup, Validators} from "@angular/forms"; +import {DynamicInput, DynamicMultiSelect, DynamicNumber, DynamicSelect} from "../../models/dynamicInput"; + +@Component({ + selector: 'dynamic-inputs', + templateUrl: './dynamic-inputs.html', + styleUrls: ['./dynamic-inputs.scss'] +}) + +export class DynamicInputsComponent implements OnInit{ + @Input() public list:any[] = []; + @Input() public group: FormGroup; + + private dynamicList:DynamicInput<any>[] = []; + + isDynamicNumber(item: any): item is DynamicNumber { + return item; + } + + buildValidators(item: DynamicInput<any>) { + let validatorArr = []; + item.maxLength && validatorArr.push(Validators.maxLength(item.maxLength)); + item.minLength && validatorArr.push(Validators.minLength(item.minLength)); + if(this.isDynamicNumber(item)) { + item.max && validatorArr.push(Validators.max(item.max)); + item.min && validatorArr.push(Validators.min(item.min)); + } + return Validators.compose(validatorArr); + } + + ngOnInit(): void { + this.list.forEach((item)=> { + let dynamicItem: DynamicInput<any>; + switch (item.type) { + case 'multi_select': + item.optionList.forEach(function(option) { option.id = option.id||option.name; + option.itemName = option.name;}); + item.settings = { + disabled: !item.isEnabled, + text: item.prompt, + }; + dynamicItem = new DynamicMultiSelect(item); + break; + case 'select': + let defaultValue:any = item.optionList.find((option) => option.isDataLoading && option.name); + item.value = defaultValue && defaultValue.id; + dynamicItem = new DynamicSelect(item); + break; + case 'boolean': + item.value = item.value || false; + item.optionList = [{name: true, isPermitted: true, isDataLoading: item.value}, {name: false, isPermitted: true, isDataLoading: !item.value}]; + + dynamicItem = new DynamicSelect(item); + break; + case 'number': + dynamicItem = new DynamicNumber(item); + break; + case 'file': + dynamicItem = new DynamicInput<any>(item); + break; + case 'checkbox': + dynamicItem = new DynamicInput<boolean>(item); + break; + case 'map': + item.prompt = "{<key1>: <value1>,\.\.\.,<keyN>: <valueN>}"; + dynamicItem = new DynamicInput<string>(item); + break; + case 'list': + item.prompt = "[<value1>,...,<valueN>]"; + dynamicItem = new DynamicInput<string>(item); + break; + default: dynamicItem = new DynamicInput<string>(item); + } + this.dynamicList.push(dynamicItem); + this.group.addControl(dynamicItem.name, new FormControl({value: dynamicItem.value, disabled: !dynamicItem.isEnabled}, this.buildValidators(dynamicItem))); + }) + } + +} diff --git a/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.html b/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.html new file mode 100644 index 000000000..740b798e4 --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.html @@ -0,0 +1,22 @@ +<div *ngFor="let item of dynamicList"> + <div id="{{item.id}}" class="details-item" [ngSwitch]="item.type" [formGroup]="group" [hidden]="!item.isVisible"> + <label [ngClass]="{'required' : item.isRequired && item.isVisible}">{{item.name | dynamicInputLabel }}</label> + <select *ngSwitchCase="item.type === 'select'|| item.type === 'boolean'? item.type: ''" name="{{item.name}}" class="form-control input-text" [formControlName]="item.name" title="{{item.description}}" [required]="item.isRequired && item.isVisible" maxlength="{{item.maxLength}}" minlength="{{item.minLength}}"> + <option value="null" [selected]="item.value == null || item.value == undefined" hidden disabled>{{item.prompt}}</option> + <option *ngFor="let option of item.optionList" [ngValue]="option.id || option.name" [disabled]="!option.isPermitted" [selected]="option.isDataLoading">{{option.name}}</option> + </select> + <angular2-multiselect *ngSwitchCase="'multi_select'" [formControlName]="item.name" [(ngModel)]="item.selectedItems" [data]="item.optionList" [settings]="item.settings" title="{{item.description}}" [required]="item.isRequired && item.isVisible"></angular2-multiselect> + <input *ngSwitchCase="'number'" name="{{item.name}}" class="form-control input-text" [formControlName]="item.name" type="number" placeholder="{{item.prompt}}" title="{{item.description}}" min="{{item.min}}" max="{{item.max}}" [readonly]="item.isReadOnly" [required]="item.isRequired && item.isVisible"> + <div *ngSwitchCase="'file'"> + + <label class="dynamicFileName" for="dynamicFileInput-{{item.name}}"> + <input id="dynamicFileInput-{{item.name}}" name="{{item.name}}" class="form-control input-text" [formControlName]="item.name" type="file" placeholder="{{item.prompt}}" [readonly]="item.isReadOnly" [required]="item.isRequired && item.isVisible"> + <label for="dynamicFileInput-{{item.name}}" class="labelForImage"> + <span class="icon-browse"></span> + </label> + </label> + </div> + <input *ngSwitchCase="'checkbox'" name="{{item.name}}" [formControlName]="item.name" type="checkbox" data-toggle="toggle" title="{{item.description}}" [readonly]="item.isReadOnly" [required]="item.isRequired && item.isVisible"> + <input *ngSwitchDefault name="{{item.name}}" class="form-control input-text" [formControlName]="item.name" placeholder="{{item.prompt}}" title="{{item.description}}" maxlength="{{item.maxLength}}" minlength="{{item.minLength}}" [readonly]="item.isReadOnly" [required]="item.isRequired && item.isVisible"/> + </div> +</div> diff --git a/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.scss b/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.scss new file mode 100644 index 000000000..11a141420 --- /dev/null +++ b/vid-webpack-master/src/app/shared/components/dynamic-inputs/dynamic-inputs.scss @@ -0,0 +1,58 @@ +input[type=file] { + opacity: 0; + position: relative; + z-index: 1; + width: 0.5px; + height: 0.5px; + display: inline-block; + input { + display: none; + } +} + +.dynamicFileName { + width: 100%; + height: 34px; + background: #FFFFFF; + border: 1px solid #D2D2D2; + border-radius: 2px; + display: inline-block; + line-height: 34px; + font-weight: normal !important; + padding-left: 3px; + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} + +.labelForImage { + background: #F2F2F2; + border-left: 1px solid #D2D2D2; + float: right; + height: 32px; +} + +.icon-browse:before { + content: "\e90d"; + color: #5A5A5A; + font-size: 15px; + cursor: pointer; + width: 34px; + height: 100%; + line-height: 34px; + text-align: center; + display: inline-block; + vertical-align: super; + border-radius: 2px; + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.icon-browse:hover::before { + background-color: #E6F6FB; + color: #009FDB; +} + +.icon-browse:active::before { + background-color: #E6F6FB; + color: #009FDB; +} |