blob: ecfe7df116b01db219dbae00c9839a01be9b539b [file] [log] [blame]
AviZi280f8012017-06-09 02:39:56 +03001/*!
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 */
Michael Landoefa037d2017-02-19 12:57:33 +020016import React from 'react';
Michael Landoefa037d2017-02-19 12:57:33 +020017import i18n from 'nfvo-utils/i18n/i18n.js';
18
AviZi280f8012017-06-09 02:39:56 +030019import {actionsEnum, statusEnum, statusBarTextMap } from './VersionControllerConstants.js';
Avi Zivb8e2faf2017-07-18 19:45:38 +030020import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
AviZi280f8012017-06-09 02:39:56 +030021import Tooltip from 'react-bootstrap/lib/Tooltip.js';
22import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
Michael Landoefa037d2017-02-19 12:57:33 +020023
24
25class VersionController extends React.Component {
26
27 static propTypes = {
AviZi280f8012017-06-09 02:39:56 +030028 version: React.PropTypes.object,
Michael Landoefa037d2017-02-19 12:57:33 +020029 viewableVersions: React.PropTypes.array,
30 onVersionSwitching: React.PropTypes.func,
31 isCheckedOut: React.PropTypes.bool.isRequired,
32 status: React.PropTypes.string.isRequired,
33 callVCAction: React.PropTypes.func,
34 onSave: React.PropTypes.func,
35 onClose: React.PropTypes.func,
36 isFormDataValid: React.PropTypes.bool
37 };
38
39 render() {
AviZi280f8012017-06-09 02:39:56 +030040 let {status, isCheckedOut, version = {}, viewableVersions = [], onVersionSwitching, callVCAction, onSave, isFormDataValid, onClose} = this.props;
Michael Landoefa037d2017-02-19 12:57:33 +020041 let isCheckedIn = Boolean(status === statusEnum.CHECK_IN_STATUS);
AviZi280f8012017-06-09 02:39:56 +030042 let isLatestVersion = Boolean(version.id === viewableVersions[viewableVersions.length - 1].id);
Michael Landoefa037d2017-02-19 12:57:33 +020043 if (!isLatestVersion) {
44 status = statusEnum.PREVIOUS_VERSION;
45 }
Michael Landoefa037d2017-02-19 12:57:33 +020046 return (
47 <div className='version-controller-bar'>
AviZi280f8012017-06-09 02:39:56 +030048 <div className='vc-container'>
49 <div className='version-status-container'>
50 <VersionSelector viewableVersions={viewableVersions} version={version} onVersionSwitching={onVersionSwitching} />
51 <StatusBarUpdates status={status}/>
52 </div>
53 <div className='save-submit-cancel-container'>
54 <ActionButtons onSubmit={callVCAction ? () => this.submit(callVCAction, version) : undefined}
55 onRevert={callVCAction ? () => this.revertCheckout(callVCAction, version) : undefined}
56 status={status}
57 onCheckinCheckout={callVCAction ? () => this.checkinCheckoutVersion(callVCAction, version) : undefined}
58 onSave={onSave ? () => onSave() : undefined}
59 isLatestVersion={isLatestVersion}
60 isCheckedOut={isCheckedOut}
61 isCheckedIn={isCheckedIn} isFormDataValid={isFormDataValid} version={version}/>
62 {onClose && <div className='vc-nav-item-close' onClick={() => onClose()} data-test-id='vc-cancel-btn'> X</div>}
63 </div>
64 </div>
Michael Landoefa037d2017-02-19 12:57:33 +020065 </div>
66 );
67 }
68
AviZi280f8012017-06-09 02:39:56 +030069 submit(callVCAction, version) {
70 const action = actionsEnum.SUBMIT;
71 callVCAction(action, version);
Michael Landoefa037d2017-02-19 12:57:33 +020072 }
73
AviZi280f8012017-06-09 02:39:56 +030074 revertCheckout(callVCAction, version) {
75 const action = actionsEnum.UNDO_CHECK_OUT;
76 callVCAction(action, version);
77 }
78
79 checkinCheckoutVersion(callVCAction, version) {
Michael Landoefa037d2017-02-19 12:57:33 +020080 if (this.props.isCheckedOut) {
AviZi280f8012017-06-09 02:39:56 +030081 this.checkin(callVCAction, version);
Michael Landoefa037d2017-02-19 12:57:33 +020082 }
83 else {
AviZi280f8012017-06-09 02:39:56 +030084 this.checkout(callVCAction, version);
Michael Landoefa037d2017-02-19 12:57:33 +020085 }
86 }
AviZi280f8012017-06-09 02:39:56 +030087 checkin(callVCAction, version) {
Michael Landoefa037d2017-02-19 12:57:33 +020088 const action = actionsEnum.CHECK_IN;
Michael Landoefa037d2017-02-19 12:57:33 +020089 if (this.props.onSave) {
90 this.props.onSave().then(()=>{
AviZi280f8012017-06-09 02:39:56 +030091 callVCAction(action, version);
92 });
Michael Landoefa037d2017-02-19 12:57:33 +020093 }else{
AviZi280f8012017-06-09 02:39:56 +030094 callVCAction(action, version);
Michael Landoefa037d2017-02-19 12:57:33 +020095 }
96
97 }
AviZi280f8012017-06-09 02:39:56 +030098 checkout(callVCAction, version) {
Michael Landoefa037d2017-02-19 12:57:33 +020099 const action = actionsEnum.CHECK_OUT;
AviZi280f8012017-06-09 02:39:56 +0300100 callVCAction(action, version);
Michael Landoefa037d2017-02-19 12:57:33 +0200101 }
AviZi280f8012017-06-09 02:39:56 +0300102}
Michael Landoefa037d2017-02-19 12:57:33 +0200103
AviZi280f8012017-06-09 02:39:56 +0300104class ActionButtons extends React.Component {
105 static propTypes = {
106 version: React.PropTypes.object,
107 onSubmit: React.PropTypes.func,
108 onRevert: React.PropTypes.func,
109 onSave: React.PropTypes.func,
110 isLatestVersion: React.PropTypes.bool,
111 isCheckedIn: React.PropTypes.bool,
112 isCheckedOut: React.PropTypes.bool,
113 isFormDataValid: React.PropTypes.bool
114 };
115 render() {
116 const {onSubmit, onRevert, onSave, isLatestVersion, isCheckedIn, isCheckedOut, isFormDataValid, version, status, onCheckinCheckout} = this.props;
117 const [checkinBtnIconSvg, checkinCheckoutBtnTitle] = status === statusEnum.CHECK_OUT_STATUS ?
Avi Zivb8e2faf2017-07-18 19:45:38 +0300118 ['versionControllerLockOpen', i18n('Check In')] :
119 ['versionControllerLockClosed', i18n('Check Out')];
AviZi280f8012017-06-09 02:39:56 +0300120 const disabled = (isLatestVersion && onCheckinCheckout && status !== statusEnum.LOCK_STATUS) ? false : true;
121 return (
122 <div className='action-buttons'>
123 <VCButton dataTestId='vc-checkout-btn' onClick={onCheckinCheckout} isDisabled={disabled}
124 name={checkinBtnIconSvg} tooltipText={checkinCheckoutBtnTitle}/>
125 {onSubmit && onRevert &&
126 <div className='version-control-buttons'>
127 <VCButton dataTestId='vc-submit-btn' onClick={onSubmit} isDisabled={!isCheckedIn || !isLatestVersion}
Avi Zivb8e2faf2017-07-18 19:45:38 +0300128 name='versionControllerSubmit' tooltipText={i18n('Submit')}/>
AviZi280f8012017-06-09 02:39:56 +0300129 <VCButton dataTestId='vc-revert-btn' onClick={onRevert} isDisabled={!isCheckedOut || version.label === '0.1' || !isLatestVersion}
Avi Zivb8e2faf2017-07-18 19:45:38 +0300130 name='versionControllerRevert' tooltipText={i18n('Revert')}/>
AviZi280f8012017-06-09 02:39:56 +0300131 </div>
132 }
133 {onSave &&
134 <VCButton dataTestId='vc-save-btn' onClick={() => onSave()} isDisabled={!isCheckedOut || !isFormDataValid || !isLatestVersion}
Avi Zivb8e2faf2017-07-18 19:45:38 +0300135 name='versionControllerSave' tooltipText={i18n('Save')}/>
AviZi280f8012017-06-09 02:39:56 +0300136 }
137 </div>
138 );
Michael Landoefa037d2017-02-19 12:57:33 +0200139 }
AviZi280f8012017-06-09 02:39:56 +0300140}
Michael Landoefa037d2017-02-19 12:57:33 +0200141
AviZi280f8012017-06-09 02:39:56 +0300142function StatusBarUpdates({status}) {
143 return (
144 <div className='vc-status'>
145 <span className='status-text'>{i18n(statusBarTextMap[status])}</span>
146 </div>
147 );
148}
149
150function VCButton({name, tooltipText, isDisabled, onClick, dataTestId}) {
151 let onClickAction = isDisabled ? ()=>{} : onClick;
152 let disabled = isDisabled ? 'disabled' : '';
153
154 return (
155 <OverlayTrigger placement='top' overlay={<Tooltip id='vc-tooltip'>{tooltipText}</Tooltip>}>
156 <div disabled={disabled} className='action-buttons-svg'>
157 <SVGIcon data-test-id={dataTestId} iconClassName={disabled} onClick={onClickAction ? onClickAction : undefined} name={name}/>
158 </div>
159 </OverlayTrigger>
160 );
161}
162
163function VersionSelector(props) {
164 let {version = {}, viewableVersions = [], onVersionSwitching} = props;
165 const includedVersions = viewableVersions.filter(ver => {return ver.id === version.id;});
166 return (<div className='version-section-wrapper'>
167 <select className='version-selector'
168 onChange={ev => onVersionSwitching && onVersionSwitching({id: ev.target.value, label: ev.target.value})}
169 value={version.label}>
170 {viewableVersions && viewableVersions.map(viewVersion => {
171 return (
172 <option key={viewVersion.id} value={viewVersion.id} data-test-id='vc-version-option'>{`V ${viewVersion.label}`}</option>
173 );
174 })
175 }
176 {!includedVersions.length &&
177 <option key={version.id} value={version.id}>{`V ${version.label}`}</option>}
178 </select>
179 </div>);
Michael Landoefa037d2017-02-19 12:57:33 +0200180}
181
182export default VersionController;