Passed
Push — master ( 3991b7...550535 )
by Guangyu
27:53 queued 11:12
created

web/src/components/MyEMS/Monitoring/StoreEquipments.js   A

Complexity

Total Complexity 10
Complexity/F 0

Size

Lines of Code 323
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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