Skip to content

Commit ce743a6

Browse files
committed
Merge branch 'main' into make-wizard-stepper-more-robust
2 parents 854af36 + f0663df commit ce743a6

File tree

86 files changed

+996
-894
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+996
-894
lines changed

package-lock.json

Lines changed: 349 additions & 297 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,34 @@
88
"@emotion/react": "^11.14.0",
99
"@emotion/styled": "^11.14.0",
1010
"@hello-pangea/dnd": "^18.0.1",
11-
"@mui/material": "^6.4.6",
12-
"@mui/x-date-pickers": "^7.27.1",
13-
"@reduxjs/toolkit": "^2.6.0",
11+
"@mui/material": "^7.0.1",
12+
"@mui/x-date-pickers": "^7.28.2",
13+
"@reduxjs/toolkit": "^2.6.1",
1414
"array-move": "^4.0.0",
15-
"axios": "^1.8.1",
15+
"axios": "^1.8.4",
1616
"classnames": "^2.5.1",
1717
"date-fns": "^4.1.0",
1818
"dompurify": "^3.2.4",
1919
"font-awesome": "^4.7.0",
2020
"formik": "^2.4.6",
2121
"http-proxy-middleware": "^3.0.3",
22-
"i18next": "^24.2.2",
22+
"i18next": "^25.0.2",
2323
"i18next-browser-languagedetector": "^8.0.4",
2424
"i18next-http-backend": "^3.0.2",
2525
"lodash": "^4.17.21",
2626
"moment": "^2.30.1",
27-
"moment-timezone": "^0.5.47",
28-
"react": "^19.0.0",
27+
"moment-timezone": "^0.5.48",
28+
"react": "^19.1.0",
2929
"react-chartjs-2": "^5.3.0",
30-
"react-datepicker": "^8.1.0",
31-
"react-dom": "^19.0.0",
30+
"react-datepicker": "^8.2.1",
31+
"react-dom": "^19.1.0",
3232
"react-hotkeys-hook": "^4.6.1",
3333
"react-i18next": "^15.4.1",
3434
"react-icons": "^5.5.0",
3535
"react-redux": "^9.2.0",
36-
"react-router": "^7.2.0",
37-
"react-select": "^5.10.0",
36+
"react-router": "^7.4.1",
37+
"react-select": "^5.10.1",
38+
"react-textarea-autosize": "^8.5.7",
3839
"redux": "^5.0.1",
3940
"redux-persist": "^6.0.0",
4041
"redux-thunk": "^3.1.0",
@@ -63,20 +64,19 @@
6364
"@opencast/eslint-config-ts-react": "^0.3.0",
6465
"@redux-devtools/extension": "^3.3.0",
6566
"@types/lodash": "^4.17.16",
66-
"@types/node": "^22.13.8",
67-
"@types/react-dom": "^19.0.0",
67+
"@types/node": "^22.13.17",
68+
"@types/react-dom": "^19.0.5",
6869
"@types/uuid": "^10.0.0",
69-
"@vitejs/plugin-react-swc": "^3.8.0",
70-
"eslint": "^9.20.1",
70+
"@vitejs/plugin-react-swc": "^3.8.1",
71+
"eslint": "^9.23.0",
7172
"prop-types": "^15.8.1",
72-
"rollup-preserve-directives": "^1.1.3",
73-
"sass": "^1.85.1",
73+
"sass": "^1.86.1",
7474
"typescript": "^5.8.2",
75-
"typescript-eslint": "^8.23.0",
75+
"typescript-eslint": "^8.29.0",
7676
"uuid": "^11.1.0",
77-
"vite": "^6.2.0",
77+
"vite": "^6.2.4",
7878
"vite-plugin-svgr": "^4.3.0",
7979
"vite-tsconfig-paths": "^5.1.4",
80-
"vitest": "^3.0.4"
80+
"vitest": "^3.1.1"
8181
}
8282
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from "react";
2+
import { useTranslation } from "react-i18next";
3+
import { renderValidDate } from "../../../utils/dateUtils";
4+
import { ThemeDetailsType } from "../../../slices/themeSlice";
5+
6+
/**
7+
* This component renders the creation date cells of themes in the table view
8+
*/
9+
const ThemesDateTimeCell = ({
10+
row
11+
}: {
12+
row: ThemeDetailsType
13+
}) => {
14+
const { t } = useTranslation();
15+
16+
return (
17+
// Link template for creation date of themes
18+
<span>
19+
{t("dateFormats.date.short", {
20+
date: row.creationDate ? renderValidDate(row.creationDate) : "",
21+
})}
22+
</span>
23+
);
24+
};
25+
26+
export default ThemesDateTimeCell;

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import WizardNavigationButtons from "../../../shared/wizard/WizardNavigationButt
1919
import { ParseKeys } from "i18next";
2020
import ModalContentTable from "../../../shared/modals/ModalContentTable";
2121

