1 import { Component, Input, OnInit } from '@angular/core';
2 import { Store } from '@ngxs/store';
6 Component as TopologyTemplate,
13 import { CompositionService } from 'app/ng2/pages/composition/composition.service';
14 import { WorkspaceService } from 'app/ng2/pages/workspace/workspace.service';
15 import { GroupByPipe } from 'app/ng2/pipes/groupBy.pipe';
16 import { ResourceNamePipe } from 'app/ng2/pipes/resource-name.pipe';
17 import { TopologyTemplateService } from 'app/ng2/services/component-services/topology-template.service';
18 import { ComponentInstanceServiceNg2 } from "app/ng2/services/component-instance-services/component-instance.service";
19 import { ComponentGenericResponse } from 'app/ng2/services/responses/component-generic-response';
20 import { TranslateService } from 'app/ng2/shared/translator/translate.service';
21 import { ModalsHandler } from 'app/utils';
22 import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular';
23 import {SelectedComponentType, TogglePanelLoadingAction} from "../../../common/store/graph.actions";
26 selector: 'properties-tab',
27 templateUrl: './properties-tab.component.html',
28 styleUrls: ['./properties-tab.component.less']
30 export class PropertiesTabComponent implements OnInit {
31 attributes: AttributesGroup;
32 isComponentInstanceSelected: boolean;
33 properties: PropertiesGroup;
34 groupPropertiesByInstance: boolean;
35 propertiesMessage: string;
36 metadata: ComponentMetadata;
37 objectKeys = Object.keys;
38 isUnboundedChecked: boolean;
39 isOccurrencesEnabled: boolean = false;
42 @Input() isViewOnly: boolean;
43 @Input() componentType: SelectedComponentType;
44 @Input() component: FullComponentInstance | TopologyTemplate;
45 @Input() input: {title: string};
47 constructor(private store: Store,
48 private workspaceService: WorkspaceService,
49 private compositionService: CompositionService,
50 private modalsHandler: ModalsHandler,
51 private topologyTemplateService: TopologyTemplateService,
52 private componentInstanceService: ComponentInstanceServiceNg2,
53 private modalService: SdcUiServices.ModalService,
54 private translateService: TranslateService,
55 private groupByPipe: GroupByPipe) {
59 this.metadata = this.workspaceService.metadata;
60 this.isComponentInstanceSelected = this.componentType === SelectedComponentType.COMPONENT_INSTANCE;
61 this.getComponentInstancesPropertiesAndAttributes();
64 public isPropertyOwner = (): boolean => {
65 return this.component instanceof TopologyTemplate && this.component.isResource();
68 public updateProperty = (property: PropertyModel): void => {
69 this.openEditPropertyModal(property);
72 public deleteProperty = (property: PropertyModel): void => {
74 const onOk: Function = (): void => {
75 this.store.dispatch(new TogglePanelLoadingAction({isLoading: true}));
76 this.topologyTemplateService.deleteProperty(this.component.componentType, this.component.uniqueId, property.uniqueId)
77 .subscribe((response) => {
78 this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
79 this.component.properties = this.component.properties.filter((prop) => prop.uniqueId !== property.uniqueId);
80 this.initComponentProperties();
82 this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
86 const title: string = this.translateService.translate('PROPERTY_VIEW_DELETE_MODAL_TITLE');
87 const message: string = this.translateService.translate('PROPERTY_VIEW_DELETE_MODAL_TEXT', {name: property.name});
91 type: SdcUiCommon.ButtonType.info,
93 closeModal: true} as SdcUiComponents.ModalButtonComponent;
94 this.modalService.openInfoModal(title, message, 'delete-modal', [okButton]);
97 public groupNameByKey = (key: string): string => {
102 case this.metadata.uniqueId:
103 return ResourceNamePipe.getDisplayName(this.metadata.name);
106 return this.getComponentInstanceNameFromInstanceByKey(key);
110 public getComponentInstanceNameFromInstanceByKey = (key: string): string => {
111 let instanceName: string = '';
112 const componentInstance = this.compositionService.getComponentInstances().find((item) => item.uniqueId === key);
113 if (key !== undefined && componentInstance) {
115 instanceName = ResourceNamePipe.getDisplayName(componentInstance.name);
120 private getComponentInstancesPropertiesAndAttributes = () => {
121 this.topologyTemplateService.getComponentInstanceAttributesAndProperties(
122 this.workspaceService.metadata.uniqueId,
123 this.workspaceService.metadata.componentType)
124 .subscribe((genericResponse: ComponentGenericResponse) => {
125 this.compositionService.componentInstancesAttributes = genericResponse.componentInstancesAttributes || new AttributesGroup();
126 this.compositionService.componentInstancesProperties = genericResponse.componentInstancesProperties;
127 this.initPropertiesAndAttributes();
131 private initComponentProperties = (): void => {
132 let result: PropertiesGroup = {};
134 this.propertiesMessage = undefined;
135 this.groupPropertiesByInstance = false;
136 if (this.component instanceof FullComponentInstance) {
137 result[this.component.uniqueId] = _.orderBy(this.compositionService.componentInstancesProperties[this.component.uniqueId], ['name']);
138 if (this.component.originType === 'VF') {
139 this.groupPropertiesByInstance = true;
140 result[this.component.uniqueId] = Array.from(this.groupByPipe.transform(result[this.component.uniqueId], 'path'));
142 } else if (this.metadata.isService()) {
143 // Temporally fix to hide properties for service (UI stack when there are many properties)
144 result = this.compositionService.componentInstancesProperties;
145 this.propertiesMessage = 'Note: properties for service are disabled';
147 const componentUid = this.component.uniqueId;
148 result[componentUid] = Array<PropertyModel>();
149 const derived = Array<PropertyModel>();
150 _.forEach(this.component.properties, (property: PropertyModel) => {
151 if (componentUid === property.parentUniqueId) {
152 result[componentUid].push(property);
154 property.readonly = true;
155 derived.push(property);
158 if (derived.length) {
159 result['derived'] = derived;
161 this.objectKeys(result).forEach((key) => { result[key] = _.orderBy(result[key], ['name']); });
163 this.properties = result;
166 private initComponentAttributes = (): void => {
167 let result: AttributesGroup = {};
169 if (this.component) {
170 if (this.component instanceof FullComponentInstance) {
171 result[this.component.uniqueId] = this.compositionService.componentInstancesAttributes[this.component.uniqueId] || [];
172 } else if (this.metadata.isService()) {
173 result = this.compositionService.componentInstancesAttributes;
175 result[this.component.uniqueId] = (this.component as TopologyTemplate).attributes;
177 this.attributes = result;
178 this.objectKeys(this.attributes).forEach((key) => {
179 this.attributes[key] = _.orderBy(this.attributes[key], ['name']);
185 private initComponentOccurrences = (): void => {
186 if (this.component instanceof FullComponentInstance) {
187 if(this.component.minOccurrences != null && this.component.maxOccurrences != null){
188 this.isOccurrencesEnabled = true;
190 this.isUnboundedChecked = this.component.maxOccurrences == "UNBOUNDED" ? true: false;
195 * This function is checking if the component is the value owner of the current property
196 * in order to notify the edit property modal which fields to disable
198 private isPropertyValueOwner = (): boolean => {
199 return this.metadata.isService() || !!this.component;
203 * The function opens the edit property modal.
204 * It checks if the property is from the VF or from one of it's resource instances and sends the needed property list.
205 * For create property reasons an empty array is transferd
207 * @param property the wanted property to edit/create
209 private openEditPropertyModal = (property: PropertyModel): void => {
210 this.modalsHandler.newOpenEditPropertyModal(property,
211 (this.isPropertyOwner() ?
212 this.properties[property.parentUniqueId] :
213 this.properties[property.resourceInstanceUniqueId]) || [],
214 this.isPropertyValueOwner(), 'component', property.resourceInstanceUniqueId).then((updatedProperty: PropertyModel) => {
215 if (updatedProperty) {
216 const oldProp = _.find(this.properties[updatedProperty.resourceInstanceUniqueId],
217 (prop: PropertyModel) => prop.uniqueId === updatedProperty.uniqueId);
218 oldProp.value = updatedProperty.value;
223 private initPropertiesAndAttributes = (): void => {
224 this.initComponentProperties();
225 this.initComponentAttributes();
226 this.initComponentOccurrences();
229 onUnboundedChanged(component: ComponentInstance) {
230 this.isUnboundedChecked = !this.isUnboundedChecked;
231 component.maxOccurrences = this.isUnboundedChecked ? "UNBOUNDED" : "1";
234 private updateComponentInstance(component: ComponentInstance) {
235 this.store.dispatch(new TogglePanelLoadingAction({isLoading: true}));
237 this.componentInstanceService.updateComponentInstance(this.workspaceService.metadata.componentType,
238 this.workspaceService.metadata.uniqueId, component)
239 .subscribe((updatedComponentInstance: ComponentInstance) => {
240 component = new ComponentInstance(updatedComponentInstance);
241 this.compositionService.getComponentInstances().find((item) => item.uniqueId === component.uniqueId).maxOccurrences = component.maxOccurrences;
242 this.compositionService.getComponentInstances().find((item) => item.uniqueId === component.uniqueId).minOccurrences = component.minOccurrences;
243 this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
245 this.store.dispatch(new TogglePanelLoadingAction({isLoading: false}));
251 private enableOccurrences = () => {
252 if(this.component instanceof FullComponentInstance){
253 if(!this.isOccurrencesEnabled){
254 this.component.minOccurrences = null;
255 this.component.maxOccurrences = null;
257 this.component.minOccurrences = "1";
258 this.component.maxOccurrences = "1";
260 this.updateComponentInstance(this.component);
264 private isOccurrencesFormValid(component: FullComponentInstance) {
266 component.minOccurrences && parseInt(component.minOccurrences) >= 0 &&
267 component.maxOccurrences && (parseInt(component.maxOccurrences) >= parseInt(component.minOccurrences) || component.maxOccurrences === "UNBOUNDED")
275 private saveOccurrences = () => {
276 if(this.component instanceof FullComponentInstance && this.isOccurrencesFormValid(this.component)) {
277 this.updateComponentInstance(this.component);