Projekt

Obecné

Profil

Stáhnout (7.98 KB) Statistiky
| Větev: | Tag: | Revize:
1
import 'antd/dist/antd.css';
2
import React, { useContext, useEffect, useState } from 'react';
3

    
4
import { useUnauthRedirect } from '../../../hooks';
5
import { useRouter } from 'next/router';
6
import { Button, Input, Space, Table, Typography } from 'antd';
7
import { faFileLines, faUser } from '@fortawesome/free-solid-svg-icons';
8
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
9
import { LoggedUserContext } from '../../../contexts/LoggedUserContext';
10
import { MainLayout } from '../../../layouts/MainLayout';
11
import AddDocumentModal from '../../../components/modals/AddDocumentModal';
12
import { DocumentListInfo, UserInfo } from '../../../api';
13
import { documentController, userController } from '../../../controllers';
14
import AssignDocumentModal from '../../../components/modals/AssignDocumentModal';
15
import { ShowToast } from '../../../utils/alerts';
16
import { TableDocInfo } from '../../../components/types/TableDocInfo';
17
import { SearchOutlined } from '@ant-design/icons';
18
import { UserFilter } from '../../../components/types/UserFilter';
19

    
20
function AdminDocumentPage() {
21
    const redirecting = useUnauthRedirect('/login');
22
    const { logout, role } = useContext(LoggedUserContext);
23
    const [visibleAdd, setVisibleAdd] = React.useState(false);
24
    const [visibleAssign, setVisibleAssign] = React.useState(false);
25
    const router = useRouter();
26

    
27
    const [documents, setDocuments] = useState<TableDocInfo[]>([]);
28
    const [userFilters, setUserFilters] = useState<UserFilter[]>([]);
29
    const [selectedDocs, setSelectedDocs] = useState<string[] | undefined[]>([]);
30

    
31
    async function fetchData() {
32
        const docs = (await documentController.documentsGet(0, 1000)).data.documents;
33
        // @ts-ignore
34
        const tableDocs: TableDocInfo[] = docs?.map((doc, index) => {
35
            return { key: index, ...doc };
36
        });
37

    
38
        const users = (await userController.usersGet()).data.users;
39
        // @ts-ignore
40
        const filters: UserFilter[] = users?.map((user) => {
41
            return {
42
                text: user.name + ' ' + user.surname,
43
                value: user.username,
44
            };
45
        });
46
        setUserFilters(filters);
47

    
48
        if (!docs) {
49
            setDocuments([]);
50
        } else {
51
            setDocuments(tableDocs);
52
        }
53
    }
54

    
55
    useEffect(() => {
56
        if (!redirecting && role === 'ADMINISTRATOR') {
57
            fetchData();
58
        }
59
    }, [logout, redirecting, role, router]);
60

    
61
    const showAssignModal = () => {
62
        if (selectedDocs.length == 0) {
63
            ShowToast('Vyberte dokument pro přiřazení', 'warning', 3000, 'top-end');
64
        } else {
65
            setVisibleAssign(true);
66
        }
67
    };
68

    
69
    const showAddModal = () => {
70
        setVisibleAdd(true);
71
    };
72

    
73
    const hideModal = () => {
74
        fetchData();
75
        setVisibleAdd(false);
76
        setVisibleAssign(false);
77
    };
78

    
79
    const handleSearch = (
80
        selectedKeys: React.SetStateAction<string>[],
81
        confirm: () => void
82
    ) => {
83
        confirm();
84
    };
85

    
86
    const handleReset = (clearFilters: () => void) => {
87
        clearFilters();
88
    };
89

    
90
    const getColumnSearchProps = (dataIndex: string, searchLabel: string) => ({
91
        // @ts-ignore
92
        filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
93
            <div style={{ padding: 8 }}>
94
                <Input
95
                    placeholder={`Vyhledat ${searchLabel}`}
96
                    value={selectedKeys[0]}
97
                    onChange={(e) =>
98
                        setSelectedKeys(e.target.value ? [e.target.value] : [])
99
                    }
100
                    onPressEnter={() => handleSearch(selectedKeys, confirm)}
101
                    style={{ marginBottom: 8, display: 'block' }}
102
                />
103
                <Space>
104
                    <Button
105
                        type="primary"
106
                        onClick={() => handleSearch(selectedKeys, confirm)}
107
                        icon={<SearchOutlined />}
108
                        style={{ width: 90 }}
109
                    >
110
                        Hledat
111
                    </Button>
112
                    <Button
113
                        onClick={() => handleReset(clearFilters)}
114
                        style={{ width: 90 }}
115
                    >
116
                        Smazat
117
                    </Button>
118
                </Space>
119
            </div>
120
        ),
121
        filterIcon: (filtered: any) => (
122
            <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />
123
        ),
124
        onFilter: (value: string, record: { [x: string]: { toString: () => string } }) =>
125
            record[dataIndex]
126
                ? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
127
                : '',
128
    });
