Projekt

Obecné

Profil

Stáhnout (7.16 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 { Badge, Button, Input, Space, Table, Typography } from 'antd';
7
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
8
import { faUsers } from '@fortawesome/free-solid-svg-icons';
9
import { LoggedUserContext } from '../../contexts/LoggedUserContext';
10
import { MainLayout } from '../../layouts/MainLayout';
11
import { UserInfo } from '../../api';
12
import { userController } from '../../controllers';
13
import AddUserModal from '../../components/modals/AddUserModal';
14
import UserDocumentsModal from '../../components/modals/UserDocumentsModal';
15
import { ShowConfirmDelete } from '../../utils/alerts';
16
import EditUserModal from '../../components/modals/EditUserModal';
17
import { SearchOutlined } from '@ant-design/icons';
18

    
19
function UsersPage() {
20
    const redirecting = useUnauthRedirect('/login');
21
    const { logout, role } = useContext(LoggedUserContext);
22
    const router = useRouter();
23

    
24
    const [addVisible, setAddVisible] = React.useState(false);
25
    const [editVisible, setEditVisible] = React.useState(false);
26
    const [docsVisible, setDocsVisible] = React.useState(false);
27
    const [users, setUsers] = useState<UserInfo[]>([]);
28

    
29
    const [user, setUser] = useState<UserInfo>({});
30

    
31
    async function fetchData() {
32
        let usrs = (await userController.usersGet()).data.users;
33
        if (!usrs) {
34
            setUsers([]);
35
        } else {
36
            setUsers(usrs);
37
        }
38
    }
39

    
40
    useEffect(() => {
41
        if (!redirecting && role === 'ADMINISTRATOR') {
42
            fetchData();
43
        }
44
    }, [logout, redirecting, role, router]);
45

    
46
    const setUserInfo = (userId: string) => {
47
        const userInfo = users.find((user) => user.id === userId);
48
        if (userInfo) {
49
            setUser(userInfo);
50
        }
51
    };
52

    
53
    const deleteUser = (userId: string) => {
54
        ShowConfirmDelete(() => {
55
            userController.userUserIdDelete(userId).then(() => fetchData());
56
        }, 'uživatele');
57
    };
58

    
59
    const showAddModal = () => {
60
        setAddVisible(true);
61
    };
62
    const showEditModal = (userId: string) => {
63
        setUserInfo(userId);
64
        setEditVisible(true);
65
    };
66
    const showDocsModal = (userId: string) => {
67
        setUserInfo(userId);
68
        setDocsVisible(true);
69
    };
70

    
71
    const hideModals = () => {
72
        fetchData();
73
        setAddVisible(false);
74
        setDocsVisible(false);
75
        setEditVisible(false);
76
    };
77

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

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

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

    
129
    const columns = [
130
        {
131
            title: 'Jméno',
132
            dataIndex: 'name',
133
            key: 'name',
134
            ...getColumnSearchProps('name', 'jméno'),
135
        },
136
        {
137
            title: 'Příjmení',
138
            dataIndex: 'surname',
139
            key: 'surname',
140
            ...getColumnSearchProps('surname', 'příjmení'),
141
        },
142
        {
143
            title: 'Uživatelské jméno',
144
            dataIndex: 'username',
145
            key: 'username',
146
            ...getColumnSearchProps('username', 'uživatelské jméno'),
147
        },
148
        {
149
            title: 'Přiřazeno dokumentů',
150
            key: 'docCounts',
151
            align: 'center' as 'center',
152
            dataIndex: ['id', 'assignedDocumentsCount'],
153
            // @ts-ignore
154
            render: (text, row) => (
155
                <div>
156
                    <Space size={'middle'}>
157
                        <Badge count={row.assignedDocumentsCount}>
158
                            <Button onClick={() => showDocsModal(row.id)}>
159
                                Dokumenty
160
                            </Button>
161
                        </Badge>
162
                    </Space>
163
                </div>
164
            ),
165
            // @ts-ignore
166
            sorter: (a, b) => a.assignedDocumentsCount - b.assignedDocumentsCount,
167
        },
168
        {
169
            title: '',
170
            key: 'operations',
171
            dataIndex: 'id',
172
            align: 'center' as 'center',
173
            // @ts-ignore
174
            render: (id) => (
175
                <div>
176
                    <Space size={'middle'}>
177
                        <Button onClick={() => showEditModal(id)}>Upravit</Button>
178
                        <Button onClick={() => deleteUser(id)}>Smazat</Button>
179
                    </Space>
180
                </div>
181
            ),
182
        },
183
    ];
184

    
185
    // @ts-ignore
186
    return redirecting || role !== 'ADMINISTRATOR' ? null : (
187
        <MainLayout>
188
            <Typography.Title level={2}>
189
                <FontAwesomeIcon icon={faUsers} /> Uživatelé
190
            </Typography.Title>
191
            <Button type={'primary'} onClick={showAddModal}>
192
                Přidat uživatele
193
            </Button>
194
            {addVisible && <AddUserModal onCancel={hideModals} />}
195
            {editVisible && <EditUserModal userInfo={user} onCancel={hideModals} />}
196
            {docsVisible && <UserDocumentsModal userId={user.id} onCancel={hideModals} />}
197

    
198
            <Table
199
                locale={{
200
                    triggerDesc: 'Seřadit sestupně',
201
                    triggerAsc: 'Seřadit vzestupně',
202
                    cancelSort: 'Vypnout řazení',
203
                }}
204
                // @ts-ignore
205
                columns={columns}
206
                dataSource={users}
207
                scroll={{ y: 500 }}
208
            />
209
        </MainLayout>
210
    );
211
}
212

    
213
export default UsersPage;
    (1-1/1)