You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
6.9 KiB
TypeScript

// Copyright (C) 2020 Intel Corporation
//
// SPDX-License-Identifier: MIT
import React from 'react';
import { withRouter, RouteComponentProps } from 'react-router';
import { connect } from 'react-redux';
import { ClickParam } from 'antd/lib/menu/index';
import { CombinedState, TaskStatus } from 'reducers/interfaces';
import AnnotationMenuComponent, { Actions } from 'components/annotation-page/top-bar/annotation-menu';
import { dumpAnnotationsAsync, exportDatasetAsync, updateJobAsync } from 'actions/tasks-actions';
import {
uploadJobAnnotationsAsync,
removeAnnotationsAsync,
saveAnnotationsAsync,
switchRequestReviewDialog as switchRequestReviewDialogAction,
switchSubmitReviewDialog as switchSubmitReviewDialogAction,
setForceExitAnnotationFlag as setForceExitAnnotationFlagAction,
} from 'actions/annotation-actions';
interface StateToProps {
annotationFormats: any;
jobInstance: any;
loadActivity: string | null;
dumpActivities: string[] | null;
exportActivities: string[] | null;
user: any;
}
interface DispatchToProps {
loadAnnotations(job: any, loader: any, file: File): void;
dumpAnnotations(task: any, dumper: any): void;
exportDataset(task: any, exporter: any): void;
removeAnnotations(sessionInstance: any): void;
switchRequestReviewDialog(visible: boolean): void;
switchSubmitReviewDialog(visible: boolean): void;
setForceExitAnnotationFlag(forceExit: boolean): void;
saveAnnotations(jobInstance: any, afterSave?: () => void): void;
updateJob(jobInstance: any): void;
}
function mapStateToProps(state: CombinedState): StateToProps {
const {
annotation: {
activities: { loads: jobLoads },
job: { instance: jobInstance },
},
formats: { annotationFormats },
tasks: {
activities: { dumps, loads, exports: activeExports },
},
auth: { user },
} = state;
const taskID = jobInstance.task.id;
const jobID = jobInstance.id;
return {
dumpActivities: taskID in dumps ? dumps[taskID] : null,
exportActivities: taskID in activeExports ? activeExports[taskID] : null,
loadActivity: taskID in loads || jobID in jobLoads ? loads[taskID] || jobLoads[jobID] : null,
jobInstance,
annotationFormats,
user,
};
}
function mapDispatchToProps(dispatch: any): DispatchToProps {
return {
loadAnnotations(job: any, loader: any, file: File): void {
dispatch(uploadJobAnnotationsAsync(job, loader, file));
},
dumpAnnotations(task: any, dumper: any): void {
dispatch(dumpAnnotationsAsync(task, dumper));
},
exportDataset(task: any, exporter: any): void {
dispatch(exportDatasetAsync(task, exporter));
},
removeAnnotations(sessionInstance: any): void {
dispatch(removeAnnotationsAsync(sessionInstance));
},
switchRequestReviewDialog(visible: boolean): void {
dispatch(switchRequestReviewDialogAction(visible));
},
switchSubmitReviewDialog(visible: boolean): void {
dispatch(switchSubmitReviewDialogAction(visible));
},
setForceExitAnnotationFlag(forceExit: boolean): void {
dispatch(setForceExitAnnotationFlagAction(forceExit));
},
saveAnnotations(jobInstance: any, afterSave?: () => void): void {
dispatch(saveAnnotationsAsync(jobInstance, afterSave));
},
updateJob(jobInstance: any): void {
dispatch(updateJobAsync(jobInstance));
},
};
}
type Props = StateToProps & DispatchToProps & RouteComponentProps;
function AnnotationMenuContainer(props: Props): JSX.Element {
const {
jobInstance,
user,
annotationFormats: { loaders, dumpers },
history,
loadActivity,
dumpActivities,
exportActivities,
loadAnnotations,
dumpAnnotations,
exportDataset,
removeAnnotations,
switchRequestReviewDialog,
switchSubmitReviewDialog,
setForceExitAnnotationFlag,
saveAnnotations,
updateJob,
} = props;
const onClickMenu = (params: ClickParam, file?: File): void => {
if (params.keyPath.length > 1) {
const [additionalKey, action] = params.keyPath;
if (action === Actions.DUMP_TASK_ANNO) {
const format = additionalKey;
const [dumper] = dumpers.filter((_dumper: any): boolean => _dumper.name === format);
if (dumper) {
dumpAnnotations(jobInstance.task, dumper);
}
} else if (action === Actions.LOAD_JOB_ANNO) {
const format = additionalKey;
const [loader] = loaders.filter((_loader: any): boolean => _loader.name === format);
if (loader && file) {
loadAnnotations(jobInstance, loader, file);
}
} else if (action === Actions.EXPORT_TASK_DATASET) {
const format = additionalKey;
const [exporter] = dumpers.filter((_exporter: any): boolean => _exporter.name === format);
if (exporter) {
exportDataset(jobInstance.task, exporter);
}
}
} else {
const [action] = params.keyPath;
if (action === Actions.REMOVE_ANNO) {
removeAnnotations(jobInstance);
} else if (action === Actions.REQUEST_REVIEW) {
switchRequestReviewDialog(true);
} else if (action === Actions.SUBMIT_REVIEW) {
switchSubmitReviewDialog(true);
} else if (action === Actions.RENEW_JOB) {
jobInstance.status = TaskStatus.ANNOTATION;
updateJob(jobInstance);
history.push(`/tasks/${jobInstance.task.id}`);
} else if (action === Actions.FINISH_JOB) {
jobInstance.status = TaskStatus.COMPLETED;
updateJob(jobInstance);
history.push(`/tasks/${jobInstance.task.id}`);
} else if (action === Actions.OPEN_TASK) {
history.push(`/tasks/${jobInstance.task.id}`);
}
}
};
const isReviewer = jobInstance.reviewer?.id === user.id || user.isSuperuser;
return (
<AnnotationMenuComponent
taskMode={jobInstance.task.mode}
loaders={loaders}
dumpers={dumpers}
loadActivity={loadActivity}
dumpActivities={dumpActivities}
exportActivities={exportActivities}
onClickMenu={onClickMenu}
setForceExitAnnotationFlag={setForceExitAnnotationFlag}
saveAnnotations={saveAnnotations}
jobInstance={jobInstance}
isReviewer={isReviewer}
/>
);
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(AnnotationMenuContainer));