[SDC-29] Amdocs OnBoard 1707 initial commit.
[sdc.git] / dox-sequence-diagram-ui / src / main / webapp / lib / ecomp / asdc / sequencer / components / editor / components / designer / components / lifeline / Lifeline.jsx
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
17 import React from 'react';
18 import { DragSource, DropTarget } from 'react-dnd';
19
20 import Common from '../../../../../../common/Common';
21
22 import Icon from '../../../../../icons/Icon';
23 import iconHandle from '../../../../../../../../../../res/ecomp/asdc/sequencer/sprites/icons/handle.svg';
24 import iconDelete from '../../../../../../../../../../res/ecomp/asdc/sequencer/sprites/icons/delete.svg';
25
26 /**
27  * LHS lifeline row view.
28  */
29 class Lifeline extends React.Component {
30
31   // ///////////////////////////////////////////////////////////////////////////////////////////////
32
33   /**
34    * Construct editor view.
35    * @param props element properties.
36    * @param context react context.
37    */
38   constructor(props, context) {
39     super(props, context);
40
41     this.state = {
42       active: false,
43       name: props.lifeline.name,
44     };
45
46     const metamodel = Common.assertNotNull(this.props.metamodel).unwrap();
47     this.canReorder = metamodel.diagram.lifelines.constraints.reorder;
48     this.canDelete = metamodel.diagram.lifelines.constraints.delete;
49
50     // Bindings.
51
52     this.onChangeName = this.onChangeName.bind(this);
53     this.onBlurName = this.onBlurName.bind(this);
54     this.onClickDelete = this.onClickDelete.bind(this);
55     this.onMouseEnter = this.onMouseEnter.bind(this);
56     this.onMouseLeave = this.onMouseLeave.bind(this);
57   }
58
59   // ///////////////////////////////////////////////////////////////////////////////////////////////
60
61   /**
62    * Handle name change.
63    * @param event change event.
64    */
65   onChangeName(event) {
66     this.setState({ name: event.target.value });
67   }
68
69   // ///////////////////////////////////////////////////////////////////////////////////////////////
70
71   /**
72    * Handle name change.
73    * @param event change event.
74    */
75   onBlurName(event) {
76     const options = this.props.application.getOptions();
77     const sanitized = Common.sanitizeText(event.target.value, options, 'lifeline');
78     const props = {
79       id: this.props.lifeline.id,
80       name: sanitized,
81     };
82     this.props.designer.updateLifeline(props);
83     this.setState({ name: sanitized });
84   }
85
86   // ///////////////////////////////////////////////////////////////////////////////////////////////
87
88   /**
89    * Handle lifeline delete.
90    */
91   onClickDelete() {
92     this.props.designer.deleteLifeline(this.props.lifeline.id);
93   }
94
95   // ///////////////////////////////////////////////////////////////////////////////////////////////
96
97   /**
98    * Handle mouseover event.
99    */
100   onMouseEnter() {
101     this.setState({ active: true });
102     this.props.designer.onMouseEnterLifeline(this.props.lifeline.id);
103   }
104
105   // ///////////////////////////////////////////////////////////////////////////////////////////////
106
107   /**
108    * Handle mouseleave event.
109    */
110   onMouseLeave() {
111     this.setState({ active: false });
112     this.props.designer.onMouseLeaveLifeline(this.props.lifeline.id);
113   }
114
115   // ///////////////////////////////////////////////////////////////////////////////////////////////
116
117   /**
118    * Get whether metadata permits reorder.
119    * @returns true if reorderable.
120    */
121   isCanReorder() {
122     return this.canReorder;
123   }
124
125   // ///////////////////////////////////////////////////////////////////////////////////////////////
126
127   /**
128    * Get whether metadata permits delete.
129    * @returns true if lifeline can be deleted.
130    */
131   isCanDelete() {
132     return this.canDelete;
133   }
134
135   // ///////////////////////////////////////////////////////////////////////////////////////////////
136
137   /**
138    * React render.
139    * @returns {*}
140    */
141   render() {
142
143     const id = this.props.lifeline.id;
144     const activeClass = (this.props.active === true) ? 'asdcs-active' : '';
145     const { connectDragSource, connectDropTarget } = this.props;
146     return connectDragSource(connectDropTarget(
147
148       <div
149         className={`asdcs-designer-lifeline ${activeClass}`}
150         data-id={id}
151         onMouseEnter={this.onMouseEnter}
152         onMouseLeave={this.onMouseLeave}
153       >
154         <table className="asdcs-designer-layout asdcs-designer-lifeline-row1">
155           <tbody>
156             <tr>
157               <td>
158                 <div className="asdcs-designer-sort asdcs-designer-icon">
159                   <Icon glyph={iconHandle} />
160                 </div>
161               </td>
162               <td>
163                 <div className="asdcs-designer-lifeline-index">{this.props.lifeline.index}.</div>
164               </td>
165               <td>
166                 <div className="asdcs-designer-lifeline-name">
167                   <input
168                     type="text"
169                     className="asdcs-editable"
170                     placeholder="Unnamed"
171                     value={this.state.name}
172                     onChange={this.onChangeName}
173                     onBlur={this.onBlurName}
174                   />
175                 </div>
176               </td>
177               <td>
178                 <div className="asdcs-designer-delete asdcs-designer-icon" onClick={this.onClickDelete}>
179                   <Icon glyph={iconDelete} />
180                 </div>
181               </td>
182             </tr>
183           </tbody>
184         </table>
185       </div>
186     ));
187   }
188 }
189
190 /**
191  * Declare properties.
192  */
193 Lifeline.propTypes = {
194   application: React.PropTypes.object.isRequired,
195   designer: React.PropTypes.object.isRequired,
196   lifeline: React.PropTypes.object.isRequired,
197   active: React.PropTypes.bool.isRequired,
198   metamodel: React.PropTypes.object.isRequired,
199   id: React.PropTypes.any.isRequired,
200   index: React.PropTypes.number.isRequired,
201   lifelines: React.PropTypes.object.isRequired,
202   isDragging: React.PropTypes.bool.isRequired,
203   connectDragSource: React.PropTypes.func.isRequired,
204   connectDropTarget: React.PropTypes.func.isRequired,
205 };
206
207 /** DND. */
208 const source = {
209   beginDrag(props) {
210     return {
211       id: props.id,
212       index: props.index,
213     };
214   },
215 };
216
217 /** DND. */
218 const sourceCollect = function collection(connect, monitor) {
219   return {
220     connectDragSource: connect.dragSource(),
221     isDragging: monitor.isDragging(),
222   };
223 };
224
225 /** DND. */
226 const target = {
227   drop(props, monitor, component) {
228     Common.assertNotNull(props);
229     Common.assertNotNull(monitor);
230     const decorated = component.getDecoratedComponentInstance();
231     if (decorated) {
232       const lifelines = decorated.props.lifelines;
233       if (lifelines) {
234         const dragIndex = monitor.getItem().index;
235         const hoverIndex = lifelines.getHoverIndex();
236         lifelines.onDrop(dragIndex, hoverIndex);
237       }
238     }
239   },
240   hover(props, monitor, component) {
241     Common.assertNotNull(props);
242     Common.assertNotNull(monitor);
243     if (component) {
244       const decorated = component.getDecoratedComponentInstance();
245       if (decorated) {
246         const lifelines = decorated.props.lifelines;
247         if (lifelines) {
248           lifelines.setHoverIndex(decorated.props.index);
249         }
250       }
251     }
252   },
253 };
254
255 /** DND. */
256 function targetCollect(connect, monitor) {
257   return {
258     connectDropTarget: connect.dropTarget(),
259     isOver: monitor.isOver(),
260   };
261 }
262
263 const wrapper1 = DragSource('lifeline', source, sourceCollect)(Lifeline);
264 export default DropTarget(['lifeline', 'lifeline-new'], target, targetCollect)(wrapper1);