Add collaboration feature

Issue-ID: SDC-767
Change-Id: I14fb4c1f54086ed03a56a7ff7fab9ecd40381795
Signed-off-by: talig <talig@amdocs.com>
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/components/ActionButtons.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/components/ActionButtons.jsx
new file mode 100644
index 0000000..4346a0e
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/components/ActionButtons.jsx
@@ -0,0 +1,109 @@
+/*!
+ * 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.
+ */
+import React, {Component} from 'react';
+import PropTypes from 'prop-types';
+import enhanceWithClickOutside from 'react-click-outside';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
+import Overlay from 'nfvo-components/overlay/Overlay.jsx';
+import Permissions from './Permissions.jsx';
+
+class ClickOutsideWrapper extends Component {
+	handleClickOutside() {
+		this.props.onClose();
+	}
+	render() {
+		return <div>{this.props.children}</div>;
+	}
+}
+
+const EnhancedClickOutsideWrapper = enhanceWithClickOutside(ClickOutsideWrapper);
+
+const VCButton = ({name, tooltipText, disabled, onClick, dataTestId}) => {
+	let onClickAction = disabled ? ()=>{} : onClick;
+	return (
+		<div className={`action-button-wrapper ${disabled ? 'disabled' : 'clickable'}`} onClick={onClickAction}>
+			<div className='action-buttons-svg'>
+				<SVGIcon label={tooltipText} labelPosition='bottom' labelClassName='action-button-label'
+					 data-test-id={dataTestId} name={name} disabled={disabled}/>
+			</div>
+		</div>
+	);
+};
+
+const Separator = () => (<div className='vc-separator'></div>);
+
+const SubmitButton = ({onClick, disabled}) => (
+	<div onClick={()=>onClick()} data-test-id='vc-submit-btn' className={`vc-submit-button ${disabled ? 'disabled' : ''}`}>
+		<SVGIcon name='check' iconClassName='vc-v-submit' disabled={disabled} />
+		{i18n('Submit')}
+	</div>
+);
+
+
+const ActionButtons = ({isReadOnlyMode, onSubmit, onRevert, onSave, isFormDataValid, onClickPermissions, onSync, onCommit,
+	onOpenCommentCommitModal, showPermissions, onClosePermissions, permissions, onManagePermissions, userInfo, onOpenRevisionsModal, isManual,
+	itemPermissions: {isCertified, isCollaborator, isDirty, isOutOfSync, isUpToDate}}) => (
+	<div className='action-buttons'>
+		<EnhancedClickOutsideWrapper onClose={onClosePermissions}>
+			<VCButton disabled={isManual} dataTestId='vc-permission-btn' onClick={onClickPermissions}
+				name='version-controller-permissions' tooltipText={i18n('Permissons')} />
+			{showPermissions &&
+				<Overlay>
+					<Permissions userInfo={userInfo} onManagePermissions={onManagePermissions} permissions={permissions} onClosePermissions={onClosePermissions}/>
+				</Overlay>
+			}
+		</EnhancedClickOutsideWrapper>
+		{isCollaborator && <div className='collaborator-action-buttons'>
+			<Separator />
+			{onSave && <div className='vc-save-section'>
+					<VCButton dataTestId='vc-save-btn' onClick={() => onSave()}
+						name='version-controller-save'  tooltipText={i18n('Save')} disabled={isReadOnlyMode || !isFormDataValid} />
+					<Separator />
+				</div>
+			}
+			<VCButton dataTestId='vc-sync-btn' onClick={onSync}
+				name='version-controller-sync' tooltipText={i18n('Sync')} disabled={!isCollaborator || isUpToDate || isCertified} />
+			<VCButton dataTestId='vc-commit-btn' onClick={() => onOpenCommentCommitModal({onCommit, title: i18n('Commit')})}
+				name='version-controller-commit' tooltipText={i18n('Share')} disabled={isReadOnlyMode || !isDirty || isOutOfSync} />
+			{onRevert &&
+				<VCButton dataTestId='vc-revert-btn' onClick={onOpenRevisionsModal}
+					name='version-controller-revert' tooltipText={i18n('Revert')} disabled={isReadOnlyMode || isOutOfSync} />
+			}
+			{onSubmit && (permissions.owner && permissions.owner.userId === userInfo.userId) &&
+				<div className='vc-submit-section'>
+					<Separator />
+					<SubmitButton onClick={onSubmit}
+						disabled={isReadOnlyMode || isOutOfSync || !isUpToDate || isCertified} />
+				</div>
+			}
+		</div>}
+	</div>
+);
+
+ActionButtons.propTypes = {
+	version: PropTypes.object,
+	onSubmit: PropTypes.func,
+	onRevert: PropTypes.func,
+	onSave: PropTypes.func,
+	isLatestVersion: PropTypes.bool,
+	isCheckedIn: PropTypes.bool,
+	isCheckedOut: PropTypes.bool,
+	isFormDataValid: PropTypes.bool,
+	isReadOnlyMode: PropTypes.bool
+};
+
+export default ActionButtons;
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/components/CommitCommentModal.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/components/CommitCommentModal.jsx
new file mode 100644
index 0000000..600eaee
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/components/CommitCommentModal.jsx
@@ -0,0 +1,73 @@
+/*!
+ * 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.
+ */
+
+import React from 'react';
+import {connect} from 'react-redux';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const CommitModalType = keyMirror({
+	COMMIT: null,
+	COMMIT_SUBMIT: null
+
+});
+
+export const mapActionToProps = (dispatch) => {
+	return {
+		onClose: () => dispatch({
+			type: modalActionTypes.GLOBAL_MODAL_CLOSE
+		})
+	};
+};
+
+class CommitCommentModal extends React.Component {
+
+	state = {
+		comment: ''
+	};
+
+	render() {
+		const {onCommit, onClose, type} = this.props;
+		const [commitButtonText, descriptionText] = type === CommitModalType.COMMIT ?
+			[i18n('Commit'), i18n('You are about to commit your version')] :
+			[i18n('Commit & Submit'), i18n('You must commit your changes before the submit')];
+
+		return (
+			<Form
+				ref='validationForm'
+				hasButtons={true}
+				onSubmit={ () => {onCommit(this.state.comment); onClose();} }
+				onReset={onClose}
+				submitButtonText={commitButtonText}
+				labledButtons={true}
+				isValid={true}
+				className='comment-commit-form'>
+				<div className='commit-modal-text'>{descriptionText}</div>
+				<Input
+					data-test-id='commit-comment-text'
+					onChange={comment => this.setState({comment: comment})}
+					label={i18n('Enter Commit Comment:')}
+					value={this.state.comment}
+					type='textarea'/>
+			</Form>
+		);
+	}
+}
+
+export default connect(null, mapActionToProps)(CommitCommentModal);
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/components/Permissions.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/components/Permissions.jsx
new file mode 100644
index 0000000..952bd4f
--- /dev/null
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/components/Permissions.jsx
@@ -0,0 +1,65 @@
+/*!
+ * 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.
+ */
+
+import React from 'react';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
+
+const Contributor = ({name, role, id, userInfo}) => {
+
+	const selected = id === userInfo.userId ? 'selected' : '';
+
+	return(
+		<div className='contributor'>
+			<div className='contributor-content'>
+				<div className={`contributor-icon-circle ${selected}`}>
+					<div className={`contributer-icon ${selected}`}>
+						<SVGIcon name='user'/>
+					</div>
+				</div>
+				<div className='contributer-info'>
+					<div className='contributer-name'>{name}</div>
+					<div className='contributer-role'><p>{role}</p></div>
+				</div>
+			</div>
+		</div>
+	);
+};
+
+const Permissions = ({permissions: {owner, contributors}, onManagePermissions, userInfo, onClosePermissions}) => {
+
+	return (
+		<div className='permissions-overlay'>
+			<div className='permissions-overlay-header'>
+					<h4 className='permissions-overlay-header-title'>{i18n('PERMISSIONS')}</h4>
+				</div>
+				<div className='permissions-overlay-content'>
+					<Contributor userInfo={userInfo} id={owner.userId} key={owner.fullName} name={owner.fullName} role={owner.role}/>
+					{contributors.map(item => item.userId !== owner.userId && <Contributor userInfo={userInfo} id={item.userId} key={item.fullName} name={item.fullName} role={item.role}/>)}
+				</div>
+				<div className='permissions-overlay-footer'>
+				{
+				 owner.userId === userInfo.userId &&
+					<div onClick={() => { onClosePermissions(); onManagePermissions(); }} className='manage-permissions-btn'>
+						{i18n('Manage Permissions')}
+					</div>
+				}
+				</div>
+		</div>
+	);
+};
+
+export default Permissions;