Passed
Push — master ( c04ae7...0fa5b5 )
by Guangyu
08:11 queued 03:39
created

src/components/MyEMS/Monitoring/CombinedEquipments.js   A

Complexity

Total Complexity 10
Complexity/F 0

Size

Lines of Code 325
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 10
eloc 279
mnd 10
bc 10
fnc 0
dl 0
loc 325
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import React, { Fragment, useState, useEffect } from 'react';
2
import {
3
  Breadcrumb,
4
  BreadcrumbItem,
5
  Button,
6
  ButtonGroup,
7
  Card,
8
  CardBody,
9
  Col,
10
  CustomInput,
11
  Row,
12
  Form,
13
  FormGroup,
14
  Input,
15
  Label,
16
  Spinner,
17
} from 'reactstrap';
18
import Loader from '../../common/Loader';
19
import useFakeFetch from '../../../hooks/useFakeFetch';
20
import { isIterableArray } from '../../../helpers/utils';
21
import Flex from '../../common/Flex';
22
import Cascader from 'rc-cascader';
23
import classNames from 'classnames';
24
import EquipmentList from './EquipmentList';
25
import EquipmentFooter from './EquipmentFooter';
26
import usePagination from '../../../hooks/usePagination';
27
import equipments from './equipments';
28
import { getCookieValue, createCookie } from '../../../helpers/utils';
29
import withRedirect from '../../../hoc/withRedirect';
30
import { withTranslation } from 'react-i18next';
31
import { toast } from 'react-toastify';
32
import { APIBaseURL } from '../../../config';
33
34
35
const CombinedEquipments = ({ setRedirect, setRedirectUrl, t }) => {
36
  useEffect(() => {
37
    let is_logged_in = getCookieValue('is_logged_in');
38
    let user_name = getCookieValue('user_name');
39
    let user_display_name = getCookieValue('user_display_name');
40
    let user_uuid = getCookieValue('user_uuid');
41
    let token = getCookieValue('token');
42
    if (is_logged_in === null || !is_logged_in) {
43
      setRedirectUrl(`/authentication/basic/login`);
44
      setRedirect(true);
45
    } else {
46
      //update expires time of cookies
47
      createCookie('is_logged_in', true, 1000 * 60 * 60 * 8);
48
      createCookie('user_name', user_name, 1000 * 60 * 60 * 8);
49
      createCookie('user_display_name', user_display_name, 1000 * 60 * 60 * 8);
50
      createCookie('user_uuid', user_uuid, 1000 * 60 * 60 * 8);
51
      createCookie('token', token, 1000 * 60 * 60 * 8);
52
    }
53
  });
54
  // State
55
  const [selectedSpaceName, setSelectedSpaceName] = useState(undefined);
56
  const [selectedSpaceID, setSelectedSpaceID] = useState(undefined);
57
  const [combinedEquipmentList, setCombinedEquipmentList] = useState([]);
58
  const [selectedCombinedEquipment, setSelectedCombinedEquipment] = useState(undefined);
59
  const [equipmentIds, setEquipmentIds] = useState([]);
60
  const [cascaderOptions, setCascaderOptions] = useState(undefined);
61
  
62
  // button
63
  const [submitButtonDisabled, setSubmitButtonDisabled] = useState(true);
64
  const [spinnerHidden, setSpinnerHidden] = useState(true);
65
66
  useEffect(() => {
67
    let isResponseOK = false;
68
    fetch(APIBaseURL + '/spaces/tree', {
69
      method: 'GET',
70
      headers: {
71
        "Content-type": "application/json",
72
        "User-UUID": getCookieValue('user_uuid'),
73
        "Token": getCookieValue('token')
74
      },
75
      body: null,
76
77
    }).then(response => {
78
      console.log(response);
79
      if (response.ok) {
80
        isResponseOK = true;
81
      }
82
      return response.json();
83
    }).then(json => {
84
      console.log(json);
85
      if (isResponseOK) {
86
        // rename keys 
87
        json = JSON.parse(JSON.stringify([json]).split('"id":').join('"value":').split('"name":').join('"label":'));
88
        setCascaderOptions(json);
89
        setSelectedSpaceName([json[0]].map(o => o.label));
90
        setSelectedSpaceID([json[0]].map(o => o.value));
91
        // get Combined Equipments by root Space ID
92
        let isResponseOK = false;
93
        fetch(APIBaseURL + '/spaces/' + [json[0]].map(o => o.value) + '/combinedequipments', {
94
          method: 'GET',
95
          headers: {
96
            "Content-type": "application/json",
97
            "User-UUID": getCookieValue('user_uuid'),
98
            "Token": getCookieValue('token')
99
          },
100
          body: null,
101
102
        }).then(response => {
103
          if (response.ok) {
104
            isResponseOK = true;
105
          }
106
          return response.json();
107
        }).then(json => {
108
          if (isResponseOK) {
109
            json = JSON.parse(JSON.stringify([json]).split('"id":').join('"value":').split('"name":').join('"label":'));
110
            console.log(json);
111
            setCombinedEquipmentList(json[0]);
112
            if (json[0].length > 0) {
113
              setSelectedCombinedEquipment(json[0][0].value);
114
              // enable submit button
115
              setSubmitButtonDisabled(false);
116
            } else {
117
              setSelectedCombinedEquipment(undefined);
118
              // disable submit button
119
              setSubmitButtonDisabled(true);
120
            }
121
          } else {
122
            toast.error(json.description)
123
          }
124
        }).catch(err => {
125
          console.log(err);
126
        });
127
        // end of get Combined Equipments by root Space ID
128
      } else {
129
        toast.error(json.description);
130
      }
131
    }).catch(err => {
132
      console.log(err);
133
    });
134
135
  }, []);
136
137
  const labelClasses = 'ls text-uppercase text-600 font-weight-semi-bold mb-0';
138
139
  const sliderSettings = {
140
    infinite: true,
141
    speed: 500,
142
    slidesToShow: 1,
143
    slidesToScroll: 1
144
  };
145
146
  let onSpaceCascaderChange = (value, selectedOptions) => {
147
    setSelectedSpaceName(selectedOptions.map(o => o.label).join('/'));
148
    setSelectedSpaceID(value[value.length - 1]);
149
150
    let isResponseOK = false;
151
    fetch(APIBaseURL + '/spaces/' + value[value.length - 1] + '/combinedequipments', {
152
      method: 'GET',
153
      headers: {
154
        "Content-type": "application/json",
155
        "User-UUID": getCookieValue('user_uuid'),
156
        "Token": getCookieValue('token')
157
      },
158
      body: null,
159
160
    }).then(response => {
161
      if (response.ok) {
162
        isResponseOK = true;
163
      }
164
      return response.json();
165
    }).then(json => {
166
      if (isResponseOK) {
167
        json = JSON.parse(JSON.stringify([json]).split('"id":').join('"value":').split('"name":').join('"label":'));
168
        console.log(json)
169
        setCombinedEquipmentList(json[0]);
170
        if (json[0].length > 0) {
171
          setSelectedCombinedEquipment(json[0][0].value);
172
          // enable submit button
173
          setSubmitButtonDisabled(false);
174
        } else {
175
          setSelectedCombinedEquipment(undefined);
176
          // disable submit button
177
          setSubmitButtonDisabled(true);
178
        }
179
      } else {
180
        toast.error(json.description)
181
      }
182
    }).catch(err => {
183
      console.log(err);
184
    });
185
  }
186
  // Hook
187
  const { loading } = useFakeFetch(equipments);
188
  const { data: paginationData, meta: paginationMeta, handler: paginationHandler } = usePagination(equipmentIds, 4);
189
  const { total, itemsPerPage, from, to } = paginationMeta;
190
  const { perPage } = paginationHandler;
191
192
  const isList = true;
193
  const isGrid = false;
194
195
  useEffect(() => {
196
    setEquipmentIds(equipments.map(equipment => equipment.id));
197
  }, []);
198
199
  // Handler
200
  const handleSubmit = e => {
201
    e.preventDefault();
202
    console.log('handleSubmit');
203
    console.log(selectedSpaceID);
204
    console.log(selectedCombinedEquipment);
205
    // // disable submit button
206
    // setSubmitButtonDisabled(true);
207
    // // show spinner
208
    // setSpinnerHidden(false);
209
        
210
    // // enable submit button
211
    // setSubmitButtonDisabled(false);
212
    // // hide spinner
213
    // setSpinnerHidden(true);
214
215
  };
216
  
217
218
  return (
219
    <Fragment>
220
      <div>
221
        <Breadcrumb>
222
          <BreadcrumbItem>{t('Monitoring')}</BreadcrumbItem><BreadcrumbItem active>{t('Combined Equipments')}</BreadcrumbItem>
223
        </Breadcrumb>
224
      </div>
225
      <Card className="bg-light mb-3">
226
        <CardBody className="p-3">
227
          <Form onSubmit={handleSubmit}>
228
            <Row form>
229
              <Col xs="auto">
230
                <FormGroup className="form-group">
231
                  <Label className={labelClasses} for="space">
232
                    {t('Space')}
233
                  </Label>
234
                  <br />
235
                  <Cascader options={cascaderOptions}
236
                    onChange={onSpaceCascaderChange}
237
                    changeOnSelect
238
                    expandTrigger="hover">
239
                    <Input value={selectedSpaceName || ''} readOnly />
240
                  </Cascader>
241
                </FormGroup>
242
              </Col>
243
              <Col xs="auto">
244
                <FormGroup>
245
                  <Label className={labelClasses} for="combinedEquipmentSelect">
246
                    {t('Combined Equipment')}
247
                  </Label>
248
                  <CustomInput type="select" id="combinedEquipmentSelect" name="combinedEquipmentSelect" onChange={({ target }) => setSelectedCombinedEquipment(target.value)}
249
                  >
250
                    {combinedEquipmentList.map((combinedEquipment, index) => (
251
                      <option value={combinedEquipment.value} key={combinedEquipment.value}>
252
                        {combinedEquipment.label}
253
                      </option>
254
                    ))}
255
                  </CustomInput>
256
                </FormGroup>
257
              </Col>
258
              <Col xs="auto">
259
                <FormGroup>
260
                  <br></br>
261
                  <ButtonGroup id="submit">
262
                    <Button color="success" disabled={submitButtonDisabled} >{t('Submit')}</Button>
263
                  </ButtonGroup>
264
                </FormGroup>
265
              </Col>
266
              <Col xs="auto">
267
                <FormGroup>
268
                  <br></br>
269
                  <Spinner color="primary" hidden={spinnerHidden}  />
270
                </FormGroup>
271
              </Col>
272
            </Row>
273
          </Form>
274
        </CardBody>
275
      </Card>
276
277
278
      <Card>
279
        <CardBody className={classNames({ 'p-0  overflow-hidden': isList, 'pb-0': isGrid })}>
280
          {loading ? (
281
            <Loader />
282
          ) : (
283
              <Row noGutters={isList}>
284
                {isIterableArray(equipments) &&
285
                  equipments
286
                    .filter(equipment => paginationData.includes(equipment.id))
287
                    .map((equipment, index) => <EquipmentList {...equipment} sliderSettings={sliderSettings} key={equipment.id} index={index} />)}
288
              </Row>
289
            )}
290
        </CardBody>
291
        <EquipmentFooter meta={paginationMeta} handler={paginationHandler} />
292
      </Card>
293
      <Card className="mb-3">
294
        <CardBody>
295
          <Row className="justify-content-between align-items-center">
296
            <Col sm="auto" className="mb-2 mb-sm-0" tag={Flex} align="center">
297
              <h6 className="mb-0 text-nowrap ml-2">
298
                {t('Show Up to')}
299
              </h6>
300
              <CustomInput
301
                id="itemsPerPage"
302
                type="select"
303
                bsSize="sm"
304
                value={itemsPerPage}
305
                onChange={({ target }) => perPage(Number(target.value))}
306
              >
307
                <option value={2}>2</option>
308
                <option value={4}>4</option>
309
                <option value={6}>6</option>
310
                <option value={total}>{t('All')}</option>
311
              </CustomInput>
312
              <h6 className="mb-0 text-nowrap ml-2">
313
                {t('FROM - TO of TOTAL Equipments', { 'FROM': from, 'TO': to, 'TOTAL': total })}
314
              </h6>
315
            </Col>
316
317
          </Row>
318
        </CardBody>
319
      </Card>
320
    </Fragment>
321
  );
322
};
323
324
export default withTranslation()(withRedirect(CombinedEquipments));
325