4c90fc0be2c7abbe9fe1ea4db4fbbf233b13ccca
[sdc.git] /
1 /*!
2  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13  * or implied. See the License for the specific language governing
14  * permissions and limitations under the License.
15  */
16 import React from 'react';
17 import PropTypes from 'prop-types';
18 import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
19 import i18n from 'nfvo-utils/i18n/i18n.js';
20
21 import Form from 'nfvo-components/input/validation/Form.jsx';
22 import Input from 'nfvo-components/input/validation/Input.jsx';
23
24 import GridSection from 'nfvo-components/grid/GridSection.jsx';
25 import GridItem from 'nfvo-components/grid/GridItem.jsx';
26
27 const prefix = 'highAvailabilityAndLoadBalancing/';
28
29 const pointers = [
30     {
31         key: 'failureLoadDistribution',
32         description:
33             'How is load distributed across live vms in the event of a vm/host failure? please describe'
34     },
35     {
36         key: 'nkModelImplementation',
37         description:
38             'Does each VM implement the N+K model for redundancy and failure protection? Please describe.'
39     },
40     {
41         key: 'architectureChoice',
42         description:
43             'What architecture is being implemented: ACTIVE-ACTIVE and/or ACTIVE-PASSIVE. ',
44         added: 'Will the arrangement be 1-1 or N-M? Please describe.'
45     },
46     {
47         key: 'slaRequirements',
48         description: 'Specify application SLA requirements on Cloud platform.'
49     },
50     {
51         key: 'horizontalScaling',
52         description:
53             'Is horizontal scaling the preferred solution for HA and resiliency? Please describe.'
54     },
55     {
56         key: 'loadDistributionMechanism',
57         description:
58             'Can load be distributed across VMs? If so, are special mechanisms needed to re-balance data across VMs?',
59         added: 'Please describe.'
60     }
61 ];
62 //TODO check for buttons
63
64 const TextAreaItem = ({
65     item,
66     toggle,
67     expanded,
68     genericFieldInfo,
69     dataMap,
70     onQDataChanged
71 }) => (
72     <GridItem colSpan={3} key={item.key}>
73         <div
74             className={expanded ? 'title' : 'title add-padding'}
75             data-test-id={`btn-${item.key}`}
76             onClick={() => toggle(item.key)}>
77             <SVGIcon name={expanded ? 'chevronUp' : 'chevronDown'} />
78             <span className="title-text">{i18n(item.description)}</span>
79             {item.added && <div className="new-line">{i18n(item.added)}</div>}
80         </div>
81         <div className={expanded ? 'collapse in' : 'collapse'}>
82             <div>
83                 <div>
84                     <Input
85                         data-test-id={`input-${item.key}`}
86                         type="textarea"
87                         isValid={
88                             genericFieldInfo[`${prefix}${item.key}`].isValid
89                         }
90                         errorText={
91                             genericFieldInfo[`${prefix}${item.key}`].errorText
92                         }
93                         value={dataMap[`${prefix}${item.key}`]}
94                         onChange={val =>
95                             onQDataChanged({ [`${prefix}${item.key}`]: val })
96                         }
97                     />
98                 </div>
99             </div>
100         </div>
101     </GridItem>
102 );
103
104 class SoftwareProductComponentLoadBalancingView extends React.Component {
105     static propTypes = {
106         componentId: PropTypes.string.isRequired,
107         softwareProductId: PropTypes.string.isRequired,
108         qdata: PropTypes.object,
109         qschema: PropTypes.object,
110         currentSoftwareProduct: PropTypes.object
111     };
112
113     state = {
114         expanded: {}
115     };
116
117     render() {
118         let {
119             dataMap,
120             genericFieldInfo,
121             onQDataChanged,
122             isReadOnlyMode
123         } = this.props;
124         return (
125             <div className="vsp-components-load-balancing">
126                 <div className="halb-data">
127                     {genericFieldInfo && (
128                         <Form
129                             formReady={null}
130                             isValid={true}
131                             onSubmit={() => this.save()}
132                             isReadOnlyMode={isReadOnlyMode}
133                             hasButtons={false}>
134                             <GridSection
135                                 title={i18n(
136                                     'High Availability & Load Balancing'
137                                 )}>
138                                 <GridItem colSpan={1}>
139                                     <Input
140                                         data-test-id="input-is-component-mandatory"
141                                         label={i18n('Is Component Mandatory')}
142                                         type="select"
143                                         className="input-options-select"
144                                         groupClassName="bootstrap-input-options"
145                                         isValid={
146                                             genericFieldInfo[
147                                                 `${prefix}isComponentMandatory`
148                                             ].isValid
149                                         }
150                                         errorText={
151                                             genericFieldInfo[
152                                                 `${prefix}isComponentMandatory`
153                                             ].errorText
154                                         }
155                                         value={
156                                             dataMap[
157                                                 `${prefix}isComponentMandatory`
158                                             ]
159                                         }
160                                         onChange={e => {
161                                             const selectedIndex =
162                                                 e.target.selectedIndex;
163                                             const val =
164                                                 e.target.options[selectedIndex]
165                                                     .value;
166                                             onQDataChanged({
167                                                 [`${prefix}isComponentMandatory`]: val
168                                             });
169                                         }}>
170                                         <option key="placeholder" value="">
171                                             {i18n('Select...')}
172                                         </option>
173                                         {genericFieldInfo[
174                                             `${prefix}isComponentMandatory`
175                                         ].enum.map(isMan => (
176                                             <option
177                                                 value={isMan.enum}
178                                                 key={isMan.enum}>
179                                                 {isMan.title}
180                                             </option>
181                                         ))}
182                                     </Input>
183                                 </GridItem>
184                                 <GridItem colSpan={3} />
185                                 <GridItem colSpan={1}>
186                                     <Input
187                                         data-test-id="input-high-availability-mode"
188                                         label={i18n('High Availability Mode')}
189                                         type="select"
190                                         className="input-options-select"
191                                         groupClassName="bootstrap-input-options"
192                                         isValid={
193                                             genericFieldInfo[
194                                                 `${prefix}highAvailabilityMode`
195                                             ].isValid
196                                         }
197                                         errorText={
198                                             genericFieldInfo[
199                                                 `${prefix}highAvailabilityMode`
200                                             ].errorText
201                                         }
202                                         value={
203                                             dataMap[
204                                                 `${prefix}highAvailabilityMode`
205                                             ]
206                                         }
207                                         onChange={e => {
208                                             const selectedIndex =
209                                                 e.target.selectedIndex;
210                                             const val =
211                                                 e.target.options[selectedIndex]
212                                                     .value;
213                                             onQDataChanged({
214                                                 [`${prefix}highAvailabilityMode`]: val
215                                             });
216                                         }}>
217                                         <option key="placeholder" value="">
218                                             {i18n('Select...')}
219                                         </option>
220                                         {genericFieldInfo[
221                                             `${prefix}highAvailabilityMode`
222                                         ].enum.map(hmode => (
223                                             <option
224                                                 value={hmode.enum}
225                                                 key={hmode.enum}>
226                                                 {hmode.title}
227                                             </option>
228                                         ))}
229                                     </Input>
230                                 </GridItem>
231                                 <GridItem colSpan={3} />
232                             </GridSection>
233                             <GridSection>
234                                 {pointers.map(pointer => (
235                                     <TextAreaItem
236                                         onQDataChanged={onQDataChanged}
237                                         genericFieldInfo={genericFieldInfo}
238                                         dataMap={dataMap}
239                                         item={pointer}
240                                         key={pointer.key + 'pKey'}
241                                         expanded={
242                                             this.state.expanded[pointer.key]
243                                         }
244                                         toggle={name => {
245                                             this.toggle(name);
246                                         }}
247                                     />
248                                 ))}
249                             </GridSection>
250                         </Form>
251                     )}
252                 </div>
253             </div>
254         );
255     }
256
257     toggle(name) {
258         let st = this.state.expanded[name] ? true : false;
259         let newState = { ...this.state };
260         newState.expanded[name] = !st;
261         this.setState(newState);
262     }
263
264     save() {
265         let { onSubmit, qdata } = this.props;
266         return onSubmit({ qdata });
267     }
268 }
269
270 export default SoftwareProductComponentLoadBalancingView;