update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b third try
[osm/UI.git] / skyquake / plugins / redundancy / src / dashboard / config.jsx
1 /*
2  * STANDARD_RIFT_IO_COPYRIGHT
3  */
4
5 import React from 'react';
6 import ReactDOM from 'react-dom';
7 import AppHeader from 'widgets/header/header.jsx';
8 import RedundancyStore from './redundancyStore.js';
9 import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
10 import SkyquakeRBAC from 'widgets/skyquake_rbac/skyquakeRBAC.jsx';
11 import 'style/layout.scss';
12 import {Panel, PanelWrapper} from 'widgets/panel/panel';
13 import {InputCollection, FormSection} from 'widgets/form_controls/formControls.jsx';
14
15 import TextInput from 'widgets/form_controls/textInput.jsx';
16 import Input from 'widgets/form_controls/input.jsx';
17 import Button, {ButtonGroup} from 'widgets/button/sq-button.jsx';
18 import SelectOption from 'widgets/form_controls/selectOption.jsx';
19 import 'widgets/form_controls/formControls.scss';
20 import imgAdd from '../../node_modules/open-iconic/svg/plus.svg'
21 import imgRemove from '../../node_modules/open-iconic/svg/trash.svg'
22 import _  from 'lodash';
23 import ROLES from 'utils/roleConstants.js';
24
25 import './redundancy.scss';
26 const PLATFORM = ROLES.PLATFORM;
27
28 class ConfigDashboard extends React.Component {
29     constructor(props) {
30         super(props);
31         this.Store = this.props.flux.stores.hasOwnProperty('RedundancyStore') ? this.props.flux.stores.RedundancyStore : this.props.flux.createStore(RedundancyStore, 'RedundancyStore');
32         this.state = this.Store.getState();
33         this.actions = this.state.actions;
34     }
35     componentDidUpdate() {
36     }
37     componentWillMount() {
38         this.state = this.Store.getState();
39         this.Store.getRedundancy();
40         this.Store.listen(this.updateState);
41     }
42     componentWillUnmount() {
43         this.Store.unlisten(this.updateState);
44     }
45     updateState = (state) => {
46         this.setState(state);
47     }
48     updateConfigInput = (containerName, key, e) => {
49         let configData = this.state[containerName];
50         if(!configData) {
51             configData = {};
52         }
53         configData[key] = e.target.value;
54         this.actions.handleUpdateConfigInput({[containerName]:configData})
55     }
56     updateDnsIpFqdnConfigInput = (e) => {
57         let value = e.target.value;
58         this.actions.handleUpdateConfigInput({'dns-ip-fqdn':value})
59     }
60     updateConfig = (e) => {
61         let self = this;
62         e.preventDefault();
63         e.stopPropagation();
64         let configData = self.state.configData;
65         let userCredentials = configData['user-credentials'];
66         if (!userCredentials || (userCredentials['username'].trim() == '' ) || (userCredentials['password'].trim() == '' )) {
67             self.props.flux.actions.global.showNotification("Please enter your user credentials");
68             return;
69         }
70         this.Store.updateConfig(configData);
71     }
72      evaluateSubmit = (e) => {
73         if (e.keyCode == 13) {
74             if (this.props.isEdit) {
75                 this.updateConfig(e);
76             } else {
77                 this.updateConfig(e);
78             }
79             e.preventDefault();
80             e.stopPropagation();
81         }
82     }
83     failOverDecisionChange = (e) => {
84         let value = e.target.value;
85         value = value.toUpperCase();
86         this.actions.handleFailOverDecisionChange(value);
87     }
88     render() {
89         let self = this;
90         let html;
91         let props = this.props;
92         let state = this.state;
93         let passwordSectionHTML = null;
94         let configData = state.configData;
95         let formButtonsHTML = (
96             <ButtonGroup className="buttonGroup">
97                 <Button label="Update" type="submit" onClick={this.updateConfig} />
98             </ButtonGroup>
99         )
100         let GeoFailoverDecision = this.state.configData['geographic-failover-decision'];
101
102         html = (
103                 <PanelWrapper onKeyUp={this.evaluateSubmit}
104                     className={`SiteAdmin column`} column>
105                     <AppHeader nav={[{ name: 'SITES', onClick: this.context.router.push.bind(this, { pathname: '/sites' })  }, { name: 'CONFIG'}, { name: 'STATUS', onClick: this.context.router.push.bind(this, { pathname: '/status' }) }]} />
106                     <PanelWrapper onKeyUp={this.evaluateSubmit}
107                     className={`SiteAdmin column`} style={{overflow: 'auto'}} column>
108                     <Panel
109                         title="GEOGRAPHIC FAILOVER DECISION"
110                         style={{flex: `0 0 ${GeoFailoverDecision != "INDIRECT" ? '150px' : '220px'}`}}
111                         no-corners>
112                         <Input className="userInfo-section"
113                             type="radiogroup"
114                             onChange={this.failOverDecisionChange}
115                             value={GeoFailoverDecision}
116                             options={state.failOverDecisionOptions}
117                         />
118                         {
119                             GeoFailoverDecision != "INDIRECT" ? null :
120                             <Input type="text"  onChange={self.updateDnsIpFqdnConfigInput.bind(self)} label="DNS FQDN/IP Address" value={state.configData['dns-ip-fqdn']} />
121                         }
122                     </Panel>
123                     {
124                         GeoFailoverDecision == "DIRECT" ?
125                             <Panel
126                                 title="Preferred Failback Site"
127                                 style={{flex: '0 0 160px'}}
128                                 no-corners>
129                                 <Input type="text"  onChange={self.updateConfigInput.bind(self, 'revertive-preference', 'preferred-site-name')} label="Site Name" value={state.configData['revertive-preference'] && state.configData['revertive-preference']['preferred-site-name']} />
130                             </Panel>
131                        : null
132                     }
133                      <Panel
134                         title="User Credentials"
135                         style={{flex: '0 0 250px'}}
136                         no-corners>
137                         <Input type="text"  onChange={self.updateConfigInput.bind(self, 'user-credentials', 'username')} label="Username" value={state.configData['user-credentials'] && state.configData['user-credentials']['username']}
138                         required />
139                         <Input type="password"  onChange={self.updateConfigInput.bind(self, 'user-credentials', 'password')} label="Password" value={state.configData['user-credentials'] && state.configData['user-credentials']['password']}
140                         required />
141                     </Panel>
142                     <Panel
143                         title="Polling Configuration"
144                         style={{flex: `0 0 ${GeoFailoverDecision != "INDIRECT" ? '390px' : '230px'}`}}
145                         no-corners>
146                             <Input type="text"  onChange={self.updateConfigInput.bind(self, 'polling-config', 'poll-interval')} label="polling interval (s)" value={state.configData['polling-config'] && state.configData['polling-config']['poll-interval']} />
147                             {
148                                 GeoFailoverDecision == "DIRECT" ?
149                                     <Input type="text"  onChange={self.updateConfigInput.bind(self, 'polling-config', 'failover-timeo')} label="Failover Timeout (s)" value={state.configData['polling-config'] && state.configData['polling-config']['failover-timeo']} />
150                                : null
151                             }
152                             {
153                                 GeoFailoverDecision == "DIRECT" ?
154                                     <Input type="text"  onChange={self.updateConfigInput.bind(self, 'polling-config', 'failback-timeo')} label="Failback Timeout (s)" value={state.configData['polling-config'] && state.configData['polling-config']['failback-timeo']} />
155                                : null
156                             }
157                             <Input type="text" onChange={self.updateConfigInput.bind(self,'polling-config', 'no-response-counter')} label="No Response Counter" value={state.configData['polling-config'] && state.configData['polling-config']['no-response-counter']} />
158
159
160                     </Panel>
161                     </PanelWrapper>
162                      <SkyquakeRBAC allow={[PLATFORM.SUPER, PLATFORM.ADMIN]} site={this.state.name} className="rbacButtonGroup">
163                         {formButtonsHTML}
164                      </SkyquakeRBAC>
165                 </PanelWrapper>
166         );
167         return html;
168     }
169 }
170 // onClick={this.Store.update.bind(null, Account)}
171 ConfigDashboard.contextTypes = {
172     router: React.PropTypes.object,
173     userProfile: React.PropTypes.object
174 };
175
176 ConfigDashboard.defaultProps = {
177     siteList: [],
178     selectedSite: {}
179 }
180
181 export default SkyquakeComponent(ConfigDashboard);
182
183
184 function isElementInView(el) {
185     var rect = el && el.getBoundingClientRect() || {};
186
187     return (
188         rect.top >= 0 &&
189         rect.left >= 0 &&
190         rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
191         rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
192     );
193 }
194
195
196 // isReadOnly={state.isReadOnly} disabled={state.disabled} onChange={this.disableChange}
197
198 class isDisabled extends React.Component {
199     constructor(props) {
200         super(props);
201     }
202     render() {
203         let props = this.props;
204         return (<div/>)
205     }
206 }
207
208 function showInput(e){
209   let target = e.target;
210   if(target.parentElement.classList.contains("addInput")) {
211     target = target.parentElement;
212   }
213   target.style.display = 'none';
214   target.parentElement.nextElementSibling.style.display = 'flex';
215   // e.target.parentElement.nextElementSibling.children[1].style.display = 'initial';
216 }
217 function hideInput(e){
218   let target = e.target;
219   if(target.parentElement.classList.contains("removeInput")) {
220     target = target.parentElement;
221   }
222   target.parentElement.style.display = 'none';
223   target.parentElement.previousElementSibling.children[1].style.display = 'inline';
224   target.previousSibling.value = '';
225 }
226
227