diff options
Diffstat (limited to 'openecomp-ui/src/nfvo-components/panel')
5 files changed, 434 insertions, 0 deletions
diff --git a/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx b/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx new file mode 100644 index 0000000000..feb0f813ea --- /dev/null +++ b/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx @@ -0,0 +1,73 @@ +import React from 'react'; +import classnames from 'classnames'; +import Collapse from 'react-bootstrap/lib/Collapse.js'; + +class NavigationSideBar extends React.Component { + + static PropTypes = { + activeItemId: React.PropTypes.string.isRequired, + onSelect: React.PropTypes.func, + onToggle: React.PropTypes.func, + groups: React.PropTypes.array + }; + + render() { + let {groups, activeItemId} = this.props; + + return ( + <div className='navigation-side-content'> + {groups.map(group => ( + <div className='navigation-group' key={group.id}> + <div className='group-name'>{group.name}</div> + <div className='navigation-group-items'> + { + group.items && group.items.map(item => this.renderGroupItem(item, activeItemId)) + } + </div> + </div> + ))} + </div> + ); + } + + renderGroupItem(item, activeItemId) { + let isGroup = item.items && item.items.length > 0; + return ( + <div className={classnames('navigation-group-item', {'selected-item': item.id === activeItemId})}> + <div + key={item.id} + className={classnames('navigation-group-item-name', { + 'selected': item.id === activeItemId, + 'disabled': item.disabled, + 'bold-name': item.expanded, + 'hidden': item.hidden + })} + onClick={(event) => this.handleItemClicked(event, item)}> + {item.name} + </div> + {isGroup && + <Collapse in={item.expanded}> + <div> + {item.items.map(item => this.renderGroupItem(item, activeItemId))} + </div> + </Collapse> + } + </div> + ); + } + + handleItemClicked(event, item) { + event.stopPropagation(); + if(this.props.onToggle) { + this.props.onToggle(this.props.groups, item.id); + } + if(item.onSelect) { + item.onSelect(); + } + if(this.props.onSelect) { + this.props.onSelect(item); + } + } +} + +export default NavigationSideBar; diff --git a/openecomp-ui/src/nfvo-components/panel/SlidePanel.jsx b/openecomp-ui/src/nfvo-components/panel/SlidePanel.jsx new file mode 100644 index 0000000000..10c5326300 --- /dev/null +++ b/openecomp-ui/src/nfvo-components/panel/SlidePanel.jsx @@ -0,0 +1,109 @@ +import React from 'react'; +import FontAwesome from 'react-fontawesome'; +import ReactDOM from 'react-dom'; + +class SlidePanel extends React.Component { + + static PropTypes = { + direction: React.PropTypes.string.isRequired, + className: React.PropTypes.string, + title: React.PropTypes.string, + isOpen: React.PropTypes.bool + }; + + static defaultProps = { + title: '', + className: '', + isOpen: true + }; + + state = { + isOpen: this.props.isOpen, + direction: this.props.direction, + width: 0, + arrowWidth: 0 + }; + + componentDidMount() { + this.setSliderPosition(); + } + + componentDidUpdate() { + this.setSliderPosition(); + } + + render() { + + let {children, className} = this.props; + let {isOpen} = this.state; + + return ( + <div className={ `slide-panel ${className}`}> + {this.renderHeader(isOpen)} + <div className={'slide-panel-content ' + (isOpen ? 'opened' : 'closed')}>{children}</div> + </div> + ); + } + + renderHeader(isOpen) { + let {direction: initialDirection, title} = this.props; + let {direction: currentDirection} = this.state; + + let iconName = currentDirection === 'right' ? 'angle-double-right collapse-double-icon' : 'angle-double-left collapse-double-icon'; + + let awestyle = {padding: '5px'}; + + if (!isOpen && initialDirection === 'right') { + awestyle.marginLeft = '-1px'; + } + return ( + <div className='slide-panel-header'> + { initialDirection === 'left' && <span className='slide-panel-header-title'>{title}</span>} + <FontAwesome + ref='arrowIcon' + style={awestyle} + onClick={this.handleClick} + className='pull-right' + name={iconName} + size='2x'/> + { initialDirection === 'right' && <span className='slide-panel-header-title'>{title}</span>} + </div> + ); + } + + handleClick = () => { + this.setState({ + isOpen: !this.state.isOpen, + direction: this.state.direction === 'left' ? 'right' : 'left' + }); + } + + setSliderPosition = () => { + + let el = ReactDOM.findDOMNode(this); + let {style} = el; + + let {direction: initialDirection} = this.props; + let arrowIconSize = Math.floor(ReactDOM.findDOMNode(this.refs.arrowIcon).getBoundingClientRect().width) * 2; + if (!this.state.isOpen) { + if (this.props.direction === 'left') { + style.left = arrowIconSize - el.getBoundingClientRect().width + 'px'; + } + if (initialDirection === 'right') { + style.right = arrowIconSize - el.getBoundingClientRect().width + 'px'; + } + } + else { + if (initialDirection === 'left') { + style.left = '0px'; + } + + if (this.props.direction === 'right') { + style.right = '0px'; + } + } + } + +} + +export default SlidePanel;
\ No newline at end of file diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx new file mode 100644 index 0000000000..78525f84c6 --- /dev/null +++ b/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx @@ -0,0 +1,165 @@ +import React from 'react'; +import classnames from 'classnames'; +import i18n from 'nfvo-utils/i18n/i18n.js'; + +import Navbar from 'react-bootstrap/lib/Navbar.js'; +import Nav from 'react-bootstrap/lib/Nav.js'; +import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx'; +import {actionsEnum, statusEnum} from './VersionControllerConstants.js'; + + +class VersionController extends React.Component { + + static propTypes = { + version: React.PropTypes.string, + viewableVersions: React.PropTypes.array, + onVersionSwitching: React.PropTypes.func, + isCheckedOut: React.PropTypes.bool.isRequired, + status: React.PropTypes.string.isRequired, + callVCAction: React.PropTypes.func, + onSave: React.PropTypes.func, + onClose: React.PropTypes.func, + isFormDataValid: React.PropTypes.bool + }; + + render() { + let {status, isCheckedOut, version = '', viewableVersions = [], onVersionSwitching, callVCAction, onSave, isFormDataValid, onClose} = this.props; + let isCheckedIn = Boolean(status === statusEnum.CHECK_IN_STATUS); + let isLatestVersion = Boolean(version === viewableVersions[viewableVersions.length - 1]); + if (!isLatestVersion) { + status = statusEnum.PREVIOUS_VERSION; + } + + return ( + <div className='version-controller-bar'> + <Navbar inverse className='navbar'> + <Navbar.Collapse> + <Nav className='items-in-left'> + <div className='version-section'> + <ValidationInput + type='select' + selectedEnum={version} + onEnumChange={value => onVersionSwitching && onVersionSwitching(value)}> + {viewableVersions && viewableVersions.map(viewVersion => { + return ( + <option key={viewVersion} value={viewVersion}>{`V ${viewVersion}`}</option> + ); + }) + } + {!viewableVersions.includes(version) && + <option key={version} value={version}>{`V ${version}`}</option>} + </ValidationInput> + </div> + <div className='vc-status'> + <div className='onboarding-status-icon'></div> + <div className='status-text'> {i18n('ONBOARDING')} + <div className='status-text-dash'> -</div> + </div> + {this.renderStatus(status)} + </div> + </Nav> + <Nav pullRight> + <div className='items-in-right'> + <div className='action-buttons'> + {callVCAction && + <div className='version-control-buttons'> + <div + className={classnames('vc-nav-item-button button-submit', {'disabled': !isCheckedIn || !isLatestVersion})} + onClick={() => this.submit(callVCAction)}> + {i18n('Submit')} + </div> + <div + className={classnames('vc-nav-item-button button-checkin-checkout', {'disabled': status === statusEnum.LOCK_STATUS || !isLatestVersion})} + onClick={() => this.checkinCheckoutVersion(callVCAction)}> + {`${isCheckedOut ? i18n('Check In') : i18n('Check Out')}`} + </div> + <div + className={classnames('sprite-new revert-btn ng-scope ng-isolate-scope', {'disabled': !isCheckedOut || version === '0.1' || !isLatestVersion})} + onClick={() => this.revertCheckout(callVCAction)}> + </div> + </div> + } + {onSave && + <div + className={classnames('sprite-new save-btn ng-scope ng-isolate-scope', {'disabled': !isCheckedOut || !isFormDataValid || !isLatestVersion})} + onClick={() => onSave()}> + </div> + } + </div> + <div className='vc-nav-item-close' onClick={() => onClose && onClose()}> X</div> + </div> + </Nav> + </Navbar.Collapse> + </Navbar> + </div> + ); + } + + renderStatus(status) { + switch (status) { + case statusEnum.CHECK_OUT_STATUS: + return ( + <div className='checkout-status-icon'> + <div className='catalog-tile-check-in-status sprite-new checkout-editable-status-icon'></div> + <div className='status-text'> {i18n('CHECKED OUT')} </div> + </div> + ); + case statusEnum.LOCK_STATUS: + return ( + <div className='status-text'> {i18n('LOCKED')} </div> + ); + case statusEnum.CHECK_IN_STATUS: + return ( + <div className='status-text'> {i18n('CHECKED IN')} </div> + ); + case statusEnum.SUBMIT_STATUS: + return ( + <div className='status-text'> {i18n('SUBMITTED')} </div> + ); + default: + return ( + <div className='status-text'> {i18n(status)} </div> + ); + } + } + + checkinCheckoutVersion(callVCAction) { + if (this.props.isCheckedOut) { + this.checkin(callVCAction); + } + else { + this.checkout(callVCAction); + } + } + + checkin(callVCAction) { + + const action = actionsEnum.CHECK_IN; + + if (this.props.onSave) { + this.props.onSave().then(()=>{ + callVCAction(action); + }); + }else{ + callVCAction(action); + } + + } + + checkout(callVCAction) { + const action = actionsEnum.CHECK_OUT; + callVCAction(action); + } + + submit(callVCAction) { + const action = actionsEnum.SUBMIT; + callVCAction(action); + } + + revertCheckout(callVCAction) { + const action = actionsEnum.UNDO_CHECK_OUT; + callVCAction(action); + } +} + +export default VersionController; diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js new file mode 100644 index 0000000000..9251fd12c4 --- /dev/null +++ b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +import keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionsEnum = keyMirror({ + CHECK_IN: 'Checkin', + CHECK_OUT: 'Checkout', + UNDO_CHECK_OUT: 'Undo_Checkout', + SUBMIT: 'Submit', + CREATE_PACKAGE: 'Create_Package' +}); + +export const statusEnum = keyMirror({ + CHECK_OUT_STATUS: 'Locked', + CHECK_IN_STATUS: 'Available', + SUBMIT_STATUS: 'Final', + LOCK_STATUS: 'LockedByUser', + PREVIOUS_VERSION: 'READ ONLY' +}); + diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerUtils.js b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerUtils.js new file mode 100644 index 0000000000..de9914454c --- /dev/null +++ b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerUtils.js @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +import Configuration from 'sdc-app/config/Configuration.js'; +import {statusEnum} from './VersionControllerConstants.js'; + + +const VersionControllerUtils = { + + getCheckOutStatusKindByUserID(status, lockingUser) { + let currentLoginUserID = Configuration.get('ATTUserID'); + let isCheckedOut = currentLoginUserID === lockingUser; + + return { + status: isCheckedOut ? status : statusEnum.LOCK_STATUS, + isCheckedOut + }; + }, + + isCheckedOutByCurrentUser(resource) { + let currentLoginUserID = Configuration.get('ATTUserID'); + return resource.lockingUser !== undefined && resource.lockingUser === currentLoginUserID; + }, + + isReadOnly(resource) { + const {version, viewableVersions = []} = resource; + const latestVersion = viewableVersions[viewableVersions.length - 1]; + return version !== latestVersion || !VersionControllerUtils.isCheckedOutByCurrentUser(resource); + } +}; + +export default VersionControllerUtils; |