Skip to content

Commit 52cf056

Browse files
committed
Merge branch 'workflow-scheduling-tab-does-not-show-in-event-details' of Arnei/opencast-admin-interface into r/18.x
Pull request #1460 Fixes #1459 Fix workflow tab not showing for scheduled events
2 parents e0164a1 + a4287a2 commit 52cf056

3 files changed

Lines changed: 271 additions & 217 deletions

File tree

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
import React, { useEffect } from "react";
2+
import { Formik, FormikProps } from "formik";
3+
import {
4+
getBaseWorkflow,
5+
getWorkflow,
6+
getWorkflowConfiguration,
7+
getWorkflowDefinitions,
8+
isFetchingWorkflows,
9+
} from "../../../../selectors/eventDetailsSelectors";
10+
import Notifications from "../../../shared/Notifications";
11+
import RenderWorkflowConfig from "../wizards/RenderWorkflowConfig";
12+
import { getUserInformation } from "../../../../selectors/userInfoSelectors";
13+
import { hasAccess, parseBooleanInObject } from "../../../../utils/utils";
14+
import DropDown from "../../../shared/DropDown";
15+
import { useAppDispatch, useAppSelector } from "../../../../store";
16+
import {
17+
fetchWorkflows,
18+
saveWorkflowConfig,
19+
} from "../../../../slices/eventDetailsSlice";
20+
import { removeNotificationWizardForm } from "../../../../slices/notificationSlice";
21+
import { useTranslation } from "react-i18next";
22+
import { formatWorkflowsForDropdown } from "../../../../utils/dropDownUtils";
23+
import ModalContent from "../../../shared/modals/ModalContent";
24+
25+
type InitialValues = {
26+
workflowDefinition: string;
27+
configuration: {
28+
[key: string]: any;
29+
} | undefined;
30+
}
31+
32+
/**
33+
* This component manages the workflows tab of the event details modal
34+
*/
35+
const EventDetailsWorkflowSchedulingTab = ({
36+
eventId,
37+
formikRef,
38+
}: {
39+
eventId: string,
40+
formikRef?: React.RefObject<FormikProps<InitialValues> | null>
41+
}) => {
42+
const { t } = useTranslation();
43+
const dispatch = useAppDispatch();
44+
45+
const user = useAppSelector(state => getUserInformation(state));
46+
const baseWorkflow = useAppSelector(state => getBaseWorkflow(state));
47+
const workflow = useAppSelector(state => getWorkflow(state));
48+
const workflowConfiguration = useAppSelector(state => getWorkflowConfiguration(state));
49+
const workflowDefinitions = useAppSelector(state => getWorkflowDefinitions(state));
50+
const isLoading = useAppSelector(state => isFetchingWorkflows(state));
51+
52+
const isRoleWorkflowEdit = hasAccess(
53+
"ROLE_UI_EVENTS_DETAILS_WORKFLOWS_EDIT",
54+
user,
55+
);
56+
57+
useEffect(() => {
58+
dispatch(removeNotificationWizardForm());
59+
dispatch(fetchWorkflows(eventId)).then();
60+
// eslint-disable-next-line react-hooks/exhaustive-deps
61+
}, []);
62+
63+
const hasCurrentAgentAccess = () => {
64+
// todo
65+
return true;
66+
};
67+
68+
const setInitialValues = () => {
69+
let initialConfig = undefined;
70+
71+
if (baseWorkflow.configuration) {
72+
initialConfig = parseBooleanInObject(baseWorkflow.configuration);
73+
}
74+
75+
return {
76+
workflowDefinition: "workflowId" in workflow && !!workflow.workflowId
77+
? workflow.workflowId
78+
: baseWorkflow.workflowId,
79+
configuration: initialConfig,
80+
};
81+
};
82+
83+
const handleSubmit = (values: {
84+
workflowDefinition: string,
85+
configuration: { [key: string]: unknown } | undefined
86+
}) => {
87+
dispatch(saveWorkflowConfig({ values, eventId }));
88+
};
89+
90+
return (
91+
<ModalContent>
92+
{/* Notifications */}
93+
<Notifications context="not_corner" />
94+
95+
{(isLoading || (
96+
<Formik<InitialValues>
97+
initialValues={setInitialValues()}
98+
enableReinitialize
99+
onSubmit={values => handleSubmit(values)}
100+
innerRef={formikRef}
101+
>
102+
{formik => (
103+
<div className="obj list-obj">
104+
<header>
105+
{t("EVENTS.EVENTS.DETAILS.WORKFLOW_DETAILS.CONFIGURATION") /* Workflow configuration */}
106+
</header>
107+
<div className="obj-container">
108+
<div className="obj list-obj quick-actions">
109+
<table className="main-tbl">
110+
<thead>
111+
<tr>
112+
<th>
113+
{t("EVENTS.EVENTS.DETAILS.WORKFLOWS.WORKFLOW") /* Select Workflow */}
114+
</th>
115+
</tr>
116+
</thead>
117+
118+
<tbody>
119+
<tr>
120+
<td>
121+
<div className="obj-container padded">
122+
<div className="editable">
123+
<DropDown
124+
value={
125+
formik.values.workflowDefinition
126+
}
127+
text={
128+
workflowDefinitions.find(
129+
workflowDef =>
130+
workflowDef.id ===
131+
formik.values.workflowDefinition,
132+
)?.title ?? ""
133+
}
134+
options={
135+
!!workflowDefinitions &&
136+
workflowDefinitions.length > 0
137+
? formatWorkflowsForDropdown(workflowDefinitions)
138+
: []
139+
}
140+
required={true}
141+
handleChange={element => {
142+
if (element) {
143+
formik.setFieldValue("workflowDefinition", element.value);
144+
}
145+
}}
146+
placeholder={
147+
!!workflowDefinitions &&
148+
workflowDefinitions.length > 0
149+
? t(
150+
"EVENTS.EVENTS.NEW.PROCESSING.SELECT_WORKFLOW",
151+
)
152+
: t(
153+
"EVENTS.EVENTS.NEW.PROCESSING.SELECT_WORKFLOW_EMPTY",
154+
)
155+
}
156+
disabled={
157+
!hasCurrentAgentAccess() ||
158+
!isRoleWorkflowEdit
159+
}
160+
customCSS={{ width: "100%" }}
161+
/>
162+
{/* pre-select-from="workflowDefinitionIds" */}
163+
</div>
164+
<div className="obj-container padded">
165+
{workflow.description}
166+
</div>
167+
</div>
168+
</td>
169+
</tr>
170+
</tbody>
171+
</table>
172+
</div>
173+
174+
<div className="obj list-obj quick-actions">
175+
<table className="main-tbl">
176+
<thead>
177+
<tr>
178+
<th>
179+
{t("EVENTS.EVENTS.DETAILS.WORKFLOWS.CONFIGURATION") /* Configuration */}
180+
</th>
181+
</tr>
182+
</thead>
183+
184+
<tbody>
185+
<tr>
186+
<td>
187+
<div className="obj-container padded">
188+
{hasCurrentAgentAccess() &&
189+
isRoleWorkflowEdit &&
190+
!!workflowConfiguration &&
191+
!!workflowConfiguration.workflowId && (
192+
<div
193+
id="event-workflow-configuration"
194+
className="checkbox-container obj-container"
195+
>
196+
<RenderWorkflowConfig
197+
workflowId={
198+
workflowConfiguration.workflowId
199+
}
200+
formik={formik}
201+
/>
202+
</div>
203+
)}
204+
{(!!workflowConfiguration &&
205+
!!workflowConfiguration.workflowId) || (
206+
<div>
207+
{t("EVENTS.EVENTS.DETAILS.WORKFLOWS.NO_CONFIGURATION") /* No config */}
208+
</div>
209+
)}
210+
</div>
211+
</td>
212+
</tr>
213+
</tbody>
214+
</table>
215+
</div>
216+
</div>
217+
218+
{/* Save and cancel buttons */}
219+
{hasCurrentAgentAccess() &&
220+
isRoleWorkflowEdit &&
221+
!!workflowConfiguration &&
222+
!!workflowConfiguration.workflowId &&
223+
formik.dirty && (
224+
<footer style={{ padding: "0 15px" }}>
225+
<div className="pull-left">
226+
<button
227+
type="reset"
228+
onClick={() => {
229+
formik.resetForm();
230+
}}
231+
disabled={!formik.isValid}
232+
className={`cancel ${
233+
!formik.isValid ? "disabled" : ""
234+
}`}
235+
>
236+
{t("CANCEL") /* Cancel */}
237+
</button>
238+
</div>
239+
<div className="pull-right">
240+
<button
241+
onClick={() => formik.handleSubmit()}
242+
disabled={!(formik.dirty && formik.isValid)}
243+
aria-disabled={!(formik.dirty && formik.isValid)}
244+
className={`save green ${
245+
!(formik.dirty && formik.isValid)
246+
? "disabled"
247+
: ""
248+
}`}
249+
>
250+
{t("SAVE") /* Save */}
251+
</button>
252+
</div>
253+
</footer>
254+
)}
255+
</div>
256+
)}
257+
</Formik>
258+
))}
259+
</ModalContent>
260+
);
261+
};
262+
263+
export default EventDetailsWorkflowSchedulingTab;

0 commit comments

Comments
 (0)