From 77d17a06871d85b0c4aed3bcb7b90cd9772b4837 Mon Sep 17 00:00:00 2001 From: sagarika-padmanaban Date: Wed, 11 Dec 2024 15:35:07 +0530 Subject: [PATCH] fix --- src/common/CompareEdits.jsx | 384 ++++++++++++++++++ .../Organization/OrgLevelTaskList.jsx | 33 +- .../Organization/Project/TaskList.jsx | 35 +- src/redux/actions/api/Project/Compare.js | 42 ++ src/redux/actions/api/Project/CompareTrans.js | 42 ++ src/styles/Compare.css | 6 + 6 files changed, 540 insertions(+), 2 deletions(-) create mode 100644 src/common/CompareEdits.jsx create mode 100644 src/redux/actions/api/Project/Compare.js create mode 100644 src/redux/actions/api/Project/CompareTrans.js create mode 100644 src/styles/Compare.css diff --git a/src/common/CompareEdits.jsx b/src/common/CompareEdits.jsx new file mode 100644 index 00000000..a166e4f4 --- /dev/null +++ b/src/common/CompareEdits.jsx @@ -0,0 +1,384 @@ +import { + Dialog, + DialogContent, + DialogContentText, + Box, + IconButton, + DialogTitle, + Typography, + CircularProgress, +} from "@mui/material"; +import '../styles/Compare.css'; +import React, { useCallback, useEffect, useState,useRef} from "react"; +import CloseIcon from "@mui/icons-material/Close"; +import FullscreenIcon from "@mui/icons-material/Fullscreen"; +import FullscreenExitIcon from "@mui/icons-material/FullscreenExit"; +import { FetchpreviewTaskAPI, setSnackBar } from "redux/actions"; +import { useDispatch } from "react-redux"; +import Loader from "./Spinner"; +import TimeBoxes from "./TimeBoxes"; +import DiffViewer,{DiffMethod} from "react-diff-viewer"; +import { diffWords } from "diff"; +import Compare from "redux/actions/api/Project/Compare"; +import Comparetrans from "redux/actions/api/Project/Compare"; + +const CompareEdits = ({ + openPreviewDialog, + handleClose, + videoId, + taskType, + currentSubs, + targetLanguage, +}) => { + const dispatch = useDispatch(); + const [isFullscreen, setIsFullscreen] = useState(false); + + const [EditCompleteTexts, setEditCompleteTexts] = useState(); + const [SelectSourceTexts,setSelectSourceTexts] = useState(); + const [loading, setLoading] = useState(false); + const [totalAdded, setTotalAdded] = useState(0); + const [totalDeleted, setTotalDeleted] = useState(0); + const [ratio, setRatio] = useState(0); + const [selectedDiffMethod, setSelectedDiffMethod] = useState(DiffMethod.WORDS); + + const handleDiffMethodChange = (event) => { + setSelectedDiffMethod(event.target.value); + }; + + const dialogRef = useRef(null); + + // const selectSource = [ + // "What he wants, that conversation is very interesting for a couple of reasons.", + // "Power.", + // "So, Muni thinks that a conversation endorses the viewpoint of the shopkeeper.", + // ]; + + // const editComplete = [ + // "Though that narrative is unsuccessful in getting him what he wants, that conversation is very interesting for a couple of reasons.", + // "123 Power.", + // "Muni thinks that a conversation endorses the viewpoint of the shopkeeper will make him happy.", + // ]; + + + + + const fetchPreviewData = useCallback(async () => { + setLoading(true) + if(taskType=="TRANSCRIPTION_EDIT"){ + var taskObj = new Compare(videoId); + + }else{ + var taskObj = new Comparetrans(videoId); + } + try { + const res = await fetch(taskObj.apiEndPoint(), { + method: "GET", + headers: taskObj.getHeaders().headers, + }); + + const data = await res.json(); + console.log(data); + if(taskType=="TRANSCRIPTION_EDIT"){ + if (data?.transcripts) { + const editComplete = []; + const selectSource = []; + console.log(data); + + data.transcripts.forEach((transcript) => { + if (transcript.status === "TRANSCRIPTION_EDIT_COMPLETE") { + editComplete.push( + ...transcript.data.payload.map((item) => item.text) + ); + } else if (transcript.status === "TRANSCRIPTION_SELECT_SOURCE") { + selectSource.push( + ...transcript.data.payload.map((item) => item.text) + ); + } + }); + console.log(editComplete,selectSource); + + setEditCompleteTexts(editComplete); + setSelectSourceTexts(selectSource); + } + }else{ + if (data) { + const editComplete = []; + const selectSource = []; + console.log(data); + + data.forEach((translate) => { + if (translate.status === "TRANSLATION_EDIT_COMPLETE") { + editComplete.push( + ...translate.data.payload.map((item) => item.target_text) + ); + } else if (translate.status === "TRANSLATION_SELECT_SOURCE") { + selectSource.push( + ...translate.data.payload.map((item) => item.target_text) + ); + } + }); + console.log(editComplete,selectSource); + + setEditCompleteTexts(editComplete); + setSelectSourceTexts(selectSource); + } + + } + setLoading(false) + } catch (error) { + setLoading(false) + dispatch( + setSnackBar({ + open: true, + message: "Something went wrong!!", + variant: "error", + }) + ); + } + }, [ dispatch,videoId]); + + useEffect(() => { + if (openPreviewDialog) { + fetchPreviewData(); + } + }, [fetchPreviewData, openPreviewDialog]); + + + + + const calculateWordDiff = (sourceText, editedText) => { + const diff = diffWords(sourceText, editedText); + let addedWords = 0; + let deletedWords = 0; + + diff.forEach((part) => { + if (part.added) { + addedWords += part.value.split(/\s+/).filter(Boolean).length; + } + if (part.removed) { + deletedWords += part.value.split(/\s+/).filter(Boolean).length; + } + }); + + return { addedWords, deletedWords }; + }; + + useEffect(() => { + if (openPreviewDialog) { + let added = 0; + let deleted = 0; + + SelectSourceTexts?.forEach((sourceText, index) => { + const { addedWords, deletedWords } = calculateWordDiff( + sourceText, + EditCompleteTexts[index] || "" + ); + added += addedWords; + deleted += deletedWords; + }); + + setTotalAdded(added); + setTotalDeleted(deleted); + setRatio((deleted / (added || 1)).toFixed(2)); + } + }, [openPreviewDialog, SelectSourceTexts, EditCompleteTexts]); + + const handleFullscreenToggle = () => { + const elem = dialogRef.current; + if (!isFullscreen) { + if (elem.requestFullscreen) { + elem.requestFullscreen(); + } else if (elem.mozRequestFullScreen) { + /* Firefox */ + elem.mozRequestFullScreen(); + } else if (elem.webkitRequestFullscreen) { + /* Chrome, Safari and Opera */ + elem.webkitRequestFullscreen(); + } else if (elem.msRequestFullscreen) { + /* IE/Edge */ + elem.msRequestFullscreen(); + } + setIsFullscreen(true); + } else { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.mozCancelFullScreen) { + /* Firefox */ + document.mozCancelFullScreen(); + } else if (document.webkitExitFullscreen) { + /* Chrome, Safari and Opera */ + document.webkitExitFullscreen(); + } else if (document.msExitFullscreen) { + /* IE/Edge */ + document.msExitFullscreen(); + } + setIsFullscreen(false); + } + }; + + + + useEffect(() => { + const handleFullscreenChange = () => { + if (!document.fullscreenElement) { + setIsFullscreen(false); + } + }; + + document.addEventListener('fullscreenchange', handleFullscreenChange); + document.addEventListener('webkitfullscreenchange', handleFullscreenChange); + document.addEventListener('mozfullscreenchange', handleFullscreenChange); + document.addEventListener('msfullscreenchange', handleFullscreenChange); + + return () => { + document.removeEventListener('fullscreenchange', handleFullscreenChange); + document.removeEventListener('webkitfullscreenchange', handleFullscreenChange); + document.removeEventListener('mozfullscreenchange', handleFullscreenChange); + document.removeEventListener('msfullscreenchange', handleFullscreenChange); + }; + }, []); + + return ( + + + Source vs Edit Comparison{" "} + + {isFullscreen ? : } + + + + + + + + +
+ + +
+ + {loading ? ( +
+ +
+ ) : ( + + +
+ {SelectSourceTexts?.map((sourceText, index) => { + const editedText = EditCompleteTexts[index] || ""; + const hasDifferences = sourceText !== editedText; + + return ( +
+
Card - {index + 1}
+ {hasDifferences ? ( + + ) : ( +
+
+
{sourceText || "No Source Text"}
+
+
+
{EditCompleteTexts[index] || "No Edited Text"}
+
+
+ + )} +
+ ); + })} + + +
+
+ Total Changes: {totalAdded} +
+
+ Total Deletions: {totalDeleted} +
+
+
+ +
+ )} +
+
+ ); +}; + +export default CompareEdits; diff --git a/src/containers/Organization/OrgLevelTaskList.jsx b/src/containers/Organization/OrgLevelTaskList.jsx index e7ac3a8d..9b178318 100644 --- a/src/containers/Organization/OrgLevelTaskList.jsx +++ b/src/containers/Organization/OrgLevelTaskList.jsx @@ -3,6 +3,7 @@ import React, { useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useNavigate } from "react-router-dom"; import C from "redux/constants"; +import CompareArrowsIcon from '@mui/icons-material/CompareArrows' import { exportFile, exportVoiceover, @@ -22,6 +23,7 @@ import { renderTaskListColumnCell } from "config/tableColumns"; //Themes import { DatasetStyle, TableStyles } from "styles"; import { tableTheme } from "theme"; +import CompareEdits from "common/CompareEdits"; //Components import { @@ -134,6 +136,7 @@ const OrgLevelTaskList = () => { viewTaskDialog: false, previewDialog: false, editTaskDialog: false, + CompareEdits:false, uploadDialog: false, speakerInfoDialog: false, tableDialog: false, @@ -174,7 +177,9 @@ const OrgLevelTaskList = () => { const orgId = userData?.organization?.id; const apiStatus = useSelector((state) => state.apiStatus); - + const handleCompareEdits = () => { + handleDialogOpen("CompareEdits"); + }; //Fiters and Search const orgSelectedFilters = useSelector( (state) => state.orgTaskFilters.orgSelectedFilters @@ -701,6 +706,10 @@ const OrgLevelTaskList = () => { case "Preview": handlePreviewTask(); break; + case "CompareEdits": + handleCompareEdits(); + break; + case "Delete": handleDialogOpen("deleteTaskDialog", "", id); @@ -951,6 +960,19 @@ const OrgLevelTaskList = () => { } + {((selectedTask?.task_type == "TRANSLATION_VOICEOVER_EDIT"|| selectedTask?.task_type == "TRANSCRIPTION_EDIT" || selectedTask?.task_type == "TRANSLATION_EDIT" )&& selectedTask?.status === "COMPLETE") && + + + handleActionButtonClick(tableMeta, "CompareEdits") + } + color="primary" + > + + + + } + {buttonConfig.map((item) => { return ( @@ -1364,6 +1386,15 @@ const OrgLevelTaskList = () => { projectId={currentTaskDetails?.project} /> )} +{openDialogs.CompareEdits && ( + handleDialogClose("CompareEdits")} + taskType={currentTaskDetails?.task_type} + videoId={currentTaskDetails?.video} + targetLanguage={currentTaskDetails?.target_language} + /> + )} {openDialogs.previewDialog && ( { viewTaskDialog: false, previewDialog: false, editTaskDialog: false, + CompareEdits:false, uploadDialog: false, speakerInfoDialog: false, tableDialog: false, @@ -228,6 +231,9 @@ const TaskList = () => { setTaskColDisplayState(displayCols); localStorage.setItem("taskColDisplayFilter", JSON.stringify(displayCols)); }, []); + const handleCompareEdits = () => { + handleDialogOpen("CompareEdits"); + }; useEffect(() => { const { progress, success, apiType, data } = apiStatus; @@ -822,7 +828,11 @@ const TaskList = () => { case "Preview": handlePreviewTask(); break; - + case "CompareEdits": + handleCompareEdits(); + break; + + case "Delete": handleDialogOpen("deleteTaskDialog", "", id); break; @@ -1043,6 +1053,19 @@ const TaskList = () => { } + {((selectedTask?.task_type == "TRANSLATION_VOICEOVER_EDIT"|| selectedTask?.task_type == "TRANSCRIPTION_EDIT" || selectedTask?.task_type == "TRANSLATION_EDIT" )&& selectedTask?.status === "COMPLETE") && + + + handleActionButtonClick(tableMeta, "CompareEdits") + } + color="primary" + > + + + + } + {buttonConfig.map((item) => { return ( @@ -1383,6 +1406,16 @@ const TaskList = () => { targetLanguage={currentTaskDetails?.target_language} /> )} +{openDialogs.CompareEdits && ( + handleDialogClose("CompareEdits")} + taskType={currentTaskDetails?.task_type} + videoId={currentTaskDetails?.video} + targetLanguage={currentTaskDetails?.target_language} + /> + )} + {Boolean(anchorEl) && (