Passed
Push — master ( 4762c7...2b838c )
by Guangyu
08:55
created

src/components/MyEMS/Notification/Notification.js   A

Complexity

Total Complexity 11
Complexity/F 0

Size

Lines of Code 374
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 11
eloc 319
mnd 11
bc 11
fnc 0
dl 0
loc 374
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import React, { createRef, Fragment, useEffect, useState } from 'react';
2
import paginationFactory, { PaginationProvider } from 'react-bootstrap-table2-paginator';
3
import BootstrapTable from 'react-bootstrap-table-next';
4
import { toast } from 'react-toastify';
5
import {
6
  Row,
7
  Col,
8
  Card,
9
  CardBody,
10
  Button,
11
  CustomInput,
12
  DropdownItem,
13
  DropdownMenu,
14
  DropdownToggle,
15
  InputGroup,
16
  UncontrolledDropdown,
17
  Spinner,
18
} from 'reactstrap';
19
import ButtonIcon from '../../common/ButtonIcon';
20
import { Link } from 'react-router-dom';
21
import Badge from 'reactstrap/es/Badge';
22
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
23
import FalconCardHeader from '../../common/FalconCardHeader';
24
import uuid from 'uuid/v1';
25
import { getPaginationArray } from '../../../helpers/utils';
26
import { getCookieValue, createCookie } from '../../../helpers/utils';
27
import withRedirect from '../../../hoc/withRedirect';
28
import { withTranslation } from 'react-i18next';
29
import moment from 'moment';
30
import { APIBaseURL } from '../../../config';
31
32
33
34
35
const Notification = ({ setRedirect, setRedirectUrl, t }) => {
36
  let current_moment = moment();
37
  const [startDatetime, setStartDatetime] = useState(current_moment.clone().subtract(1, 'months'));
38
  const [endDatetime, setEndDatetime] = useState(current_moment);
39
  
40
  const [fetchSuccess, setFetchSuccess] = useState(false);
41
  //Results
42
  const [notifications, setNotifications] = useState([]);
43
44
  const [spinnerHidden, setSpinnerHidden] = useState(false);
45
46
  useEffect(() => {
47
    let is_logged_in = getCookieValue('is_logged_in');
48
    let user_name = getCookieValue('user_name');
49
    let user_display_name = getCookieValue('user_display_name');
50
    let user_uuid = getCookieValue('user_uuid');
51
    let token = getCookieValue('token');
52
    if (is_logged_in === null || !is_logged_in) {
53
      setRedirectUrl(`/authentication/basic/login`);
54
      setRedirect(true);
55
    } else {
56
      //update expires time of cookies
57
      createCookie('is_logged_in', true, 1000 * 60 * 60 * 8);
58
      createCookie('user_name', user_name, 1000 * 60 * 60 * 8);
59
      createCookie('user_display_name', user_display_name, 1000 * 60 * 60 * 8);
60
      createCookie('user_uuid', user_uuid, 1000 * 60 * 60 * 8);
61
      createCookie('token', token, 1000 * 60 * 60 * 8);
62
63
      let isResponseOK = false;
64
      if (!fetchSuccess) { 
65
        fetch(APIBaseURL + '/notifications?' + 
66
        'startdatetime=' + startDatetime.format('YYYY-MM-DDTHH:mm:ss') +
67
        '&enddatetime=' + endDatetime.format('YYYY-MM-DDTHH:mm:ss'), {
68
          method: 'GET',
69
          headers: {
70
            "Content-type": "application/json",
71
            "User-UUID": getCookieValue('user_uuid'),
72
            "Token": getCookieValue('token')
73
          },
74
          body: null,
75
76
        }).then(response => {
77
          if (response.ok) {
78
            isResponseOK = true;
79
          }
80
          return response.json();
81
        }).then(json => {
82
          if (isResponseOK) {
83
            console.log(json);
84
            setFetchSuccess(true);
85
86
            let notificationList = []
87
88
            if (json.length > 0) {
89
              json.forEach((currentValue, index) => {
90
                let notification = {}
91
                notification['id'] = json[index]['id'];
92
                notification['subject'] = json[index]['subject'];
93
                notification['created_datetime'] = json[index]['created_datetime']; 
94
                notification['message'] = json[index]['message'];
95
                notification['status'] = json[index]['status'];
96
                notification['url'] = json[index]['url'];
97
98
                notificationList.push(notification);
99
              });
100
            }
101
          
102
            setNotifications(notificationList);
103
            setSpinnerHidden(true);
104
          }
105
        });
106
      }
107
    }
108
  }, );
109
  // State
110
  let table = createRef();
111
112
  const [isSelected, setIsSelected] = useState(false);
113
  const handleNextPage = ({ page, onPageChange }) => () => {
114
    onPageChange(page + 1);
115
  };
116
117
  const handlePrevPage = ({ page, onPageChange }) => () => {
118
    onPageChange(page - 1);
119
  };
120
121
  const onSelect = () => {
122
    setImmediate(() => {
123
      setIsSelected(!!table.current.selectionContext.selected.length);
124
    });
125
  };
126
127
128
  const subjectFormatter = (dataField, { url }) => (
129
    <Fragment>
130
      <a href={`${url}`}>{dataField}</a>
131
    </Fragment>
132
  );
133
134
  const messageFormatter = (dataField,) => (
135
    <Fragment>
136
      {dataField}
137
    </Fragment>
138
  );
139
140
  const statusFormatter = status => {
141
    let color = '';
142
    let icon = '';
143
    let text = '';
144
    switch (status) {
145
      case 'read':
146
        color = 'success';
147
        icon = 'envelope-open';
148
        text = t('Notification Read');
149
        break;
150
      case 'unread':
151
        color = 'primary';
152
        icon = 'envelope';
153
        text = t('Notification Unread');
154
        break;
155
      default:
156
        color = 'primary';
157
        icon = 'envelope';
158
        text = t('Notification Unread');
159
    }
160
161
    return (
162
      <Badge color={`soft-${color}`} className="rounded-capsule fs--1 d-block">
163
        {text}
164
        <FontAwesomeIcon icon={icon} transform="shrink-2" className="ml-1" />
165
      </Badge>
166
    );
167
  };
168
169
  const actionFormatter = (dataField, { id }) => (
170
    // Control your row with this id
171
    <UncontrolledDropdown>
172
      <DropdownToggle color="link" size="sm" className="text-600 btn-reveal mr-3">
173
        <FontAwesomeIcon icon="ellipsis-h" className="fs--1" />
174
      </DropdownToggle>
175
      <DropdownMenu right className="border py-2">
176
        <DropdownItem onClick={() => handleRead(id)}>{t('Notification Mark As Read')}</DropdownItem>
177
        <DropdownItem onClick={() => console.log('Archive: ', id)}>{t('Notification Archive')}</DropdownItem>
178
        <DropdownItem divider />
179
        <DropdownItem onClick={() => console.log('Delete: ', id)} className="text-danger">{t('Notification Delete')}</DropdownItem>
180
      </DropdownMenu>
181
    </UncontrolledDropdown>
182
  );
183
  const columns = [
184
    {
185
      dataField: 'subject',
186
      text: t('Notification Subject'),
187
      classes: 'py-2 align-middle',
188
      formatter: subjectFormatter,
189
      sort: true
190
    },
191
    {
192
      dataField: 'created_datetime',
193
      text: t('Notification Created Datetime'),
194
      classes: 'py-2 align-middle',
195
      sort: true
196
    },
197
    {
198
      dataField: 'message',
199
      text: t('Notification Message'),
200
      classes: 'py-2 align-middle',
201
      formatter: messageFormatter,
202
      sort: true
203
    },
204
    {
205
      dataField: 'status',
206
      text: t('Notification Status'),
207
      classes: 'py-2 align-middle',
208
      formatter: statusFormatter,
209
      sort: true
210
    },
211
    {
212
      dataField: '',
213
      text: '',
214
      classes: 'py-2 align-middle',
215
      formatter: actionFormatter,
216
      align: 'right'
217
    }
218
  ];
219
220
  const options = {
221
    custom: true,
222
    sizePerPage: 10,
223
    totalSize: notifications.length
224
  };
225
226
  const SelectRowInput = ({ indeterminate, rowIndex, ...rest }) => (
227
    <div className="custom-control custom-checkbox">
228
      <input
229
        className="custom-control-input"
230
        {...rest}
231
        onChange={() => { }}
232
        ref={input => {
233
          if (input) input.indeterminate = indeterminate;
234
        }}
235
      />
236
      <label className="custom-control-label" />
237
    </div>
238
  );
239
240
  const selectRow = onSelect => ({
241
    mode: 'checkbox',
242
    classes: 'py-2 align-middle',
243
    clickToSelect: false,
244
    selectionHeaderRenderer: ({ mode, ...rest }) => <SelectRowInput type="checkbox" {...rest} />,
245
    selectionRenderer: ({ mode, ...rest }) => <SelectRowInput type={mode} {...rest} />,
246
    onSelect: onSelect,
247
    onSelectAll: onSelect
248
  });
249
250
  const handleRead = (id, ) => {
251
    console.log('Mark As Read: ', id)
252
    let isResponseOK = false;
253
    fetch(APIBaseURL + '/notifications/' + id, {
254
      method: 'PUT',
255
      headers: {
256
        "Content-type": "application/json",
257
        "User-UUID": getCookieValue('user_uuid'),
258
        "Token": getCookieValue('token')
259
      },
260
      body: JSON.stringify({
261
        "data": {
262
          "status": 'read'
263
        }
264
      }),
265
    }).then(response => {
266
      if (response.ok) {
267
        isResponseOK = true;
268
        return null;
269
      } else {
270
        return response.json();
271
      }
272
    }).then(json => {
273
      console.log(isResponseOK);
274
      if (isResponseOK) {
275
        
276
      } else {
277
        toast.error(json.description)
278
      }
279
    }).catch(err => {
280
      console.log(err);
281
    });
282
  };
283
284
285
  return (
286
    <Fragment>
287
      <Card className="mb-3">
288
        <Spinner color="primary" hidden={spinnerHidden}  />
289
        <FalconCardHeader title={t('Notification List')} light={false}>
290
          {isSelected ? (
291
            <InputGroup size="sm" className="input-group input-group-sm">
292
              <CustomInput type="select" id="bulk-select">
293
                <option>{t('Bulk actions')}</option>
294
                <option value="MarkAsRead">{t('Notification Mark As Read')}</option>
295
                <option value="Archive">{t('Notification Archive')}</option>
296
                <option value="Delete">{t('Notification Delete')}</option>
297
              </CustomInput>
298
              <Button color="falcon-default" size="sm" className="ml-2">
299
              {t('Notification Apply')}
300
                </Button>
301
            </InputGroup>
302
          ) : (
303
              <Fragment>
304
                
305
              </Fragment>
306
            )}
307
        </FalconCardHeader>
308
        <CardBody className="p-0">
309
          <PaginationProvider pagination={paginationFactory(options)}>
310
            {({ paginationProps, paginationTableProps }) => {
311
              const lastIndex = paginationProps.page * paginationProps.sizePerPage;
312
313
              return (
314
                <Fragment>
315
                  <div className="table-responsive">
316
                    <BootstrapTable
317
                      ref={table}
318
                      bootstrap4
319
                      keyField="id"
320
                      data={notifications}
321
                      columns={columns}
322
                      selectRow={selectRow(onSelect)}
323
                      bordered={false}
324
                      classes="table-dashboard table-striped table-sm fs--1 border-bottom mb-0 table-dashboard-th-nowrap"
325
                      rowClasses="btn-reveal-trigger"
326
                      headerClasses="bg-200 text-900"
327
                      {...paginationTableProps}
328
                    />
329
                  </div>
330
                  <Row noGutters className="px-1 py-3 flex-center">
331
                    <Col xs="auto">
332
                      <Button
333
                        color="falcon-default"
334
                        size="sm"
335
                        onClick={handlePrevPage(paginationProps)}
336
                        disabled={paginationProps.page === 1}
337
                      >
338
                        <FontAwesomeIcon icon="chevron-left" />
339
                      </Button>
340
                      {getPaginationArray(paginationProps.totalSize, paginationProps.sizePerPage).map(pageNo => (
341
                        <Button
342
                          color={paginationProps.page === pageNo ? 'falcon-primary' : 'falcon-default'}
343
                          size="sm"
344
                          className="ml-2"
345
                          onClick={() => paginationProps.onPageChange(pageNo)}
346
                          key={pageNo}
347
                        >
348
                          {pageNo}
349
                        </Button>
350
                      ))}
351
                      <Button
352
                        color="falcon-default"
353
                        size="sm"
354
                        className="ml-2"
355
                        onClick={handleNextPage(paginationProps)}
356
                        disabled={lastIndex >= paginationProps.totalSize}
357
                      >
358
                        <FontAwesomeIcon icon="chevron-right" />
359
                      </Button>
360
                    </Col>
361
                  </Row>
362
                </Fragment>
363
              );
364
            }}
365
          </PaginationProvider>
366
        </CardBody>
367
      </Card>
368
369
    </Fragment>
370
  );
371
};
372
373
export default withTranslation()(withRedirect(Notification));
374