Skip to content

Commit

Permalink
Merge pull request #1046 from AI4Bharat/Contextual-TransliterationCon…
Browse files Browse the repository at this point in the history
…tactSource-fix

Contextual transliteration logging source fix
  • Loading branch information
ishvindersethi22 authored Jun 24, 2024
2 parents 963fb8c + 0505b2a commit 231ae43
Show file tree
Hide file tree
Showing 10 changed files with 817 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/config/apiendpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const apiendpoint = {
authUser:"/users/auth/users/",
functions:"/functions/",
Glossary:"/v1/",
transliteration_log: "logs/transliteration-log/",
};

export default apiendpoint;
47 changes: 47 additions & 0 deletions src/redux/actions/api/Annotation/PostTransliterationForLogging.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import API from "../../../api";
import ENDPOINTS from "../../../../config/apiendpoint";
import constants from "../../../constants";

export default class PostTransliterationForLogging extends API {
constructor(source_text, target_text, orginal_romanised_text,edited_romanised_text,target_language, timeout = 2000) {
super("POST", timeout, false);
this.transliterationLog = {
source_english_text: source_text,
indic_translation_text: target_text,
romanised_text: orginal_romanised_text,
edited_romanised_text: edited_romanised_text,
language: target_language,
};
this.type = constants.POST_TRANSLITERATION_LOG;
this.endpoint = `${super.apiEndPointAuto()}${ENDPOINTS.transliteration_log}`;
}

processResponse(res) {
super.processResponse(res);
if (res) {
this.newTransliterationLog = res;
}
}

apiEndPoint() {
return this.endpoint;
}

getBody() {
return this.transliterationLog;
}

getHeaders() {
this.headers = {
headers: {
"Content-Type": "application/json",
"Authorization": `JWT ${localStorage.getItem('shoonya_access_token')}`
},
};
return this.headers;
}

getPayload() {
return this.newTransliterationLog;
}
}
24 changes: 24 additions & 0 deletions src/redux/actions/api/LSFAPI/LSFAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,29 @@ const fetchAnnotation = async (taskID) => {
}
};


const fetchTransliteration = async (sourceText,tgtLng) => {
const url = `https://xlit-api.ai4bharat.org/rt/${encodeURIComponent(tgtLng)}/${encodeURIComponent(sourceText)}`;
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return {
timestamp: data.at,
error: data.error,
input: data.input,
romanised_transliteration: data.result.join(", "), // Assuming result is always an array; join elements for a single string output
success: data.success
};
};

