Fix errors and warnings
[sdc/sdc-workflow-designer.git] / workflow-designer-ui / src / main / frontend / src / features / version / composition / CompositionView.js
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 import React, { Component } from 'react';
17 import fileSaver from 'file-saver';
18 import CustomModeler from './custom-modeler';
19 import propertiesPanelModule from 'bpmn-js-properties-panel';
20 import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda';
21 import camundaModuleDescriptor from 'camunda-bpmn-moddle/resources/camunda';
22 import newDiagramXML from './newDiagram.bpmn';
23 import PropTypes from 'prop-types';
24 import CompositionButtons from './components/CompositionButtonsPanel';
25
26 class CompositionView extends Component {
27     static propTypes = {
28         compositionUpdate: PropTypes.func,
29         showErrorModal: PropTypes.func,
30         composition: PropTypes.bool,
31         name: PropTypes.string
32     };
33     constructor() {
34         super();
35         this.generatedId = 'bpmn-container' + Date.now();
36         this.fileInput = React.createRef();
37         this.state = {
38             diagram: false
39         };
40     }
41
42     componentDidMount() {
43         const { composition } = this.props;
44
45         this.modeler = new CustomModeler({
46             propertiesPanel: {
47                 parent: '#js-properties-panel'
48             },
49             additionalModules: [
50                 propertiesPanelModule,
51                 propertiesProviderModule
52             ],
53             moddleExtensions: {
54                 camunda: camundaModuleDescriptor
55             }
56         });
57         window.modeler = this.modeler;
58         this.modeler.attachTo('#' + this.generatedId);
59         this.setDiagram(composition ? composition : newDiagramXML);
60         var eventBus = this.modeler.get('eventBus');
61         eventBus.on('element.out', () => {
62             this.exportDiagramToStore();
63         });
64     }
65
66     setDiagram = diagram => {
67         this.setState(
68             {
69                 diagram
70             },
71             this.importXML
72         );
73     };
74
75     importXML = () => {
76         const { diagram } = this.state;
77         let modeler = this.modeler;
78         this.modeler.importXML(diagram, err => {
79             if (err) {
80                 //TDOD add i18n
81                 return this.props.showErrorModal('could not import diagram');
82             }
83             let canvas = modeler.get('canvas');
84             canvas.zoom('fit-viewport');
85         });
86     };
87
88     exportDiagramToStore = () => {
89         this.modeler.saveXML({ format: true }, (err, xml) => {
90             if (err) {
91                 //TODO   add i18n
92                 return this.props.showErrorModal('could not save diagram');
93             }
94             return this.props.compositionUpdate(xml);
95         });
96     };
97
98     exportDiagram = () => {
99         const { name, showErrorModal } = this.props;
100         this.modeler.saveXML({ format: true }, (err, xml) => {
101             if (err) {
102                 //TODO add i18n
103                 return showErrorModal('could not save diagram');
104             }
105             const blob = new Blob([xml], { type: 'text/html;charset=utf-8' });
106             fileSaver.saveAs(blob, `${name}-diagram.bpmn`);
107         });
108     };
109
110     loadNewDiagram = () => {
111         this.setDiagram(newDiagramXML);
112     };
113
114     uploadDiagram = () => {
115         this.fileInput.current.click();
116     };
117
118     handleFileInputChange = filesList => {
119         const file = filesList[0];
120         const reader = new FileReader();
121         reader.onloadend = event => {
122             var xml = event.target.result;
123             this.setDiagram(xml);
124             this.fileInput.value = '';
125         };
126         reader.readAsText(file);
127     };
128
129     render() {
130         return (
131             <div className="composition-view content">
132                 <input
133                     ref={this.fileInput}
134                     onChange={e => this.handleFileInputChange(e.target.files)}
135                     id="file-input"
136                     accept=".bpmn, .xml"
137                     type="file"
138                     name="file-input"
139                     style={{ display: 'none' }}
140                 />
141                 <div
142                     onBlur={() => {
143                         this.exportDiagramToStore();
144                     }}
145                     className="bpmn-container"
146                     id={this.generatedId}
147                 />
148                 <div className="bpmn-sidebar">
149                     <div
150                         className="properties-panel"
151                         id="js-properties-panel"
152                     />
153                     <CompositionButtons
154                         onClean={this.loadNewDiagram}
155                         onDownload={this.exportDiagram}
156                         onUpload={this.uploadDiagram}
157                     />
158                 </div>
159             </div>
160         );
161     }
162 }
163
164 export default CompositionView;