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

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);