{"size": 4695, "ext": "js", "max_stars_repo_path": "src/Ml.Cli.WebApp/ClientApp/src/Local/Annotation/AnnotationsContainer.js", "max_stars_repo_name": "AxaGuilDEv/ml-cli", "max_stars_repo_stars_event_min_datetime": "2021-07-02T07:53:41.000Z", "max_stars_repo_stars_event_max_datetime": "2022-01-31T19:40:59.000Z", "max_issues_repo_path": "src/Ml.Cli.WebApp/ClientApp/src/Local/Annotation/AnnotationsContainer.js", "max_issues_repo_name": "AxaGuilDEv/ml-cli", "max_issues_repo_issues_event_min_datetime": "2021-07-02T15:47:01.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-31T14:53:48.000Z", "max_forks_repo_path": "src/Ml.Cli.WebApp/ClientApp/src/Local/Annotation/AnnotationsContainer.js", "max_forks_repo_name": "AxaGuilDEv/ml-cli", "max_forks_repo_forks_event_min_datetime": "2022-01-14T13:10:19.000Z", "max_forks_repo_forks_event_max_datetime": "2022-01-21T09:41:05.000Z"}
{"max_stars_count": 19, "max_issues_count": 168, "max_forks_count": 2, "avg_line_length": 31.5100671141, "max_line_length": 138, "alphanum_fraction": 0.585942492}
﻿import React, {useEffect, useState} from "react";

import {useHistory} from "react-router";
import {useMutation} from "react-query";
import {fetchGetData, fetchPostJson, utf8_to_b64} from "../FetchHelper";
import {toast} from "react-toastify";
import Annotations from "../../Toolkit/Annotations/Annotations";

const selectItemById = (annotationState, id) => {
    if(id === "end")
        return null;
    if(id === "empty")
        return null;
    return annotationState.items.find(x => x.id === id);
};


const fetchImages = async data => {
    if (data.status === 200) {
        const hardDriveLocations = await data.json();
        return hardDriveLocations.map(element => {
            return `api/local/files/${utf8_to_b64(element)}`;
        });
    } else {
        return [];
    }
};

const getImages = (fetchFunction) => async (item) => {
    const params = "fileName=" + item.fileName + "&stringsMatcher="+ item.frontDefaultStringsMatcher + "&directory=" + item.imageDirectory
    const fetchResult = await fetchGetData(fetchFunction)("api/local/datasets/"+utf8_to_b64(params));
    return fetchImages(fetchResult);
};

const sendConfirmationMessage = (isSuccess) => {
    const message = isSuccess ? "Annotation saved" : "Impossible to save annotation";
    const type = isSuccess ? "success" : "error";
    toast(message, {
        position: "top-left",
        autoClose: 800,
        hideProgressBar: true,
        closeOnClick: true,
        pauseOnHover: false,
        draggable: true,
        progress: undefined,
        type: type
    });
}


const AnnotationsContainer = ({state, id, url, dataset, fetchFunction}) => {
    const history = useHistory();
    
    const item = selectItemById(state, id);
    const itemNumber= state.items.indexOf(item);
    
    const onSubmit = async (annotation) => {
        const annotationObject = {
            datasetLocation: state.datasetLocation,
            annotationType: state.annotationType,
            fileName: item.fileName,
            annotation: annotation
        };
        await mutationDataset.mutateAsync(annotationObject, {
            onSuccess: () => {
                sendConfirmationMessage(true);
                onNext();
            },
            onError: () => sendConfirmationMessage(false)
        });
    }
    
    const onPrevious = () => {
        if(id === "end"){
            history.push(`${url}/${dataset}/${state.items[state.items.length - 1].id}`);
        } else{
            history.push(`${url}/${dataset}/${state.items[itemNumber - 1].id}`);
        }
    };
    
    const onNext = () => {
        if((itemNumber + 1) < state.items.length){
            history.push(`${url}/${dataset}/${state.items[itemNumber + 1].id}`);
        } else {
            history.push(`${url}/${dataset}/end`);
        }
    };

    const isPreviousDisabled = itemNumber === 0;
    const isNextDisabled = item == null;

    const [localState, setState] = useState({
        filePrimaryUrl: "",
    });

    const mutationDataset = useMutation(newData => fetchPostJson(fetchFunction)("/api/local/annotations", newData));

    const getUrls = async () => {
        const newUrls = await getImages(fetchFunction)(item);
        const newFileUrl = newUrls != null ? newUrls[0] : "";
        return {fileUrls: newUrls, filePrimaryUrl: newFileUrl};
    };

    const getBoundingBoxes = () => {
        if(item && item.annotations){
            const annotationsArray = JSON.parse(item.annotations);
            const lastAnnotation = annotationsArray[annotationsArray.length - 1];
            return lastAnnotation.labels.boundingBoxes;
        }
        return null;
    }

    useEffect(() => {
        setState({
            filePrimaryUrl: "",
        })
        if(!item || !item.imageDirectory){
            return;
        }
        getUrls().then(urls => {
                setState({
                    filePrimaryUrl: urls.filePrimaryUrl,
            })
        });
    }, [id]);
    
    
    const toolbarText = item ? item.fileName: "";
    const annotationType = state.annotationType;
    const labels = state.configuration;
    const expectedOutput = getBoundingBoxes();

    return <Annotations
            onPrevious={onPrevious}
            isPreviousDisabled={isPreviousDisabled}
            onNext={onNext}
            toolbarText={toolbarText}
            isEmpty={state.items.length <= 0}
            isNextDisabled={isNextDisabled}
            url={localState.filePrimaryUrl}
            annotationType={annotationType}
            labels={labels}
            expectedOutput={expectedOutput}
            onSubmit={onSubmit}
        />;
};

export default React.memo(AnnotationsContainer);
