Merge branch 'application-mgt-new' into 'application-mgt-new'

Create new lifecycle component

See merge request entgra/carbon-device-mgt!144
feature/appm-store/pbac
Dharmakeerthi Lasantha 6 years ago
commit caa3ae76fc

@ -22,6 +22,7 @@
"react-dom": "^16.8.4",
"react-highlight-words": "^0.16.0",
"react-infinite-scroller": "^1.2.4",
"react-quill": "^1.3.3",
"react-router": "latest",
"react-router-config": "^5.0.0",
"react-router-dom": "latest",

@ -1,7 +0,0 @@
.srd-diagram{
height: 100%;
min-height: 300px;
background-color: #3c3c3c !important;
background-image: linear-gradient(0deg, transparent 24%, rgba(255, 255, 255, 0.05) 25%, rgba(255, 255, 255, 0.05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, 0.05) 75%, rgba(255, 255, 255, 0.05) 76%, transparent 77%, transparent), linear-gradient(90deg, transparent 24%, rgba(255, 255, 255, 0.05) 25%, rgba(255, 255, 255, 0.05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, 0.05) 75%, rgba(255, 255, 255, 0.05) 76%, transparent 77%, transparent);
background-size: 50px 50px;
}

@ -41,7 +41,7 @@ class ReleaseView extends React.Component {
<Button htmlType="button"
type="primary"
icon="shop"
disabled={release.currentStatus !== "PUBLISHED"}
disabled={this.props.currentLifecycleStatus !== "PUBLISHED"}
onClick={() => {
window.open("https://"+ config.serverConfig.hostname + ':' + config.serverConfig.httpsPort+"/store/"+app.deviceType+"/apps/"+release.uuid)
}}>

@ -0,0 +1,17 @@
.ql-editor{
min-height: 100px !important;
max-height: 400px;
overflow: hidden;
overflow-y: scroll;
overflow-x: scroll;
}
.ql-toolbar.ql-snow{
border-radius: 10px 10px 0 0;
}
.ql-toolbar.ql-snow + .ql-container.ql-snow{
border-radius: 0 0 10px 10px;
}
.ql-editor.ql-blank::before {
font-style: unset;
}

@ -0,0 +1,253 @@
import React from "react";
import {Typography, Tag, Divider, Select, Button, Modal, message, notification, Collapse} from "antd";
import axios from "axios";
import config from "../../../../../public/conf/config.json";
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import './LifeCycle.css';
const {Text, Title, Paragraph} = Typography;
const {Option} = Select;
const Panel = Collapse.Panel;
const modules = {
toolbar: [
[{'header': [1, 2, false]}],
['bold', 'italic', 'underline', 'strike', 'blockquote', 'code-block'],
[{'list': 'ordered'}, {'list': 'bullet'}],
['link', 'image']
],
};
const formats = [
'header',
'bold', 'italic', 'underline', 'strike', 'blockquote', 'code-block',
'list', 'bullet',
'link', 'image'
];
class LifeCycle extends React.Component {
constructor(props) {
super(props);
this.state = {
currentStatus: props.currentStatus,
selectedStatus: null,
lifecycle: [],
reasonText: '',
isReasonModalVisible: false,
isConfirmButtonLoading: false
}
}
componentDidMount() {
this.fetchData();
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (prevProps.currentStatus !== this.props.currentStatus || prevProps.uuid !== this.props.uuid) {
this.setState({
currentStatus: this.props.currentStatus
});
}
}
fetchData = () => {
axios.get(config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/lifecycle-config",
{
headers: {'X-Platform': config.serverConfig.platform}
}).then(res => {
if (res.status === 200) {
const lifecycle = res.data.data;
console.log(lifecycle);
this.setState({
lifecycle: lifecycle
})
}
}).catch(function (error) {
if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
}
});
};
handleChange = (value) => {
this.setState({reasonText: value})
};
handleSelectChange = (value) => {
this.setState({selectedStatus: value})
};
showReasonModal = () => {
this.setState({
isReasonModalVisible: true
});
};
closeReasonModal = () => {
this.setState({
isReasonModalVisible: false
});
};
addLifeCycle = () => {
const {selectedStatus, reasonText} = this.state;
const {uuid} = this.props;
const data = {
action: selectedStatus,
reason: reasonText
};
this.setState({
isConfirmButtonLoading: true,
});
axios.post(config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.publisher + "/applications/life-cycle/" + uuid,
data,
{
headers: {'X-Platform': config.serverConfig.platform}
}).then(res => {
if (res.status === 201) {
this.setState({
isReasonModalVisible: false,
isConfirmButtonLoading: false,
currentStatus: selectedStatus,
selectedStatus: null,
reasonText: ''
});
this.props.changeCurrentLifecycleStatus(selectedStatus);
notification["success"]({
message: "Done!",
description:
"Lifecycle state updated successfully!",
});
}
}).catch((error) => {
if (error.hasOwnProperty("response") && error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else {
notification["error"]({
message: "Error",
description:
"Something went wrong",
});
}
this.setState({
isConfirmButtonLoading: false
});
});
};
render() {
const {currentStatus, lifecycle, selectedStatus} = this.state;
const selectedValue = selectedStatus == null ? [] : selectedStatus;
return (
<div>
<Title level={4}>Manage Lifecycle</Title>
<Divider/>
<Paragraph>
Ensure that your security policies are not violated by the application. Have a thorough review and
approval process before directly publishing it to your app store. You can easily transition from one
state to another. <br/>Note: Change State To displays only the next states allowed from the
current state
</Paragraph>
<Divider dashed={true}/>
<Text strong={true}>Current State: </Text> <Tag color="blue">{currentStatus}</Tag><br/><br/>
<Text>Change State to: </Text>
<Select
placeholder="Select state"
style={{width: 120}}
size="small"
onChange={this.handleSelectChange}
value={selectedValue}
showSearch={true}
>
{
Object.keys(lifecycle).map(lifecycleState => {
return (
<Option
disabled={!(lifecycle[currentStatus].proceedingStates.includes(lifecycleState))}
key={lifecycleState}
value={lifecycleState}>
{lifecycleState}
</Option>
)
})
}
</Select>
<Button
style={{marginLeft: 10}}
size="small"
type="primary"
htmlType="button"
onClick={this.showReasonModal}
disabled={selectedStatus == null}
>
Change
</Button>
<Divider/>
<Text strong={true}>Lorem Ipsum</Text>
<Collapse defaultActiveKey={currentStatus}>
{
Object.keys(lifecycle).map(lifecycleState => {
return (
<Panel header={lifecycleState} key={lifecycleState}>
{
Object.keys(lifecycle).map(state => {
// console.log(lifecycle[lifecycleState].proceedingStates);
const isEnabled = lifecycle[lifecycleState].hasOwnProperty("proceedingStates") && (lifecycle[lifecycleState].proceedingStates.includes(state));
const color = isEnabled ? "green" : "";
return (
<Tag
disabled={!isEnabled}
key={state} style={{marginBottom: 5}} color={color}>{state}</Tag>
)
})
}
</Panel>
)
})
}
</Collapse>
<Modal
title="Confirm changing lifecycle state"
visible={this.state.isReasonModalVisible}
onOk={this.addLifeCycle}
onCancel={this.closeReasonModal}
okText="confirm"
>
<Text>
You are going to change the lifecycle state from,<br/>
<Tag color="blue">{currentStatus}</Tag>to <Tag
color="blue">{selectedStatus}</Tag>
</Text>
<br/><br/>
<ReactQuill
theme="snow"
value={this.state.reasonText}
onChange={this.handleChange}
modules={modules}
formats={formats}
placeholder="Leave a comment (optional)"
/>
</Modal>
</div>
);
}
}
export default LifeCycle;

@ -42,7 +42,7 @@ class Reviews extends React.Component {
}).catch(function (error) {
if (error.response.status === 401) {
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login';
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else {
message.warning('Something went wrong');

@ -4,24 +4,10 @@ import {PageHeader, Typography, Row, Col, message, Card} from "antd";
import axios from 'axios';
import config from "../../../../../public/conf/config.json";
import ReleaseView from "../../../../components/apps/release/ReleaseView";
import LifeCycle from "../../../../components/apps/release/LifeCycle";
import LifeCycle from "../../../../components/apps/release/lifeCycle/LifeCycle";
const {Title} = Typography;
const routes = [
{
path: 'index',
breadcrumbName: 'Publisher',
},
{
path: 'first',
breadcrumbName: 'Dashboard',
},
{
path: 'second',
breadcrumbName: 'Apps',
},
];
class Release extends React.Component {
@ -33,7 +19,9 @@ class Release extends React.Component {
this.state = {
loading: true,
app: null,
uuid: null
uuid: null,
release: null,
currentLifecycleStatus: null,
}
}
@ -48,6 +36,11 @@ class Release extends React.Component {
this.fetchData(uuid);
}
}
changeCurrentLifecycleStatus = (status) =>{
this.setState({
currentLifecycleStatus: status
});
};
fetchData = (uuid) => {
@ -59,19 +52,23 @@ class Release extends React.Component {
}
).then(res => {
if (res.status === 200) {
let app = res.data.data;
const app = res.data.data;
const release = (app !== null) ? app.applicationReleases[0] : null;
const currentLifecycleStatus = (release!==null) ? release.currentStatus : null;
this.setState({
app: app,
release: release,
currentLifecycleStatus: currentLifecycleStatus,
loading: false,
uuid: uuid
})
});
}
}).catch((error) => {
if (error.hasOwnProperty("response") && error.response.status === 401) {
//todo display a popop with error
message.error('You are not logged in');
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/store/login';
window.location.href = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + '/publisher/login';
} else {
message.error('Something went wrong... :(');
}
@ -81,9 +78,9 @@ class Release extends React.Component {
};
render() {
const {app} = this.state;
const {app, release, currentLifecycleStatus} = this.state;
if (app == null) {
if (release == null) {
return (
<div style={{background: '#f0f2f5', padding: 24, minHeight: 780}}>
<Title level={3}>No Apps Found</Title>
@ -98,12 +95,12 @@ class Release extends React.Component {
<Row style={{padding: 10}}>
<Col lg={16} md={24} style={{padding: 3}}>
<Card>
<ReleaseView app={app}/>
<ReleaseView app={app} currentLifecycleStatus={currentLifecycleStatus}/>
</Card>
</Col>
<Col lg={8} md={24} style={{padding: 3}}>
<Card lg={8} md={24}>
{/*<LifeCycle currentStatus={release.currentStatus.toUpperCase()}/>*/}
<LifeCycle uuid={release.uuid} currentStatus={release.currentStatus.toUpperCase()} changeCurrentLifecycleStatus={this.changeCurrentLifecycleStatus}/>
</Card>
</Col>
</Row>

Loading…
Cancel
Save