const postAnnotation = async (
result,
task,
Expand Down Expand Up @@ -273,6 +296,7 @@ export {
patchAnnotation,
deleteAnnotation,
fetchAnnotation,
fetchTransliteration,
postReview,
patchReview,
patchSuperChecker,
Expand Down
1 change: 1 addition & 0 deletions src/redux/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ const constants = {
SUBTITLES: "SUBTITLES",
PATCH_ANNOTATION:"PATCH_ANNOTATION",
UPDATE_UI_PREFS: "UPDATE_UI_PREFS",
POST_TRANSLITERATION_LOG : "POST_TRANSLITERATION_LOG"

};

Expand Down
14 changes: 14 additions & 0 deletions src/ui/pages/component/common/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ const Header = () => {
const [selectedNotificationId, setSelectedNotificationId] = useState(null);
const [showTransliterationModel, setShowTransliterationModel] =
useState(false);

const ProjectDetails = useSelector((state) => state.getProjectDetails.data);

const [snackbar, setSnackbarInfo] = useState({
open: false,
message: "",
Expand Down Expand Up @@ -758,6 +761,17 @@ console.log(unseenNotifications,'uuu');
// onclick: () => {},
// },
];

if (ProjectDetails?.project_type?.includes("ContextualTranslationEditing")) {
appSettings.splice(1, 0, {
name: "Romanised Transliteration",
onclick: () => {
handleCloseSettingsMenu();
localStorage.setItem("showRomanisedTransliterationModel", "true" );
},
});
}

const helpMenu = [
{
name: "Help",
Expand Down
195 changes: 192 additions & 3 deletions src/ui/pages/container/Label-Studio/LSF.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
patchAnnotation,
deleteAnnotation,
fetchAnnotation,
fetchTransliteration,
} from "../../../../redux/actions/api/LSFAPI/LSFAPI";
import GetProjectDetailsAPI from "../../../../redux/actions/api/ProjectDetails/GetProjectDetails";
import APITransport from "../../../../redux/actions/apitransport/apitransport";
Expand All @@ -51,6 +52,12 @@ import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
import getTaskAssignedUsers from "../../../../utils/getTaskAssignedUsers";
import LightTooltip from "../../component/common/Tooltip";
import { labelConfigJS } from "./labelConfigJSX";
import CustomButton from "../../component/common/Button";
import CircularProgress from '@mui/material/CircularProgress';
import LanguageCode from "../../../../utils/LanguageCode";
import PostTransliterationForLogging from "../../../../redux/actions/api/Annotation/PostTransliterationForLogging";
import RomanisedTransliteration from "../Transliteration/RomanisedTransliteration";


const filterAnnotations = (
annotations,
Expand Down Expand Up @@ -206,7 +213,19 @@ const LabelStudioWrapper = ({
const [filterMessage, setFilterMessage] = useState(null);
const [disableButton, setDisableButton] = useState(false);
const [assignedUsers, setAssignedUsers] = useState(null);
//console.log("projectId, taskId", projectId, taskId);
const [romanisedTransliterationData, setRomanisedTransliterationData] = useState({
timestamp: '',
error: '',
input: '',
romanised_transliteration: '',
success: false
});
const [showRomanisedTransliterationModel, setShowRomanisedTransliterationModel] = useState(true);
const [showSpinner , setShowSpinner] = useState(false);
const [originalRomanisedText, setOriginalRomanisedText] = useState("");
const [editedRomanisedText, setEditedRomanisedText] = useState("")
const [indicText, setIndicText] = useState("");
//console.log("projectId, taskId", projectId, taskId);
// debugger
// const projectType = ProjectDetails?.project_type?.includes("Audio")

Expand Down Expand Up @@ -553,6 +572,16 @@ const LabelStudioWrapper = ({
temp[i].value.text = [temp[i].value.text[0]];
}
}
if(originalRomanisedText.length==0 && projectType.includes("ContextualTranslationEditing")){
setSnackbarInfo({
open: true,
message: "Please click on Check Transliteration button first",
variant: "info",
});
// dont allow to move forward
hideLoader();
}

patchAnnotation(
taskId,
temp,
Expand Down Expand Up @@ -965,7 +994,151 @@ const LabelStudioWrapper = ({
tasksComplete(res?.id || null);
});
};
useEffect(() => {
if (taskId) {
fetchAnnotationTask();
}
}, [taskId]);
const fetchAnnotationTask = async () => {
const res = await fetchAnnotation(taskId);
// console.log(res);
if(res[0]?.result[0])
{
setIndicText(res[0]?.result[0]?.value?.text[0]);
}
setTaskData(res);
setAnnotations(res?.annotations);
};

// create a handleSubmitRomanisedText function
const handleSubmitRomanisedText = async () => {
if(taskData?.data?.input_text && taskData?.data?.output_language){
const language = LanguageCode.languages
let output_lng_code = ''

language.filter((lang) => {
if(lang.label === taskData?.data?.output_language){
output_lng_code= lang.code
}
});
// Create a new instance of the class
const postTransliterationForLogging = new PostTransliterationForLogging(
taskData?.data?.input_text,
indicText ,
originalRomanisedText,
editedRomanisedText,
output_lng_code
);

const res = dispatch(APITransport(postTransliterationForLogging));
if(res){
setRomanisedTransliterationData(
{
timestamp: '',
error: '',
input: '',
romanised_transliteration: '',
success: false
}
)
setOriginalRomanisedText("");
setEditedRomanisedText("");
setSnackbarInfo({
open: true,
message: "Transliteration Logged",
variant: "success",
});
setShowSpinner(false)

}else{
setSnackbarInfo({
open: true,
message: "Error in logging transliteration",
variant: "error",
});
setShowSpinner(false)
}
}
}

const handleTranslitrationOnClick = async () => {
setShowSpinner(true)
const language = LanguageCode.languages
let output_lng_code = ''

language.filter((lang) => {
if(lang.label == taskData?.data?.output_language){
output_lng_code = lang.code
}
})
try {

const res = await fetchTransliteration(indicText, output_lng_code);
if(res?.success && res?.romanised_transliteration) {
setRomanisedTransliterationData(res);
if(res?.romanised_transliteration)
{
setOriginalRomanisedText(res.romanised_transliteration);
}
setSnackbarInfo({
open: true,
message: "Transliteration Done",
variant: "success",
});
setShowSpinner(false)
}
}
catch (error) {
setSnackbarInfo({
open: true,
message: "Error in fetching romanised text",
variant: "error",
});
setShowSpinner(false)
}

}
useEffect(() => {
if(originalRomanisedText) {
setEditedRomanisedText(originalRomanisedText);
}
}, [originalRomanisedText]);

useEffect(() => {
let annotation = lsfRef?.current?.store?.annotationStore?.selected;
let temp;
for (let i = 0; i < annotations?.length; i++) {
if (
!annotations[i]?.result?.length ||
annotation.serializeAnnotation()[0].id ===
annotations[i]?.result[0].id
) {
temp = annotation.serializeAnnotation();
if (annotations[i]?.annotation_type !== 1) continue;
for (let i = 0; i < temp?.length; i++) {
if(temp[i].type === "relation"){
continue;
}else if (temp[i]?.value.text) {
temp[i].value.text = [temp[i].value.text[0]];
}
}
if(temp[0]?.value?.text[0]?.length >0){
setIndicText(temp[0]?.value?.text[0])
}
}
}
}, [annotations, fetchTransliteration, handleSubmitRomanisedText]);

const handleEditableRomanisedText =(e)=>{
setEditedRomanisedText(e.target.value)
}

// call the handleTransliteration for first time if the indic text is present
useEffect(() => {
if(indicText){
handleTranslitrationOnClick()
}
}, [indicText]);
const renderSnackBar = () => {
return (
<CustomizedSnackbars
Expand Down Expand Up @@ -1142,6 +1315,24 @@ const LabelStudioWrapper = ({
>
{tagSuggestionList}
</Popover>

{!loader && showRomanisedTransliterationModel &&
<RomanisedTransliteration
open = {localStorage.getItem("showRomanisedTransliterationModel") == "true"}
onClose = {() => {
setShowRomanisedTransliterationModel(false)
}}
setShowRomanisedTransliterationModel = {setShowRomanisedTransliterationModel}
indicText={indicText}
originalRomanisedText={originalRomanisedText}
editedRomanisedText={editedRomanisedText}
handleEditableRomanisedText={handleEditableRomanisedText}
handleTranslitrationOnClick={handleTranslitrationOnClick}
handleSubmitRomanisedText={handleSubmitRomanisedText}
showSpinner={showSpinner}
/>
}

</Box>
{!loader && ProjectDetails?.project_type?.includes("OCRSegmentCategorization") &&
<>
Expand Down Expand Up @@ -1296,15 +1487,13 @@ export default function LSF() {
useEffect(() => {
fetchAnnotation(taskId).then((data) => {
if (data && Array.isArray(data) && data.length > 0) {
console.log(annotationNotesRef);
annotationNotesRef.current.value = data[0].annotation_notes ?? "";
reviewNotesRef.current.value = data[0].review_notes ?? "";
try {
const newDelta2 =
annotationNotesRef.current.value !== ""
? JSON.parse(annotationNotesRef.current.value)
: "";
console.log(newDelta2);
annotationNotesRef.current.getEditor().setContents(newDelta2);
} catch (err) {
if (err instanceof SyntaxError) {
Expand Down
Loading

0 comments on commit 231ae43

Please sign in to comment.