129

    
130
    const columns = [
131
        {
132
            title: 'Název dokumentu',
133
            dataIndex: 'name',
134
            key: 'name',
135
            ...getColumnSearchProps('name', 'název'),
136
        },
137
        {
138
            title: 'Délka',
139
            dataIndex: 'length',
140
            key: 'length',
141
            sorter: {
142
                // @ts-ignore
143
                compare: (a, b) => a.length - b.length,
144
                multiple: 1,
145
            },
146
            sortDirections: ['descend', 'ascend'],
147
        },
148
        {
149
            title: 'Anotátoři',
150
            dataIndex: 'annotatingUsers',
151
            key: 'annotatingUsers',
152
            render: (columnData: UserInfo[], record: DocumentListInfo, index: number) => {
153
                return (
154
                    <div>
155
                        {columnData.map((e) => (
156
                            <span
157
                                key={e.username + '.' + record.id}
158
                                title={e.username ?? ''}
159
                            >
160
                                <FontAwesomeIcon
161
                                    icon={faUser}
162
                                    title={e.username ?? ''}
163
                                    className={'me-2'}
164
                                />
165
                            </span>
166
                        ))}
167
                    </div>
168
                );
169
            },
170
            filters: userFilters,
171
            filterSearch: true,
172
            // @ts-ignore
173
            onFilter: (value, record) =>
174
                // @ts-ignore
175
                record.annotatingUsers.find((user) => user['username'] === value),
176
            sorter: {
177
                // @ts-ignore
178
                compare: (a, b) => a.annotatingUsers.length - b.annotatingUsers.length,
179
                multiple: 1,
180
            },
181
            sortDirections: ['descend', 'ascend'],
182
        },
183
    ];
184

    
185
    const rowSelection = {
186
        onChange: (selectedRowKeys: React.Key[], selectedRows: DocumentListInfo[]) => {
187
            // @ts-ignore
188
            setSelectedDocs(selectedRows.map((row) => row.id));
189
        },
190
    };
191

    
192
    return redirecting || role !== 'ADMINISTRATOR' ? null : (
193
        <MainLayout>
194
            <Typography.Title level={2}>
195
                <FontAwesomeIcon icon={faFileLines} /> Dokumenty
196
            </Typography.Title>
197
            <Button type={'primary'} onClick={showAddModal}>
198
                Nahrát dokument
199
            </Button>
200
            <Button onClick={showAssignModal}>Přiřadit dokumenty</Button>
201
            {visibleAdd && <AddDocumentModal onCancel={hideModal} />}
202
            {visibleAssign && (
203
                <AssignDocumentModal documentsIds={selectedDocs} onCancel={hideModal} />
204
            )}
205

    
206
            <Table
207
                locale={{
208
                    filterSearchPlaceholder: 'Hledat uživatele',
209
                    triggerDesc: 'Seřadit sestupně',
210
                    triggerAsc: 'Seřadit vzestupně',
211
                    cancelSort: 'Vypnout řazení',
212
                }}
213
                rowSelection={{
214
                    type: 'checkbox',
215
                    ...rowSelection,
216
                }}
217
                // @ts-ignore
218
                columns={columns}
219
                dataSource={documents}
220
                size="middle"
221
                scroll={{ y: 600 }}
222
            />
223
        </MainLayout>
224
    );
225
}
226

    
227
export default AdminDocumentPage;
    (1-1/1)