From 843e470162b44cb201ca2b9ea79635afdf81c090 Mon Sep 17 00:00:00 2001 From: Arnei Date: Tue, 19 Dec 2023 16:19:23 +0100 Subject: [PATCH 1/7] Fix addNotification([...]) typing Turns out even more of the parameters for the addNotification function in the notificationThunks are perfectly optional. --- app/src/thunks/aclDetailsThunks.ts | 2 -- app/src/thunks/aclThunks.ts | 4 ---- app/src/thunks/eventDetailsThunks.ts | 2 -- app/src/thunks/eventThunks.ts | 17 ----------------- app/src/thunks/groupDetailsThunks.ts | 3 --- app/src/thunks/groupThunks.ts | 5 ----- app/src/thunks/notificationThunks.ts | 2 +- app/src/thunks/recordingThunks.ts | 3 --- app/src/thunks/seriesThunks.ts | 6 ------ app/src/thunks/taskThunks.ts | 2 -- app/src/thunks/themeDetailsThunks.ts | 2 -- app/src/thunks/themeThunks.ts | 4 ---- app/src/thunks/userDetailsThunks.ts | 2 -- app/src/thunks/userInfoThunks.ts | 1 - app/src/thunks/userThunks.ts | 4 ---- 15 files changed, 1 insertion(+), 58 deletions(-) diff --git a/app/src/thunks/aclDetailsThunks.ts b/app/src/thunks/aclDetailsThunks.ts index 75025f78b6..f5642605a2 100644 --- a/app/src/thunks/aclDetailsThunks.ts +++ b/app/src/thunks/aclDetailsThunks.ts @@ -121,12 +121,10 @@ export const updateAclDetails = (values, aclId) => async (dispatch) => { .put(`/admin-ng/acl/${aclId}`, data) .then((response) => { console.info(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "ACL_UPDATED")); }) .catch((response) => { console.error(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "ACL_NOT_SAVED")); }); }; diff --git a/app/src/thunks/aclThunks.ts b/app/src/thunks/aclThunks.ts index 4a505a0bba..c8126be65e 100644 --- a/app/src/thunks/aclThunks.ts +++ b/app/src/thunks/aclThunks.ts @@ -69,12 +69,10 @@ export const postNewAcl = (values) => async (dispatch) => { }) .then((response) => { console.info(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "ACL_ADDED")); }) .catch((response) => { console.error(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "ACL_NOT_SAVED")); }); }; @@ -86,13 +84,11 @@ export const deleteAcl = (id) => async (dispatch) => { .then((res) => { console.info(res); //add success notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "ACL_DELETED")); }) .catch((res) => { console.error(res); // add error notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "ACL_NOT_DELETED")); }); }; diff --git a/app/src/thunks/eventDetailsThunks.ts b/app/src/thunks/eventDetailsThunks.ts index ac3239cb39..e1de916d59 100644 --- a/app/src/thunks/eventDetailsThunks.ts +++ b/app/src/thunks/eventDetailsThunks.ts @@ -578,14 +578,12 @@ export const updateAssets = (values, eventId) => async (dispatch, getState) => { .then((response) => { console.info(response); dispatch( -// @ts-expect-error TS(2554): Expected 5 arguments, but got 4. addNotification("success", "EVENTS_UPDATED", null, NOTIFICATION_CONTEXT) ); }) .catch((response) => { console.error(response); dispatch( -// @ts-expect-error TS(2554): Expected 5 arguments, but got 4. addNotification( "error", "EVENTS_NOT_UPDATED", diff --git a/app/src/thunks/eventThunks.ts b/app/src/thunks/eventThunks.ts index e9623e2e72..23b853d392 100644 --- a/app/src/thunks/eventThunks.ts +++ b/app/src/thunks/eventThunks.ts @@ -184,7 +184,6 @@ export const updateBulkMetadata = (metadataFields, values) => async ( .then((res) => { console.info(res); dispatch( -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. addNotification("success", "BULK_METADATA_UPDATE.ALL_EVENTS_UPDATED") ); }) @@ -196,19 +195,16 @@ export const updateBulkMetadata = (metadataFields, values) => async ( // if this error data is undefined then an unexpected error occurred if (!err.data) { dispatch( -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. addNotification("error", "BULK_METADATA_UPDATE.UNEXPECTED_ERROR") ); } else { if (err.data.updated && err.data.updated.length === 0) { dispatch( -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. addNotification("error", "BULK_METADATA_UPDATE.NO_EVENTS_UPDATED") ); } if (err.data.updateFailures && err.data.updateFailures.length > 0) { dispatch( -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. addNotification( "warning", "BULK_METADATA_UPDATE.SOME_EVENTS_NOT_UPDATED" @@ -217,7 +213,6 @@ export const updateBulkMetadata = (metadataFields, values) => async ( } if (err.data.notFound && err.data.notFound.length > 0) { dispatch( -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. addNotification( "warning", "BULK_ACTIONS.EDIT_EVENTS_METADATA.REQUEST_ERRORS.NOT_FOUND" @@ -227,7 +222,6 @@ export const updateBulkMetadata = (metadataFields, values) => async ( } } else { dispatch( -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. addNotification("error", "BULK_METADATA_UPDATE.UNEXPECTED_ERROR") ); } @@ -485,12 +479,10 @@ export const postNewEvent = (values, metadataInfo, extendedMetadata) => async ( .post("/admin-ng/event/new", formData, config) .then((response) => { console.info(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "EVENTS_CREATED")); }) .catch((response) => { console.error(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "EVENTS_NOT_CREATED")); }); }; @@ -504,20 +496,16 @@ export const deleteEvent = (id) => async (dispatch) => { .then((res) => { // add success notification depending on status code if (res.status === 200) { -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "EVENT_DELETED")); } else { -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "EVENT_WILL_BE_DELETED")); } }) .catch((res) => { // add error notification depending on status code if (res.status === 401) { -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "EVENTS_NOT_DELETED_NOT_AUTHORIZED")); } else { -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "EVENTS_NOT_DELETED")); } }); @@ -539,13 +527,11 @@ export const deleteMultipleEvent = (events) => async (dispatch) => { .then((res) => { console.info(res); //add success notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "EVENTS_DELETED")); }) .catch((res) => { console.error(res); //add error notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "EVENTS_NOT_DELETED")); }); }; @@ -706,7 +692,6 @@ export const updateScheduledEventsBulk = (values) => async (dispatch) => { if (!eventChanges || !originalEvent) { dispatch( -// @ts-expect-error TS(2554): Expected 5 arguments, but got 4. addNotification( "error", "EVENTS_NOT_UPDATED_ID", @@ -772,12 +757,10 @@ export const updateScheduledEventsBulk = (values) => async (dispatch) => { .put("/admin-ng/event/bulk/update", formData) .then((res) => { console.info(res); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "EVENTS_UPDATED_ALL")); }) .catch((res) => { console.error(res); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "EVENTS_NOT_UPDATED_ALL")); }); }; diff --git a/app/src/thunks/groupDetailsThunks.ts b/app/src/thunks/groupDetailsThunks.ts index acb54b1b0e..db772da1dc 100644 --- a/app/src/thunks/groupDetailsThunks.ts +++ b/app/src/thunks/groupDetailsThunks.ts @@ -55,16 +55,13 @@ export const updateGroupDetails = (values, groupId) => async (dispatch) => { .put(`/admin-ng/groups/${groupId}`, data) .then((response) => { console.info(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "GROUP_UPDATED")); }) .catch((response) => { console.error(response); if (response.status === 409) { -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "GROUP_CONFLICT")); } else { -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "GROUP_NOT_SAVED")); } }); diff --git a/app/src/thunks/groupThunks.ts b/app/src/thunks/groupThunks.ts index be9a9e88c2..c42f9ec97e 100644 --- a/app/src/thunks/groupThunks.ts +++ b/app/src/thunks/groupThunks.ts @@ -43,16 +43,13 @@ export const postNewGroup = (values) => async (dispatch) => { }) .then((response) => { console.info(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "GROUP_ADDED")); }) .catch((response) => { console.error(response); if (response.status === 409) { -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "GROUP_CONFLICT")); } else { -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "GROUP_NOT_SAVED")); } }); @@ -66,13 +63,11 @@ export const deleteGroup = (id) => async (dispatch) => { .then((res) => { console.info(res); // add success notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "GROUP_DELETED")); }) .catch((res) => { console.error(res); // add error notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "GROUP_NOT_DELETED")); }); }; diff --git a/app/src/thunks/notificationThunks.ts b/app/src/thunks/notificationThunks.ts index 2267a9e601..96cbe65d91 100644 --- a/app/src/thunks/notificationThunks.ts +++ b/app/src/thunks/notificationThunks.ts @@ -11,7 +11,7 @@ import { } from "../configs/generalConfig"; // @ts-expect-error TS(7006): Parameter 'dispatch' implicitly has an 'any' type. -export const addNotification = (type, key, duration, parameter, context, id?) => ( +export const addNotification = (type, key, duration?, parameter?, context?, id?) => ( // @ts-expect-error TS(7006): Parameter 'dispatch' implicitly has an 'any' type. dispatch, // @ts-expect-error TS(7006): Parameter 'getState' implicitly has an 'any' type. diff --git a/app/src/thunks/recordingThunks.ts b/app/src/thunks/recordingThunks.ts index f08584ecd8..cd1d7ddc37 100644 --- a/app/src/thunks/recordingThunks.ts +++ b/app/src/thunks/recordingThunks.ts @@ -67,7 +67,6 @@ export const deleteRecording = (id) => async (dispatch) => { .then((res) => { console.info(res); // add success notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "LOCATION_DELETED")); }) .catch((res) => { @@ -75,11 +74,9 @@ export const deleteRecording = (id) => async (dispatch) => { // add error notification depending on status code if (res.status === 401) { dispatch( -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. addNotification("error", "LOCATION_NOT_DELETED_NOT_AUTHORIZED") ); } else { -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "LOCATION_NOT_DELETED")); } }); diff --git a/app/src/thunks/seriesThunks.ts b/app/src/thunks/seriesThunks.ts index 6065ef99a8..304c215767 100644 --- a/app/src/thunks/seriesThunks.ts +++ b/app/src/thunks/seriesThunks.ts @@ -155,12 +155,10 @@ export const postNewSeries = (values, metadataInfo, extendedMetadata) => async ( }) .then((response) => { console.info(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "SERIES_ADDED")); }) .catch((response) => { console.error(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "SERIES_NOT_SAVED")); }); }; @@ -195,13 +193,11 @@ export const deleteSeries = (id) => async (dispatch) => { .then((res) => { console.info(res); // add success notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "SERIES_DELETED")); }) .catch((res) => { console.error(res); // add error notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "SERIES_NOT_DELETED")); }); }; @@ -222,13 +218,11 @@ export const deleteMultipleSeries = (series) => async (dispatch) => { .then((res) => { console.info(res); //add success notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "SERIES_DELETED")); }) .catch((res) => { console.error(res); //add error notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "SERIES_NOT_DELETED")); }); }; diff --git a/app/src/thunks/taskThunks.ts b/app/src/thunks/taskThunks.ts index fc7b0bf58c..a2e76fc79d 100644 --- a/app/src/thunks/taskThunks.ts +++ b/app/src/thunks/taskThunks.ts @@ -33,12 +33,10 @@ export const postTasks = (values: any) => async (dispatch: any) => { }) .then((response) => { console.info(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "TASK_CREATED")); }) .catch((response) => { console.error(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "TASK_NOT_CREATED")); }); }; diff --git a/app/src/thunks/themeDetailsThunks.ts b/app/src/thunks/themeDetailsThunks.ts index 878f7cedec..3a67d0a8ca 100644 --- a/app/src/thunks/themeDetailsThunks.ts +++ b/app/src/thunks/themeDetailsThunks.ts @@ -56,12 +56,10 @@ export const updateThemeDetails = (id, values) => async (dispatch) => { }) .then((response) => { console.info(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "THEME_CREATED")); }) .catch((response) => { console.error(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "THEME_NOT_CREATED")); }); }; diff --git a/app/src/thunks/themeThunks.ts b/app/src/thunks/themeThunks.ts index 177f97bd91..c7288ebc48 100644 --- a/app/src/thunks/themeThunks.ts +++ b/app/src/thunks/themeThunks.ts @@ -42,12 +42,10 @@ export const postNewTheme = (values) => async (dispatch) => { }) .then((response) => { console.info(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "THEME_CREATED")); }) .catch((response) => { console.error(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "THEME_NOT_CREATED")); }); }; @@ -59,13 +57,11 @@ export const deleteTheme = (id) => async (dispatch) => { .then((res) => { console.info(res); // add success notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "THEME_DELETED")); }) .catch((res) => { console.error(res); // add error notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "THEME_NOT_DELETED")); }); }; diff --git a/app/src/thunks/userDetailsThunks.ts b/app/src/thunks/userDetailsThunks.ts index 77318c3eba..8d6d44928b 100644 --- a/app/src/thunks/userDetailsThunks.ts +++ b/app/src/thunks/userDetailsThunks.ts @@ -40,12 +40,10 @@ export const updateUserDetails = (values, username) => async (dispatch) => { .put(`/admin-ng/users/${username}.json`, data) .then((response) => { console.info(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "USER_UPDATED")); }) .catch((response) => { console.error(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "USER_NOT_SAVED")); }); }; diff --git a/app/src/thunks/userInfoThunks.ts b/app/src/thunks/userInfoThunks.ts index 3511319b59..be4ceadca7 100644 --- a/app/src/thunks/userInfoThunks.ts +++ b/app/src/thunks/userInfoThunks.ts @@ -29,7 +29,6 @@ export const fetchUserInfo = () => async (dispatch) => { } catch (e) { console.error(e); dispatch(loadUserInfoFailure()); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "PROBLEM_ON_START")); } }; diff --git a/app/src/thunks/userThunks.ts b/app/src/thunks/userThunks.ts index 77ee5e5402..9ac6033c04 100644 --- a/app/src/thunks/userThunks.ts +++ b/app/src/thunks/userThunks.ts @@ -55,12 +55,10 @@ export const postNewUser = (values) => async (dispatch) => { }) .then((response) => { console.info(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "USER_ADDED")); }) .catch((response) => { console.error(response); -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "USER_NOT_SAVED")); }); }; @@ -74,13 +72,11 @@ export const deleteUser = (id) => async (dispatch) => { .then((res) => { console.info(res); // add success notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("success", "USER_DELETED")); }) .catch((res) => { console.error(res); // add error notification -// @ts-expect-error TS(2554): Expected 5 arguments, but got 2. dispatch(addNotification("error", "USER_NOT_DELETED")); }); }; From 2f4a93d7916fe780963187836b2ff0ce63cdcbbf Mon Sep 17 00:00:00 2001 From: Arnei Date: Thu, 21 Dec 2023 10:05:05 +0100 Subject: [PATCH 2/7] Move eventsTableMap into its own file Fixes a "can't access lexical declaration 'X' before initialization" error, by resolving a kind of circular dependency. --- app/src/components/events/Events.tsx | 2 +- .../configs/tableConfigs/eventsTableConfig.ts | 28 ------------------- .../configs/tableConfigs/eventsTableMap.ts | 27 ++++++++++++++++++ 3 files changed, 28 insertions(+), 29 deletions(-) create mode 100644 app/src/configs/tableConfigs/eventsTableMap.ts diff --git a/app/src/components/events/Events.tsx b/app/src/components/events/Events.tsx index a90dcdffe9..5662770d37 100644 --- a/app/src/components/events/Events.tsx +++ b/app/src/components/events/Events.tsx @@ -13,7 +13,7 @@ import DeleteEventsModal from "./partials/modals/DeleteEventsModal"; import StartTaskModal from "./partials/modals/StartTaskModal"; import EditScheduledEventsModal from "./partials/modals/EditScheduledEventsModal"; import EditMetadataEventsModal from "./partials/modals/EditMetadataEventsModal"; -import { eventsTemplateMap } from "../../configs/tableConfigs/eventsTableConfig"; +import { eventsTemplateMap } from "../../configs/tableConfigs/eventsTableMap"; import { fetchEventMetadata, fetchEvents } from "../../thunks/eventThunks"; import { loadEventsIntoTable, diff --git a/app/src/configs/tableConfigs/eventsTableConfig.ts b/app/src/configs/tableConfigs/eventsTableConfig.ts index 7e1f99cd1d..ea2a71acc8 100644 --- a/app/src/configs/tableConfigs/eventsTableConfig.ts +++ b/app/src/configs/tableConfigs/eventsTableConfig.ts @@ -1,14 +1,3 @@ -import EventActionCell from "../../components/events/partials/EventActionCell"; -import EventsDateCell from "../../components/events/partials/EventsDateCell"; -import EventsPresentersCell from "../../components/events/partials/EventsPresentersCell"; -import EventsSeriesCell from "../../components/events/partials/EventsSeriesCell"; -import EventsStatusCell from "../../components/events/partials/EventsStatusCell"; -import EventsTechnicalDateCell from "../../components/events/partials/EventsTechnicalDateCell"; -import PublishedCell from "../../components/events/partials/PublishedCell"; -import EventsLocationCell from "../../components/events/partials/EventsLocationCell"; -import EventsEndCell from "../../components/events/partials/EventsEndCell"; -import EventsStartCell from "../../components/events/partials/EventsStartCell"; - /** * Config that contains the columns and further information regarding events. These are the information that never or hardly changes. * That's why it is hard coded here and not fetched from server. @@ -94,20 +83,3 @@ export const eventsTableConfig = { category: "events", multiSelect: true, }; - -/** - * This map contains the mapping between the template strings above and the corresponding react component. - * This helps to render different templates of cells more dynamically - */ -export const eventsTemplateMap = { - EventActionsCell: EventActionCell, - EventsDateCell: EventsDateCell, - EventsStartCell: EventsStartCell, - EventsEndCell: EventsEndCell, - EventsLocationCell: EventsLocationCell, - EventsPresentersCell: EventsPresentersCell, - EventsSeriesCell: EventsSeriesCell, - EventsStatusCell: EventsStatusCell, - EventsTechnicalDateCell: EventsTechnicalDateCell, - PublishedCell: PublishedCell, -}; diff --git a/app/src/configs/tableConfigs/eventsTableMap.ts b/app/src/configs/tableConfigs/eventsTableMap.ts new file mode 100644 index 0000000000..218bcb92bb --- /dev/null +++ b/app/src/configs/tableConfigs/eventsTableMap.ts @@ -0,0 +1,27 @@ +import EventActionCell from "../../components/events/partials/EventActionCell"; +import EventsDateCell from "../../components/events/partials/EventsDateCell"; +import EventsPresentersCell from "../../components/events/partials/EventsPresentersCell"; +import EventsSeriesCell from "../../components/events/partials/EventsSeriesCell"; +import EventsStatusCell from "../../components/events/partials/EventsStatusCell"; +import EventsTechnicalDateCell from "../../components/events/partials/EventsTechnicalDateCell"; +import PublishedCell from "../../components/events/partials/PublishedCell"; +import EventsLocationCell from "../../components/events/partials/EventsLocationCell"; +import EventsEndCell from "../../components/events/partials/EventsEndCell"; +import EventsStartCell from "../../components/events/partials/EventsStartCell"; + +/** + * This map contains the mapping between the template strings above and the corresponding react component. + * This helps to render different templates of cells more dynamically + */ +export const eventsTemplateMap = { + EventActionsCell: EventActionCell, + EventsDateCell: EventsDateCell, + EventsStartCell: EventsStartCell, + EventsEndCell: EventsEndCell, + EventsLocationCell: EventsLocationCell, + EventsPresentersCell: EventsPresentersCell, + EventsSeriesCell: EventsSeriesCell, + EventsStatusCell: EventsStatusCell, + EventsTechnicalDateCell: EventsTechnicalDateCell, + PublishedCell: PublishedCell, +}; From 220e9be7d54407e7693e1af3f89088ef8d5caf0a Mon Sep 17 00:00:00 2001 From: Arnei Date: Thu, 21 Dec 2023 17:27:04 +0100 Subject: [PATCH 3/7] Modernize redux: workflowSlice Switching to redux toolkit for getting workflows for the start workflow dropdowns. Does not work yet. - Workflow Configuration cannot be edited. - Console errors. --- app/src/actions/workflowActions.ts | 24 ---- .../ModalTabsAndPages/NewProcessingPage.tsx | 47 +++---- .../StartTaskSummaryPage.tsx | 41 +++--- .../StartTaskWorkflowPage.tsx | 52 +++----- .../events/partials/modals/StartTaskModal.tsx | 1 - .../partials/wizards/NewEventSummary.tsx | 7 +- .../partials/wizards/RenderWorkflowConfig.tsx | 51 ++++---- app/src/reducers/workflowReducers.ts | 49 -------- app/src/selectors/workflowSelectors.ts | 21 ++-- app/src/slices/workflowSlice.ts | 119 ++++++++++++++++++ app/src/store.ts | 2 +- app/src/thunks/eventDetailsThunks.ts | 2 +- app/src/thunks/workflowThunks.ts | 72 ----------- 13 files changed, 206 insertions(+), 282 deletions(-) delete mode 100644 app/src/actions/workflowActions.ts delete mode 100644 app/src/reducers/workflowReducers.ts create mode 100644 app/src/slices/workflowSlice.ts delete mode 100644 app/src/thunks/workflowThunks.ts diff --git a/app/src/actions/workflowActions.ts b/app/src/actions/workflowActions.ts deleted file mode 100644 index b91f36afc4..0000000000 --- a/app/src/actions/workflowActions.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * This file contains all redux actions that can be executed on workflows - */ - -// Constants of actions types for fetching workflow definitions from server -export const LOAD_WORKFLOW_DEF_IN_PROGRESS = "LOAD_WORKFLOW_DEF_IN_PROGRESS"; -export const LOAD_WORKFLOW_DEF_SUCCESS = "LOAD_WORKFLOW_DEF_SUCCESS"; -export const LOAD_WORKFLOW_DEF_FAILURE = "LOAD_WORKFLOW_DEF_FAILURE"; - -// Actions affecting fetching of workflow definitions from server - -export const loadWorkflowDefInProgress = () => ({ - type: LOAD_WORKFLOW_DEF_IN_PROGRESS, -}); - -// @ts-expect-error TS(7006): Parameter 'workflowDef' implicitly has an 'any' ty... Remove this comment to see the full error message -export const loadWorkflowDefSuccess = (workflowDef) => ({ - type: LOAD_WORKFLOW_DEF_SUCCESS, - payload: { workflowDef }, -}); - -export const loadWorkflowDefFailure = () => ({ - type: LOAD_WORKFLOW_DEF_FAILURE, -}); diff --git a/app/src/components/events/partials/ModalTabsAndPages/NewProcessingPage.tsx b/app/src/components/events/partials/ModalTabsAndPages/NewProcessingPage.tsx index 6f9b207510..8c82a8c2fd 100644 --- a/app/src/components/events/partials/ModalTabsAndPages/NewProcessingPage.tsx +++ b/app/src/components/events/partials/ModalTabsAndPages/NewProcessingPage.tsx @@ -1,33 +1,33 @@ import React, { useEffect } from "react"; import { useTranslation } from "react-i18next"; import cn from "classnames"; -import { connect } from "react-redux"; -import { fetchWorkflowDef } from "../../../../thunks/workflowThunks"; import { getWorkflowDef } from "../../../../selectors/workflowSelectors"; import RenderWorkflowConfig from "../wizards/RenderWorkflowConfig"; import { setDefaultConfig } from "../../../../utils/workflowPanelUtils"; import DropDown from "../../../shared/DropDown"; +import { useAppDispatch, useAppSelector } from "../../../../store"; +import { fetchWorkflowDef } from "../../../../slices/workflowSlice"; /** * This component renders the processing page for new events in the new event wizard. */ -const NewProcessingPage = ({ -// @ts-expect-error TS(7031): Binding element 'previousPage' implicitly has an '... Remove this comment to see the full error message +const NewProcessingPage: React.FC<{ + previousPage: any //TODO: Add type + nextPage: any //TODO: Add type + formik: any //TODO: Add type +}> = ({ previousPage, -// @ts-expect-error TS(7031): Binding element 'nextPage' implicitly has an 'any'... Remove this comment to see the full error message nextPage, -// @ts-expect-error TS(7031): Binding element 'formik' implicitly has an 'any' t... Remove this comment to see the full error message formik, -// @ts-expect-error TS(7031): Binding element 'loadingWorkflowDef' implicitly ha... Remove this comment to see the full error message - loadingWorkflowDef, -// @ts-expect-error TS(7031): Binding element 'workflowDef' implicitly has an 'a... Remove this comment to see the full error message - workflowDef, }) => { const { t } = useTranslation(); + const dispatch = useAppDispatch(); + + const workflowDef = useAppSelector(state => getWorkflowDef(state)); useEffect(() => { // Load workflow definitions for selecting - loadingWorkflowDef(); + dispatch(fetchWorkflowDef("default")); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -68,17 +68,10 @@ const NewProcessingPage = ({ formik.values.processingWorkflow === workflow.id - ) - ? workflowDef.find( -// @ts-expect-error TS(7006): Parameter 'workflow' implicitly has an 'any' type. - (workflow) => - formik.values.processingWorkflow === workflow.id - ).title - : "" + )?.title ?? "" } options={workflowDef} type={"workflow"} @@ -147,16 +140,4 @@ const NewProcessingPage = ({ ); }; -// Getting state data out of redux store -// @ts-expect-error TS(7006): Parameter 'state' implicitly has an 'any' type. -const mapStateToProps = (state) => ({ - workflowDef: getWorkflowDef(state), -}); - -// @ts-expect-error TS(7006): Parameter 'dispatch' implicitly has an 'any' type. -const mapDispatchToProps = (dispatch) => ({ -// @ts-expect-error TS(2554): Expected 1 arguments, but got 0. - loadingWorkflowDef: () => dispatch(fetchWorkflowDef()), -}); - -export default connect(mapStateToProps, mapDispatchToProps)(NewProcessingPage); +export default NewProcessingPage; diff --git a/app/src/components/events/partials/ModalTabsAndPages/StartTaskSummaryPage.tsx b/app/src/components/events/partials/ModalTabsAndPages/StartTaskSummaryPage.tsx index cd27d3dad6..442577629a 100644 --- a/app/src/components/events/partials/ModalTabsAndPages/StartTaskSummaryPage.tsx +++ b/app/src/components/events/partials/ModalTabsAndPages/StartTaskSummaryPage.tsx @@ -2,18 +2,22 @@ import React from "react"; import { useTranslation } from "react-i18next"; import WizardNavigationButtons from "../../../shared/wizard/WizardNavigationButtons"; import { getWorkflowDef } from "../../../../selectors/workflowSelectors"; -import { connect } from "react-redux"; +import { useAppSelector } from "../../../../store"; /** * This component renders the summary page of the start task bulk action */ -const StartTaskSummaryPage = ({ - formik, - previousPage, - workflowDef -}: any) => { +const StartTaskSummaryPage: React.FC<{ + formik: any //TODO: Add type + previousPage: any //TODO: Add type +}> = ({ + formik, + previousPage, +}) => { const { t } = useTranslation(); + const workflowDef = useAppSelector(state => getWorkflowDef(state)); + return ( <>
@@ -42,17 +46,12 @@ const StartTaskSummaryPage = ({ {t("BULK_ACTIONS.SCHEDULE_TASK.SUMMARY.WORKFLOW")}

- {!!workflowDef.find( -// @ts-expect-error TS(7006): Parameter 'workflowDef' implicitly has an 'any' ty... Remove this comment to see the full error message - (workflowDef) => - workflowDef.id === formik.values.workflow - ) - ? workflowDef.find( -// @ts-expect-error TS(7006): Parameter 'workflowDef' implicitly has an 'any' ty... Remove this comment to see the full error message - (workflowDef) => - workflowDef.id === formik.values.workflow - ).title - : ""} + { + workflowDef.find( + (workflow) => + formik.values.processingWorkflow === workflow.id + )?.title ?? "" + }

  • @@ -85,10 +84,4 @@ const StartTaskSummaryPage = ({ ); }; -// Getting state data out of redux store -// @ts-expect-error TS(7006): Parameter 'state' implicitly has an 'any' type. -const mapStateToProps = (state) => ({ - workflowDef: getWorkflowDef(state), -}); - -export default connect(mapStateToProps, null)(StartTaskSummaryPage); +export default StartTaskSummaryPage; diff --git a/app/src/components/events/partials/ModalTabsAndPages/StartTaskWorkflowPage.tsx b/app/src/components/events/partials/ModalTabsAndPages/StartTaskWorkflowPage.tsx index 707ba005df..10992ddfad 100644 --- a/app/src/components/events/partials/ModalTabsAndPages/StartTaskWorkflowPage.tsx +++ b/app/src/components/events/partials/ModalTabsAndPages/StartTaskWorkflowPage.tsx @@ -1,35 +1,35 @@ import React, { useEffect } from "react"; import { useTranslation } from "react-i18next"; import RenderWorkflowConfig from "../wizards/RenderWorkflowConfig"; -import { fetchWorkflowDef } from "../../../../thunks/workflowThunks"; import { getWorkflowDef } from "../../../../selectors/workflowSelectors"; -import { connect } from "react-redux"; import cn from "classnames"; import { setDefaultConfig } from "../../../../utils/workflowPanelUtils"; import DropDown from "../../../shared/DropDown"; +import { useAppDispatch, useAppSelector } from "../../../../store"; +import { fetchWorkflowDef } from "../../../../slices/workflowSlice"; /** * This component renders the workflow selection for start task bulk action */ -const StartTaskWorkflowPage = ({ -// @ts-expect-error TS(7031): Binding element 'formik' implicitly has an 'any' t... Remove this comment to see the full error message +const StartTaskWorkflowPage: React.FC<{ + formik: any //TODO: Add type + previousPage: any //TODO: Add type + nextPage: any //TODO: Add type + setPageCompleted: any //TODO: Add type +}> = ({ formik, -// @ts-expect-error TS(7031): Binding element 'previousPage' implicitly has an '... Remove this comment to see the full error message previousPage, -// @ts-expect-error TS(7031): Binding element 'nextPage' implicitly has an 'any'... Remove this comment to see the full error message nextPage, -// @ts-expect-error TS(7031): Binding element 'setPageCompleted' implicitly has ... Remove this comment to see the full error message setPageCompleted, -// @ts-expect-error TS(7031): Binding element 'loadingWorkflowDef' implicitly ha... Remove this comment to see the full error message - loadingWorkflowDef, -// @ts-expect-error TS(7031): Binding element 'workflowDef' implicitly has an 'a... Remove this comment to see the full error message - workflowDef, }) => { const { t } = useTranslation(); + const dispatch = useAppDispatch(); + const workflowDef = useAppSelector(state => getWorkflowDef(state)); + useEffect(() => { // Load workflow definitions for selecting - loadingWorkflowDef(); + dispatch(fetchWorkflowDef("default")); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -59,17 +59,10 @@ const StartTaskWorkflowPage = ({ workflowDef.id === formik.values.workflow - ) - ? workflowDef.find( -// @ts-expect-error TS(7006): Parameter 'workflowDef' implicitly has an 'any' ty... Remove this comment to see the full error message - (workflowDef) => - workflowDef.id === formik.values.workflow - ).title - : "" + )?.title ?? "" } options={workflowDef} type={"workflow"} @@ -144,19 +137,4 @@ const StartTaskWorkflowPage = ({ ); }; -// Getting state data out of redux store -// @ts-expect-error TS(7006): Parameter 'state' implicitly has an 'any' type. -const mapStateToProps = (state) => ({ - workflowDef: getWorkflowDef(state), -}); - -// Mapping actions to dispatch -// @ts-expect-error TS(7006): Parameter 'dispatch' implicitly has an 'any' type. -const mapDispatchToProps = (dispatch) => ({ - loadingWorkflowDef: () => dispatch(fetchWorkflowDef("tasks")), -}); - -export default connect( - mapStateToProps, - mapDispatchToProps -)(StartTaskWorkflowPage); +export default StartTaskWorkflowPage; diff --git a/app/src/components/events/partials/modals/StartTaskModal.tsx b/app/src/components/events/partials/modals/StartTaskModal.tsx index efdc794380..01b36dfc50 100644 --- a/app/src/components/events/partials/modals/StartTaskModal.tsx +++ b/app/src/components/events/partials/modals/StartTaskModal.tsx @@ -121,7 +121,6 @@ const StartTaskModal = ({ )} {page === 2 && ( ; previousPage: an... Remove this comment to see the full error message formik={formik} previousPage={previousPage} /> diff --git a/app/src/components/events/partials/wizards/NewEventSummary.tsx b/app/src/components/events/partials/wizards/NewEventSummary.tsx index e0b95b96d0..5e45eac307 100644 --- a/app/src/components/events/partials/wizards/NewEventSummary.tsx +++ b/app/src/components/events/partials/wizards/NewEventSummary.tsx @@ -11,6 +11,7 @@ import MetadataSummaryTable from "./summaryTables/MetadataSummaryTable"; import MetadataExtendedSummaryTable from "./summaryTables/MetadataExtendedSummaryTable"; import AccessSummaryTable from "./summaryTables/AccessSummaryTable"; import WizardNavigationButtons from "../../../shared/wizard/WizardNavigationButtons"; +import { useAppSelector } from "../../../../store"; /** * This component renders the summary page for new events in the new event wizard. @@ -28,13 +29,13 @@ const NewEventSummary = ({ metadataEvents, // @ts-expect-error TS(7031): Binding element 'extendedMetadata' implicitly has ... Remove this comment to see the full error message extendedMetadata, -// @ts-expect-error TS(7031): Binding element 'workflowDef' implicitly has an 'a... Remove this comment to see the full error message - workflowDef, // @ts-expect-error TS(7031): Binding element 'uploadAssetOptions' implicitly ha... Remove this comment to see the full error message uploadAssetOptions, }) => { const { t } = useTranslation(); + const workflowDef = useAppSelector(state => getWorkflowDef(state)); + // Get upload assets that are not of type track const uploadAssetsOptionsNonTrack = uploadAssetOptions.filter( // @ts-expect-error TS(7006): Parameter 'asset' implicitly has an 'any' type. @@ -63,7 +64,6 @@ const NewEventSummary = ({ // Get additional information about chosen workflow definition const workflowDefinition = workflowDef.find( -// @ts-expect-error TS(7006): Parameter 'workflow' implicitly has an 'any' type. (workflow) => workflow.id === formik.values.processingWorkflow ); @@ -306,7 +306,6 @@ const NewEventSummary = ({ const mapStateToProps = (state) => ({ metadataEvents: getEventMetadata(state), extendedMetadata: getExtendedEventMetadata(state), - workflowDef: getWorkflowDef(state), uploadAssetOptions: getAssetUploadOptions(state), }); diff --git a/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx b/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx index 64454b412c..7bb11e542a 100644 --- a/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx +++ b/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx @@ -1,29 +1,35 @@ import React from "react"; -import { connect } from "react-redux"; // @ts-expect-error TS(7016): Could not find a declaration file for module 'uuid... Remove this comment to see the full error message import { v4 as uuidv4 } from "uuid"; import { Field } from "formik"; import { getWorkflowDefById, - makeGetWorkflowDefById, } from "../../../../selectors/workflowSelectors"; +import { useAppSelector } from "../../../../store"; /** * This component renders the configuration panel for the selected workflow in the processing step of the new event * wizard chosen via dropdown. - * Here, props is used instead of {} containing name of each prop because props are needed in the selector for finding - * the workflow definition with the matching id. In this case props need to be considered in mapStateToProps and - * therefore {} containing names of props not works. */ -// @ts-expect-error TS(7006): Parameter 'props' implicitly has an 'any' type. -const RenderWorkflowConfig = (props) => { +const RenderWorkflowConfig: React.FC<{ + workflowId: string + formik: any //TODO: Add type + displayDescription?: any +}> = ({ + workflowId, + formik, + displayDescription +}) => { + + const workflowDef = useAppSelector(state => getWorkflowDefById(state, workflowId)); + // Get html for configuration panel - const configPanel = !!props.configuration_panel_json - ? props.configuration_panel_json + const configPanel = !!workflowDef && workflowDef.configuration_panel_json + ? workflowDef.configuration_panel_json : []; - const description = !!props.description ? props.description : ""; - const displayDescription = !!props.displayDescription; - let formik = props.formik; + const description = !!workflowDef && workflowDef.description + ? workflowDef.description + : ""; const descriptionBoxStyle = { margin: "15px 0 0 0", @@ -98,15 +104,15 @@ const renderInputByType = (field, key, formik) => { // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message const RenderDatetimeLocal = ({ field, key, formik }) => { - field.value = undefined; + // field.value = undefined; return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message const RenderCheckbox = ({ field, key, formik }) => { - field.defaultValue = field.value; - field.value = undefined; + // field.defaultValue = field.value; + // field.value = undefined; return ; }; @@ -128,15 +134,15 @@ const RenderNumber = ({ field, key, formik }) => { return error; }; - field.defaultValue = field.value; - field.value = undefined; + // field.defaultValue = field.value; + // field.value = undefined; return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message const RenderText = ({ field, key, formik }) => { - field.value = undefined; + // field.value = undefined; return ; }; @@ -207,11 +213,4 @@ const RenderField : React.FC<{ ); } -// Getting state data out of redux store -const mapStateToProps = () => { - getWorkflowDefById(); -// @ts-expect-error TS(7006): Parameter 'state' implicitly has an 'any' type. - return (state, props) => makeGetWorkflowDefById(state, props); -}; - -export default connect(mapStateToProps)(RenderWorkflowConfig); +export default RenderWorkflowConfig; diff --git a/app/src/reducers/workflowReducers.ts b/app/src/reducers/workflowReducers.ts deleted file mode 100644 index 277a19add3..0000000000 --- a/app/src/reducers/workflowReducers.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { - LOAD_WORKFLOW_DEF_FAILURE, - LOAD_WORKFLOW_DEF_IN_PROGRESS, - LOAD_WORKFLOW_DEF_SUCCESS, -} from "../actions/workflowActions"; - -/** - * This file contains redux reducer for actions affecting the state of workflows - */ - -// Initial state of workflows in redux store -const initialState = { - isLoading: false, - defaultWorkflowId: "", - workflows: [], -}; - -// Reducer for workflows -// @ts-expect-error TS(7006): Parameter 'action' implicitly has an 'any' type. -const workflows = (state = initialState, action) => { - const { type, payload } = action; - switch (type) { - case LOAD_WORKFLOW_DEF_IN_PROGRESS: { - return { - ...state, - isLoading: true, - }; - } - case LOAD_WORKFLOW_DEF_SUCCESS: { - const { workflowDef } = payload; - return { - ...state, - isLoading: false, - defaultWorkflowId: workflowDef.defaultWorkflowId, - workflows: workflowDef.workflows, - }; - } - case LOAD_WORKFLOW_DEF_FAILURE: { - return { - ...state, - isLoading: false, - }; - } - default: - return state; - } -}; - -export default workflows; diff --git a/app/src/selectors/workflowSelectors.ts b/app/src/selectors/workflowSelectors.ts index 2de8211c49..81158cf5d0 100644 --- a/app/src/selectors/workflowSelectors.ts +++ b/app/src/selectors/workflowSelectors.ts @@ -1,17 +1,18 @@ import { createSelector } from "reselect"; +import { RootState } from "../store"; /** * This file contains selectors regarding workflows */ +export const getWorkflowDef = (state: RootState) => state.workflows.workflows; -export const getWorkflowDef = (state: any) => state.workflows.workflows; +const workflows = (state: RootState) => state.workflows -// Selector for getting a workflow definition by its id -// first you have to find said id in state then put these in selector because reselect need one input selector -export const makeGetWorkflowDefById = (state: any, props: any) => - state.workflows.workflows.find( -// @ts-expect-error TS(7006): Parameter 'workflow' implicitly has an 'any' type. - (workflow) => workflow.id === props.workflowId - ); -export const getWorkflowDefById = () => - createSelector(makeGetWorkflowDefById, (workflowDef) => ({ workflowDef })); +export const getWorkflowDefById = createSelector( + [workflows, (workflows, workflowId: string) => workflowId], + (workflows, workflowId) => { + return workflows.workflows.find( + (workflow) => workflow.id === workflowId + ); + } +); diff --git a/app/src/slices/workflowSlice.ts b/app/src/slices/workflowSlice.ts new file mode 100644 index 0000000000..c0a465c3db --- /dev/null +++ b/app/src/slices/workflowSlice.ts @@ -0,0 +1,119 @@ +import { PayloadAction, SerializedError, createAsyncThunk, createSlice } from '@reduxjs/toolkit' +import axios from 'axios'; + +/** + * This file contains redux reducer for actions affecting the state of workflows + */ +type Workflow = { + configuration_panel: string, //XML + configuration_panel_json: any, //Both the Json string AND the parsed Json!? + description: string, + displayOrder: number, + id: string, + tags: string[], + title: string, +} + +type WorkflowState = { + status: 'uninitialized' | 'loading' | 'succeeded' | 'failed', + error: SerializedError | null, + defaultWorkflowId: string, + workflows: Workflow[], +}; + +// Initial state of workflows in redux store +const initialState: WorkflowState = { + status: 'uninitialized', + error: null, + defaultWorkflowId: "", + workflows: [], +}; + +// fetch workflow definitions from server +export const fetchWorkflowDef = createAsyncThunk('workflow/fetchWorkflowDef', async (type: any) => { + let urlParams; + + switch (type) { + case "tasks": { + urlParams = { + tags: "archive", + }; + break; + } + case "delete-event": { + urlParams = { + tags: "delete", + }; + break; + } + case "event-details": + urlParams = { + tags: "schedule", + }; + break; + default: { + urlParams = { + tags: "upload,schedule", + }; + } + } + + // Just make the async request here, and return the response. + // This will automatically dispatch a `pending` action first, + // and then `fulfilled` or `rejected` actions based on the promise. + const res = await axios.get("/admin-ng/event/new/processing?", { params: urlParams }); + let workflows: Workflow[] = res.data.workflows; + + workflows = workflows.map((workflow) => { + if (workflow.configuration_panel_json.length > 0) { + return { + ...workflow, + configuration_panel_json: JSON.parse( + workflow.configuration_panel_json + ), + }; + } else { + return workflow; + } + }); + + const workflowDef = { + defaultWorkflowId: res.data.default_workflow_id, + workflows: workflows, + }; + + return workflowDef; +}); + +const workflowSlice = createSlice({ + name: 'workflow', + initialState, + reducers: {}, + // These are used for thunks + extraReducers: builder => { + builder + .addCase(fetchWorkflowDef.pending, (state) => { + state.status = 'loading'; + }) + // Pass the generated action creators to `.addCase()` + .addCase(fetchWorkflowDef.fulfilled, (state, action: PayloadAction<{ + defaultWorkflowId: WorkflowState["defaultWorkflowId"], + workflows: WorkflowState["workflows"], + }>) => { + // Same "mutating" update syntax thanks to Immer + state.status = 'succeeded'; + const acls = action.payload; + state.defaultWorkflowId = acls.defaultWorkflowId; + state.workflows = acls.workflows; + }) + .addCase(fetchWorkflowDef.rejected, (state, action) => { + state.status = 'failed'; + state.error = action.error; + }); + } +}); + +// export const {} = workflowSlice.actions; + +// Export the slice reducer as the default export +export default workflowSlice.reducer; diff --git a/app/src/store.ts b/app/src/store.ts index 790807712c..e466b04928 100644 --- a/app/src/store.ts +++ b/app/src/store.ts @@ -18,7 +18,7 @@ import acls from "./slices/aclSlice"; import themes from "./reducers/themeReducers"; import health from "./reducers/healthReducers"; import { notifications } from "./reducers/notificationReducers"; -import workflows from "./reducers/workflowReducers"; +import workflows from "./slices/workflowSlice"; import eventDetails from "./reducers/eventDeatilsReducers"; import seriesDetails from "./reducers/seriesDetailsReducers"; import recordingDetails from "./reducers/recordingDetailsReducer"; diff --git a/app/src/thunks/eventDetailsThunks.ts b/app/src/thunks/eventDetailsThunks.ts index e1de916d59..49bc909593 100644 --- a/app/src/thunks/eventDetailsThunks.ts +++ b/app/src/thunks/eventDetailsThunks.ts @@ -88,7 +88,7 @@ import { transformMetadataForUpdate, } from "../utils/resourceUtils"; import { NOTIFICATION_CONTEXT } from "../configs/modalConfig"; -import { fetchWorkflowDef } from "./workflowThunks"; +import { fetchWorkflowDef } from "../slices/workflowSlice"; import { fetchStatistics, fetchStatisticsValueUpdate, diff --git a/app/src/thunks/workflowThunks.ts b/app/src/thunks/workflowThunks.ts deleted file mode 100644 index decc8c9df2..0000000000 --- a/app/src/thunks/workflowThunks.ts +++ /dev/null @@ -1,72 +0,0 @@ -import axios from "axios"; -import { - loadWorkflowDefFailure, - loadWorkflowDefInProgress, - loadWorkflowDefSuccess, -} from "../actions/workflowActions"; - -// fetch workflow definitions from server -// @ts-expect-error TS(7006): Parameter 'type' implicitly has an 'any' type. -export const fetchWorkflowDef = (type) => async (dispatch) => { - try { - dispatch(loadWorkflowDefInProgress()); - - let urlParams; - - switch (type) { - case "tasks": { - urlParams = { - tags: "archive", - }; - break; - } - case "delete-event": { - urlParams = { - tags: "delete", - }; - break; - } - case "event-details": - urlParams = { - tags: "schedule", - }; - break; - default: { - urlParams = { - tags: "upload,schedule", - }; - } - } - - let data = await axios.get("/admin-ng/event/new/processing?", { - params: urlParams, - }); - - const response = await data.data; - - let workflows = response.workflows; - -// @ts-expect-error TS(7006): Parameter 'workflow' implicitly has an 'any' type. - workflows = workflows.map((workflow) => { - if (workflow.configuration_panel_json.length > 0) { - return { - ...workflow, - configuration_panel_json: JSON.parse( - workflow.configuration_panel_json - ), - }; - } else { - return workflow; - } - }); - - const workflowDef = { - defaultWorkflowId: response.default_workflow_id, - workflows: workflows, - }; - dispatch(loadWorkflowDefSuccess(workflowDef)); - } catch (e) { - dispatch(loadWorkflowDefFailure()); - console.error(e); - } -}; From f9b611fae41fd5e258ad06db5b62c52d572a9613 Mon Sep 17 00:00:00 2001 From: Arnei Date: Thu, 21 Dec 2023 17:43:41 +0100 Subject: [PATCH 4/7] Fix "key is not a prop" in RenderWorkflowConfig.tsx Apparently we don't need to pass the key all the way down, React just handles that for us and complains if it we try to do it ourselves. --- .../partials/wizards/RenderWorkflowConfig.tsx | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx b/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx index 7bb11e542a..9cf6005ea2 100644 --- a/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx +++ b/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx @@ -103,27 +103,27 @@ const renderInputByType = (field, key, formik) => { }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message -const RenderDatetimeLocal = ({ field, key, formik }) => { +const RenderDatetimeLocal = ({ field, formik }) => { // field.value = undefined; - return ; + return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message -const RenderCheckbox = ({ field, key, formik }) => { +const RenderCheckbox = ({ field, formik }) => { // field.defaultValue = field.value; // field.value = undefined; - return ; + return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message -const RenderRadio = ({ field, key, formik }) => { - return ; +const RenderRadio = ({ field, formik }) => { + return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message -const RenderNumber = ({ field, key, formik }) => { +const RenderNumber = ({ field, formik }) => { // validate that value of number is between max and min // @ts-expect-error TS(7006): Parameter 'value' implicitly has an 'any' type. const validate = (value) => { @@ -137,24 +137,22 @@ const RenderNumber = ({ field, key, formik }) => { // field.defaultValue = field.value; // field.value = undefined; - return ; + return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message -const RenderText = ({ field, key, formik }) => { +const RenderText = ({ field, formik }) => { // field.value = undefined; - return ; + return ; }; const RenderField : React.FC<{ field: any, - key: any, formik: any, validate?: (value: any) => string | undefined, }> = ({ field, - key, formik, validate = undefined }) => { @@ -198,7 +196,7 @@ const RenderField : React.FC<{ } return ( -
  • +
  • {renderField()} {/* if input has an additional fieldset or further configuration inputs From 3981e48586846e6f1a8206557b9325927b542c79 Mon Sep 17 00:00:00 2001 From: Arnei Date: Wed, 3 Jan 2024 12:13:58 +0100 Subject: [PATCH 5/7] Fix "Can't change workflow config" Fixes an issue where the workflow configuration could not be changed when trying to start a new task. Also fixes some minor display issues. --- .../StartTaskSummaryPage.tsx | 4 +-- .../events/partials/modals/StartTaskModal.tsx | 3 +- .../partials/wizards/RenderWorkflowConfig.tsx | 31 +------------------ 3 files changed, 4 insertions(+), 34 deletions(-) diff --git a/app/src/components/events/partials/ModalTabsAndPages/StartTaskSummaryPage.tsx b/app/src/components/events/partials/ModalTabsAndPages/StartTaskSummaryPage.tsx index 442577629a..e6b7634b12 100644 --- a/app/src/components/events/partials/ModalTabsAndPages/StartTaskSummaryPage.tsx +++ b/app/src/components/events/partials/ModalTabsAndPages/StartTaskSummaryPage.tsx @@ -49,7 +49,7 @@ const StartTaskSummaryPage: React.FC<{ { workflowDef.find( (workflow) => - formik.values.processingWorkflow === workflow.id + formik.values.workflow === workflow.id )?.title ?? "" }

    @@ -60,7 +60,7 @@ const StartTaskSummaryPage: React.FC<{ {Object.keys(formik.values.configuration).map( (config, key) => ( -

    +

    {config} :{" "} {formik.values.configuration[config].toString()}

    diff --git a/app/src/components/events/partials/modals/StartTaskModal.tsx b/app/src/components/events/partials/modals/StartTaskModal.tsx index 01b36dfc50..3ef989abb2 100644 --- a/app/src/components/events/partials/modals/StartTaskModal.tsx +++ b/app/src/components/events/partials/modals/StartTaskModal.tsx @@ -58,8 +58,7 @@ const StartTaskModal = ({ steps[page].name !== "general" && !( !!values.workflow && - values.workflow !== "" && - values.configuration && Object.keys(values.configuration).length === 0 + values.workflow !== "" ) ) { // @ts-expect-error TS(2339): Property 'worflow' does not exist on type '{}'. diff --git a/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx b/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx index 9cf6005ea2..159c642b39 100644 --- a/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx +++ b/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx @@ -104,16 +104,11 @@ const renderInputByType = (field, key, formik) => { // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message const RenderDatetimeLocal = ({ field, formik }) => { - // field.value = undefined; - return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message const RenderCheckbox = ({ field, formik }) => { - // field.defaultValue = field.value; - // field.value = undefined; - return ; }; @@ -134,16 +129,11 @@ const RenderNumber = ({ field, formik }) => { return error; }; - // field.defaultValue = field.value; - // field.value = undefined; - return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message const RenderText = ({ field, formik }) => { - // field.value = undefined; - return ; }; @@ -160,27 +150,9 @@ const RenderField : React.FC<{ const uuid = uuidv4(); const disabled = !!field.disabled ? field.disabled : false; - // Only set value to *anything* if there is actually a value to be had - // Otherwise it empties the displayed value when switching between tabs const renderField = () => { - if (field.value) { - return( - - ) - } else { return( - ) - } } return ( From ef60efbad508e650c62a790a0845a1c0a4a67053 Mon Sep 17 00:00:00 2001 From: Arnei Date: Wed, 3 Jan 2024 12:15:41 +0100 Subject: [PATCH 6/7] Consistent indentation in RenderWorkflowConfig.tsx Replaces spaces with tabs --- .../partials/wizards/RenderWorkflowConfig.tsx | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx b/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx index 159c642b39..3f5ffa2782 100644 --- a/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx +++ b/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx @@ -95,8 +95,8 @@ const renderInputByType = (field, key, formik) => { return ; case "text": return ; - case "datetime-local": - return ; + case "datetime-local": + return ; default: return ""; } @@ -104,17 +104,17 @@ const renderInputByType = (field, key, formik) => { // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message const RenderDatetimeLocal = ({ field, formik }) => { - return ; + return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message const RenderCheckbox = ({ field, formik }) => { - return ; + return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message const RenderRadio = ({ field, formik }) => { - return ; + return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message @@ -129,49 +129,49 @@ const RenderNumber = ({ field, formik }) => { return error; }; - return ; + return ; }; // @ts-expect-error TS(7031): Binding element 'field' implicitly has an 'any' ty... Remove this comment to see the full error message const RenderText = ({ field, formik }) => { - return ; + return ; }; const RenderField : React.FC<{ - field: any, - formik: any, - validate?: (value: any) => string | undefined, + field: any, + formik: any, + validate?: (value: any) => string | undefined, }> = ({ - field, - formik, - validate = undefined + field, + formik, + validate = undefined }) => { // id used for Field and label const uuid = uuidv4(); const disabled = !!field.disabled ? field.disabled : false; - const renderField = () => { - return( + const renderField = () => { + return( - ) - } + id={uuid} + defaultValue={field.defaultValue} + validate={validate} + className="configField" + name={"configuration." + field.name} + disabled={disabled} + type={field.type} + min={field.min} + max={field.max} + /> + ) + } return (
  • {renderField()} {/* if input has an additional fieldset or further configuration inputs - then render again by input type*/} + then render again by input type*/} {!!field.fieldset && !!formik.values.configuration[field.name] && (
      {/* @ts-expect-error TS(7006): Parameter 'f' implicitly has an 'any' type. */} From 3c3d8d91920774622759d52c4bece0316ec7819b Mon Sep 17 00:00:00 2001 From: Arnei Date: Mon, 12 Feb 2024 14:21:47 +0100 Subject: [PATCH 7/7] Add missing typing for configurationPanel Also removed an instance where response data was typed as state data. --- .../partials/wizards/RenderWorkflowConfig.tsx | 3 +-- app/src/slices/workflowSlice.ts | 14 +++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx b/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx index 3f5ffa2782..7fe686b71d 100644 --- a/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx +++ b/app/src/components/events/partials/wizards/RenderWorkflowConfig.tsx @@ -56,10 +56,9 @@ const RenderWorkflowConfig: React.FC<{
  • )} - {configPanel.length > 0 && ( + {Array.isArray(configPanel) && configPanel.length > 0 && (
    -{/* @ts-expect-error TS(7006): Parameter 'configOption' implicitly has an 'any' t... Remove this comment to see the full error message */} {configPanel.map((configOption, key) => (
    {!!configOption.legend && ( diff --git a/app/src/slices/workflowSlice.ts b/app/src/slices/workflowSlice.ts index c0a465c3db..f5b1c407fd 100644 --- a/app/src/slices/workflowSlice.ts +++ b/app/src/slices/workflowSlice.ts @@ -4,9 +4,17 @@ import axios from 'axios'; /** * This file contains redux reducer for actions affecting the state of workflows */ +type ConfigurationPanelField = { + // We could potentially specify 'fieldset' more, but I cannot find a definition + // for which key value pairs are allowed + fieldset?: { [key: string]: any } // Values can be anything + legend?: string, + description?: string, +} + type Workflow = { configuration_panel: string, //XML - configuration_panel_json: any, //Both the Json string AND the parsed Json!? + configuration_panel_json: string | ConfigurationPanelField[], // 'string' will always be the empty string description: string, displayOrder: number, id: string, @@ -62,9 +70,9 @@ export const fetchWorkflowDef = createAsyncThunk('workflow/fetchWorkflowDef', as // This will automatically dispatch a `pending` action first, // and then `fulfilled` or `rejected` actions based on the promise. const res = await axios.get("/admin-ng/event/new/processing?", { params: urlParams }); - let workflows: Workflow[] = res.data.workflows; + let workflows = res.data.workflows; - workflows = workflows.map((workflow) => { + workflows = workflows.map((workflow: any) => { if (workflow.configuration_panel_json.length > 0) { return { ...workflow,