22+
type InitialValues = {
23+
[key: string]: string | string[];
24+
}
25+
2226
/**
2327
* This component renders metadata details of a certain event or series
2428
*/
@@ -27,6 +31,7 @@ const DetailsMetadataTab = ({
2731
metadata,
2832
updateResource,
2933
editAccessRole,
34+
formikRef,
3035
header,
3136
}: {
3237
resourceId: string,
@@ -37,6 +42,7 @@ const DetailsMetadataTab = ({
3742
catalog: MetadataCatalog;
3843
}, any> //(id: string, values: { [key: string]: any }, catalog: MetadataCatalog) => void,
3944
editAccessRole: string,
45+
formikRef?: React.RefObject<FormikProps<InitialValues> | null>
4046
header?: ParseKeys
4147
}) => {
4248
const { t } = useTranslation();
@@ -81,11 +87,12 @@ const DetailsMetadataTab = ({
8187
metadata.length > 0 &&
8288
metadata.map((catalog, key) => (
8389
// initialize form
84-
<Formik
90+
<Formik<InitialValues>
8591
key={key}
8692
enableReinitialize
8793
initialValues={getInitialValues(catalog)}
8894
onSubmit={(values) => handleSubmit(values, catalog)}
95+
innerRef={formikRef}
8996
>
9097
{(formik) => (
9198
/* Render table for each metadata catalog */
@@ -127,13 +134,15 @@ const DetailsMetadataTab = ({
127134
name={field.id}
128135
fieldInfo={field}
129136
showCheck
137+
isFirstField={index === 0}
130138
component={RenderMultiField}
131139
/>
132140
) : (
133141
<Field
134142
name={field.id}
135143
metadataField={field}
136144
showCheck
145+
isFirstField={index === 0}
137146
component={RenderField}
138147
/>
139148
)}

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import NewTobiraPage, { TobiraFormProps } from "./NewTobiraPage";
1212
import { fetchSeriesDetailsTobira, removeSeriesTobiraPath, setTobiraTabHierarchy, TobiraData, updateSeriesTobiraPath } from "../../../../slices/seriesDetailsSlice";
1313
import { fetchSeriesDetailsTobiraNew, TobiraPage } from "../../../../slices/seriesSlice";
1414
import ConfirmModal from "../../../shared/ConfirmModal";
15-
import { Tooltip } from "../../../shared/Tooltip";
1615
import ButtonLikeAnchor from "../../../shared/ButtonLikeAnchor";
1716
import { ModalHandle } from "../../../shared/modals/Modal";
1817
import { fetchEventDetailsTobira } from "../../../../slices/eventDetailsSlice";
@@ -213,13 +212,12 @@ const TobiraTable = ({ tobiraData, i18nKey, openSubTab, handleDelete }: TobiraTa
213212
{tobiraData.hostPages.length === 0 && <tr>
214213
<td className="tobira-not-mounted">
215214
{t(`EVENTS.${i18nKey}.DETAILS.TOBIRA.NOT_MOUNTED`)}
216-
{i18nKey === "SERIES" && <Tooltip title={t("EVENTS.SERIES.DETAILS.TOBIRA.MOUNT_SERIES")}>
217-
<ButtonLikeAnchor
218-
style={{ margin: 5 }}
219-
extraClassName="edit fa fa-pencil-square pull-right"
220-
onClick={() => openSubTab("edit-path")}
221-
/>
222-
</Tooltip>}
215+
{i18nKey === "SERIES" && <ButtonLikeAnchor
216+
style={{ margin: 5 }}
217+
extraClassName="edit fa fa-pencil-square pull-right"
218+
onClick={() => openSubTab("edit-path")}
219+
tooltipText="EVENTS.SERIES.DETAILS.TOBIRA.MOUNT_SERIES"
220+
/>}
223221
</td>
224222
</tr>}
225223
{tobiraData.hostPages.map(hostPage => <tr key={hostPage.path}>

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

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,34 @@ import { Recording } from "../../../../slices/recordingSlice";
4747
import { useTranslation } from "react-i18next";
4848
import WizardNavigationButtons from "../../../shared/wizard/WizardNavigationButtons";
4949
import SchedulingTime from "../wizards/scheduling/SchedulingTime";
50-
import SchedulingEndDateDisplay from "../wizards/scheduling/SchedulingEndDateDisplay";
5150
import SchedulingLocation from "../wizards/scheduling/SchedulingLocation";
5251
import SchedulingInputs from "../wizards/scheduling/SchedulingInputs";
5352
import SchedulingConflicts from "../wizards/scheduling/SchedulingConflicts";
5453
import { ParseKeys } from "i18next";
5554
import ModalContentTable from "../../../shared/modals/ModalContentTable";
5655

57-
/**../wizards/scheduling/SchedulingTime
56+
export type InitialValues = {
57+
scheduleStartDate: string;
58+
scheduleStartHour: string;
59+
scheduleStartMinute: string;
60+
scheduleDurationHours: string;
61+
scheduleDurationMinutes: string;
62+
scheduleEndDate: string;
63+
scheduleEndHour: string;
64+
scheduleEndMinute: string;
65+
captureAgent: string;
66+
inputs: string[];
67+
}
68+
69+
/**
5870
* This component manages the main assets tab of event details modal
5971
*/
6072
const EventDetailsSchedulingTab = ({
6173
eventId,
74+
formikRef
6275
}: {
6376
eventId: string,
77+
formikRef?: React.RefObject<FormikProps<InitialValues> | null>
6478
}) => {
6579
const { t } = useTranslation();
6680
const dispatch = useAppDispatch();
@@ -234,10 +248,11 @@ const EventDetailsSchedulingTab = ({
234248
/* Scheduling configuration */
235249
hasSchedulingProperties && (
236250
/* Initialize form */
237-
<Formik
251+
<Formik<InitialValues>
238252
enableReinitialize
239253
initialValues={getInitialValues()}
240254
onSubmit={(values) => submitForm(values).then((r) => {})}
255+
innerRef={formikRef}
241256
>
242257
{(formik) => (
243258
<div className="obj tbl-details">
@@ -415,16 +430,15 @@ const EventDetailsSchedulingTab = ({
415430
checkConflictsWrapper
416431
)
417432
}}
433+
date={
434+
hasAccessRole &&
435+
(new Date(formik.values.scheduleEndDate).getDate() !==
436+
new Date(formik.values.scheduleStartDate).getDate())
437+
? formik.values.scheduleEndDate
438+
: undefined
439+
}
418440
/>
419441
)}
420-
{hasAccessRole &&
421-
formik.values.scheduleEndDate.toString() !==
422-
formik.values.scheduleStartDate.toString() && (
423-
<SchedulingEndDateDisplay
424-
scheduleEndDate={formik.values.scheduleEndDate}
425-
/>
426-
)
427-
}
428442
{!hasAccessRole && (
429443
<tr>
430444
<td>

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useAppSelector } from "../../../../store";
88
import { fetchEventStatisticsValueUpdate } from "../../../../slices/eventDetailsSlice";
99
import { useTranslation } from "react-i18next";
1010
import { createChartOptions } from "../../../../utils/statisticsUtils";
11+
import { NotificationComponent } from "../../../shared/Notifications";
1112
import { ParseKeys } from "i18next";
1213
import ModalContentTable from "../../../shared/modals/ModalContentTable";
1314

@@ -40,9 +41,13 @@ const EventDetailsStatisticsTab = ({
4041
/* error message */
4142
<div className="obj">
4243
<header>{t(header) /* Statistics */}</header>
43-
<div className="modal-alert danger">
44-
{t("STATISTICS.NOT_AVAILABLE")}
45-
</div>
44+
<NotificationComponent
45+
notification={{
46+
type: "error",
47+
message: "STATISTICS.NOT_AVAILABLE",
48+
id: 0,
49+
}}
50+
/>
4651
</div>
4752
) : (
4853
/* iterates over the different available statistics */
@@ -74,9 +79,13 @@ const EventDetailsStatisticsTab = ({
7479
</div>
7580
) : (
7681
/* unsupported type message */
77-
<div className="modal-alert danger">
78-
{t("STATISTICS.UNSUPPORTED_TYPE")}
79-
</div>
82+
<NotificationComponent
83+
notification={{
84+
type: "error",
85+
message: "STATISTICS.UNSUPPORTED_TYPE",
86+
id: 0,
87+
}}
88+
/>
8089
)}
8190
</div>
8291
))

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useEffect } from "react";
2-
import { Formik } from "formik";
2+
import { Formik, FormikProps } from "formik";
33
import {
44
deletingWorkflow as getDeletingWorkflow,
55
getBaseWorkflow,
@@ -32,13 +32,22 @@ import ButtonLikeAnchor from "../../../shared/ButtonLikeAnchor";
3232
import { formatWorkflowsForDropdown } from "../../../../utils/dropDownUtils";
3333
import { ParseKeys } from "i18next";
3434

35+
type InitialValues = {
36+
workflowDefinition: string;
37+
configuration: {
38+
[key: string]: any;
39+
} | undefined;
40+
}
41+
3542
/**
3643
* This component manages the workflows tab of the event details modal
3744
*/
3845
const EventDetailsWorkflowTab = ({
3946
eventId,
47+
formikRef,
4048
}: {
4149
eventId: string,
50+
formikRef?: React.RefObject<FormikProps<InitialValues> | null>
4251
}) => {
4352
const { t } = useTranslation();
4453
const dispatch = useAppDispatch();
@@ -280,10 +289,11 @@ const EventDetailsWorkflowTab = ({
280289

281290
{workflows.scheduling &&
282291
(isLoading || (
283-
<Formik
292+
<Formik<InitialValues>
284293
initialValues={setInitialValues()}
285294
enableReinitialize
286295
onSubmit={(values) => handleSubmit(values)}
296+
innerRef={formikRef}
287297
>
288298
{(formik) => (
289299
<div className="obj list-obj">

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ const NewAssetUploadPage = <T extends RequiredFormProps>({
3030

3131
const uploadAssetOptions = useAppSelector(state => getAssetUploadOptions(state));
3232

33-
// if user not chose upload in step before, the skip this step
34-
if (formik.values.sourceMode !== "UPLOAD") {
35-
nextPage(formik.values);
36-
return null;
37-
}
38-
3933
const handleChange = (e: React.ChangeEvent<HTMLInputElement>, assetId: string) => {
4034
if (e.target.files) {
4135
if (e.target.files.length === 0) {

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

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ import { checkConflicts, UploadAssetsTrack } from "../../../../slices/eventSlice
4444
import ModalContentTable from "../../../shared/modals/ModalContentTable";
4545
import ButtonLikeAnchor from "../../../shared/ButtonLikeAnchor";
4646
import SchedulingTime from "../wizards/scheduling/SchedulingTime";
47-
import SchedulingEndDateDisplay from "../wizards/scheduling/SchedulingEndDateDisplay";
4847
import SchedulingLocation from "../wizards/scheduling/SchedulingLocation";
4948
import SchedulingInputs from "../wizards/scheduling/SchedulingInputs";
5049
import SchedulingConflicts from "../wizards/scheduling/SchedulingConflicts";
@@ -599,17 +598,15 @@ const Schedule = <T extends {
599598
);
600599
}
601600
}}
601+
date={
602+
formik.values.sourceMode === "SCHEDULE_SINGLE" &&
603+
(new Date(formik.values.scheduleEndDate).getDate() !==
604+
new Date(formik.values.scheduleStartDate).getDate())
605+
? formik.values.scheduleEndDate
606+
: undefined
607+
}
602608
/>
603609

604-
{/* display end date if on different day to start date, only if this is current source mode */}
605-
{formik.values.sourceMode === "SCHEDULE_SINGLE" &&
606-
formik.values.scheduleEndDate.toString() !==
607-
formik.values.scheduleStartDate.toString() && (
608-
<SchedulingEndDateDisplay
609-
scheduleEndDate={formik.values.scheduleEndDate}
610-
/>
611-
)}
612-
613610
<SchedulingLocation
614611
location={formik.values.location}
615612
inputDevices={inputDevices}

0 commit comments

Comments
 (0)