Skip to content

Commit dadefea

Browse files
committed
Add cancel workflow
Add update workflow status on Manage page Add store changes Code refactoring
1 parent 5482474 commit dadefea

File tree

22 files changed

+3047
-159
lines changed

22 files changed

+3047
-159
lines changed

client/src/App.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import Hero from './pages/Hero/Hero.jsx';
55
import HomeAuthenticated from './pages/Home/Home.jsx';
66
import ManageWorkflowAuthenticated from './pages/ManageWorkflow/ManageWorkflow.jsx';
77
import TriggerWorkflowAuthenticated from './pages/TriggerWorkflow/TriggerWorkflow.jsx';
8+
import TriggerWorkflowFormAuthenticated from './pages/TriggerWorkflowForm/TriggerWorkflowForm.jsx';
89
import { LoginStatus, ROUTE } from './constants.js';
910
import { api } from './api';
10-
import TriggerWorkflowFormAuthenticated from './pages/TriggerWorkflowForm/TriggerWorkflowForm.jsx';
1111

1212
function App() {
1313
const location = useLocation();
@@ -19,10 +19,10 @@ function App() {
1919
useEffect(() => {
2020
const fetchCallback = async () => {
2121
if (code && code.length > 0) {
22-
const res = await api.acg.callbackExecute(code);
22+
const { data: userInfo } = await api.acg.callbackExecute(code);
2323
dispatch({
2424
type: 'LOGIN',
25-
payload: { authType: LoginStatus.ACG, userName: res.data.name, userEmail: res.data.email },
25+
payload: { authType: LoginStatus.ACG, userName: userInfo.name, userEmail: userInfo.email },
2626
});
2727
navigate(ROUTE.HOME);
2828
dispatch({ type: 'CLOSE_POPUP' });
@@ -39,7 +39,7 @@ function App() {
3939
<Route path={ROUTE.HOME} element={<HomeAuthenticated />} />
4040
<Route path={ROUTE.TRIGGER} element={<TriggerWorkflowAuthenticated />} />
4141
<Route path={ROUTE.MANAGE} element={<ManageWorkflowAuthenticated />} />
42-
<Route path={`${ROUTE.TRIGGERFORM}/:definitionId`} element={<TriggerWorkflowFormAuthenticated />} />
42+
<Route path={`${ROUTE.TRIGGERFORM}/:workflowId`} element={<TriggerWorkflowFormAuthenticated />} />
4343
</Routes>
4444
);
4545
}

client/src/api/index.js

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import axios from 'axios';
2-
import { store } from '../store/store';
2+
import { persistor, store } from '../store/store';
33

44
const apiUrl = process.env.BACKEND_API;
55

@@ -22,22 +22,23 @@ export const api = Object.freeze({
2222
jwt: {
2323
// Login by JSON Web Token
2424
login: async () => {
25-
const res = await instance.get('/auth/jwt/login');
25+
const response = await instance.get('/auth/jwt/login');
2626
// If user has never logged in before, redirect to consent screen
27-
if (res.status === 210) {
28-
window.location = res.data;
27+
if (response.status === 210) {
28+
window.location = response.data;
2929
return;
3030
}
3131

32-
return res;
32+
return response;
3333
},
3434
logout: async () => {
3535
await instance.get('/auth/jwt/logout');
36+
await persistor.purge();
3637
localStorage.clear();
3738
},
3839
loginStatus: async () => {
39-
const res = await instance.get('/auth/jwt/login-status');
40-
return JSON.parse(res.data); // response boolean
40+
const response = await instance.get('/auth/jwt/login-status');
41+
return JSON.parse(response.data); // response boolean
4142
},
4243
},
4344
acg: {
@@ -48,23 +49,23 @@ export const api = Object.freeze({
4849
},
4950
logout: async () => {
5051
await instance.get('/auth/passport/logout');
52+
await persistor.purge();
5153
localStorage.clear();
5254
},
5355
callbackExecute: async code => {
54-
const res = await instance.get(`/auth/passport/callback?code=${code}`);
55-
return res;
56+
const response = await instance.get(`/auth/passport/callback?code=${code}`);
57+
return response;
5658
},
5759
loginStatus: async () => {
58-
const res = await instance.get('/auth/passport/login-status');
59-
return JSON.parse(res.data); // response boolean
60+
const response = await instance.get('/auth/passport/login-status');
61+
return JSON.parse(response.data); // response boolean
6062
},
6163
},
6264
workflows: {
63-
// YES
6465
createWorkflowDefinition: async templateType => {
6566
try {
66-
const res = await instance.post('/workflows/create', { templateType: templateType });
67-
return res;
67+
const response = await instance.post('/workflows/create', { templateType: templateType });
68+
return response;
6869
} catch (error) {
6970
if (error.response && error.response.status === 400) {
7071
return error.response;
@@ -74,22 +75,18 @@ export const api = Object.freeze({
7475
},
7576
cancelWorkflowInstance: async workflow => {
7677
try {
77-
const res = await instance.put(`/workflows/${workflow.definitionId}/instances/${workflow.dacId}/cancel`);
78-
return res;
78+
const response = await instance.put(`/workflows/${workflow.id}/instances/${workflow.instanceId}/cancel`);
79+
return response;
7980
} catch (error) {
80-
if (error.response && error.response.status === 400) {
81-
return error.response;
82-
}
83-
throw error;
81+
console.log(error);
8482
}
8583
},
86-
// YES
8784
publishWorkflow: async workflowId => {
88-
const res = await instance.post('/workflows/publish', { workflowId });
85+
const response = await instance.post('/workflows/publish', { workflowId });
8986

90-
if (res.status === 210) {
87+
if (response.status === 210) {
9188
try {
92-
window.open(res.data, 'newTab', 'width=800,height=600');
89+
window.open(response.data, 'newTab', 'width=800,height=600');
9390
await new Promise(r => setTimeout(r, 3000));
9491

9592
const published = await instance.post('/workflows/publish', { workflowId });
@@ -99,32 +96,28 @@ export const api = Object.freeze({
9996
}
10097
}
10198

102-
return res;
99+
return response;
103100
},
104-
// YES
105101
triggerWorkflow: async (workflowId, body) => {
106102
try {
107-
const res = await instance.put(`/workflows/${workflowId}/trigger`, body);
108-
return res;
103+
const response = await instance.put(`/workflows/${workflowId}/trigger`, body);
104+
return response;
109105
} catch (error) {
110106
console.log(error);
111107
}
112108
},
113-
// YES
114109
getWorkflowDefinitions: async () => {
115-
const res = await instance.get(`/workflows/definitions`);
116-
return res;
110+
const response = await instance.get(`/workflows/definitions`);
111+
return response;
117112
},
118113
getWorkflowInstance: async workflow => {
119-
const res = await instance.get(`/workflows/${workflow.definitionId}/instances/${workflow.dacId}`);
120-
return res;
114+
const response = await instance.get(`/workflows/${workflow.id}/instances/${workflow.instanceId}`);
115+
return response;
121116
},
122-
// YES
123-
getWorkflowInstances: async definitionId => {
124-
const res = await instance.get(`/workflows/${definitionId}/instances`);
125-
return res;
117+
getWorkflowInstances: async workflowId => {
118+
const response = await instance.get(`/workflows/${workflowId}/instances`);
119+
return response;
126120
},
127-
// YES
128121
downloadWorkflowTemplate: async templateName => {
129122
try {
130123
const response = await fetch(`/workflows/download/${templateName}`);

client/src/components/Card/Card.jsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import { useState } from 'react';
12
import { Link } from 'react-router-dom';
3+
import { useDispatch, useSelector } from 'react-redux';
24
import styles from './Card.module.css';
35
import Dropdown from '../Dropdown/Dropdown.jsx';
46
import { WorkflowOptions } from '../../constants.js';
5-
import { useDispatch, useSelector } from 'react-redux';
67
import CreateWorkflowMoreinfoPopup from '../Popups/CreateWorkflowMoreInfo/CreateWorkflowMoreInfo.jsx';
7-
import { useState } from 'react';
88

99
const Card = props => {
1010
const [isBtsOpened, setBtsOpened] = useState(false);
@@ -31,10 +31,14 @@ const Card = props => {
3131
) : (
3232
<div>
3333
<div className={styles.buttonGroup}>
34-
{props.moreInfo ? <button className={styles.moreInfo} onClick={togglePopup}>More Info</button> : null}
34+
{props.moreInfo && (
35+
<button className={styles.moreInfo} onClick={togglePopup}>
36+
More Info
37+
</button>
38+
)}
3539
<Dropdown options={WorkflowOptions} />
3640
</div>
37-
{isBtsOpened && (<CreateWorkflowMoreinfoPopup togglePopup={togglePopup}/>)}
41+
{isBtsOpened && <CreateWorkflowMoreinfoPopup togglePopup={togglePopup} />}
3842
</div>
3943
)}
4044
</div>

client/src/components/Dropdown/Dropdown.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const Dropdown = ({ options }) => {
2727
return;
2828
}
2929

30-
dispatch({ type: 'CREATED_WORKFLOW', payload: { workflowDefinitionId: data.workflowDefinitionId } });
30+
dispatch({ type: 'CREATED_WORKFLOW', payload: { workflowId: data.workflowDefinitionId } });
3131
dispatch({ type: 'LOADED_POPUP' });
3232
};
3333

client/src/components/LoginForm/LoginForm.jsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ const LoginForm = ({ togglePopup, setLoading }) => {
1717

1818
try {
1919
if (authType === LoginStatus.JWT) {
20-
const res = await api.jwt.login();
21-
dispatch({ type: 'LOGIN', payload: { authType, userName: res.data.name, userEmail: res.data.email } });
20+
const { data: userInfo } = await api.jwt.login();
21+
dispatch({ type: 'LOGIN', payload: { authType, userName: userInfo.name, userEmail: userInfo.email } });
2222
navigate(ROUTE.HOME);
2323
dispatch({ type: 'CLOSE_POPUP' });
2424
dispatch({ type: 'LOADED_POPUP' });
@@ -54,8 +54,9 @@ const LoginForm = ({ togglePopup, setLoading }) => {
5454
/>
5555
{LoginStatus.ACG}
5656
</label>
57-
<label className={styles.subLabel}>This authentication type provides functionality of creating, triggering
58-
and managing workflows.</label>
57+
<label className={styles.subLabel}>
58+
This authentication type provides functionality of creating, triggering and managing workflows.
59+
</label>
5960
</div>
6061
<div className={styles.radioButtonWrapper}>
6162
<label className={styles.label}>
@@ -68,7 +69,9 @@ const LoginForm = ({ togglePopup, setLoading }) => {
6869
/>
6970
{LoginStatus.JWT}
7071
</label>
71-
<label className={styles.subLabel}>This authentication type provides functionality of only triggering and managing workflows.</label>
72+
<label className={styles.subLabel}>
73+
This authentication type provides functionality of only triggering and managing workflows.
74+
</label>
7275
</div>
7376
</div>
7477
<div className={styles.formButtons}>

client/src/components/Popups/WorkflowDefinitionCreation/WorkflowDefinitionCreation.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const WorkflowDefinitionCreation = ({ message }) => {
2121
dispatch({ type: 'LOADING_POPUP' });
2222
const workflow = await api.workflows.publishWorkflow(lastCreatedWorkflow.id);
2323

24-
if (workflow.status === 200) {
24+
if (workflow?.status === 200) {
2525
dispatch({ type: 'PUBLISHED_LAST_WORKFLOW' });
2626
}
2727

client/src/components/Popups/WorkflowTriggerResult/WorkflowTriggerResult.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
import { useNavigate } from 'react-router-dom';
2+
import { useDispatch } from 'react-redux';
13
import styles from './WorkflowTriggerResult.module.css';
24
import withPopup from '../../../hocs/withPopup/withPopup.jsx';
35
import imgSuccess from '../../../assets/img/success.svg';
4-
import { useNavigate } from 'react-router-dom';
56
import { ROUTE } from '../../../constants.js';
6-
import { useDispatch } from 'react-redux';
77

88
const WorkflowTriggerResult = ({ workflowInstanceUrl }) => {
99
const navigate = useNavigate();

client/src/components/TriggerForm/TriggerForm.jsx

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import styles from './TriggerForm.module.css';
44
import WorkflowTriggerResultPopup from '../Popups/WorkflowTriggerResult/WorkflowTriggerResult.jsx';
55
import { api } from '../../api';
66

7-
const TriggerForm = ({ definitionId }) => {
7+
const TriggerForm = ({ workflowId }) => {
88
const dispatch = useDispatch();
99
const isOpened = useSelector(state => state.popup.isOpened);
10-
const workflowDefinitions = useSelector(state => state.workflows.workflowDefinitions);
10+
const workflows = useSelector(state => state.workflows.workflows);
1111
const [instanceName, setInstanceName] = useState('');
1212
const [signerName, setSignerName] = useState('');
1313
const [signerEmail, setSignerEmail] = useState('');
@@ -19,47 +19,32 @@ const TriggerForm = ({ definitionId }) => {
1919
const handleSubmit = async event => {
2020
event.preventDefault();
2121

22-
// const body = {
23-
// instanceName,
24-
// signerEmail,
25-
// signerName,
26-
// ccEmail,
27-
// ccName,
28-
// };
29-
3022
const body = {
31-
instanceName: 'Contract for Rent 2024',
32-
signerEmail: '[email protected]',
33-
signerName: 'Bob Swager',
34-
ccEmail: '[email protected]',
35-
ccName: 'My Name (John Doe)',
23+
instanceName,
24+
signerEmail,
25+
signerName,
26+
ccEmail,
27+
ccName,
3628
};
3729

3830
setDataSending(true);
39-
const { data } = await api.workflows.triggerWorkflow(definitionId, body);
40-
setWorkflowInstanceUrl(data.workflowInstanceUrl);
31+
const { data: triggeredWorkflow } = await api.workflows.triggerWorkflow(workflowId, body);
32+
setWorkflowInstanceUrl(triggeredWorkflow.workflowInstanceUrl);
4133

4234
// Update workflowDefinitions. ...workflow creates new workflow-object to avoid mutation in redux
43-
const updatedWorkflowDefinitions = workflowDefinitions.map(workflow => {
44-
if (workflow.definitionId === definitionId) {
35+
const updatedWorkflowDefinitions = workflows.map(workflow => {
36+
if (workflow.id === workflowId) {
4537
return {
4638
...workflow,
47-
instanceId: data.instanceId,
39+
instanceId: triggeredWorkflow.instanceId,
4840
isTriggered: true,
4941
};
50-
} else {
51-
return {
52-
...workflow,
53-
instanceId: undefined,
54-
isTriggered: false,
55-
};
5642
}
57-
});
5843

59-
dispatch({
60-
type: 'UPDATE_WORKFLOW_DEFINITIONS',
61-
payload: { workflowDefinitions: updatedWorkflowDefinitions },
44+
return { ...workflow };
6245
});
46+
47+
dispatch({ type: 'UPDATE_WORKFLOWS', payload: { workflows: updatedWorkflowDefinitions } });
6348
setDataSending(false);
6449

6550
setInstanceName('');

0 commit comments

Comments
 (0)