// Copyright (C) 2019-2022 Intel Corporation // Copyright (C) 2022 CVAT.ai Corporation // // SPDX-License-Identifier: MIT import './styles.scss'; import React, { useEffect, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { useHistory, useParams } from 'react-router'; import Spin from 'antd/lib/spin'; import { Row, Col } from 'antd/lib/grid'; import Result from 'antd/lib/result'; import Button from 'antd/lib/button'; import Dropdown from 'antd/lib/dropdown'; import Title from 'antd/lib/typography/Title'; import Pagination from 'antd/lib/pagination'; import { MutliPlusIcon } from 'icons'; import { PlusOutlined } from '@ant-design/icons'; import Empty from 'antd/lib/empty'; import Input from 'antd/lib/input'; import { CombinedState, Task, Indexable } from 'reducers'; import { getProjectsAsync, getProjectTasksAsync } from 'actions/projects-actions'; import { cancelInferenceAsync } from 'actions/models-actions'; import TaskItem from 'components/tasks-page/task-item'; import MoveTaskModal from 'components/move-task-modal/move-task-modal'; import ModelRunnerDialog from 'components/model-runner-modal/model-runner-dialog'; import { SortingComponent, ResourceFilterHOC, defaultVisibility, updateHistoryFromQuery, } from 'components/resource-sorting-filtering'; import CvatDropdownMenuPaper from 'components/common/cvat-dropdown-menu-paper'; import DetailsComponent from './details'; import ProjectTopBar from './top-bar'; import { localStorageRecentKeyword, localStorageRecentCapacity, predefinedFilterValues, config, } from './project-tasks-filter-configuration'; const FilteringComponent = ResourceFilterHOC( config, localStorageRecentKeyword, localStorageRecentCapacity, predefinedFilterValues, ); interface ParamType { id: string; } export default function ProjectPageComponent(): JSX.Element { const id = +useParams().id; const dispatch = useDispatch(); const history = useHistory(); const projects = useSelector((state: CombinedState) => state.projects.current).map((project) => project.instance); const projectsFetching = useSelector((state: CombinedState) => state.projects.fetching); const deletes = useSelector((state: CombinedState) => state.projects.activities.deletes); const taskDeletes = useSelector((state: CombinedState) => state.tasks.activities.deletes); const tasksActiveInferences = useSelector((state: CombinedState) => state.models.inferences); const tasks = useSelector((state: CombinedState) => state.tasks.current); const tasksCount = useSelector((state: CombinedState) => state.tasks.count); const tasksQuery = useSelector((state: CombinedState) => state.projects.tasksGettingQuery); const tasksFetching = useSelector((state: CombinedState) => state.tasks.fetching); const [isMounted, setIsMounted] = useState(false); const [visibility, setVisibility] = useState(defaultVisibility); const queryParams = new URLSearchParams(history.location.search); const updatedQuery = { ...tasksQuery }; for (const key of Object.keys(updatedQuery)) { (updatedQuery as Indexable)[key] = queryParams.get(key) || null; if (key === 'page') { updatedQuery.page = updatedQuery.page ? +updatedQuery.page : 1; } } useEffect(() => { dispatch(getProjectTasksAsync({ ...updatedQuery, projectId: id })); setIsMounted(true); }, []); const [project] = projects.filter((_project) => _project.id === id); const projectSubsets: Array = []; for (const task of tasks) { if (!projectSubsets.includes(task.instance.subset)) projectSubsets.push(task.instance.subset); } useEffect(() => { if (!project) { dispatch(getProjectsAsync({ id }, updatedQuery)); } }, []); useEffect(() => { if (isMounted) { history.replace({ search: updateHistoryFromQuery(tasksQuery), }); } }, [tasksQuery]); useEffect(() => { if (project && id in deletes && deletes[id]) { history.push('/projects'); } }, [deletes]); if (projectsFetching) { return ; } if (!project) { return ( ); } const content = tasksCount ? ( <> {projectSubsets.map((subset: string) => ( {subset && {subset}} {tasks .filter((task) => task.instance.projectId === project.id && task.instance.subset === subset) .map((task: Task) => ( ))} { dispatch(getProjectTasksAsync({ ...tasksQuery, projectId: id, page, })); }} showSizeChanger={false} total={tasksCount} pageSize={10} current={tasksQuery.page} showQuickJumper /> ) : ( ); return (
{ dispatch(getProjectTasksAsync({ ...tasksQuery, page: 1, projectId: id, search: _search, })); }} defaultValue={tasksQuery.search || ''} className='cvat-project-page-tasks-search-bar' placeholder='Search ...' />
( setVisibility({ ...defaultVisibility, sorting: visible }) )} defaultFields={tasksQuery.sort?.split(',') || ['-ID']} sortingFields={['ID', 'Owner', 'Status', 'Assignee', 'Updated date', 'Subset', 'Mode', 'Dimension', 'Name']} onApplySorting={(sorting: string | null) => { dispatch(getProjectTasksAsync({ ...tasksQuery, page: 1, projectId: id, sort: sorting, })); }} /> ( setVisibility({ ...defaultVisibility, predefined: visible }) )} onBuilderVisibleChange={(visible: boolean) => ( setVisibility({ ...defaultVisibility, builder: visible }) )} onRecentVisibleChange={(visible: boolean) => ( setVisibility({ ...defaultVisibility, builder: visibility.builder, recent: visible, }) )} onApplyFilter={(filter: string | null) => { dispatch(getProjectTasksAsync({ ...tasksQuery, page: 1, projectId: id, filter, })); }} />
)} >
{ tasksFetching ? ( ) : content }
); }