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.
193 lines
5.9 KiB
TypeScript
193 lines
5.9 KiB
TypeScript
import React from 'react';
|
|
import { RouteComponentProps } from 'react-router';
|
|
import { withRouter } from 'react-router-dom';
|
|
|
|
import {
|
|
Spin,
|
|
Modal,
|
|
} from 'antd';
|
|
|
|
import {
|
|
TasksQuery,
|
|
} from '../../reducers/interfaces';
|
|
|
|
import TopBar from './top-bar';
|
|
import EmptyListComponent from './empty-list';
|
|
import TaskListContainer from '../../containers/tasks-page/tasks-list';
|
|
|
|
interface TasksPageProps {
|
|
deletingError: string;
|
|
dumpingError: string;
|
|
loadingError: string;
|
|
tasksFetchingError: string;
|
|
loadingDoneMessage: string;
|
|
tasksAreBeingFetched: boolean;
|
|
gettingQuery: TasksQuery;
|
|
numberOfTasks: number;
|
|
numberOfVisibleTasks: number;
|
|
onGetTasks: (gettingQuery: TasksQuery) => void;
|
|
}
|
|
|
|
class TasksPageComponent extends React.PureComponent<TasksPageProps & RouteComponentProps> {
|
|
constructor(props: any) {
|
|
super(props);
|
|
}
|
|
|
|
private updateURL(gettingQuery: TasksQuery) {
|
|
let queryString = '?';
|
|
for (const field of Object.keys(gettingQuery)) {
|
|
if (gettingQuery[field] !== null) {
|
|
queryString += `${field}=${gettingQuery[field]}&`;
|
|
}
|
|
}
|
|
this.props.history.replace({
|
|
search: queryString.slice(0, -1),
|
|
});
|
|
}
|
|
|
|
private getSearchField(gettingQuery: TasksQuery): string {
|
|
let searchString = '';
|
|
for (const field of Object.keys(gettingQuery)) {
|
|
if (gettingQuery[field] !== null && field !== 'page') {
|
|
if (field === 'search') {
|
|
return (gettingQuery[field] as any) as string;
|
|
} else {
|
|
if (typeof (gettingQuery[field] === 'number')) {
|
|
searchString += `${field}:${gettingQuery[field]} AND `;
|
|
} else {
|
|
searchString += `${field}:"${gettingQuery[field]}" AND `;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return searchString.slice(0, -5);
|
|
}
|
|
|
|
private handleSearch = (value: string): void => {
|
|
const gettingQuery = { ...this.props.gettingQuery };
|
|
const search = value.replace(/\s+/g, ' ').replace(/\s*:+\s*/g, ':').trim();
|
|
|
|
const fields = ['name', 'mode', 'owner', 'assignee', 'status', 'id'];
|
|
for (const field of fields) {
|
|
gettingQuery[field] = null;
|
|
}
|
|
gettingQuery.search = null;
|
|
|
|
let specificRequest = false;
|
|
for (const param of search.split(/[\s]+and[\s]+|[\s]+AND[\s]+/)) {
|
|
if (param.includes(':')) {
|
|
const [name, value] = param.split(':');
|
|
if (fields.includes(name) && !!value) {
|
|
specificRequest = true;
|
|
if (name === 'id') {
|
|
if (Number.isInteger(+value)) {
|
|
gettingQuery[name] = +value;
|
|
}
|
|
} else {
|
|
gettingQuery[name] = value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
gettingQuery.page = 1;
|
|
if (!specificRequest && value) { // only id
|
|
gettingQuery.search = value;
|
|
}
|
|
|
|
this.updateURL(gettingQuery);
|
|
this.props.onGetTasks(gettingQuery);
|
|
}
|
|
|
|
private handlePagination = (page: number): void => {
|
|
const gettingQuery = { ...this.props.gettingQuery };
|
|
|
|
gettingQuery.page = page;
|
|
this.updateURL(gettingQuery);
|
|
this.props.onGetTasks(gettingQuery);
|
|
}
|
|
|
|
public componentDidMount() {
|
|
const gettingQuery = { ...this.props.gettingQuery };
|
|
const params = new URLSearchParams(this.props.location.search);
|
|
|
|
for (const field of Object.keys(gettingQuery)) {
|
|
if (params.has(field)) {
|
|
const value = params.get(field);
|
|
if (value) {
|
|
if (field === 'id' || field === 'page') {
|
|
if (Number.isInteger(+value)) {
|
|
gettingQuery[field] = +value;
|
|
}
|
|
} else {
|
|
gettingQuery[field] = value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.updateURL(gettingQuery);
|
|
this.props.onGetTasks(gettingQuery);
|
|
}
|
|
|
|
public componentDidUpdate() {
|
|
if (this.props.tasksFetchingError) {
|
|
Modal.error({
|
|
title: 'Could not receive tasks',
|
|
content: this.props.tasksFetchingError,
|
|
});
|
|
}
|
|
|
|
if (this.props.dumpingError) {
|
|
Modal.error({
|
|
title: 'Could not dump annotations',
|
|
content: this.props.dumpingError,
|
|
});
|
|
}
|
|
|
|
if (this.props.loadingError) {
|
|
Modal.error({
|
|
title: 'Could not load annotations',
|
|
content: this.props.loadingError,
|
|
});
|
|
}
|
|
|
|
if (this.props.deletingError) {
|
|
Modal.error({
|
|
title: 'Could not delete the task',
|
|
content: this.props.deletingError,
|
|
});
|
|
}
|
|
|
|
if (this.props.loadingDoneMessage) {
|
|
Modal.info({
|
|
title: 'Successful loading of annotations',
|
|
content: this.props.loadingDoneMessage,
|
|
});
|
|
}
|
|
}
|
|
|
|
public render() {
|
|
if (this.props.tasksAreBeingFetched) {
|
|
return (
|
|
<Spin size='large' style={{margin: '25% 45%'}}/>
|
|
);
|
|
} else {
|
|
return (
|
|
<div className='cvat-tasks-page'>
|
|
<TopBar
|
|
onSearch={this.handleSearch}
|
|
searchValue={this.getSearchField(this.props.gettingQuery)}
|
|
/>
|
|
{this.props.numberOfVisibleTasks ?
|
|
<TaskListContainer
|
|
onSwitchPage={this.handlePagination}
|
|
/> : <EmptyListComponent/>}
|
|
</div>
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
export default withRouter(TasksPageComponent); |