/* * * Copyright 2016 RIFT.IO Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import React from 'react'; import Button from 'widgets/button/rw.button.js'; import _cloneDeep from 'lodash/cloneDeep'; import _isEmpty from 'lodash/isEmpty'; import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx'; import Crouton from 'react-crouton'; import TextInput from 'widgets/form_controls/textInput.jsx'; import {AccountConnectivityStatus} from '../account_sidebar/accountSidebar.jsx'; import Utils from 'utils/utils.js'; import 'style/common.scss'; import './account.scss'; function isAccessDenied (error) { const rpcResult = Utils.rpcError(error); return rpcResult && rpcResult['rpc-reply']['rpc-error']['error-tag'] === 'access-denied'; } class Account extends React.Component { constructor(props) { super(props); // console.log(this.state.account) } storeListener = (state) => { if(state.socket) { if((!state.account || _isEmpty(state.account)) && state.userProfile) { this.setUp(this.props, state.savedData) } state.account && state.account.params && this.setState({ account: state.account, accountType: state.accountType, types: state.types, sdnOptions: state.sdnOptions, savedData: state.savedData, userProfile: state.userProfile }) } } componentWillMount() { this.state = this.props.store.getState(); this.props.store.listen(this.storeListener); } componentWillUpdate(nextProps, nextState, nextContext) { if(!_isEmpty(nextContext.userProfile) && !nextState.userProfile) { this.props.store.getTransientAccountForUser(nextContext.userProfile) } } componentWillReceiveProps(nextProps) { if(JSON.stringify(nextProps.params) != JSON.stringify(this.props.params)){ this.setUp(nextProps); } } componentWillUnmount() { console.log('unmounting') // this.setState({account: null, accountType: null, types: []}) this.props.store.unlisten(this.storeListener); } setUp(props, savedData){ console.log('Setting up'); var SD = savedData || this.state.savedData; if(props.params.name && props.params.name != 'create') { if (SD && SD == props.params.name) { this.props.store.viewAccount({type: props.params.type, name: props.params.name}, SD); } else { this.props.store.viewAccount({type: props.params.type, name: props.params.name}); } } else { this.props.store.setAccountTemplate(props.params.type, null, SD); } } create(e) { e.preventDefault(); var self = this; var Account = this.state.account; let AccountType = this.state.accountType; if (Account.name == "") { self.props.flux.actions.global.showNotification("Please give the account a name"); return; } else { if(!wasAllDetailsFilled(Account)) { self.props.flux.actions.global.showNotification("Please fill all account details"); return; } } let newAccount = _cloneDeep(removeTrailingWhitespace(Account)); delete newAccount.params; newAccount.nestedParams && newAccount.nestedParams['container-name'] && delete newAccount[newAccount.nestedParams['container-name']]; delete newAccount.nestedParams; if(AccountType == 'resource-orchestrator') { newAccount['ro-account-type'] = newAccount['account-type'] || newAccount['ro-account-type']; delete newAccount['account-type']; } if(AccountType == 'cloud' && self.props.vduInstanceTimeout != '') { newAccount['vdu-instance-timeout'] = self.props.vduInstanceTimeout; } this.props.flux.actions.global.showScreenLoader(); this.props.store.create(newAccount, AccountType).then( function() { self.props.router.push({pathname:'accounts'}); self.props.flux.actions.global.hideScreenLoader.defer(); }, function(error) { self.props.flux.actions.global.showNotification(error); self.props.flux.actions.global.hideScreenLoader.defer(); } ); } update(e) { e.preventDefault(); var self = this; var Account = this.state.account; let AccountType = this.state.accountType; if(!wasAllDetailsFilled(Account)) { self.props.flux.actions.global.showNotification("Please fill all account details"); return; } if(AccountType == 'cloud' && self.props.vduInstanceTimeout != '') { Account['vdu-instance-timeout'] = self.props.vduInstanceTimeout; } this.props.flux.actions.global.showScreenLoader(); this.props.store.update(Account, AccountType).then( function() { self.props.router.push({pathname:'accounts'}); self.props.flux.actions.global.hideScreenLoader(); }, function(error){ let msg = isAccessDenied(error) ? "Update of account failed. No authorization to modify accounts." : "Update of account failed. This could be because the account is in use or no longer exists."; self.props.flux.actions.global.hideScreenLoader.defer(); self.props.flux.actions.global.showNotification.defer(msg); } ); } cancel = (e) => { e.preventDefault(); e.stopPropagation(); this.props.flux.actions.global.handleCancelAccount(); this.props.router.push({pathname:'accounts'}); } handleDelete = () => { let self = this; let msg = 'Preparing to delete "' + self.state.account.name + '"' + ' Are you sure you want to delete this ' + self.state.accountType + ' account?"'; if (window.confirm(msg)) { this.props.flux.actions.global.showScreenLoader(); this.props.store.delete(self.state.accountType, self.state.account.name).then( function() { self.props.flux.actions.global.hideScreenLoader(); self.props.router.push({pathname:'accounts'}); }, function(error){ let msg = isAccessDenied(error) ? "Deletion of account failed. No authorization to delete accounts." : "Deletion of account failed. This could be because the account is in use or has already been deleted."; self.props.flux.actions.global.hideScreenLoader.defer(); self.props.flux.actions.global.showNotification.defer(msg); } ); } } handleNameChange(event) { this.props.store.handleNameChange(event); } handleAccountTypeChange(node, isRo, event) { this.props.store.handleAccountTypeChange(node, isRo, event); } handleSelectSdnAccount = (e) => { var tmp = this.state.account; if(e) { tmp['sdn-account'] = e; } else { if(tmp['sdn-account']) { delete tmp['sdn-account']; } } console.log(e, tmp) } updateVduInstanceTimeout(event) { this.props.store.updateVduTimeout(event) } preventDefault = (e) => { e.preventDefault(); e.stopPropagation(); } evaluateSubmit = (e) => { if (e.keyCode == 13) { if (this.props.params.name != 'create') { this.update(e); } else { this.create(e); } e.preventDefault(); e.stopPropagation(); } } render() { let self = this; let {store, ...props} = this.props; // This section builds elements that only show up on the create page. // var name = ; let Account = this.state.account || {}; var name = ; let params = null; let selectAccount = null; let resfreshStatus = null; // AccountType is for the view, not the data account-type value; let AccountType = this.state.accountType; let Types = this.state.types; let isEdit = this.props.params.name != 'create'; var buttons; let cloudResources = Account['cloud-resources-state'] && Account['cloud-resources-state'][Account['account-type']]; let cloudResourcesStateHTML = null; // Account Type Radio var selectAccountStack = []; let setVduTimeout = null; if (!isEdit) { buttons = [ ,