diff --git a/client/src/components/job-lifecycle/job-lifecycle.component.jsx b/client/src/components/job-lifecycle/job-lifecycle.component.jsx
new file mode 100644
index 000000000..dc6925055
--- /dev/null
+++ b/client/src/components/job-lifecycle/job-lifecycle.component.jsx
@@ -0,0 +1,77 @@
+import {createStructuredSelector} from "reselect";
+import {selectBodyshop} from "../../redux/user/user.selectors";
+import {connect} from "react-redux";
+import {useEffect, useState} from "react";
+import axios from "axios";
+import {Card, Space, Table, Timeline} from "antd";
+
+const mapStateToProps = createStructuredSelector({
+ bodyshop: selectBodyshop,
+});
+const mapDispatchToProps = (dispatch) => ({
+ //setUserLanguage: language => dispatch(setUserLanguage(language))
+});
+
+export function JobLifecycleComponent({bodyshop, job, ...rest}) {
+ const [loading, setLoading] = useState(false);
+ const [lifecycleData, setLifecycleData] = useState(null);
+
+
+ useEffect(() => {
+ async function getLifecycleData() {
+ if (job && job.id) {
+ setLoading(true);
+ const response = await axios.post("/job/lifecycle", {
+ jobids: job.id,
+ });
+ console.dir(response.data.data.transitions, {depth: null});
+ setLifecycleData(response.data.data.transitions);
+ setLoading(false);
+ }
+ }
+
+ getLifecycleData().catch((err) => {
+ console.log(`Something went wrong getting Job Lifecycle Data: ${err.message}`);
+ setLoading(false);
+ });
+ }, [job]);
+
+ const columnKeys = [
+ 'start',
+ 'end',
+ 'value',
+ 'prev_value',
+ 'next_value',
+ 'duration',
+ 'type',
+ 'created_at',
+ 'updated_at'
+ ];
+
+ const columns = columnKeys.map(key => ({
+ title: key.charAt(0).toUpperCase() + key.slice(1), // Capitalize the first letter for the title
+ dataIndex: key,
+ key: key,
+ }));
+
+ return (
+
+
+
+
+
+
+
+ {lifecycleData.map((item, index) => (
+
+ {item.value} - {new Date(item.start).toLocaleString()}
+
+ ))}
+
+
+
+
+ );
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(JobLifecycleComponent);
diff --git a/client/src/pages/jobs-detail/jobs-detail.page.component.jsx b/client/src/pages/jobs-detail/jobs-detail.page.component.jsx
index 001a18166..a7d51d5e3 100644
--- a/client/src/pages/jobs-detail/jobs-detail.page.component.jsx
+++ b/client/src/pages/jobs-detail/jobs-detail.page.component.jsx
@@ -54,6 +54,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
import UndefinedToNull from "../../utils/undefinedtonull";
import { DateTimeFormat } from "./../../utils/DateFormatter";
+import JobLifecycleComponent from "../../components/job-lifecycle/job-lifecycle.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -288,6 +289,13 @@ export function JobsDetailPage({
form={form}
/>
+ Lifecycle}
+ key="lifecycle"
+ >
+
+
{
const {jobids} = req.body;
@@ -11,11 +12,17 @@ const handleMultipleJobs = (jobIDs, req, res) => {
return res.status(200).send(jobIDs);
}
-const handleSingleJob = (req, res) => {
-
+const handleSingleJob = async (jobIds, req, res) => {
const client = req.userGraphQLClient;
- return res.status(200).send(req.body);
+ const resp = await client.request(queries.QUERY_TRANSITIONS_BY_JOBID, {jobid: jobIds,});
+
+ const response = {
+ jobIds,
+ data: resp
+ }
+
+ return res.status(200).json(response);
}
module.exports = jobLifecycle;
\ No newline at end of file
diff --git a/server/middleware/eventAuthorizationMIddleware.js b/server/middleware/eventAuthorizationMIddleware.js
index c766ceda5..423fbc73f 100644
--- a/server/middleware/eventAuthorizationMIddleware.js
+++ b/server/middleware/eventAuthorizationMIddleware.js
@@ -1,3 +1,11 @@
+const path = require("path");
+require("dotenv").config({
+ path: path.resolve(
+ process.cwd(),
+ `.env.${process.env.NODE_ENV || "development"}`
+ ),
+});
+
/**
* Checks if the event secret is correct
* It adds the following properties to the request object:
diff --git a/server/routes/jobRoutes.js b/server/routes/jobRoutes.js
index e11187041..9b4a5e9f6 100644
--- a/server/routes/jobRoutes.js
+++ b/server/routes/jobRoutes.js
@@ -7,14 +7,12 @@ const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebas
const {totals, statustransition, totalsSsu, costing, lifecycle, costingmulti} = require("../job/job");
const withUserGraphQLClientMiddleware = require("../middleware/withUserGraphQLClientMiddleware");
-router.use(validateFirebaseIdTokenMiddleware);
-
-router.post('/totals', withUserGraphQLClientMiddleware, totals);
+router.post('/totals', validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, totals);
router.post('/statustransition', eventAuthorizationMiddleware, statustransition);
-router.post('/totalsssu', withUserGraphQLClientMiddleware,totalsSsu);
-router.post('/costing', withUserGraphQLClientMiddleware,costing);
-router.get('/lifecycle', withUserGraphQLClientMiddleware, lifecycle);
-router.post('/costingmulti', withUserGraphQLClientMiddleware, costingmulti);
-router.post('/partsscan', withUserGraphQLClientMiddleware, partsScan);
+router.post('/totalsssu', validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware,totalsSsu);
+router.post('/costing', validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware,costing);
+router.post('/lifecycle', validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, lifecycle);
+router.post('/costingmulti', validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, costingmulti);
+router.post('/partsscan', validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, partsScan);
module.exports = router;