update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b third try
[osm/UI.git] / skyquake / plugins / composer / src / src / components / model / LeafField.jsx
1 /*
2  *
3  *   Copyright 2017 RIFT.IO Inc
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  *
17  */
18 import React from 'react';
19 import Button from '../Button'
20 import ClassNames from 'classnames'
21 import changeCase from 'change-case'
22 import Property from '../../libraries/model/DescriptorModelMetaProperty'
23 import { Input, Empty, Boolean, Reference, Enumeration } from './LeafEditor'
24
25 import '../../styles/EditDescriptorModelProperties.scss'
26
27 function buildEditor(container, property, path, value, readOnly, id, onChange, onError, onExit) {
28         const title = path.join('.');
29
30         let editor = null;
31         if (Property.isEnumeration(property)) {
32                 editor = <Enumeration
33                         property={property}
34                         id={id}
35                         value={value}
36                         title={title}
37                         onChange={onChange} onError={onError} onExit={onExit}
38                         readOnly={readOnly}
39                 />
40         } else if (Property.isLeafRef(property)) {
41                 editor = <Reference
42                         container={container}
43                         property={property}
44                         path={path}
45                         value={value}
46                         id={id}
47                         title={title}
48                         onChange={onChange} onError={onError} onExit={onExit}
49                         readOnly={readOnly}
50                 />
51         } else if (Property.isBoolean(property)) {
52                 editor = <Boolean
53                         property={property}
54                         id={id}
55                         value={value}
56                         title={title}
57                         onChange={onChange} onError={onError} onExit={onExit}
58                         readOnly={readOnly}
59                 />
60         } else if (Property.isLeafEmpty(property)) {
61                 editor = <Empty
62                         property={property}
63                         id={id}
64                         value={value}
65                         title={title}
66                         onChange={onChange} onError={onError} onExit={onExit}
67                         readOnly={readOnly}
68                 />
69         } else if (Property.name === 'meta') {
70                 if (typeof value === 'object') {
71                         value = JSON.stringify(value, undefined, 12);
72                 } else if (typeof value !== 'string') {
73                         value = '{}';
74                 }
75         } else {
76                 editor = <Input
77                         property={property}
78                         id={id}
79                         value={value}
80                         title={title}
81                         onChange={onChange} onError={onError} onExit={onExit}
82                         readOnly={readOnly}
83                 />
84         }
85         return editor;
86 }
87
88 export default class LeafField extends React.Component {
89         constructor(props) {
90                 super(props);
91                 this.state = { showHelp: props.showHelp, isInError: props.errorMessage };
92         }
93         componentWillReceiveProps(nextProps) {
94                 const { showHelp, errorMessage } = nextProps
95                 if (showHelp !== this.state.showHelp && !this.state.isInError) {
96                         this.setState({ showHelp })
97                 }
98                 if (errorMessage !== this.state.errorMessage) {
99                         this.setState({ showHelp: !!errorMessage || showHelp, isInError: errorMessage })
100                 }
101         }
102         render() {
103                 const { container, property, path, value, id, readOnly, onChange, onError } = this.props;
104                 let title = changeCase.titleCase(property.name);
105                 const showHelp = this.state.showHelp;
106                 const description = property.description;
107                 const helpText = this.state.isInError ? this.state.isInError + " " + description : description;
108                 if (property.mandatory) {
109                         title = "* " + title;
110                 }
111                 const errorHandler = (message) => {
112                         this.setState({ showHelp: true, isInError: message });
113                 }
114                 const changeHandler = (value) => {
115                         this.setState({ showHelp: this.props.showHelp, isInError: false });
116                         onChange && onChange(value);
117                 }
118                 const exitHandler = (exitResult) => {
119                         if (!exitResult.success) {
120                                 // errorHandler(exitResult.message);
121                                 onError && onError(exitResult.message);
122                         }
123                 }
124
125                 const editor = buildEditor(
126                         container, property, path, value, readOnly, id,
127                         changeHandler, errorHandler, exitHandler);
128                 const helpStyle = {
129                         display: showHelp ? 'inline-block' : 'none',
130                         paddingTop: '2px',
131                         color: this.state.isInError ? 'red' : 'inherit'
132                 };
133                 return (
134                         <div className={ClassNames('leaf-property -is-leaf property')}>
135                                 <h3 className="property-label">
136                                         <label htmlFor={id}>
137                                                 <span className={'leaf-name name info'}>{title}</span>
138                                         </label>
139                                 </h3>
140                                 <val className="property-value">
141                                         <div className={ClassNames('property-content')}>
142                                                 {editor}
143                                         </div>
144                                 </val>
145                                 <span className={'leaf-description description'}
146                                         style={helpStyle}>{helpText}</span>
147                         </div>
148                 );
149         }
150 }