bugfix for operations screen
[sdc.git] / catalog-ui / src / app / ng2 / pages / interface-operation / operation-creator / param-row / param-row.component.ts
1 import {Component, Input} from '@angular/core';
2 import {PROPERTY_DATA} from "app/utils";
3 import {DataTypeService} from "app/ng2/services/data-type.service";
4 import {OperationModel, OperationParameter, InputBEModel, DataTypeModel, Capability} from 'app/models';
5 import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
6
7 class DropdownValueType extends DropdownValue {
8     type: String;
9
10     constructor(value: string, label: string, type?: String) {
11         super(value, label);
12         if (type) {
13             this.type = type;
14         }
15     }
16 }
17
18 @Component({
19     selector: 'param-row',
20     templateUrl: './param-row.component.html',
21     styleUrls: ['./param-row.component.less']
22 })
23
24 export class ParamRowComponent {
25     @Input() param: OperationParameter;
26     @Input() inputProps: Array<InputBEModel>;
27     @Input() operationOutputs: Array<OperationModel>;
28     @Input() capabilitiesProps: Array<Capability>;
29     @Input() onRemoveParam: Function;
30     @Input() isAssociateWorkflow: boolean;
31     @Input() readonly: boolean;
32     @Input() isInputParam: boolean;
33     @Input() validityChanged: Function;
34
35     propTypeEnum: Array<string> = [];
36     operationOutputCats: Array<{ operationName: string, outputs: Array<DropdownValueType> }> = [];
37     filteredInputProps: Array<DropdownValue> = [];
38     filteredCapabilitiesProps: Array<{capabilityName: string, properties: Array<DropdownValueType>}> = [];
39
40     constructor(private dataTypeService:DataTypeService) {}
41
42     ngOnInit() {
43         if (this.isInputParam) {
44             this.propTypeEnum = _.uniq(
45                 _.map(
46                     _.concat(
47                         this.getPrimitiveSubtypes(),
48                         _.reduce(
49                             this.operationOutputs,
50                             (acc, op) => [...acc, ...op.outputs.listToscaDataDefinition],
51                             []),
52                         _.reduce(
53                             this.capabilitiesProps,
54                             (acc, capab) => [...acc, ...capab.properties],
55                             [])
56                     ),
57                     prop => prop.type
58                 )
59             );
60         } else {
61             const dataTypes: Array<DataTypeModel> = _.toArray(this.dataTypeService.getAllDataTypes());
62             this.propTypeEnum = _.concat(
63                 _.map(
64                     _.filter(
65                         dataTypes,
66                         type => this.isTypePrimitive(type.name)
67                     ),
68                     type => type.name
69                 ).sort(),
70                 _.map(
71                     _.filter(
72                         dataTypes,
73                         type => !this.isTypePrimitive(type.name)
74                     ),
75                     type => type.name
76                 ).sort()
77             );
78         }
79
80         this.onChangeType();
81         this.validityChanged();
82     }
83
84     onChangeName() {
85         this.validityChanged();
86     }
87
88     onChangeType() {
89         if (!this.isInputParam) {
90             this.validityChanged();
91             return;
92         }
93
94         this.filteredInputProps = _.map(
95             _.filter(
96                 this.getPrimitiveSubtypes(),
97                 prop => !this.param.type || prop.type === this.param.type
98             ),
99             prop => new DropdownValue(prop.uniqueId, prop.name)
100         );
101         this.filteredInputProps.unshift(new DropdownValue("",""));
102
103         this.operationOutputCats = _.filter(
104             _.map(
105                 this.operationOutputs,
106                 op => {
107                     return {
108                         operationName: `${op.displayType()}.${op.name}`,
109                         outputs: _.map(
110                             _.filter(op.outputs.listToscaDataDefinition, output => !this.param.type || output.type === this.param.type),
111                             output => new DropdownValueType(
112                                 `${op.interfaceType}.${op.name}.${output.name}`,
113                                 output.name,
114                                 output.type
115                             )
116                         )
117                     };
118                 }
119             ),
120             category => category.outputs.length > 0
121         );
122
123         this.filteredCapabilitiesProps = _.filter(
124             _.map(
125                 this.capabilitiesProps,
126                 cap => {
127                     return {
128                         capabilityName: cap.name,
129                         properties: _.map(
130                             _.filter(cap.properties, prop => !this.param.type || prop.type === this.param.type),
131                             prop => new DropdownValueType(
132                                 prop.uniqueId,
133                                 prop.name,
134                                 prop.type
135                             )
136                         )
137                     };
138                 }
139             ),
140             capability => capability.properties.length > 0
141         );
142
143         if (this.param.inputId) {
144             const selProp = this.getSelectedProp();
145             if (selProp && selProp.type === this.param.type) {
146                 this.param.inputId = '-1';
147                 setTimeout(() => this.param.inputId = selProp.uniqueId || selProp.value);
148             } else {
149                 this.param.inputId = null;
150             }
151         }
152
153         this.validityChanged();
154     }
155
156     onChangeProperty() {
157         const newProp = this.getSelectedProp();
158
159         if (!this.param.type) {
160             this.param.type = newProp.type;
161             this.onChangeType();
162         }
163
164         if (!this.param.name) {
165             this.param.name = newProp.name || newProp.label;
166         }
167
168         this.validityChanged();
169     }
170
171     getPrimitiveSubtypes(): Array<InputBEModel> {
172         const flattenedProps: Array<any> = [];
173         const dataTypes = this.dataTypeService.getAllDataTypes();
174
175         _.forEach(this.inputProps, prop => {
176             const type:DataTypeModel = _.find(
177                 _.toArray(dataTypes),
178                 (type: DataTypeModel) => type.name === prop.type
179             );
180             flattenedProps.push(prop);
181             if (!type) {
182                 console.error('Could not find prop in dataTypes: ', prop);
183             } else {
184                 if (type.properties) {
185                     _.forEach(type.properties, subType => {
186                         if (this.isTypePrimitive(subType.type)) {
187                             flattenedProps.push({
188                                 type: subType.type,
189                                 name: `${prop.name}.${subType.name}`,
190                                 uniqueId: `${prop.uniqueId}.${subType.name}`
191                             });
192                         }
193                     });
194                 }
195             }
196         });
197
198         return flattenedProps;
199     }
200
201     getSelectedProp() {
202         return _.find(
203             this.getPrimitiveSubtypes(),
204             prop => this.param.inputId === prop.uniqueId
205         ) || _.find(
206             _.reduce(
207                 this.operationOutputCats,
208                 (acc, cat) => [...acc, ...cat.outputs],
209             []),
210             (out: DropdownValueType) => this.param.inputId === out.value
211             ) || _.find(
212                 _.reduce(
213                     this.filteredCapabilitiesProps,
214                     (acc, cap) => [...acc, ...cap.properties],
215                     []),
216                 (prop: DropdownValueType) => this.param.inputId === prop.value
217         );
218     }
219
220     isTypePrimitive(type: string): boolean {
221         return (
222             type === 'string' ||
223             type === 'integer' ||
224             type === 'float' ||
225             type === 'boolean'
226         );
227     }
228 }