diff options
author | ys9693 <ys9693@att.com> | 2020-01-19 13:50:02 +0200 |
---|---|---|
committer | Ofir Sonsino <ofir.sonsino@intl.att.com> | 2020-01-22 12:33:31 +0000 |
commit | 16a9fce0e104a38371a9e5a567ec611ae3fc7f33 (patch) | |
tree | 03a2aff3060ddb5bc26a90115805a04becbaffc9 /catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab | |
parent | aa83a2da4f911c3ac89318b8e9e8403b072942e1 (diff) |
Catalog alignment
Issue-ID: SDC-2724
Signed-off-by: ys9693 <ys9693@att.com>
Change-Id: I52b4aacb58cbd432ca0e1ff7ff1f7dd52099c6fe
Diffstat (limited to 'catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab')
3 files changed, 375 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab/properties-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab/properties-tab.component.html new file mode 100644 index 0000000000..86c6fea1ef --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab/properties-tab.component.html @@ -0,0 +1,97 @@ +<ng2-expand-collapse state="0"> + <header sdc-tooltip tooltip-text="{{input.title}}">{{input.title}}</header> + <content> + <div class="w-sdc-designer-sidebar-section"> + <div *ngIf="properties"> + <ng-container *ngFor="let key of objectKeys(properties); let idx = index"> + <sdc-accordion [title]="groupNameByKey(key) + ' Properties'" [css-class]="'properties-accordion'" [arrow-direction]="'right'" [testId]="groupNameByKey(key) + 'properties'" [open]="true"> + + <!--ng-show="isShowDetailsSection" --> + <div class="i-sdc-designer-sidebar-section-content-item" *ngIf="!groupPropertiesByInstance"> + <div class="i-sdc-designer-sidebar-section-content-item-property-and-attribute" attr.data-tests-id="propertyRow" + *ngFor="let property of properties[key]"> + + <div class="property-details"> + <span class="i-sdc-designer-sidebar-section-content-item-property-and-attribute-label" + [ngClass]="{'hand enabled': !isViewOnly}" + sdc-tooltip tooltip-text="{{property.name}}" + (click)="!isViewOnly && updateProperty(property)" + attr.data-tests-id="{{property.name}}">{{property.name}}</span> + <span class="i-sdc-designer-sidebar-section-content-item-property-value" *ngIf="isPropertyOwner()" + sdc-tooltip tooltip-text="{{property.defaultValue}}">{{property.defaultValue}}</span> + <span class="i-sdc-designer-sidebar-section-content-item-property-value" *ngIf="!isPropertyOwner()" + sdc-tooltip tooltip-text="{{property.value}}" + attr.data-tests-id="value_{{property.name}}">{{property.value}}</span> + </div> + <div class="property-buttons"> + <svg-icon *ngIf="!isViewOnly && (isPropertyOwner() && !property.readonly)" name="trash-o" clickable="true" size="medium" mode="info" testId="delete_{{property.name}}" (click)="deleteProperty(property)"></svg-icon> + </div> + </div> + </div> + <div class="i-sdc-designer-sidebar-section-content-item" *ngIf="groupPropertiesByInstance"> + <ng-container *ngFor="let InstanceProperties of properties[key]; let propIndex = index"> + <div class="vfci-properties-group"> + <div class="second-level"> + <div class="expand-collapse-title-icon"></div> + <span class="w-sdc-designer-sidebar-section-title-text" sdc-tooltip tooltip-text="{{getComponentInstanceNameFromInstanceByKey(InstanceProperties.key)}} Properties" + attr.data-tests-id="vfci-properties">{{getComponentInstanceNameFromInstanceByKey(InstanceProperties.key) + ' Properties'}}</span> + </div> + </div> + <div class="w-sdc-designer-sidebar-section-content instance-properties {{propIndex}}"> + <div class="i-sdc-designer-sidebar-section-content-item"> + <div class="i-sdc-designer-sidebar-section-content-item-property-and-attribute" attr.data-tests-id="propertyRow" + *ngFor="let instanceProperty of InstanceProperties.value"> + <div> + <span class="i-sdc-designer-sidebar-section-content-item-property-and-attribute-label" + [ngClass]="{'hand enabled': !isViewOnly}" + sdc-tooltip tooltip-text="{{instanceProperty.name}}" + attr.data-tests-id="vfci-property">{{instanceProperty.name}}</span> + </div> + <div> + <span class="i-sdc-designer-sidebar-section-content-item-property-value" + sdc-tooltip tooltip-text="{{instanceProperty.value === undefined ? instanceProperty.defaultValue : instanceProperty.value}}"> + {{instanceProperty.value === undefined ? instanceProperty.defaultValue : instanceProperty.value}}</span> + </div> + </div> + </div> + </div> + </ng-container> + </div> + <!--<div class="w-sdc-designer-sidebar-section-footer" *ngIf="(!isViewOnly && isPropertyOwner()) || showAddPropertyButton">--> + <!--<button class="w-sdc-designer-sidebar-section-footer-action tlv-btn blue" attr.data-tests-id="addGrey" (click)="addProperty()" type="button">--> + <!--Add Property--> + <!--</button>--> + <!--</div>--> + </sdc-accordion> + </ng-container> + </div> + + <!--attributes--> + <div *ngIf="attributes"> + <ng-container *ngFor="let key of objectKeys(attributes); let attrIndex = index"> + <sdc-accordion [title]="groupNameByKey(key) + ' Attributes'" [arrow-direction]="'right'" [testId]="groupNameByKey(key) + 'attributes'" [css-class]="'attributes-accordion'"> + <!--ng-show="isShowDetailsSection" --> + <div class="i-sdc-designer-sidebar-section-content-item"> + <div class="i-sdc-designer-sidebar-section-content-item-property-and-attribute" + *ngFor="let attribute of attributes[key]"> + <div> + <span class="i-sdc-designer-sidebar-section-content-item-property-and-attribute-label" + [ngClass]="{'hand enabled': !isViewOnly}" + sdc-tooltip tooltip-text="{{attribute.name}}" + (click)="!isViewOnly && viewAttribute(attribute)" + attr.data-tests-id="{{attribute.name}}-attr">{{attribute.name}}</span> + </div> + <div> + <span class="i-sdc-designer-sidebar-section-content-item-property-value" *ngIf="isPropertyOwner()" + sdc-tooltip tooltip-text="{{attribute.defaultValue}}">{{attribute.defaultValue}}</span> + <span class="i-sdc-designer-sidebar-section-content-item-property-value" *ngIf="!isPropertyOwner()" + sdc-tooltip tooltip-text="{{attribute.value}}" attr.data-tests-id="value-of-{{attribute.name}}">{{attribute.value}}</span> + </div> + </div> + </div> + </sdc-accordion> + </ng-container> + </div> + </div> + </content> +</ng2-expand-collapse> diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab/properties-tab.component.less b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab/properties-tab.component.less new file mode 100644 index 0000000000..5cb0697da1 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab/properties-tab.component.less @@ -0,0 +1,66 @@ +.scroll-container { + display: flex; + overflow-y: auto; +} + +.i-sdc-designer-sidebar-section-content-item-property-and-attribute { + color: #666666; + font-family: OpenSans-Semibold, sans-serif; + font-size: 14px; + border-bottom: 1px solid #cdcdcd; + min-height: 72px; + padding: 15px 10px 10px 18px; + // position: relative; + display:flex; + + .property-details { + flex:1; + } + + .property-buttons { + flex: 0 0 auto; + align-self: center; + } +} + +.i-sdc-designer-sidebar-section-content-item-property-and-attribute-label { + display: block; + font-weight: bold; + &:hover { + color: #3b7b9b; + } +} + +.i-sdc-designer-sidebar-section-content-item-property-and-attribute-label, .i-sdc-designer-sidebar-section-content-item-property-value { + overflow: hidden; + text-overflow: ellipsis; + max-width: 245px; + white-space: nowrap; + display: block; +} + + + +/deep/ .expand-collapse-content { + max-height: max-content; + padding: 10px 0; + + .sdc-accordion .sdc-accordion-header { + + background-color: #e6f6fb; + border-left: solid #009fdb 4px; + box-shadow: 0 0px 3px -1px rgba(0, 0, 0, 0.3); + margin-bottom: 2px; + width: auto; + height: auto; + padding: 10px; + color: #666666; + font-family: OpenSans-Semibold, sans-serif; + font-size: 14px; + + } + + /deep/.sdc-accordion .sdc-accordion-body { + padding-left: 0; + } +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab/properties-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab/properties-tab.component.ts new file mode 100644 index 0000000000..b4b8248ed0 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/properties-tab/properties-tab.component.ts @@ -0,0 +1,212 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Store } from '@ngxs/store'; +import { + AttributeModel, + AttributesGroup, + Component as TopologyTemplate, + ComponentMetadata, + FullComponentInstance, + PropertiesGroup, + PropertyModel +} from 'app/models'; +import { CompositionService } from 'app/ng2/pages/composition/composition.service'; +import { WorkspaceService } from 'app/ng2/pages/workspace/workspace.service'; +import { GroupByPipe } from 'app/ng2/pipes/groupBy.pipe'; +import { ResourceNamePipe } from 'app/ng2/pipes/resource-name.pipe'; +import { TopologyTemplateService } from 'app/ng2/services/component-services/topology-template.service'; +import { ComponentGenericResponse } from 'app/ng2/services/responses/component-generic-response'; +import { TranslateService } from 'app/ng2/shared/translator/translate.service'; +import { ModalsHandler } from 'app/utils'; +import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular'; +import {SelectedComponentType, TogglePanelLoadingAction} from "../../../common/store/graph.actions"; + +@Component({ + selector: 'properties-tab', + templateUrl: './properties-tab.component.html', + styleUrls: ['./properties-tab.component.less'] +}) +export class PropertiesTabComponent implements OnInit { + attributes: AttributesGroup; + isComponentInstanceSelected: boolean; + properties: PropertiesGroup; + groupPropertiesByInstance: boolean; + propertiesMessage: string; + metadata: ComponentMetadata; + objectKeys = Object.keys; + + @Input() isViewOnly: boolean; + @Input() componentType: SelectedComponentType; + @Input() component: FullComponentInstance | TopologyTemplate; + @Input() input: {title: string}; + + constructor(private store: Store, + private workspaceService: WorkspaceService, + private compositionService: CompositionService, + private modalsHandler: ModalsHandler, + private topologyTemplateService: TopologyTemplateService, + private modalService: SdcUiServices.ModalService, + private translateService: TranslateService, + private groupByPipe: GroupByPipe) { + } + + ngOnInit() { + this.metadata = this.workspaceService.metadata; + this.isComponentInstanceSelected = this.componentType === SelectedComponentType.COMPONENT_INSTANCE; + this.getComponentInstancesPropertiesAndAttributes(); + } + + public isPropertyOwner = (): boolean => { + return this.component instanceof TopologyTemplate && this.component.isResource(); + } + + public updateProperty = (property: PropertyModel): void => { + this.openEditPropertyModal(property); + } + + public deleteProperty = (property: PropertyModel): void => { + + const onOk: Function = (): void => { + this.store.dispatch(new TogglePanelLoadingAction({isLoading: true})); + this.topologyTemplateService.deleteProperty(this.component.componentType, this.component.uniqueId, property.uniqueId) + .subscribe((response) => { + this.store.dispatch(new TogglePanelLoadingAction({isLoading: false})); + this.component.properties = this.component.properties.filter((prop) => prop.uniqueId !== property.uniqueId); + this.initComponentProperties(); + }, () => { + this.store.dispatch(new TogglePanelLoadingAction({isLoading: false})); + }); + }; + + const title: string = this.translateService.translate('PROPERTY_VIEW_DELETE_MODAL_TITLE'); + const message: string = this.translateService.translate('PROPERTY_VIEW_DELETE_MODAL_TEXT', {name: property.name}); + const okButton = { + testId: 'OK', + text: 'OK', + type: SdcUiCommon.ButtonType.info, + callback: onOk, + closeModal: true} as SdcUiComponents.ModalButtonComponent; + this.modalService.openInfoModal(title, message, 'delete-modal', [okButton]); + } + + public groupNameByKey = (key: string): string => { + switch (key) { + case 'derived': + return 'Derived'; + + case this.metadata.uniqueId: + return ResourceNamePipe.getDisplayName(this.metadata.name); + + default: + return this.getComponentInstanceNameFromInstanceByKey(key); + } + } + + public getComponentInstanceNameFromInstanceByKey = (key: string): string => { + let instanceName: string = ''; + const componentInstance = this.compositionService.getComponentInstances().find((item) => item.uniqueId === key); + if (key !== undefined && componentInstance) { + + instanceName = ResourceNamePipe.getDisplayName(componentInstance.name); + } + return instanceName; + } + + private getComponentInstancesPropertiesAndAttributes = () => { + this.topologyTemplateService.getComponentInstanceAttributesAndProperties( + this.workspaceService.metadata.uniqueId, + this.workspaceService.metadata.componentType) + .subscribe((genericResponse: ComponentGenericResponse) => { + this.compositionService.componentInstancesAttributes = genericResponse.componentInstancesAttributes || new AttributesGroup(); + this.compositionService.componentInstancesProperties = genericResponse.componentInstancesProperties; + this.initPropertiesAndAttributes(); + }); + } + + private initComponentProperties = (): void => { + let result: PropertiesGroup = {}; + + this.propertiesMessage = undefined; + this.groupPropertiesByInstance = false; + if (this.component instanceof FullComponentInstance) { + result[this.component.uniqueId] = _.orderBy(this.compositionService.componentInstancesProperties[this.component.uniqueId], ['name']); + if (this.component.originType === 'VF') { + this.groupPropertiesByInstance = true; + result[this.component.uniqueId] = Array.from(this.groupByPipe.transform(result[this.component.uniqueId], 'path')); + } + } else if (this.metadata.isService()) { + // Temporally fix to hide properties for service (UI stack when there are many properties) + result = this.compositionService.componentInstancesProperties; + this.propertiesMessage = 'Note: properties for service are disabled'; + } else { + const componentUid = this.component.uniqueId; + result[componentUid] = Array<PropertyModel>(); + const derived = Array<PropertyModel>(); + _.forEach(this.component.properties, (property: PropertyModel) => { + if (componentUid === property.parentUniqueId) { + result[componentUid].push(property); + } else { + property.readonly = true; + derived.push(property); + } + }); + if (derived.length) { + result['derived'] = derived; + } + this.objectKeys(result).forEach((key) => { result[key] = _.orderBy(result[key], ['name']); }); + } + this.properties = result; + } + + private initComponentAttributes = (): void => { + let result: AttributesGroup = {}; + + if (this.component) { + if (this.component instanceof FullComponentInstance) { + result[this.component.uniqueId] = this.compositionService.componentInstancesAttributes[this.component.uniqueId] || []; + } else if (this.metadata.isService()) { + result = this.compositionService.componentInstancesAttributes; + } else { + result[this.component.uniqueId] = (this.component as TopologyTemplate).attributes; + } + this.attributes = result; + this.objectKeys(this.attributes).forEach((key) => { + this.attributes[key] = _.orderBy(this.attributes[key], ['name']); + }); + + } + } + + /** + * This function is checking if the component is the value owner of the current property + * in order to notify the edit property modal which fields to disable + */ + private isPropertyValueOwner = (): boolean => { + return this.metadata.isService() || !!this.component; + } + + /** + * The function opens the edit property modal. + * It checks if the property is from the VF or from one of it's resource instances and sends the needed property list. + * For create property reasons an empty array is transferd + * + * @param property the wanted property to edit/create + */ + private openEditPropertyModal = (property: PropertyModel): void => { + this.modalsHandler.newOpenEditPropertyModal(property, + (this.isPropertyOwner() ? + this.properties[property.parentUniqueId] : + this.properties[property.resourceInstanceUniqueId]) || [], + this.isPropertyValueOwner(), 'component', property.resourceInstanceUniqueId).then((updatedProperty: PropertyModel) => { + if (updatedProperty) { + const oldProp = _.find(this.properties[updatedProperty.resourceInstanceUniqueId], + (prop: PropertyModel) => prop.uniqueId === updatedProperty.uniqueId); + oldProp.value = updatedProperty.value; + } + }); + } + + private initPropertiesAndAttributes = (): void => { + this.initComponentProperties(); + this.initComponentAttributes(); + } +} |