diff options
Diffstat (limited to 'catalog-ui/src/app/ng2/components/dynamic-element')
16 files changed, 418 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/dynamic-element.component.less b/catalog-ui/src/app/ng2/components/dynamic-element/dynamic-element.component.less new file mode 100644 index 0000000000..e219d49aa4 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/dynamic-element.component.less @@ -0,0 +1,3 @@ +dynamic-element { + +} diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/dynamic-element.component.ts b/catalog-ui/src/app/ng2/components/dynamic-element/dynamic-element.component.ts new file mode 100644 index 0000000000..de5965e488 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/dynamic-element.component.ts @@ -0,0 +1,117 @@ +import { Component, Compiler, EventEmitter, ViewContainerRef, ViewChild, Input, Output, ElementRef, ComponentRef, ComponentFactory, ComponentFactoryResolver } from '@angular/core' +import { UiElementCheckBoxComponent } from './elements-ui/checkbox/ui-element-checkbox.component'; +import { UiElementDropDownComponent, DropdownValue } from './elements-ui/dropdown/ui-element-dropdown.component'; +import { UiElementInputComponent } from './elements-ui/input/ui-element-input.component'; +import {UiElementPopoverInputComponent} from "./elements-ui/popover-input/ui-element-popover-input.component"; +import {ValidationConfiguration} from "app/models"; + +@Component({ + selector: 'dynamic-element', + template: `<div #target></div>`, + styleUrls: ['./dynamic-element.component.less'], + entryComponents: [ + UiElementInputComponent, + UiElementDropDownComponent, + UiElementCheckBoxComponent, + UiElementPopoverInputComponent + ] +}) +export class DynamicElementComponent { + + @ViewChild('target', { read: ViewContainerRef }) target: any; + @Input() type: any; + @Input() name: string; + value:any; + + // Two way binding for value (need to write the "Change" word like this) + @Output('valueChange') emitter: EventEmitter<string> = new EventEmitter<any>(); + @Input('value') set setValueValue(value) { + this.value = value; + } + + cmpRef: ComponentRef<any>; + private isViewInitialized: boolean = false; + validation = ValidationConfiguration.validation; + + constructor( + private componentFactoryResolver: ComponentFactoryResolver, + private compiler: Compiler, + private el: ElementRef) { + } + + updateComponent() { + if (!this.isViewInitialized) { + return; + } + if (this.cmpRef) { + this.cmpRef.destroy(); + } + + // Factory to create component based on type or peroperty name. + switch(this.type) { + case 'list': + case 'integer': + this.createComponent(UiElementInputComponent); + this.cmpRef.instance.pattern = this.validation.validationPatterns.integer; + break; + case 'string': + switch(this.name.toUpperCase()) { + case 'SUBNETPOOLID': + this.createComponent(UiElementPopoverInputComponent); + break; + default: + this.createComponent(UiElementInputComponent); + } + break; + case 'boolean': + //this.createComponent(UiElementCheckBoxComponent); + + this.createComponent(UiElementDropDownComponent); + + // Build drop down values + let tmp = []; + tmp.push(new DropdownValue('true','TRUE')); + tmp.push(new DropdownValue('false','FALSE')); + this.cmpRef.instance.values = tmp; + break; + default: + this.createComponent(UiElementInputComponent); + console.log("ERROR: No ui component to handle type: " + this.type); + } + + // Additional attributes in base element class + if (this.cmpRef) { + this.cmpRef.instance.name = this.name; + this.cmpRef.instance.type = this.type; + this.cmpRef.instance.value = this.value; + } + + // Subscribe to change event of of ui-element-basic and fire event to change the value + this.cmpRef.instance.baseEmitter.subscribe((value):void => { + this.emitter.emit(value) + }); + + } + + createComponent(ComponentToCreate:any):void { + let factory = this.componentFactoryResolver.resolveComponentFactory(ComponentToCreate); + this.cmpRef = this.target.createComponent(factory); + } + + ngOnChanges() { + this.updateComponent(); + } + + ngAfterContentInit() { + //console.log("DynamicElementComponent: ngAfterContentInit: type: " + this.type + " value: " + this.value); + this.isViewInitialized = true; + this.updateComponent(); + } + + ngOnDestroy() { + if (this.cmpRef) { + this.cmpRef.destroy(); + } + } + +} diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/dynamic-element.module.ts b/catalog-ui/src/app/ng2/components/dynamic-element/dynamic-element.module.ts new file mode 100644 index 0000000000..18b044bc9d --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/dynamic-element.module.ts @@ -0,0 +1,34 @@ +import { NgModule } from "@angular/core"; +import { UiElementCheckBoxComponent } from './elements-ui/checkbox/ui-element-checkbox.component'; +import { UiElementDropDownComponent } from './elements-ui/dropdown/ui-element-dropdown.component'; +import { UiElementInputComponent } from './elements-ui/input/ui-element-input.component'; +import { DynamicElementComponent } from "app/ng2/components/dynamic-element/dynamic-element.component"; +import { BrowserModule } from '@angular/platform-browser' +import { FormsModule, ReactiveFormsModule } from '@angular/forms' +import { UiElementPopoverInputComponent } from "./elements-ui/popover-input/ui-element-popover-input.component"; +import {PopoverModule} from "../popover/popover.module"; +import {TooltipModule} from "../tooltip/tooltip.module"; + +@NgModule({ + declarations: [ + DynamicElementComponent, + UiElementInputComponent, + UiElementCheckBoxComponent, + UiElementDropDownComponent, + UiElementPopoverInputComponent + ], + imports: [ + BrowserModule, + FormsModule, + PopoverModule, + ReactiveFormsModule, + TooltipModule + ], + exports: [ + DynamicElementComponent + ], + providers: [] +}) +export class DynamicElementModule { + +} diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/checkbox/ui-element-checkbox.component.html b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/checkbox/ui-element-checkbox.component.html new file mode 100644 index 0000000000..2ad3d8e94a --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/checkbox/ui-element-checkbox.component.html @@ -0,0 +1 @@ +<input #{{name}} [(ngModel)]="value" type="checkbox" (change)="onSave(value)" /> diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/checkbox/ui-element-checkbox.component.less b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/checkbox/ui-element-checkbox.component.less new file mode 100644 index 0000000000..bed097fe5e --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/checkbox/ui-element-checkbox.component.less @@ -0,0 +1,2 @@ +/deep/ ui-element-checkbox { +} diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/checkbox/ui-element-checkbox.component.ts b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/checkbox/ui-element-checkbox.component.ts new file mode 100644 index 0000000000..152303aee7 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/checkbox/ui-element-checkbox.component.ts @@ -0,0 +1,27 @@ +import { Component, ViewChild, ElementRef, ContentChildren, Input } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser' +import { UiElementBase, UiElementBaseInterface } from './../ui-element-base.component'; + +@Component({ + selector: 'ui-element-checkbox', + templateUrl: './ui-element-checkbox.component.html', + styleUrls: ['./ui-element-checkbox.component.less'], +}) +export class UiElementCheckBoxComponent extends UiElementBase implements UiElementBaseInterface { + + constructor() { + super(); + } + + ngAfterContentInit() { + // Convert the value to boolean (instanceOf does not work, the type is undefined). + if (this.value==='true' || this.value==='false') { + this.value = this.value==='true'?true:false; + } + } + + onSave() { + this.baseEmitter.emit(this.value); + } + +} diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/dropdown/ui-element-dropdown.component.html b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/dropdown/ui-element-dropdown.component.html new file mode 100644 index 0000000000..589d00e42d --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/dropdown/ui-element-dropdown.component.html @@ -0,0 +1,3 @@ +<select name='{{name}}' [(ngModel)]="value" #t (change)="onSave()"> + <option *ngFor="let ddvalue of values" [value]="ddvalue.value">{{ddvalue.label}}</option> +</select> diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/dropdown/ui-element-dropdown.component.less b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/dropdown/ui-element-dropdown.component.less new file mode 100644 index 0000000000..ea3e35140e --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/dropdown/ui-element-dropdown.component.less @@ -0,0 +1,11 @@ +@import '../../../../../../assets/styles/variables'; + +/deep/ ui-element-dropdown { + + select { + text-indent: 6px; + border: solid 1px @main_color_o; + width: 100%; + } + +} diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/dropdown/ui-element-dropdown.component.ts b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/dropdown/ui-element-dropdown.component.ts new file mode 100644 index 0000000000..208bf54983 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/dropdown/ui-element-dropdown.component.ts @@ -0,0 +1,33 @@ +import { Component, EventEmitter, Output, Input } from '@angular/core' +import { BrowserModule } from '@angular/platform-browser' +import { UiElementBase, UiElementBaseInterface } from './../ui-element-base.component'; + +export class DropdownValue { + value:string; + label:string; + + constructor(value:string,label:string) { + this.value = value; + this.label = label; + } +} + +@Component({ + selector: 'ui-element-dropdown', + templateUrl: './ui-element-dropdown.component.html', + styleUrls: ['./ui-element-dropdown.component.less'], +}) +export class UiElementDropDownComponent extends UiElementBase implements UiElementBaseInterface { + + @Input() + values: DropdownValue[]; + + constructor() { + super(); + } + + onSave() { + this.baseEmitter.emit(this.value); + } + +} diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/input/ui-element-input.component.html b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/input/ui-element-input.component.html new file mode 100644 index 0000000000..00fea65b72 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/input/ui-element-input.component.html @@ -0,0 +1,13 @@ +<input + class="value-input" + [ngClass]="{'error': control.invalid}" + type="text" + [name]="name" + [(ngModel)]="value" + (change)="onSave()" + [attr.maxlength]="validation.propertyValue.max" + [attr.minlength]="validation.propertyValue.min" + [pattern]="pattern" + [formControl]="control" + tooltip="{{value}}" + /> diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/input/ui-element-input.component.less b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/input/ui-element-input.component.less new file mode 100644 index 0000000000..d320c7ff8b --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/input/ui-element-input.component.less @@ -0,0 +1,17 @@ +@import '../../../../../../assets/styles/variables'; + +/deep/ ui-element-input { + + input { + text-indent: 6px; + border: solid 1px @main_color_o; + } + + .error { + border: solid 1px @func_color_q; + color: @func_color_q; + outline: none; + box-sizing: border-box; + } + +} diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/input/ui-element-input.component.ts b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/input/ui-element-input.component.ts new file mode 100644 index 0000000000..5a14d8f206 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/input/ui-element-input.component.ts @@ -0,0 +1,22 @@ +import { Component, ViewChild, ElementRef, ContentChildren } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser' +import { UiElementBase, UiElementBaseInterface } from './../ui-element-base.component'; + +@Component({ + selector: 'ui-element-input', + templateUrl: './ui-element-input.component.html', + styleUrls: ['./ui-element-input.component.less'], +}) +export class UiElementInputComponent extends UiElementBase implements UiElementBaseInterface { + + constructor() { + super(); + this.pattern = this.validation.validationPatterns.comment; + } + + onSave() { + if (!this.control.invalid){ + this.baseEmitter.emit(this.value); + } + } +} diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/popover-input/ui-element-popover-input.component.html b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/popover-input/ui-element-popover-input.component.html new file mode 100644 index 0000000000..5adceb49a0 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/popover-input/ui-element-popover-input.component.html @@ -0,0 +1,26 @@ +<div class="popover-input-wrapper" tooltip="{{value}}"> + <input + class="value-input" + type="text" + [ngClass]="{'error': control.invalid}" + [name]="name" + [value]="value" + disabled + /> + <button [popover]="popoverForm">Edit</button> +</div> + +<popover-content #popoverForm [title]="name" [buttons]="buttonsArray" [placement]="'top'" [closeOnClickOutside]="true"> + <div class="edit-subnet-wrapper"> + <textarea rows="5" + #textArea + class="subnet-value" + [ngClass]="{'error': control.invalid}" + [(ngModel)]="value" + [attr.maxlength]="validation.propertyValue.max" + [attr.minlength]="validation.propertyValue.min" + [pattern]="pattern" + [formControl]="control" + ></textarea> + </div> +</popover-content> diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/popover-input/ui-element-popover-input.component.less b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/popover-input/ui-element-popover-input.component.less new file mode 100644 index 0000000000..5be443f7b6 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/popover-input/ui-element-popover-input.component.less @@ -0,0 +1,36 @@ +@import '../../../../../../assets/styles/variables'; + +.popover-input-wrapper { + display: flex; +} + +/deep/ ui-element-popover-input { + + .popover { + max-width: 350px; + width: 350px; + } + + .edit-subnet-wrapper { + padding: 12px; + + .subnet-value { + width: 100%; + resize: none; + } + } + + input { + padding-right: 6px; + padding-left: 6px; + border: solid 1px @main_color_o; + } + + .error { + border: solid 1px @func_color_q; + color: @func_color_q; + outline: none; + box-sizing: border-box; + } + +} diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/popover-input/ui-element-popover-input.component.ts b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/popover-input/ui-element-popover-input.component.ts new file mode 100644 index 0000000000..7300417686 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/popover-input/ui-element-popover-input.component.ts @@ -0,0 +1,39 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {UiElementBase, UiElementBaseInterface} from "../ui-element-base.component"; +import {ButtonsModelMap, ButtonModel} from "app/models"; +import { PopoverContentComponent } from "app/ng2/components/popover/popover-content.component" +import { PopoverComponent } from "app/ng2/components/popover/popover.component" + +@Component({ + selector: 'ui-element-popover-input', + templateUrl: './ui-element-popover-input.component.html', + styleUrls: ['./ui-element-popover-input.component.less'] +}) +export class UiElementPopoverInputComponent extends UiElementBase implements UiElementBaseInterface { + + @ViewChild('textArea') textArea: ElementRef; + @ViewChild('popoverForm') popoverContentComponent: PopoverContentComponent; + + saveButton: ButtonModel; + buttonsArray: ButtonsModelMap; + + onSave = ():void => { + if (!this.control.invalid){ + this.baseEmitter.emit(this.value); + this.popoverContentComponent.hide(); + } + } + + constructor() { + super(); + // Create Save button and insert to buttons map + this.saveButton = new ButtonModel('save', 'blue', this.onSave); + this.buttonsArray = { 'test': this.saveButton }; + + // Define the regex pattern for this controller + this.pattern = this.validation.validationPatterns.comment; + + // Disable / Enable button according to validation + //this.control.valueChanges.subscribe(data => this.saveButton.disabled = this.control.invalid); + } +} diff --git a/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/ui-element-base.component.ts b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/ui-element-base.component.ts new file mode 100644 index 0000000000..b60271f6f0 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/dynamic-element/elements-ui/ui-element-base.component.ts @@ -0,0 +1,34 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core' +import { ValidationConfiguration } from "app/models"; +import { FormControl, Validators } from '@angular/forms'; + +export interface UiElementBaseInterface { + onSave(); +} + +@Component({ + template: ``, + styles: [] +}) +export class UiElementBase { + + protected validation = ValidationConfiguration.validation; + protected control: FormControl; + + // Two way binding for value (need to write the "Change" word like this) + @Output('valueChange') baseEmitter: EventEmitter<string> = new EventEmitter<any>(); + @Input('value') set setValueValue(value) { + this.value = value; + } + + protected name: string; + protected type: string; + protected value: any; + protected pattern: any; + + constructor() { + //this.control = new FormControl('', [Validators.required]); + this.control = new FormControl('', []); + } + +} |