diff options
Diffstat (limited to 'catalog-ui/src/app/ng2/components/logic')
21 files changed, 515 insertions, 87 deletions
diff --git a/catalog-ui/src/app/ng2/components/logic/filter-properties-assignment/filter-properties-assignment.component.html b/catalog-ui/src/app/ng2/components/logic/filter-properties-assignment/filter-properties-assignment.component.html index ddda82ab58..cc8aed70d4 100644 --- a/catalog-ui/src/app/ng2/components/logic/filter-properties-assignment/filter-properties-assignment.component.html +++ b/catalog-ui/src/app/ng2/components/logic/filter-properties-assignment/filter-properties-assignment.component.html @@ -7,7 +7,7 @@ <checkbox [label]="'All'" [(checked)]="allSelected" (checkedChange)="selectAll()" data-tests-id="filter-checkbox-all"></checkbox> </div> <div *ngFor="let type of typesOptions"> - <checkbox [label]="type" [(checked)]="selectedTypes[type]" (checkedChange)="onTypeSelected(type)"></checkbox> + <checkbox [label]="type" [(checked)]="selectedTypes[type]" (checkedChange)="onTypeSelected(type)" [attr.data-tests-id]="'filter-checkbox-' + type.toLowerCase()"></checkbox> </div> </div> <div class="field"> diff --git a/catalog-ui/src/app/ng2/components/logic/filter-properties-assignment/filter-properties-assignment.component.ts b/catalog-ui/src/app/ng2/components/logic/filter-properties-assignment/filter-properties-assignment.component.ts index 5a9bfbcecb..fe2c7bb09a 100644 --- a/catalog-ui/src/app/ng2/components/logic/filter-properties-assignment/filter-properties-assignment.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/filter-properties-assignment/filter-properties-assignment.component.ts @@ -21,6 +21,7 @@ /** * Created by rc2122 on 5/16/2017. */ +import * as _ from "lodash"; import {Component, Input, Output, EventEmitter, ViewChild} from '@angular/core'; import {ButtonModel, ButtonsModelMap, FilterPropertiesAssignmentData} from "app/models"; import * as sdcConfig from "../../../../../../configurations/dev" diff --git a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.ts b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.ts index dc0a02c277..1698157e90 100644 --- a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.ts @@ -37,12 +37,10 @@ export class HierarchyNavigationComponent { onClick = ($event, item) => { $event.stopPropagation(); - this.selectedItem = item; this.updateSelected.emit(item); }; onSelectedUpdate = ($event) => { - this.selectedItem = $event; this.updateSelected.emit($event); } } diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html index 57e0474c66..b7cde7eb23 100644 --- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html +++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html @@ -30,11 +30,11 @@ <dynamic-element class="value-input" *ngIf="input.isSimpleType" pattern="validationUtils.getValidationPattern(input.type)" - [(value)]="input.defaultValue" + [value]="input.defaultValueObj" [type]="input.type" [name]="input.name" - (change)="onInputValueChanged(input);" - [readonly]="readonly"> + (elementChanged)="onInputChanged(input, $event)" + [readonly]="readonly"> </dynamic-element> <div class="delete-button-container"> <span *ngIf="input.instanceUniqueId && !readonly" class="sprite-new delete-btn" (click)="openDeleteModal(input)" data-tests-id="delete-input-button"></span> diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less index 0545874f53..d709f3f0c5 100644 --- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less +++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less @@ -11,7 +11,7 @@ text-align:left; .inner-cell-div{ - width: 100%; + max-width: 100%; text-overflow: ellipsis; overflow: hidden; height: 20px; @@ -85,8 +85,8 @@ border-right:#d2d2d2 solid 1px; } &.col1 { - flex: 1 0 200px; - max-width:300px; + flex: 1 0 210px; + max-width:210px; display: flex; justify-content: space-between; @@ -121,7 +121,6 @@ .value-input { flex: 1; - max-height: 24px; border: none; background-color: inherit; diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts index 0add1cd707..ebecbc9390 100644 --- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts @@ -36,7 +36,7 @@ export class InputsTableComponent { @Input() instanceNamesMap: Map<string, string>; @Input() readonly:boolean; @Input() isLoading:boolean; - @Output() inputValueChanged: EventEmitter<any> = new EventEmitter<any>(); + @Output() inputChanged: EventEmitter<any> = new EventEmitter<any>(); @Output() deleteInput: EventEmitter<any> = new EventEmitter<any>(); selectedInputToDelete:InputFEModel; @@ -44,8 +44,9 @@ export class InputsTableComponent { constructor(private modalService: ModalService){ } - onInputValueChanged = (input) => { - this.inputValueChanged.emit(input); + onInputChanged = (input, event) => { + input.updateDefaultValueObj(event.value, event.isValid); + this.inputChanged.emit(input); }; onDeleteInput = () => { diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html index 14b6c7d4c0..4805875d83 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html @@ -10,7 +10,16 @@ </div> <div class="table-cell" *ngIf="!canBeDeclared && !property.isChildOfListOrMap">{{property.name}}</div> <!-- simple children of complex type within map or list --> <div class="table-cell map-entry" *ngIf="property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP"><!-- map left cell --> - <input [value]="property.mapKey" #mapKey (change)="mapKeyChanged.emit(mapKey)" [readonly]="readonly" type="text" [ngClass]="{'disabled':readonly, 'error':!mapKey.validity.valid}" required/> + <!--<input [value]="property.mapKey" [placeholder]="property.name" (input)="mapKeyChanged.emit($event.target.value)" [readonly]="readonly" type="text" [ngClass]="{'disabled':readonly, 'error':property.mapKeyError}" required/>--> + <dynamic-element #mapKeyInput + class="value-input" + pattern="validationUtils.getValidationPattern(string)" + [value]="property.mapKey" + type="string" + [name]="property.name" + (elementChanged)="mapKeyChanged.emit($event.value)" + [readonly]="readonly" + ></dynamic-element> </div> </ng-container> <!-- RIGHT CELL OR FULL WIDTH CELL--> @@ -18,11 +27,11 @@ <div class="table-cell"> <dynamic-element class="value-input" pattern="validationUtils.getValidationPattern(property.type)" - [(value)]="property.valueObj" + [value]="property.valueObj" [type]="property.isDeclared ? 'string' : property.type" [name]="property.name" [path]="property.propertiesName" - (valueChange)="valueChanged.emit();" + (elementChanged)="onElementChanged($event)" [readonly]="readonly || property.isDeclared || property.isDisabled" ></dynamic-element> </div> @@ -54,8 +63,8 @@ [propertyNameSearchText]="propertyNameSearchText" [readonly]="readonly" [hasChildren]="getHasChildren(prop)" - (valueChanged)="childValueChanged(prop)" - (mapKeyChanged)="removeValueFromParent(prop, $event)" + (propertyChanged)="childValueChanged(prop)" + (mapKeyChanged)="updateChildKeyInParent(prop, $event)" (expandChild)="expandChildById($event)" (deleteItem)="deleteListOrMapItem($event)" (clickOnPropertyRow)="onClickPropertyRow($event)" diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts index 04cb26d030..6f7e57b643 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts @@ -18,13 +18,15 @@ * ============LICENSE_END========================================================= */ -import {Component, Input, Output, EventEmitter} from "@angular/core"; +import * as _ from "lodash"; +import {Component, Input, Output, EventEmitter, ViewChild, ComponentRef} from "@angular/core"; import { PropertyFEModel, DerivedFEProperty, DerivedPropertyType } from "app/models"; import { PROPERTY_TYPES } from 'app/utils'; import { DataTypeService } from "../../../../services/data-type.service"; import { trigger, state, style, transition, animate } from '@angular/core'; import {PropertiesUtils} from "../../../../pages/properties-assignment/services/properties.utils"; - +import {IUiElementChangeEvent} from "../../../ui/form-components/ui-element-base.component"; +import {DynamicElementComponent} from "../../../ui/dynamic-element/dynamic-element.component"; @Component({ selector: 'dynamic-property', @@ -49,7 +51,7 @@ export class DynamicPropertyComponent { @Input() hasChildren: boolean; @Input() hasDeclareOption:boolean; - @Output() valueChanged: EventEmitter<any> = new EventEmitter<any>(); + @Output('propertyChanged') emitter: EventEmitter<void> = new EventEmitter<void>(); @Output() expandChild: EventEmitter<string> = new EventEmitter<string>(); @Output() checkProperty: EventEmitter<string> = new EventEmitter<string>(); @Output() deleteItem: EventEmitter<string> = new EventEmitter<string>(); @@ -57,6 +59,7 @@ export class DynamicPropertyComponent { @Output() mapKeyChanged: EventEmitter<string> = new EventEmitter<string>(); @Output() addChildPropsToParent: EventEmitter<Array<DerivedFEProperty>> = new EventEmitter<Array<DerivedFEProperty>>(); + @ViewChild('mapKeyInput') public mapKeyInput: DynamicElementComponent; constructor(private propertiesUtils: PropertiesUtils, private dataTypeService: DataTypeService) { } @@ -68,6 +71,17 @@ export class DynamicPropertyComponent { this.nestedLevel = (this.property.propertiesName.match(/#/g) || []).length; } + ngDoCheck() { + // set custom error for mapKeyInput + if (this.mapKeyInput) { + const mapKeyInputControl = this.mapKeyInput.cmpRef.instance.control; + const mapKeyError = (<DerivedFEProperty>this.property).mapKeyError; + if (mapKeyInputControl.getError('mapKeyError') !== mapKeyError) { + mapKeyInputControl.setErrors({mapKeyError}); + } + } + } + onClickPropertyRow = (property, event) => { // Because DynamicPropertyComponent is recrusive second time the event is fire event.stopPropagation = undefined @@ -91,9 +105,15 @@ export class DynamicPropertyComponent { }).length > 1; } + onElementChanged = (event: IUiElementChangeEvent) => { + this.property.updateValueObj(event.value, event.isValid); + this.emitter.emit(); + }; + createNewChildProperty = (): void => { - let newProps: Array<DerivedFEProperty> = this.propertiesUtils.createListOrMapChildren(this.property, "", undefined); + let newProps: Array<DerivedFEProperty> = this.propertiesUtils.createListOrMapChildren(this.property, "", null); + this.propertiesUtils.assignFlattenedChildrenValues(this.property.valueObj, [newProps[0]], this.property.propertiesName); if (this.property instanceof PropertyFEModel) { this.addChildProps(newProps, this.property.name); } else { @@ -108,28 +128,25 @@ export class DynamicPropertyComponent { this.property.flattenedChildren.splice(insertIndex, 0, ...newProps); //using ES6 spread operator this.expandChildById(newProps[0].propertiesName); - - if(!newProps[0].schema.property.isSimpleType){ - if ( newProps[0].mapKey ) {//prevent update the new item value on parent property valueObj and saving on BE if it is map item, it will be updated and saved only after user enter key (when it is list item- the map key is the es type) - this.updateMapKeyValueOnMainParent(newProps); - if (this.property.getParentNamesArray(newProps[0].propertiesName, []).indexOf('') === -1) { - this.valueChanged.emit(this.property.name); - } - } - } + this.updateMapKeyValueOnMainParent(newProps); + this.emitter.emit(); } } updateMapKeyValueOnMainParent(childrenProps: Array<DerivedFEProperty>){ if (this.property instanceof PropertyFEModel) { + const property: PropertyFEModel = <PropertyFEModel>this.property; //Update only if all this property parents has key name - if (this.property.getParentNamesArray(childrenProps[0].propertiesName, []).indexOf('') === -1){ + if (property.getParentNamesArray(childrenProps[0].propertiesName, []).indexOf('') === -1){ angular.forEach(childrenProps, (prop:DerivedFEProperty):void => { //Update parent PropertyFEModel with value for each child, including nested props - (<PropertyFEModel>this.property).childPropUpdated(prop); + property.childPropUpdated(prop); + if (prop.isChildOfListOrMap && prop.mapKey !== undefined) { + property.childPropMapKeyUpdated(prop, prop.mapKey, true); + } },this); //grab the cumulative value for the new item from parent PropertyFEModel and assign that value to DerivedFEProp[0] (which is the list or map parent with UUID of the set we just added) - let parentNames = (<PropertyFEModel>this.property).getParentNamesArray(childrenProps[0].propertiesName, []); - childrenProps[0].valueObj = _.get(this.property.valueObj, parentNames.join('.')); + let parentNames = (<PropertyFEModel>property).getParentNamesArray(childrenProps[0].propertiesName, []); + childrenProps[0].valueObj = _.get(property.valueObj, parentNames.join('.'), null); } } } @@ -140,7 +157,7 @@ export class DynamicPropertyComponent { if (this.property.getParentNamesArray(property.propertiesName, []).indexOf('') === -1) {//If one of the parents is empty key -don't save this.property.childPropUpdated(property); this.dataTypeService.checkForCustomBehavior(this.property); - this.valueChanged.emit(this.property.name); + this.emitter.emit(); } } } @@ -153,46 +170,42 @@ export class DynamicPropertyComponent { } } - removeValueFromParent = (item: DerivedFEProperty, target?: any) => { + removeValueFromParent = (item: DerivedFEProperty) => { if (this.property instanceof PropertyFEModel) { - let itemParent = (item.parentName == this.property.name) ? this.property : this.property.flattenedChildren.find(prop => prop.propertiesName == item.parentName); + let itemParent = (item.parentName == this.property.name) + ? this.property : this.property.flattenedChildren.find(prop => prop.propertiesName == item.parentName); + if (!itemParent) { + return; + } if (item.derivedDataType == DerivedPropertyType.MAP) { - let oldKey = item.mapKey; - if (target && typeof target.value == 'string') { //allow saving empty string - let replaceKey:string = target.value; - if (!replaceKey) {//prevent delete map key - return; - } - if(Object.keys(itemParent.valueObj).indexOf(replaceKey) > -1){//the key is exists - target.setCustomValidity('This key is already exists.'); - return; - }else { - target.setCustomValidity(''); - _.set(itemParent.valueObj, replaceKey, itemParent.valueObj[oldKey]); - item.mapKey = replaceKey; - //If the map key was empty its valueObj was not updated on its prent property valueObj, and now we should update it. - if(!oldKey && !item.schema.property.isSimpleType){ - //Search this map item children and update these value on parent property valueOBj - let mapKeyFlattenChildren:Array<DerivedFEProperty> = _.filter(this.property.flattenedChildren, (prop:DerivedFEProperty) => { - return _.startsWith(prop.propertiesName, item.propertiesName); - }); - this.updateMapKeyValueOnMainParent(mapKeyFlattenChildren); - } - } - } + const oldKey = item.getActualMapKey(); delete itemParent.valueObj[oldKey]; + if (itemParent instanceof PropertyFEModel) { + delete itemParent.valueObjValidation[oldKey]; + itemParent.valueObjIsValid = itemParent.calculateValueObjIsValid(); + } + this.property.childPropMapKeyUpdated(item, null); // remove map key } else { - let itemIndex: number = this.property.flattenedChildren.filter(prop => prop.parentName == item.parentName).map(prop => prop.propertiesName).indexOf(item.propertiesName); + const itemIndex: number = this.property.flattenedChildren.filter(prop => prop.parentName == item.parentName).map(prop => prop.propertiesName).indexOf(item.propertiesName); itemParent.valueObj.splice(itemIndex, 1); - } - if (item.mapKey) {//prevent going to BE if user tries to delete map item without key (it was not saved in BE) - if (itemParent instanceof PropertyFEModel) { //direct child - this.valueChanged.emit(this.property.name); - } else { //nested child - need to update parent prop by getting flattened name (recurse through parents and replace map/list keys, etc) - this.childValueChanged(itemParent); + if (itemParent instanceof PropertyFEModel) { + itemParent.valueObjValidation.splice(itemIndex, 1); + itemParent.valueObjIsValid = itemParent.calculateValueObjIsValid(); } } + if (itemParent instanceof PropertyFEModel) { //direct child + this.emitter.emit(); + } else { //nested child - need to update parent prop by getting flattened name (recurse through parents and replace map/list keys, etc) + this.childValueChanged(itemParent); + } + } + } + + updateChildKeyInParent(childProp: DerivedFEProperty, newMapKey: string) { + if (this.property instanceof PropertyFEModel) { + this.property.childPropMapKeyUpdated(childProp, newMapKey); + this.emitter.emit(); } } diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html index 933b80f577..ecfa7e7c5e 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html @@ -48,7 +48,7 @@ [expandedChildId]="property.expandedChildPropertyId" [propertyNameSearchText]="propertyNameSearchText" [readonly]="readonly" - (valueChanged)="propValueChanged(property);" + (propertyChanged)="onPropertyChanged(property)" (expandChild)="property.updateExpandedChildPropertyId($event)" (clickOnPropertyRow)="onClickPropertyInnerRow($event, instanceId)" (checkProperty)="propertyChecked(property, $event)" diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts index 32bbb1b3a0..093fae1684 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts @@ -39,7 +39,7 @@ export class PropertiesTableComponent { @Input() hasDeclareOption:boolean; @Input() hidePropertyType:boolean; - @Output() valueChanged: EventEmitter<any> = new EventEmitter<any>(); + @Output('propertyChanged') emitter: EventEmitter<PropertyFEModel> = new EventEmitter<PropertyFEModel>(); @Output() selectPropertyRow: EventEmitter<PropertyRowSelectedEvent> = new EventEmitter<PropertyRowSelectedEvent>(); @Output() updateCheckedPropertyCount: EventEmitter<boolean> = new EventEmitter<boolean>();//only for hasDeclareOption @@ -49,8 +49,8 @@ export class PropertiesTableComponent { ngOnInit() { } - propValueChanged = (property) => { - this.valueChanged.emit(property); + onPropertyChanged = (property) => { + this.emitter.emit(property); }; // Click on main row (row of propertyFEModel) diff --git a/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html b/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html index bcd33efc30..6e0f93f750 100644 --- a/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html +++ b/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html @@ -22,7 +22,8 @@ </div> </div> <div class="inner-container properties-table-container" *ngIf="selectedReqOrCapOption == 'Capability'" [ngClass]="{'cap-selected':selectedReqOrCapModel}"> - <properties-table *ngIf="selectedReqOrCapModel" + <loader [display]="loadingCapabilityProperties" size="medium" [relative]="true"></loader> + <properties-table *ngIf="selectedReqOrCapModel && !loadingCapabilityProperties" class="properties-table" [readonly]="true" [fePropertiesMap]="capabilityProperties" diff --git a/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.ts b/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.ts index ab67dc1850..2e3c21c210 100644 --- a/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.ts @@ -1,10 +1,10 @@ /** * Created by rc2122 on 9/4/2017. */ +import * as _ from "lodash"; import {Component, EventEmitter, Input, OnInit, Output, SimpleChanges} from '@angular/core'; -import {RadioButtonModel, Match, PropertyModel, InstanceFePropertiesMap, Component as ComponentModel} from "app/models"; +import {RadioButtonModel, PropertyModel, InstanceFePropertiesMap, Component as ComponentModel} from "app/models"; import {Dictionary} from "lodash"; -import {DropdownValue} from "../../ui/form-components/dropdown/ui-element-dropdown.component"; import {ComponentInstanceServiceNg2} from "../../../services/component-instance-services/component-instance.service"; import {PropertiesUtils} from "app/ng2/pages/properties-assignment/services/properties.utils"; import {Requirement} from "../../../../models/requirement"; @@ -33,7 +33,6 @@ export class SelectRequirementOrCapabilityComponent implements OnInit { @Input() selectedReqOrCapModel:RequirementCapabilityModel; @Output() updateSelectedReqOrCap:EventEmitter<RequirementCapabilityModel> = new EventEmitter<RequirementCapabilityModel>(); - @Output() updateCapabilityProperties:EventEmitter<Array<PropertyModel>> = new EventEmitter<Array<PropertyModel>>(); types:Array<string> = []; selectedType:string; @@ -47,10 +46,14 @@ export class SelectRequirementOrCapabilityComponent implements OnInit { displayCapReqListFilterByType:RequirementCapabilityModel[]; capabilityProperties:InstanceFePropertiesMap; + loadingCapabilityProperties:boolean; + + private _loadingCapabilityProperties: Array<Capability>; constructor(private componentInstanceServiceNg2:ComponentInstanceServiceNg2, private propertiesUtils:PropertiesUtils) { this.selectOptions = [new RadioButtonModel(REQUIREMENT, REQUIREMENT), new RadioButtonModel(CAPABILITY, CAPABILITY)]; + this._loadingCapabilityProperties = []; } private initDefaultReqOrCapSelection = (): void => { @@ -87,14 +90,17 @@ export class SelectRequirementOrCapabilityComponent implements OnInit { initCapabilityPropertiesTable = ():void => { if(this.selectedReqOrCapModel instanceof Capability ) { let selectedCapability = <Capability>this.selectedReqOrCapModel; - if(selectedCapability.properties){ + if (selectedCapability.properties && selectedCapability.properties.length) { this.capabilityProperties = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren({ CAPABILITY : selectedCapability.properties}, false); + } else { + this.capabilityProperties = null; } } } ngOnChanges(changes:SimpleChanges) { if (changes.selectedReqOrCapModel) { + this.capabilityProperties = null; if (this.selectedReqOrCapModel && this.selectedReqOrCapOption === CAPABILITY) { this.setCapabilityProperties(); } @@ -168,15 +174,27 @@ export class SelectRequirementOrCapabilityComponent implements OnInit { private setCapabilityProperties = ():void => { let selectedCapability = <Capability>this.selectedReqOrCapModel; - if (selectedCapability.properties === undefined) { - this.componentInstanceServiceNg2.getInstanceCapabilityProperties(this.currentComponent, this.componentInstanceId, selectedCapability.type, selectedCapability.name) - .subscribe((response:Array<PropertyModel>) => { - this.capabilityProperties = (response && response.length) ? this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren({CAPABILITY : response}, false) : null; - this.updateCapabilityProperties.emit(response); - }, error => {}); - }else{ - this.capabilityProperties = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren({CAPABILITY : selectedCapability.properties}, false); - this.updateCapabilityProperties.emit(selectedCapability.properties); + if (!selectedCapability.properties) { + this.loadingCapabilityProperties = true; + if (this._loadingCapabilityProperties.indexOf(selectedCapability) == -1) { + this._loadingCapabilityProperties.push(selectedCapability); + this.componentInstanceServiceNg2.getInstanceCapabilityProperties(this.currentComponent, this.componentInstanceId, selectedCapability) + .subscribe((response: Array<PropertyModel>) => { + if (this.selectedReqOrCapModel === selectedCapability) { + delete this.loadingCapabilityProperties; + } + this.initCapabilityPropertiesTable(); + }, (error) => { + if (this.selectedReqOrCapModel === selectedCapability) { + delete this.loadingCapabilityProperties; + } + }, () => { + this._loadingCapabilityProperties.splice(this._loadingCapabilityProperties.indexOf(selectedCapability), 1); + }); + } + } else { + delete this.loadingCapabilityProperties; + this.initCapabilityPropertiesTable(); } } } diff --git a/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.module.ts b/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.module.ts index cb12dea02a..259ae12380 100644 --- a/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.module.ts +++ b/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.module.ts @@ -5,6 +5,7 @@ import {FormElementsModule} from "../../ui/form-components/form-elements.module" import {CommonModule} from "@angular/common"; import {GlobalPipesModule} from "app/ng2/pipes/global-pipes.module"; import {PropertyTableModule} from "../properties-table/property-table.module"; +import {UiElementsModule} from "../../ui/ui-elements.module"; @NgModule({ declarations: [ @@ -15,7 +16,9 @@ import {PropertyTableModule} from "../properties-table/property-table.module"; FormsModule, FormElementsModule, GlobalPipesModule, - PropertyTableModule], + UiElementsModule, + PropertyTableModule + ], exports: [SelectRequirementOrCapabilityComponent], providers: [] diff --git a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.html b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.html new file mode 100644 index 0000000000..72e083534c --- /dev/null +++ b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.html @@ -0,0 +1,11 @@ +<div class="service-path-selector"> + <label>Service Paths:</label> + <ui-element-dropdown + class="path-dropdown" + data-tests-id="service-path-selector" + [readonly]="dropdownOptions.length < 3" + [(value)]="selectedPathId" + [values]="dropdownOptions" + (valueChange)="onSelectPath()"> + </ui-element-dropdown> +</div> diff --git a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.less b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.less new file mode 100644 index 0000000000..f3cb4a3c34 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.less @@ -0,0 +1,24 @@ +@import './../../../../../assets/styles/variables.less'; +.service-path-selector { + margin: 10px 35px 10px 0; + display: flex; + font-size: 12px; + + /deep/ .path-dropdown { + width: 150px; + select { + font-size: 14px; + font-family: @font-opensans-regular; + padding: 4px 10px; + } + } + + label { + margin-right: 10px; + align-self: center; + font-size: 14px; + font-family: @font-opensans-regular; + font-weight: normal; + margin-bottom: initial; + } +} diff --git a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.ts b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.ts new file mode 100644 index 0000000000..be9966acef --- /dev/null +++ b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.ts @@ -0,0 +1,134 @@ +import * as _ from "lodash"; +import {Component, Input, KeyValueDiffer, IterableDiffers, KeyValueDiffers, DoCheck} from '@angular/core'; +import {Service} from "app/models/components/service"; +import {TranslateService} from "app/ng2/shared/translator/translate.service"; +import {ForwardingPath} from "app/models/forwarding-path"; +import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component"; + +@Component({ + selector: 'service-path-selector', + templateUrl: './service-path-selector.component.html', + styleUrls:['service-path-selector.component.less'], + providers: [TranslateService] +}) + +export class ServicePathSelectorComponent implements DoCheck { + + defaultSelectedId: string; + hideAllValue: string; + hideAllId: string = '0'; + showAllValue: string; + showAllId: string = '1'; + + paths: Array<ForwardingPath> = []; + dropdownOptions: Array<DropdownValue>; + differ: KeyValueDiffer; + + @Input() service: Service; + @Input() drawPath: Function; + @Input() deletePaths: Function; + @Input() selectedPathId: string; + + constructor(private differs: KeyValueDiffers, private translateService: TranslateService) { + + this.defaultSelectedId = this.hideAllId; + this.convertPathsToDropdownOptions(); + + this.translateService.languageChangedObservable.subscribe(lang => { + this.hideAllValue = this.translateService.translate("SERVICE_PATH_SELECTOR_HIDE_ALL_VALUE"); + this.showAllValue = this.translateService.translate("SERVICE_PATH_SELECTOR_SHOW_ALL_VALUE"); + this.convertPathsToDropdownOptions(); + }); + + } + + ngOnInit(): void { + + this.selectedPathId = this.defaultSelectedId; + this.differ = this.differs.find(this.service.forwardingPaths).create(null); + + } + + ngDoCheck(): void { + + const pathsChanged = this.differ.diff(this.service.forwardingPaths); + + if (pathsChanged) { + let oldPaths = _.cloneDeep(this.paths); + this.populatePathsFromService(); + + if (!(_.isEqual(oldPaths, this.paths))) { + this.convertPathsToDropdownOptions(); + + let temp = this.selectedPathId; + this.selectedPathId = '-1'; + + setTimeout(() => { + this.selectedPathId = temp; + this.onSelectPath(); + }, 0); + } + } + + } + + populatePathsFromService(): void { + + this.paths = []; + let {forwardingPaths} = this.service; + + _.forEach(forwardingPaths, path => { + this.paths.push(path); + }); + this.paths.sort((a:ForwardingPath, b:ForwardingPath)=> { + return a.name.localeCompare(b.name); + }); + + } + + convertPathsToDropdownOptions(): void { + + let result = [ + new DropdownValue(this.hideAllId, this.hideAllValue), + new DropdownValue(this.showAllId, this.showAllValue) + ]; + + _.forEach(this.paths, (value: ForwardingPath) => { + result[result.length] = new DropdownValue(value.uniqueId, value.name); + }); + + this.dropdownOptions = result; + + } + + onSelectPath = (): void => { + + if (this.selectedPathId !== '-1') { + this.deletePaths(); + + switch (this.selectedPathId) { + case this.hideAllId: + break; + + case this.showAllId: + _.forEach(this.paths, path => + this.drawPath(path) + ); + break; + + default: + let path = this.paths.find(path => + path.uniqueId === this.selectedPathId + ); + if (!path) { + this.selectedPathId = this.defaultSelectedId; + this.onSelectPath(); // currently does nothing in default case, but if one day it does, we want the selection to behave accordingly. + break; + } + this.drawPath(path); + break; + } + } + + } +} diff --git a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.module.ts b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.module.ts new file mode 100644 index 0000000000..c07061ce9a --- /dev/null +++ b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from "@angular/core"; +import {CommonModule} from "@angular/common"; +import {ServicePathSelectorComponent} from "./service-path-selector.component"; +import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module"; + +@NgModule({ + declarations: [ + ServicePathSelectorComponent + ], + imports: [ + CommonModule, + UiElementsModule + ], + exports: [], + entryComponents: [ + ServicePathSelectorComponent + ], + providers: [] +}) +export class ServicePathSelectorModule { +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.html b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.html new file mode 100644 index 0000000000..ff7902e2b9 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.html @@ -0,0 +1,22 @@ +<div class='service-path'> + <button class='zoom-icons create-path-button' data-tests-id="pathsMenuBtn" (click)="showServicePathMenu = !showServicePathMenu">...</button> + <div class="service-path-menu" + *ngIf="showServicePathMenu" > + <div > + <ul> + <li><div class="hand" (click)="onCreateServicePath()" data-tests-id="createPathMenuItem"> + Create Service Path + </div></li> + <li><div class="hand" (click)="onListServicePath()" data-tests-id="pathsListMenuItem"> + Service Paths List + </div></li> + </ul> + </div> + </div> + <!-- TODO - ask Orit about positioning issues and styling issues --> + <!-- + <menu-list [open]="showServicePathMenu" [position]="menuPos" > + <menu-item [action]="onCreateServicePath">Create Path</menu-item> + <menu-item [action]="onListServicePath">Paths' List</menu-item> + </menu-list> --> +</div>
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.less b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.less new file mode 100644 index 0000000000..777b206714 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.less @@ -0,0 +1,51 @@ +//@import 'src/assets/styles/variables.less'; +@import './../../../../../assets/styles/variables.less'; +.service-path { + position: relative; + .create-path-button{ + &:extend(.search-bar-button); + width: 30px; + height: 30px; + &:hover { + color: @main_color_a; + } + &:active { + background: @main_color_a; + color: @main_color_p; + } + &:focus { + outline: none; + } + } + .service-path-menu { + border: 1px solid @main_color_o; + border-radius: 0 0 2px 2px; + border-top-color: @main_color_a; + border-top-width: 3px; + + box-sizing: border-box; + box-shadow: 0 2px 4px 0 rgba(0,0,0,0.30); + + background-color: @main_color_p; + + padding: 5px 0; + right: 34px; + position: absolute; + top: 10px; + width: 150px; + font-size: 13px; + font-family: @font-opensans-regular; + + li { + color: @main_color_m; + padding: 0 10px; + line-height: 20px; + &:hover { + cursor: pointer; + color: @main_color_a; + background-color: fade(@main_color_a, 5%); + } + } + + } +} diff --git a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.ts b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.ts new file mode 100644 index 0000000000..4a6209fb6f --- /dev/null +++ b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.ts @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +import {Component, Input, ComponentRef} from '@angular/core'; +import {ModalService} from 'app/ng2/services/modal.service'; +import {ModalModel, ButtonModel} from 'app/models'; +import {ServicePathCreatorComponent} from 'app/ng2/pages/service-path-creator/service-path-creator.component'; +import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component'; +import ServicePathsListComponent from "app/ng2/pages/service-paths-list/service-paths-list.component"; +import {Service} from "app/models/components/service"; + +@Component({ + selector: 'service-path', + templateUrl: './service-path.component.html', + styleUrls: ['service-path.component.less'], + providers: [ModalService] +}) + +export class ServicePathComponent { + showServicePathMenu: boolean = false; + modalInstance: ComponentRef<ModalComponent>; + @Input() service: Service; + @Input() onCreate: Function; + @Input() onSave: Function; + + constructor(private ModalServiceNg2: ModalService) {} + + onCreateServicePath = ():void => { + this.showServicePathMenu = false; + let cancelButton: ButtonModel = new ButtonModel('Cancel', 'outline white', this.ModalServiceNg2.closeCurrentModal); + let saveButton: ButtonModel = new ButtonModel('Create', 'blue', this.createPath, this.getDisabled ); + let modalModel: ModalModel = new ModalModel('l', 'Create Service Path', '', [saveButton, cancelButton], 'standard', true); + this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel); + this.ModalServiceNg2.addDynamicContentToModal(this.modalInstance, ServicePathCreatorComponent, {service: this.service}); + this.modalInstance.instance.open(); + }; + + onListServicePath = ():void => { + this.showServicePathMenu = false; + let cancelButton: ButtonModel = new ButtonModel('Close', 'outline white', this.ModalServiceNg2.closeCurrentModal); + let modalModel: ModalModel = new ModalModel('md', 'Service Paths List','', [cancelButton], 'standard', true); + this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel); + this.ModalServiceNg2.addDynamicContentToModal(this.modalInstance, ServicePathsListComponent, {service: this.service, + onCreateServicePath: this.onCreateServicePath, onEditServicePath: this.onEditServicePath}); + this.modalInstance.instance.open(); + }; + + createPath = ():void => { + this.onCreate(this.modalInstance.instance.dynamicContent.instance.createServicePathData()); + this.ModalServiceNg2.closeCurrentModal(); + }; + + onEditServicePath = (id:string):void => { + let cancelButton: ButtonModel = new ButtonModel('Cancel', 'outline white', this.ModalServiceNg2.closeCurrentModal); + let saveButton: ButtonModel = new ButtonModel('Save', 'blue', this.createPath, this.getDisabled ); + let modalModel: ModalModel = new ModalModel('l', 'Edit Path', '', [saveButton, cancelButton]); + this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel); + this.ModalServiceNg2.addDynamicContentToModal(this.modalInstance, ServicePathCreatorComponent, {service: this.service, pathId: id}); + this.modalInstance.instance.open(); + }; + + getDisabled = ():boolean => { + return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit(); + }; +} + diff --git a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.module.ts b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.module.ts new file mode 100644 index 0000000000..96af247086 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.module.ts @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +import { NgModule } from "@angular/core"; +import {CommonModule} from "@angular/common"; +import {ServicePathComponent} from "./service-path.component"; +import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module"; + +@NgModule({ + declarations: [ + ServicePathComponent + ], + imports: [CommonModule, + UiElementsModule], + exports: [], + entryComponents: [ + ServicePathComponent + ], + providers: [] +}) +export class ServicePathModule { +}
\ No newline at end of file |