a2a06188183882b5d6d481d4289683f85dc50552
[sdc/sdc-workflow-designer.git] /
1 /*
2 * Copyright © 2018 European Support Limited
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 or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 import React from 'react';
18 import PropTypes from 'prop-types';
19 import { Translate, I18n } from 'react-redux-i18n';
20 import { SVGIcon } from 'sdc-ui/lib/react';
21
22 import SearchInput from 'shared/searchInput/SearchInput';
23 import { getValidtionsError } from 'features/version/inputOutput/inputOutputValidations';
24 import Tab from 'features/version/inputOutput/views/Tab';
25 import TableHead from 'features/version/inputOutput/views/TableHead';
26 import TableBody from 'features/version/inputOutput/views/TableBody';
27 import NoDataRow from 'features/version/inputOutput/views/NoDataRow';
28 import DataRow from 'features/version/inputOutput/views/DataRow';
29
30 class InputOutputView extends React.Component {
31     componentDidUpdate() {
32         const { dataRows, error, handleChangeError } = this.props;
33
34         const validationsError = getValidtionsError(dataRows);
35
36         const isDiff = Object.keys(validationsError).some(errorKey => {
37             if (!error.hasOwnProperty(errorKey)) {
38                 return true;
39             }
40
41             return (
42                 JSON.stringify(validationsError[errorKey].sort()) !==
43                 JSON.stringify(error[errorKey].sort())
44             );
45         });
46
47         if (isDiff) {
48             handleChangeError(validationsError);
49         }
50     }
51
52     handleInputsTabClick = () => {
53         if (!this.props.isShowInputs) {
54             this.props.handleShowInputs();
55         }
56     };
57
58     handleOutputsTabClick = () => {
59         if (this.props.isShowInputs) {
60             this.props.handleShowOutputs();
61         }
62     };
63
64     handleSearchChange = value => {
65         this.props.handleSearch(value);
66     };
67
68     handleNameChange = (key, isBlur = false) => value => {
69         let name = isBlur ? value.target.value : value;
70         name = name.replace(/\s+/g, ' ');
71         name = isBlur
72             ? name.replace(/^\s+|\s+$/g, '')
73             : name.replace(/^\s+/g, '');
74
75         this.props.handleNameChange(name, key);
76     };
77
78     handleTypeChange = key => event => {
79         this.props.handleTypeChange(event.target.value, key);
80     };
81
82     handleMandatoryChange = key => value => {
83         this.props.handleMandatoryChange(value, key);
84     };
85
86     handleRemoveClick = key => () => {
87         const { name } = this.props.dataRows[key];
88
89         let alertProps = false;
90
91         if (name.replace(/\s+/g, '')) {
92             const title = I18n.t('workflow.inputOutput.DELETE');
93             const body = I18n.t('workflow.inputOutput.confirmDlete', {
94                 name: name.replace(/s+$/g, '')
95             });
96             const closeButtonText = I18n.t('workflow.inputOutput.CANCEL');
97             const actionButtonText = title;
98
99             alertProps = {
100                 title,
101                 body,
102                 closeButtonText,
103                 actionButtonText
104             };
105         }
106
107         this.props.handleRemove(alertProps, key);
108     };
109
110     renderDataRows = () => {
111         const { dataRows, types, error } = this.props;
112
113         if (dataRows.length < 1) {
114             return (
115                 <NoDataRow>
116                     <Translate value="workflow.inputOutput.noData" />
117                 </NoDataRow>
118             );
119         }
120
121         return dataRows.map((data, i) => {
122             let errorMessage = '';
123
124             if (
125                 error.invalidCharacters &&
126                 error.invalidCharacters.includes(i)
127             ) {
128                 errorMessage = I18n.t('workflow.inputOutput.invalidCharacters');
129             } else if (error.alreadyExists && error.alreadyExists.includes(i)) {
130                 errorMessage = I18n.t('workflow.inputOutput.alreadyExists');
131             }
132
133             return (
134                 <DataRow
135                     key={`data.${i}`}
136                     data={data}
137                     types={types}
138                     nameErrorMessage={errorMessage}
139                     handleNameChange={this.handleNameChange(i)}
140                     handleNameBlur={this.handleNameChange(i, true)}
141                     handleTypeChange={this.handleTypeChange(i)}
142                     handleMandatoryChange={this.handleMandatoryChange(i)}
143                     handleRemoveClick={this.handleRemoveClick(i)}
144                 />
145             );
146         });
147     };
148
149     render() {
150         const { isShowInputs, search, handleAdd } = this.props;
151
152         const addLabel = isShowInputs
153             ? I18n.t('workflow.inputOutput.addInput')
154             : I18n.t('workflow.inputOutput.addOutput');
155
156         const dataRowsView = this.renderDataRows();
157
158         return (
159             <div className="input-output">
160                 <div className="input-output__title">
161                     <Translate value="workflow.sideBar.inputOutput" />
162                 </div>
163                 <div className="input-output__header">
164                     <Tab
165                         isActive={isShowInputs}
166                         handleTabClick={this.handleInputsTabClick}>
167                         <Translate value="workflow.inputOutput.inputs" />
168                     </Tab>
169                     <Tab
170                         isActive={!isShowInputs}
171                         handleTabClick={this.handleOutputsTabClick}>
172                         <Translate value="workflow.inputOutput.outputs" />
173                     </Tab>
174                     <div className="input-output__header__right">
175                         <div className="input-output__search">
176                             <SearchInput
177                                 onChange={this.handleSearchChange}
178                                 value={search}
179                             />
180                         </div>
181                         <div className="input-output__add" onClick={handleAdd}>
182                             <SVGIcon
183                                 label={addLabel}
184                                 labelPosition="right"
185                                 color="primary"
186                                 name="plusThin"
187                             />
188                         </div>
189                     </div>
190                 </div>
191                 <div className="input-output__table">
192                     <TableHead />
193                     <TableBody>{dataRowsView}</TableBody>
194                 </div>
195             </div>
196         );
197     }
198 }
199
200 InputOutputView.propTypes = {
201     isShowInputs: PropTypes.bool,
202     search: PropTypes.string,
203     dataRows: PropTypes.arrayOf(
204         PropTypes.shape({
205             name: PropTypes.string,
206             type: PropTypes.string,
207             mandatory: PropTypes.bool
208         })
209     ),
210     types: PropTypes.array,
211     error: PropTypes.object,
212     handleChangeError: PropTypes.func,
213     handleShowInputs: PropTypes.func,
214     handleShowOutputs: PropTypes.func,
215     handleSearch: PropTypes.func,
216     handleAdd: PropTypes.func,
217     handleCurrentDataChange: PropTypes.func,
218     handleNameChange: PropTypes.func,
219     handleTypeChange: PropTypes.func,
220     handleMandatoryChange: PropTypes.func,
221     handleRemove: PropTypes.func
222 };
223
224 export default InputOutputView;