update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b third try
[osm/UI.git] / skyquake / plugins / admin / src / components / editor / 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 ClassNames from 'classnames'
20 import changeCase from 'change-case'
21 import yang from '../../yang/leaf-utils.js'
22 import { Input, Empty, Boolean, Reference, Enumeration } from './LeafEditor'
23
24 // import '../../styles/EditDescriptorModelProperties.scss'
25
26 function buildEditor(model, path, property, value, readOnly, id, onChange, onError, onExit) {
27         const title = path.join('.');
28
29         let editor = null;
30         id = id || property.name;
31         if (yang.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 (yang.isLeafRef(property)) {
41                 editor = <Reference
42                         model={model}
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 (yang.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 (yang.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 {
70                 editor = <Input
71                         property={property}
72                         id={id}
73                         value={value}
74                         title={title}
75                         onChange={onChange} onError={onError} onExit={onExit}
76                         readOnly={readOnly}
77                 />
78         }
79         return editor;
80 }
81
82 export default class LeafField extends React.Component {
83         constructor(props) {
84                 super(props);
85                 this.state = { showHelp: props.showHelp, isInError: props.errorMessage };
86         }
87         componentWillReceiveProps(nextProps) {
88                 const { showHelp, errorMessage } = nextProps
89                 if (showHelp !== this.state.showHelp && !this.state.isInError) {
90                         this.setState({ showHelp })
91                 }
92                 if (errorMessage !== this.state.errorMessage) {
93                         this.setState({ showHelp: !!errorMessage || showHelp, isInError: errorMessage })
94                 }
95         }
96         render() {
97                 const { model, path, property, value, id, readOnly, extraHelp, onChange, onError } = this.props;
98                 let title = changeCase.titleCase(property.name);
99                 const showHelp = this.state.showHelp;
100                 const description = (extraHelp ? extraHelp + ' ' : '') + property.description;
101                 const helpText = this.state.isInError ? this.state.isInError + " " + description : description;
102                 if (property.mandatory && !readOnly) {
103                         title = "* " + title;
104                 }
105                 const errorHandler = (message) => {
106                         this.setState({ showHelp: true, isInError: message });
107                 }
108                 const changeHandler = (value) => {
109                         this.setState({ showHelp: this.props.showHelp, isInError: false });
110                         onChange && onChange(value);
111                 }
112                 const exitHandler = (exitResult) => {
113                         if (!exitResult.success) {
114                                 // errorHandler(exitResult.message);
115                                 onError && onError(exitResult.message);
116                         }
117                 }
118
119                 const editor = buildEditor(
120                         model, path, property, value, readOnly, id,
121                         changeHandler, errorHandler, exitHandler);
122                 const helpStyle = {
123                         display: showHelp ? 'inline-block' : 'none',
124                         paddingTop: '2px',
125                         paddingLeft: '8px',
126                         color: this.state.isInError ? 'red' : 'darkgray',
127                         fontSize: 'small'
128                 };
129                 return (
130                         <div className={ClassNames('leaf-property -is-leaf property')} style={{paddingBottom: '10px'}} >
131                                 <h3 className="property-label">
132                                         <label htmlFor={id}>
133                                                 <span className={'leaf-name name info'}>{title}</span>
134                                         </label>
135                                 </h3>
136                                 <div className={ClassNames('property-content')}>
137                                         {editor}
138                                 </div>
139                                 <span className={'leaf-description description'}
140                                         style={helpStyle}>{helpText}</span>
141                         </div>
142                 );
143         }
144 }