From 4e3a45fa933aa4b96bbcc54c65bdcbba9dc32574 Mon Sep 17 00:00:00 2001 From: shamalka Date: Thu, 4 Jun 2020 10:41:09 +0530 Subject: [PATCH 1/2] Improve lifecycle changing UX --- .../react-app/public/conf/config.json | 44 ++++-- .../Release/components/LifeCycle/index.js | 129 +++++++++++------- 2 files changed, 116 insertions(+), 57 deletions(-) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json index e6c00f08491..5c74935a803 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json @@ -40,28 +40,52 @@ }, "lifecycle": { "CREATED": { - "text": "The initial most state of an application." + "title": "Created", + "text": "The initial most state of an application.\n You can only proceed to one of the following states:", + "icon": "file-text", + "step": 0 }, "IN-REVIEW": { - "text": "This state can be applied when the application is being reviewed by approvers." + "title": "In-Review", + "text": "This state can be applied when the application is being reviewed by approvers.\n You can only proceed to one of the following states:", + "icon": "audit", + "step": 1 }, "APPROVED": { - "text": "The approved state is a compulsory state prior to publishing the application." - }, - "REJECTED": { - "text": "The Approvers can reject an application due to a faulty of the app or not being in compliance with company policies." + "title": "Approved", + "text": "The approved state is a compulsory state prior to publishing the application.\n You can only proceed to one of the following states:", + "icon": "file-done", + "step": 2 }, "PUBLISHED": { - "text": "The state which is applied for applications which are qualified for your Corporate App Store. Only the applications of Published state can be installed to your corporate devices." + "title": "Published", + "text": "The state which is applied for applications which are qualified for your Corporate App Store. Only the applications of Published state can be installed to your corporate devices.\n You can only proceed to one of the following states:", + "icon": "global", + "step": 3 }, "BLOCKED": { - "text": "This state allows you to block your application either to publish or deprecate at a future date." + "title": "Blocked", + "text": "This state allows you to block your application either to publish or deprecate at a future date.\n You can only proceed to one of the following states:", + "icon": "exception", + "step": 4 }, "DEPRECATED": { - "text": "The applications which are outdated and no longer suit your app store." + "title": "Deprecated", + "text": "The applications which are outdated and no longer suit your app store.\n You can only proceed to one of the following states:", + "icon": "file-excel", + "step": 5 + }, + "REJECTED": { + "title": "Rejected", + "text": "The Approvers can reject an application due to a faulty of the app or not being in compliance with company policies.\n You can only proceed to one of the following states:", + "icon": "frown", + "step": 6 }, "RETIRED": { - "text": "The final state of an application, where no transition of states will be allowed after this." + "title": "Retired", + "text": "The final state of an application, where no transition of states will be allowed after this.\n You can only proceed to one of the following states:", + "icon": "rest", + "step": 7 } }, "deviceTypes": { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/LifeCycle/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/LifeCycle/index.js index 1ac3deb8663..ba6227af870 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/LifeCycle/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/LifeCycle/index.js @@ -21,21 +21,21 @@ import { Typography, Tag, Divider, - Select, Button, Modal, notification, + Steps, + Icon, + Alert, } from 'antd'; import axios from 'axios'; import ReactQuill from 'react-quill'; import 'react-quill/dist/quill.snow.css'; import './styles.css'; -import LifeCycleDetailsModal from './components/lifeCycleDetailsModal'; import { withConfigContext } from '../../../../../../../../components/ConfigContext'; import { handleApiError } from '../../../../../../../../services/utils/errorHandler'; const { Text, Title, Paragraph } = Typography; -const { Option } = Select; const modules = { toolbar: [ @@ -60,6 +60,8 @@ const formats = [ 'image', ]; +const { Step } = Steps; + class LifeCycle extends React.Component { constructor(props) { super(props); @@ -69,9 +71,23 @@ class LifeCycle extends React.Component { reasonText: '', isReasonModalVisible: false, isConfirmButtonLoading: false, + current: 0, + lifecycleSteps: [], }; } + componentDidMount() { + const config = this.props.context; + const lifeCycleConfig = config.lifecycle; + const lifecycleSteps = Object.keys(lifeCycleConfig).map(config => { + return lifeCycleConfig[config]; + }); + this.setState({ + current: lifeCycleConfig[this.props.currentStatus].step, + lifecycleSteps, + }); + } + componentDidUpdate(prevProps, prevState, snapshot) { if ( prevProps.currentStatus !== this.props.currentStatus || @@ -87,12 +103,9 @@ class LifeCycle extends React.Component { this.setState({ reasonText: value }); }; - handleSelectChange = value => { - this.setState({ selectedStatus: value }); - }; - - showReasonModal = () => { + showReasonModal = lifecycleState => { this.setState({ + selectedStatus: lifecycleState, isReasonModalVisible: true, }); }; @@ -105,6 +118,7 @@ class LifeCycle extends React.Component { addLifeCycle = () => { const config = this.props.context; + const lifeCycleConfig = config.lifecycle; const { selectedStatus, reasonText } = this.state; const { uuid } = this.props; const data = { @@ -128,6 +142,7 @@ class LifeCycle extends React.Component { .then(res => { if (res.status === 201) { this.setState({ + current: lifeCycleConfig[selectedStatus].step, isReasonModalVisible: false, isConfirmButtonLoading: false, currentStatus: selectedStatus, @@ -149,14 +164,18 @@ class LifeCycle extends React.Component { }); }; + onChange = current => { + this.setState({ current }); + }; + render() { const { currentStatus, selectedStatus, - isConfirmButtonLoading, + current, + lifecycleSteps, } = this.state; const { lifecycle } = this.props; - const selectedValue = selectedStatus == null ? [] : selectedStatus; let proceedingStates = []; if ( @@ -176,43 +195,47 @@ class LifeCycle extends React.Component { 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.
- Note: ‘Change State To’ displays only the next states allowed from the - current state - {lifecycle !== null && } - - Current State: {' '} - {currentStatus} -
-
- Change State to: - - + +
+ + {lifecycleSteps.map((step, index) => ( + } + title={step.title} + disabled={current !== step.step} + description={ + current === step.step ? ( +
+

{step.text}

+ {proceedingStates.map(lifecycleState => { + return ( + + ); + })} +
+ ) : ( + '' + ) + } + /> + ))} +
+
{selectedStatus}
-
+ {lifecycle && + selectedStatus && + lifecycle[selectedStatus].isEndState ? ( + + ) : ( +
+ )} + Reason Date: Thu, 4 Jun 2020 13:17:22 +0530 Subject: [PATCH 2/2] Improve description --- .../react-app/public/conf/config.json | 4 ++-- .../Apps/scenes/Release/components/LifeCycle/index.js | 11 ++--------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json index 5c74935a803..72573045182 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json @@ -47,7 +47,7 @@ }, "IN-REVIEW": { "title": "In-Review", - "text": "This state can be applied when the application is being reviewed by approvers.\n You can only proceed to one of the following states:", + "text": "In this state the application is being reviewed by approvers. You can move from this state to APPROVED state if it is approved by reviewers. Otherwise, you can move the application into either REJECTED state or CREATED state based on the feedback getting by reviewers.", "icon": "audit", "step": 1 }, @@ -83,7 +83,7 @@ }, "RETIRED": { "title": "Retired", - "text": "The final state of an application, where no transition of states will be allowed after this.\n You can only proceed to one of the following states:", + "text": "The final state of an application, where no transition of states will be allowed after this.", "icon": "rest", "step": 7 } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/LifeCycle/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/LifeCycle/index.js index ba6227af870..f235ef5cfda 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/LifeCycle/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/LifeCycle/index.js @@ -177,7 +177,6 @@ class LifeCycle extends React.Component { } = this.state; const { lifecycle } = this.props; let proceedingStates = []; - if ( lifecycle !== null && lifecycle.hasOwnProperty(currentStatus) && @@ -211,7 +210,7 @@ class LifeCycle extends React.Component { title={step.title} disabled={current !== step.step} description={ - current === step.step ? ( + current === step.step && (

{step.text}

{proceedingStates.map(lifecycleState => { @@ -228,8 +227,6 @@ class LifeCycle extends React.Component { ); })}
- ) : ( - '' ) } /> @@ -251,17 +248,13 @@ class LifeCycle extends React.Component { {selectedStatus}
- {lifecycle && - selectedStatus && - lifecycle[selectedStatus].isEndState ? ( + {lifecycle && selectedStatus && lifecycle[selectedStatus].isEndState && ( - ) : ( -
)} Reason