Skip to content

Commit 4fe3fdb

Browse files
committed
Display operation on workflow error details page
With some additional information from the backend, we can display the workflow operation during which an error occured on the error details page for easy access to information about the operation. Requires backend PR opencast/opencast#6888
1 parent 61a8484 commit 4fe3fdb

5 files changed

Lines changed: 87 additions & 4 deletions

File tree

src/components/events/partials/ModalTabsAndPages/EventDetailsWorkflowErrorDetails.tsx

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import Notifications from "../../../shared/Notifications";
22
import {
3+
getModalWorkflowId,
4+
getWorkflowByJobId,
35
getWorkflowErrorDetails,
46
isFetchingWorkflowErrorDetails,
57
} from "../../../../selectors/eventDetailsSelectors";
@@ -10,24 +12,39 @@ import { removeNotificationWizardForm } from "../../../../slices/notificationSli
1012
import { renderValidDate } from "../../../../utils/dateUtils";
1113
import { WorkflowTabHierarchy } from "../modals/EventDetails";
1214
import { useTranslation } from "react-i18next";
13-
import { setModalWorkflowTabHierarchy } from "../../../../slices/eventDetailsSlice";
15+
import { fetchWorkflowOperationDetails, setModalWorkflowTabHierarchy } from "../../../../slices/eventDetailsSlice";
1416
import ModalContentTable from "../../../shared/modals/ModalContentTable";
17+
import { Operation } from "./EventDetailsWorkflowOperations";
1518

1619
/**
1720
* This component manages the workflow error details for the workflows tab of the event details modal
1821
*/
19-
const EventDetailsWorkflowErrorDetails = () => {
22+
const EventDetailsWorkflowErrorDetails = ({
23+
eventId,
24+
}: {
25+
eventId: string
26+
}) => {
2027
const { t } = useTranslation();
2128
const dispatch = useAppDispatch();
2229

2330
const errorDetails = useAppSelector(state => getWorkflowErrorDetails(state));
2431
const isFetching = useAppSelector(state => isFetchingWorkflowErrorDetails(state));
32+
const operationsEntry = useAppSelector(state => getWorkflowByJobId(state, errorDetails.rootJobId ?? errorDetails.jobId, errorDetails.jobId))
33+
const workflowId = useAppSelector(state => getModalWorkflowId(state));
2534

2635
const openSubTab = (tabType: WorkflowTabHierarchy) => {
2736
dispatch(removeNotificationWizardForm());
2837
dispatch(setModalWorkflowTabHierarchy(tabType));
2938
};
3039

40+
const openOperationDetailsSubTab = (tabType: WorkflowTabHierarchy, operationId: number | undefined = undefined) => {
41+
dispatch(removeNotificationWizardForm());
42+
dispatch(setModalWorkflowTabHierarchy(tabType));
43+
if (tabType === "workflow-operation-details") {
44+
dispatch(fetchWorkflowOperationDetails({ eventId, workflowId, operationId })).then();
45+
}
46+
};
47+
3148
return (
3249
<ModalContentTable
3350
modalContentChildren={
@@ -45,6 +62,38 @@ const EventDetailsWorkflowErrorDetails = () => {
4562
}
4663
modalBodyChildren={<Notifications context="not_corner" />}
4764
>
65+
{/* Error operation table */}
66+
<div className="obj tbl-container">
67+
<header>
68+
{t("EVENTS.EVENTS.DETAILS.ERRORS_AND_WARNINGS.DETAILS.OPERATION")}
69+
</header>
70+
<table className="main-tbl">
71+
<thead>
72+
<tr>
73+
<th>
74+
{t("EVENTS.EVENTS.DETAILS.WORKFLOW_OPERATIONS.TABLE_HEADERS.STATUS") /* Status */}
75+
</th>
76+
<th>
77+
{t("EVENTS.EVENTS.DETAILS.WORKFLOW_OPERATIONS.TABLE_HEADERS.TITLE") /* Title */}
78+
</th>
79+
<th>
80+
{t("EVENTS.EVENTS.DETAILS.WORKFLOW_OPERATIONS.TABLE_HEADERS.DESCRIPTION") /* Description */}
81+
</th>
82+
<th className="medium" />
83+
</tr>
84+
</thead>
85+
<tbody>
86+
{ operationsEntry &&
87+
<Operation
88+
operationId={operationsEntry.index}
89+
item={operationsEntry.operation}
90+
openSubTab={openOperationDetailsSubTab}
91+
/>
92+
}
93+
</tbody>
94+
</table>
95+
</div>
96+
4897
{/* 'Error Details' table */}
4998
<div className="obj tbl-details">
5099
<header>

src/components/events/partials/modals/EventDetails.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,9 @@ const EventDetails = ({
289289
<EventDetailsWorkflowOperationDetails />
290290
)) ||
291291
(workflowTabHierarchy === "workflow-error-details" && (
292-
<EventDetailsWorkflowErrorDetails />
292+
<EventDetailsWorkflowErrorDetails
293+
eventId={eventId}
294+
/>
293295
)))}
294296
{page === EventDetailsPage.AccessPolicy && (
295297
<EventDetailsAccessPolicyTab

src/i18n/org/opencastproject/adminui/languages/lang-en_US.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,8 @@
10951095
"DATE": "Date",
10961096
"HOST": "Processing host",
10971097
"TYPE": "Service type",
1098-
"TECHNICAL_DETAILS": "Technical details"
1098+
"TECHNICAL_DETAILS": "Technical details",
1099+
"OPERATION": "Operation the error occured in"
10991100
}
11001101
}
11011102
}

src/selectors/eventDetailsSelectors.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,36 @@ export const getLatestWorkflowOperation = createSelector(
131131
return null; // if none found
132132
},
133133
);
134+
// Get operation by root_job_id, or jobId
135+
export const getWorkflowByJobId = createSelector(
136+
[
137+
getWorkflowOperations,
138+
(_operations, rootJobId: number) => rootJobId,
139+
(_operations, rootJobId: number, jobId: number) => jobId,
140+
],
141+
(operations, rootJobId, jobId) => {
142+
let operation = null;
143+
let index = null;
144+
145+
index = operations.entries.findIndex(
146+
entry => entry.id === rootJobId,
147+
);
148+
operation = operations.entries[index];
149+
150+
if (!operation) {
151+
index = operations.entries.findIndex(
152+
entry => entry.id === jobId,
153+
);
154+
operation = operations.entries[index];
155+
}
156+
157+
if (operation) {
158+
return { operation, index };
159+
}
160+
161+
return null;
162+
},
163+
);
134164
export const isFetchingWorkflowOperations = (state: RootState) =>
135165
state.eventDetails.statusWorkflowOperations === "loading";
136166
export const getWorkflowOperationDetails = (state: RootState) =>

src/slices/eventDetailsSlice.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ type EventDetailsState = {
359359
}[],
360360
id: number,
361361
jobId: number,
362+
rootJobId?: number,
362363
processingHost: string,
363364
serviceType: string,
364365
severity: string,

0 commit comments

Comments
 (0)