top-bar.tsx 6.1 KB
Newer Older
1
// Copyright (C) 2020-2022 Intel Corporation
2
// Copyright (C) 2022 CVAT.ai Corporation
B
Boris Sekachev 已提交
3 4 5
//
// SPDX-License-Identifier: MIT

6
import React, { useState, useEffect } from 'react';
7
import { useDispatch } from 'react-redux';
D
Dmitry Kalinin 已提交
8
import { useHistory } from 'react-router';
9

10
import { Row, Col } from 'antd/lib/grid';
11
import Dropdown from 'antd/lib/dropdown';
12
import { PlusOutlined, UploadOutlined, LoadingOutlined } from '@ant-design/icons';
13
import Button from 'antd/lib/button';
14
import Input from 'antd/lib/input';
15
import { importActions } from 'actions/import-actions';
16
import { SortingComponent, ResourceFilterHOC, defaultVisibility } from 'components/resource-sorting-filtering';
B
Boris Sekachev 已提交
17
import { TasksQuery } from 'reducers';
18
import { usePrevious } from 'utils/hooks';
R
Roman Donchenko 已提交
19
import { MultiPlusIcon } from 'icons';
20
import CvatDropdownMenuPaper from 'components/common/cvat-dropdown-menu-paper';
21 22 23 24
import {
    localStorageRecentKeyword, localStorageRecentCapacity, predefinedFilterValues, config,
} from './tasks-filter-configuration';

25 26
import dimensions from '../projects-page/dimensions';

27 28 29
const FilteringComponent = ResourceFilterHOC(
    config, localStorageRecentKeyword, localStorageRecentCapacity, predefinedFilterValues,
);
30

31
interface VisibleTopBarProps {
32 33 34
    onApplyFilter(filter: string | null): void;
    onApplySorting(sorting: string | null): void;
    onApplySearch(search: string | null): void;
35
    query: TasksQuery;
36
    importing: boolean;
37 38
}

D
Dmitry Kalinin 已提交
39
export default function TopBarComponent(props: VisibleTopBarProps): JSX.Element {
40
    const dispatch = useDispatch();
41
    const {
42
        importing, query, onApplyFilter, onApplySorting, onApplySearch,
43
    } = props;
44
    const [visibility, setVisibility] = useState(defaultVisibility);
D
Dmitry Kalinin 已提交
45
    const history = useHistory();
46 47 48 49 50 51 52
    const prevImporting = usePrevious(importing);

    useEffect(() => {
        if (prevImporting && !importing) {
            onApplyFilter(query.filter);
        }
    }, [importing]);
B
Boris Sekachev 已提交
53

54
    return (
55
        <Row className='cvat-tasks-page-top-bar' justify='center' align='middle'>
56
            <Col {...dimensions}>
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
                <div className='cvat-tasks-page-filters-wrapper'>
                    <Input.Search
                        enterButton
                        onSearch={(phrase: string) => {
                            onApplySearch(phrase);
                        }}
                        defaultValue={query.search || ''}
                        className='cvat-tasks-page-search-bar'
                        placeholder='Search ...'
                    />
                    <div>
                        <SortingComponent
                            visible={visibility.sorting}
                            onVisibleChange={(visible: boolean) => (
                                setVisibility({ ...defaultVisibility, sorting: visible })
                            )}
                            defaultFields={query.sort?.split(',') || ['-ID']}
                            sortingFields={['ID', 'Owner', 'Status', 'Assignee', 'Updated date', 'Subset', 'Mode', 'Dimension', 'Project ID', 'Name', 'Project name']}
                            onApplySorting={onApplySorting}
                        />
                        <FilteringComponent
                            value={query.filter}
                            predefinedVisible={visibility.predefined}
                            builderVisible={visibility.builder}
                            recentVisible={visibility.recent}
                            onPredefinedVisibleChange={(visible: boolean) => (
                                setVisibility({ ...defaultVisibility, predefined: visible })
                            )}
                            onBuilderVisibleChange={(visible: boolean) => (
                                setVisibility({ ...defaultVisibility, builder: visible })
                            )}
                            onRecentVisibleChange={(visible: boolean) => (
                                setVisibility({ ...defaultVisibility, builder: visibility.builder, recent: visible })
                            )}
                            onApplyFilter={onApplyFilter}
                        />
                    </div>
                </div>
                <div>
                    <Dropdown
                        trigger={['click']}
                        overlay={(
99
                            <CvatDropdownMenuPaper>
100 101 102 103 104 105 106 107
                                <Button
                                    className='cvat-create-task-button'
                                    type='primary'
                                    onClick={(): void => history.push('/tasks/create')}
                                    icon={<PlusOutlined />}
                                >
                                    Create a new task
                                </Button>
108 109 110 111
                                <Button
                                    className='cvat-create-multi-tasks-button'
                                    type='primary'
                                    onClick={(): void => history.push('/tasks/create?many=true')}
R
Roman Donchenko 已提交
112
                                    icon={<span className='anticon'><MultiPlusIcon /></span>}
113 114 115
                                >
                                    Create multi tasks
                                </Button>
116 117 118 119 120 121
                                <Button
                                    className='cvat-import-task-button'
                                    type='primary'
                                    disabled={importing}
                                    icon={<UploadOutlined />}
                                    onClick={() => dispatch(importActions.openImportBackupModal('task'))}
122
                                >
123 124 125
                                    Create from backup
                                    {importing && <LoadingOutlined />}
                                </Button>
126
                            </CvatDropdownMenuPaper>
127 128 129 130 131
                        )}
                    >
                        <Button type='primary' className='cvat-create-task-dropdown' icon={<PlusOutlined />} />
                    </Dropdown>
                </div>
132 133
            </Col>
        </Row>
B
Boris Sekachev 已提交
134
    );
135
}