diff --git a/src/main/Discard.tsx b/src/main/Discard.tsx
index 168f59796..93650348d 100644
--- a/src/main/Discard.tsx
+++ b/src/main/Discard.tsx
@@ -5,8 +5,7 @@ import { basicButtonStyle, backOrContinueStyle, navigationButtonStyle } from "..
import { LuChevronLeft, LuXCircle } from "react-icons/lu";
-import { useAppDispatch, useAppSelector } from "../redux/store";
-import { selectFinishState } from "../redux/finishSlice";
+import { useAppDispatch } from "../redux/store";
import { setEnd } from "../redux/endSlice";
import { PageButton } from "./Finish";
@@ -22,10 +21,8 @@ const Discard: React.FC = () => {
const { t } = useTranslation();
- const finishState = useAppSelector(selectFinishState);
-
const cancelStyle = css({
- display: finishState !== "Discard changes" ? "none" : "flex",
+ display: "flex",
flexDirection: "column" as const,
alignItems: "center",
gap: "30px",
diff --git a/src/main/Finish.tsx b/src/main/Finish.tsx
index 2905ad76a..0f93dd44d 100644
--- a/src/main/Finish.tsx
+++ b/src/main/Finish.tsx
@@ -14,7 +14,7 @@ import { basicButtonStyle, navigationButtonStyle } from "../cssStyles";
import { IconType } from "react-icons";
import { useAppDispatch, useAppSelector } from "../redux/store";
-import { selectPageNumber, setPageNumber } from "../redux/finishSlice";
+import { selectFinishState, selectPageNumber, setPageNumber } from "../redux/finishSlice";
import { useTheme } from "../themes";
import { settings } from "../config";
import { useTranslation } from "react-i18next";
@@ -25,33 +25,36 @@ import { useTranslation } from "react-i18next";
const Finish: React.FC = () => {
const pageNumber = useAppSelector(selectPageNumber);
+ const finishState = useAppSelector(selectFinishState);
- const pageZeroStyle = css({
- display: pageNumber !== 0 ? "none" : "block",
- });
-
- const pageOneStyle = css({
- display: pageNumber !== 1 ? "none" : "block",
- });
-
- const pageTwoStyle = css({
- display: pageNumber !== 2 ? "none" : "block",
- });
-
- return (
-
-
+ const render = () => {
+ if (pageNumber === 0) {
+ return (
-
-
-
-
-
-
-
+ );
+ } else if (pageNumber === 1) {
+ if (finishState === "Save changes") {
+ return (
+
+ );
+ } else if (finishState === "Start processing") {
+ return (
+
+ );
+ } else if (finishState === "Discard changes") {
+ return (
+
+ );
+ }
+ } else if (pageNumber === 2) {
+ return (
-
-
+ );
+ }
+ };
+
+ return (
+ <>{render()}>
);
};
diff --git a/src/main/Save.tsx b/src/main/Save.tsx
index b1241c2e2..7e9323674 100644
--- a/src/main/Save.tsx
+++ b/src/main/Save.tsx
@@ -9,7 +9,6 @@ import {
import { LuLoader, LuCheckCircle, LuAlertCircle, LuChevronLeft, LuSave, LuCheck } from "react-icons/lu";
import { useAppDispatch, useAppSelector } from "../redux/store";
-import { selectFinishState } from "../redux/finishSlice";
import {
selectHasChanges,
selectSegments,
@@ -33,6 +32,8 @@ import {
import { serializeSubtitle } from "../util/utilityFunctions";
import { useTheme } from "../themes";
import { ThemedTooltip } from "./Tooltip";
+import { IconType } from "react-icons";
+import { setEnd } from "../redux/endSlice";
/**
* Shown if the user wishes to save.
@@ -42,8 +43,6 @@ const Save: React.FC = () => {
const { t } = useTranslation();
- const finishState = useAppSelector(selectFinishState);
-
const postWorkflowStatus = useAppSelector(selectStatus);
const postError = useAppSelector(selectError);
const theme = useTheme();
@@ -52,9 +51,9 @@ const Save: React.FC = () => {
const subtitleHasChanges = useAppSelector(selectSubtitleHasChanges);
const saveStyle = css({
- height: "100%",
- display: finishState !== "Save changes" ? "none" : "flex",
- flexDirection: "column" as const,
+ display: "flex",
+ flexDirection: "column",
+ justifyContent: "center",
alignItems: "center",
gap: "30px",
});
@@ -101,8 +100,15 @@ const Save: React.FC = () => {
/**
* Button that sends a post request to save current changes
*/
-export const SaveButton: React.FC = () => {
-
+export const SaveButton: React.FC<{
+ basicIcon?: IconType
+ text?: string
+ isTransitionToEnd?: boolean
+}> = ({
+ basicIcon = LuSave,
+ text,
+ isTransitionToEnd = false,
+}) => {
const { t } = useTranslation();
// Initialize redux variables
@@ -116,7 +122,7 @@ export const SaveButton: React.FC = () => {
const theme = useTheme();
// Update based on current fetching status
- let Icon = LuSave;
+ let Icon = basicIcon;
let spin = false;
let tooltip = null;
if (workflowStatus === "failed") {
@@ -164,6 +170,9 @@ export const SaveButton: React.FC = () => {
// Let users leave the page without warning after a successful save
useEffect(() => {
if (workflowStatus === "success") {
+ if (isTransitionToEnd) {
+ dispatch(setEnd({ hasEnded: true, value: "success" }));
+ }
dispatch(videoSetHasChanges(false));
dispatch(metadataSetHasChanges(false));
dispatch(subtitleSetHasChanges(false));
@@ -181,7 +190,7 @@ export const SaveButton: React.FC = () => {
}
}}>
- {t("save.confirm-button")}
+ {text ?? t("save.confirm-button")}
{ariaSaveUpdate()}
diff --git a/src/main/WorkflowConfiguration.tsx b/src/main/WorkflowConfiguration.tsx
index 1c8930cf4..f736c201d 100644
--- a/src/main/WorkflowConfiguration.tsx
+++ b/src/main/WorkflowConfiguration.tsx
@@ -1,38 +1,21 @@
-import React, { useEffect } from "react";
+import React from "react";
import { css } from "@emotion/react";
import {
- basicButtonStyle,
backOrContinueStyle,
errorBoxStyle,
- spinningStyle,
} from "../cssStyles";
-import { LuLoader, LuCheck, LuAlertCircle, LuChevronLeft, LuDatabase, LuMoreHorizontal } from "react-icons/lu";
+import { LuChevronLeft, LuDatabase, LuMoreHorizontal } from "react-icons/lu";
-import { useAppDispatch, useAppSelector } from "../redux/store";
-import {
- selectSegments,
- selectTracks,
- setHasChanges as videoSetHasChanges,
- selectSelectedWorkflowId,
-} from "../redux/videoSlice";
-import { postVideoInformationWithWorkflow, selectStatus, selectError } from "../redux/workflowPostAndProcessSlice";
+import { useAppSelector } from "../redux/store";
import { PageButton } from "./Finish";
-import { setEnd } from "../redux/endSlice";
import { useTranslation } from "react-i18next";
-import {
- setHasChanges as metadataSetHasChanges,
- selectCatalogs,
-} from "../redux/metadataSlice";
-import {
- selectSubtitles,
- setHasChanges as subtitleSetHasChanges,
-} from "../redux/subtitleSlice";
-import { serializeSubtitle } from "../util/utilityFunctions";
import { useTheme } from "../themes";
+import { selectError, selectStatus } from "../redux/workflowPostSlice";
+import { SaveButton } from "./Save";
/**
* Will eventually display settings based on the selected workflow index
@@ -61,7 +44,11 @@ const WorkflowConfiguration: React.FC = () => {
{t("workflowConfig.satisfied-text")}
{t("various.error-text")}
@@ -73,90 +60,4 @@ const WorkflowConfiguration: React.FC = () => {
);
};
-/**
- * Button that sends a post request to save current changes
- * and starts the selected workflow
- */
-export const SaveAndProcessButton: React.FC<{ text: string; }> = ({ text }) => {
-
- // Initialize redux variables
- const dispatch = useAppDispatch();
-
- const selectedWorkflowId = useAppSelector(selectSelectedWorkflowId);
- const segments = useAppSelector(selectSegments);
- const tracks = useAppSelector(selectTracks);
- const subtitles = useAppSelector(selectSubtitles);
- const metadata = useAppSelector(selectCatalogs);
- const workflowStatus = useAppSelector(selectStatus);
- const theme = useTheme();
-
- // Let users leave the page without warning after a successful save
- useEffect(() => {
- if (workflowStatus === "success") {
- dispatch(setEnd({ hasEnded: true, value: "success" }));
- dispatch(videoSetHasChanges(false));
- dispatch(metadataSetHasChanges(false));
- dispatch(subtitleSetHasChanges(false));
- }
- }, [dispatch, workflowStatus]);
-
- const prepareSubtitles = () => {
- const subtitlesForPosting = [];
-
- for (const identifier in subtitles) {
- subtitlesForPosting.push({
- id: identifier,
- subtitle: serializeSubtitle(subtitles[identifier].cues),
- tags: subtitles[identifier].tags,
- });
- }
- return subtitlesForPosting;
- };
-
- const saveAndProcess = () => {
- dispatch(postVideoInformationWithWorkflow({
- segments: segments,
- tracks: tracks,
- workflow: [{ id: selectedWorkflowId }],
- subtitles: prepareSubtitles(),
- metadata: metadata,
- }));
- };
-
- // Update based on current fetching status
- let Icon = LuDatabase;
- let spin = false;
- if (workflowStatus === "failed") {
- Icon = LuAlertCircle;
- spin = false;
- } else if (workflowStatus === "success") {
- Icon = LuCheck;
- spin = false;
- } else if (workflowStatus === "loading") {
- Icon = LuLoader;
- spin = true;
-
- }
-
- const saveButtonStyle = css({
- padding: "16px",
- boxShadow: `${theme.boxShadow}`,
- background: `${theme.element_bg}`,
- });
-
- return (
-
) => {
- if (event.key === " " || event.key === "Enter") {
- saveAndProcess();
- }
- }}>
-
- {text}
-
- );
-};
-
export default WorkflowConfiguration;
diff --git a/src/main/WorkflowSelection.tsx b/src/main/WorkflowSelection.tsx
index 19b773358..48fb01a92 100644
--- a/src/main/WorkflowSelection.tsx
+++ b/src/main/WorkflowSelection.tsx
@@ -5,12 +5,9 @@ import { backOrContinueStyle, errorBoxStyle } from "../cssStyles";
import { useAppDispatch, useAppSelector } from "../redux/store";
import { selectWorkflows, setSelectedWorkflowIndex } from "../redux/videoSlice";
-import { selectFinishState, selectPageNumber } from "../redux/finishSlice";
import { PageButton } from "./Finish";
-import { LuChevronLeft } from "react-icons/lu";
-import { SaveAndProcessButton } from "./WorkflowConfiguration";
-import { selectStatus, selectError } from "../redux/workflowPostAndProcessSlice";
+import { LuChevronLeft, LuDatabase } from "react-icons/lu";
import { selectStatus as saveSelectStatus, selectError as saveSelectError } from "../redux/workflowPostSlice";
import { httpRequestState, Workflow } from "../types";
import { SaveButton } from "./Save";
@@ -37,18 +34,14 @@ const WorkflowSelection: React.FC = () => {
return (b.displayOrder - a.displayOrder);
});
- const finishState = useAppSelector(selectFinishState);
- const pageNumber = useAppSelector(selectPageNumber);
const theme = useTheme();
- const postAndProcessWorkflowStatus = useAppSelector(selectStatus);
- const postAndProcessError = useAppSelector(selectError);
const saveStatus = useAppSelector(saveSelectStatus);
const saveError = useAppSelector(saveSelectError);
const workflowSelectionStyle = css({
padding: "20px",
- display: (finishState === "Start processing" && pageNumber === 1) ? "flex" : "none",
+ display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
@@ -107,7 +100,7 @@ const WorkflowSelection: React.FC = () => {
{t("various.error-text")}
{errorMessage ?
- t("various.error-details-text", { errorMessage: postAndProcessError }) :
+ t("various.error-details-text", { errorMessage: saveError }) :
t("various.error-text")}
@@ -140,9 +133,13 @@ const WorkflowSelection: React.FC = () => {
This will take some time.
,
false,
- ,
- postAndProcessWorkflowStatus,
- postAndProcessError
+ ,
+ saveStatus,
+ saveError
)
);
} else {
@@ -153,9 +150,13 @@ const WorkflowSelection: React.FC = () => {
{t("workflowSelection.manyWorkflows-text")}
,
true,
- ,
- postAndProcessWorkflowStatus,
- postAndProcessError
+ ,
+ saveStatus,
+ saveError
)
);
}
diff --git a/src/redux/store.ts b/src/redux/store.ts
index bfedf0db1..b7dd64bbb 100644
--- a/src/redux/store.ts
+++ b/src/redux/store.ts
@@ -3,7 +3,6 @@ import mainMenuStateReducer from "./mainMenuSlice";
import finishStateReducer from "./finishSlice";
import videoReducer from "./videoSlice";
import workflowPostReducer from "./workflowPostSlice";
-import workflowPostAndProcessReducer from "./workflowPostAndProcessSlice";
import endReducer from "./endSlice";
import metadataReducer from "./metadataSlice";
import subtitleReducer from "./subtitleSlice";
@@ -16,7 +15,6 @@ export const store = configureStore({
finishState: finishStateReducer,
videoState: videoReducer,
workflowPostState: workflowPostReducer,
- workflowPostAndProcessState: workflowPostAndProcessReducer,
endState: endReducer,
metadataState: metadataReducer,
subtitleState: subtitleReducer,
diff --git a/src/redux/workflowPostAndProcessSlice.ts b/src/redux/workflowPostAndProcessSlice.ts
deleted file mode 100644
index 6bb6e3491..000000000
--- a/src/redux/workflowPostAndProcessSlice.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
-import { client } from "../util/client";
-import { PostAndProcessEditArgument, httpRequestState } from "../types";
-
-import { convertSegments } from "./workflowPostSlice";
-import { settings } from "../config";
-
-const initialState: httpRequestState = {
- status: "idle",
- error: undefined,
- errorReason: "unknown",
-};
-
-export const postVideoInformationWithWorkflow =
- createAsyncThunk("video/postVideoInformationWithWorkflow", async (argument: PostAndProcessEditArgument) => {
- if (!settings.id) {
- throw new Error("Missing media package identifier");
- }
-
- const response = await client.post(`${settings.opencast.url}/editor/${settings.id}/edit.json`,
- {
- segments: convertSegments(argument.segments),
- tracks: argument.tracks,
- subtitles: argument.subtitles,
- metadataJSON: JSON.stringify(argument.metadata),
- workflows: argument.workflow,
- }
- );
- return response;
- });
-
-/**
- * Slice for managing a post request for saving current changes and starting a workflow
- * TODO: Create a wrapper for this and workflowPostAndProcessSlice
- */
-const workflowPostAndProcessSlice = createSlice({
- name: "workflowPostAndProcessState",
- initialState,
- reducers: {
- },
- extraReducers: builder => {
- builder.addCase(
- postVideoInformationWithWorkflow.pending, (state, _action) => {
- state.status = "loading";
- });
- builder.addCase(
- postVideoInformationWithWorkflow.fulfilled, (state, _action) => {
- state.status = "success";
- });
- builder.addCase(
- postVideoInformationWithWorkflow.rejected, (state, action) => {
- state.status = "failed";
- state.error = action.error.message;
- });
- },
- selectors: {
- selectStatus: state => state.status,
- selectError: state => state.error,
- },
-});
-
-export const { selectStatus, selectError } = workflowPostAndProcessSlice.selectors;
-
-
-export default workflowPostAndProcessSlice.reducer;
diff --git a/src/redux/workflowPostSlice.ts b/src/redux/workflowPostSlice.ts
index 11564c797..a86291646 100644
--- a/src/redux/workflowPostSlice.ts
+++ b/src/redux/workflowPostSlice.ts
@@ -20,6 +20,7 @@ export const postVideoInformation =
segments: convertSegments(argument.segments),
tracks: argument.tracks,
subtitles: argument.subtitles,
+ workflows: argument.workflow,
metadataJSON: JSON.stringify(argument.metadata),
}
);
diff --git a/src/types.ts b/src/types.ts
index d54f904db..1ee6ff3cd 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -70,13 +70,10 @@ export interface PostEditArgument {
segments: Segment[]
tracks: Track[]
subtitles: SubtitlesFromOpencast[]
+ workflow?: [{id: string}]
metadata: Catalog[]
}
-export interface PostAndProcessEditArgument extends PostEditArgument{
- workflow: [{id: string}]
-}
-
// Use respective i18n keys as values
export enum MainMenuStateNames {
cutting = "mainMenu.cutting-button",