Passed
Push — master ( 748935...731cdf )
by Guangyu
08:41 queued 12s
created

MeterRealtime.js ➔ getCursor   F

Complexity

Conditions 16

Size

Total Lines 12
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 12
rs 2.4
c 0
b 0
f 0
cc 16

How to fix   Complexity   

Complexity

Complex classes like MeterRealtime.js ➔ getCursor often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import React, { createRef, Fragment, useEffect, useState } from 'react';
2
import {
3
  Breadcrumb,
4
  BreadcrumbItem,
5
  Card,
6
  CardBody,
7
  Col,
8
  Form,
9
  FormGroup,
10
  Input,
11
  Label,
12
  Row,
13
  Spinner,
14
  Pagination,
15
  PaginationItem,
16
  PaginationLink
17
} from 'reactstrap';
18
import Cascader from 'rc-cascader';
19
import RealtimeChart from './RealtimeChart';
20
import { getCookieValue, createCookie } from '../../../helpers/utils';
21
import withRedirect from '../../../hoc/withRedirect';
22
import { withTranslation } from 'react-i18next';
23
import uuid from 'uuid/v1';
24
import { toast } from 'react-toastify';
25
import { APIBaseURL } from '../../../config';
26
27
const MeterRealtime = ({ setRedirect, setRedirectUrl, t }) => {
28
  const [cursor, setCursor] = useState(0);
29
  const [maxCursor, setMaxCursor] = useState(0);
30
  const [selectMeterList, setSelectMeterList] = useState([]);
31
  const len = 8;
32
  const ran = 1;
33
34
  useEffect(() => {
35
    let is_logged_in = getCookieValue('is_logged_in');
36
    let user_name = getCookieValue('user_name');
37
    let user_display_name = getCookieValue('user_display_name');
38
    let user_uuid = getCookieValue('user_uuid');
39
    let token = getCookieValue('token');
40
    if (is_logged_in === null || !is_logged_in) {
41
      setRedirectUrl(`/authentication/basic/login`);
42
      setRedirect(true);
43
    } else {
44
      //update expires time of cookies
45
      createCookie('is_logged_in', true, 1000 * 60 * 60 * 8);
46
      createCookie('user_name', user_name, 1000 * 60 * 60 * 8);
47
      createCookie('user_display_name', user_display_name, 1000 * 60 * 60 * 8);
48
      createCookie('user_uuid', user_uuid, 1000 * 60 * 60 * 8);
49
      createCookie('token', token, 1000 * 60 * 60 * 8);
50
    }
51
  });
52
  let table = createRef();
53
  // State
54
  const [selectedSpaceName, setSelectedSpaceName] = useState(undefined);
55
  const [cascaderOptions, setCascaderOptions] = useState(undefined);
56
  const [meterList, setMeterList] = useState([]);
57
  const [spinnerHidden, setSpinnerHidden] = useState(false);
58
59
  useEffect(() => {
60
    //begin of getting space tree
61
    let isResponseOK = false;
62
    fetch(APIBaseURL + '/spaces/tree', {
63
      method: 'GET',
64
      headers: {
65
        'Content-type': 'application/json',
66
        'User-UUID': getCookieValue('user_uuid'),
67
        Token: getCookieValue('token')
68
      },
69
      body: null
70
    })
71
      .then(response => {
72
        console.log(response);
73
        if (response.ok) {
74
          isResponseOK = true;
75
        }
76
        return response.json();
77
      })
78
      .then(json => {
79
        console.log(json);
80
        if (isResponseOK) {
81
          // rename keys
82
          json = JSON.parse(
83
            JSON.stringify([json])
84
              .split('"id":')
85
              .join('"value":')
86
              .split('"name":')
87
              .join('"label":')
88
          );
89
          setCascaderOptions(json);
90
          // set the default space
91
          setSelectedSpaceName([json[0]].map(o => o.label));
92
          let selectedSpaceID = [json[0]].map(o => o.value);
93
          //begin of getting meters of the default space
94
          let isSecondResponseOK = false;
95
          fetch(APIBaseURL + '/spaces/' + selectedSpaceID + '/meters', {
96
            method: 'GET',
97
            headers: {
98
              'Content-type': 'application/json',
99
              'User-UUID': getCookieValue('user_uuid'),
100
              Token: getCookieValue('token')
101
            },
102
            body: null
103
          })
104
            .then(response => {
105
              if (response.ok) {
106
                isSecondResponseOK = true;
107
              }
108
              return response.json();
109
            })
110
            .then(json => {
111
              if (isSecondResponseOK) {
112
                json = JSON.parse(JSON.stringify([json]));
113
                console.log(json);
114
                setMeterList(json[0]);
115
                setSpinnerHidden(true);
116
              } else {
117
                toast.error(json.description);
118
              }
119
            })
120
            .catch(err => {
121
              console.log(err);
122
            });
123
          //end of getting meters of the default space
124
        } else {
125
          toast.error(json.description);
126
        }
127
      })
128
      .catch(err => {
129
        console.log(err);
130
      });
131
    //end of getting space tree
132
  }, []);
133
134
  const labelClasses = 'ls text-uppercase text-600 font-weight-semi-bold mb-0';
135
136
  let onSpaceCascaderChange = (value, selectedOptions) => {
137
    setSelectedSpaceName(selectedOptions.map(o => o.label).join('/'));
138
    let selectedSpaceID = value[value.length - 1];
139
    setSpinnerHidden(false);
140
    //begin of getting meters of the selected space
141
    let isResponseOK = false;
142
    fetch(APIBaseURL + '/spaces/' + selectedSpaceID + '/meters', {
143
      method: 'GET',
144
      headers: {
145
        'Content-type': 'application/json',
146
        'User-UUID': getCookieValue('user_uuid'),
147
        Token: getCookieValue('token')
148
      },
149
      body: null
150
    })
151
      .then(response => {
152
        if (response.ok) {
153
          isResponseOK = true;
154
        }
155
        return response.json();
156
      })
157
      .then(json => {
158
        if (isResponseOK) {
159
          json = JSON.parse(JSON.stringify([json]));
160
          console.log(json);
161
          setMeterList(json[0]);
162
163
          setSpinnerHidden(true);
164
        } else {
165
          toast.error(json.description);
166
        }
167
      })
168
      .catch(err => {
169
        console.log(err);
170
      });
171
    //end of getting meters of the selected space
172
  };
173
174
  useEffect(() => {
175
    const meterLen = meterList.length;
176
    const maxCursor = Math.ceil(meterLen / len);
177
178
    setCursor(1);
179
    setMaxCursor(maxCursor);
180
181
    document.getElementById("cursor_2").hidden=true;
182
    document.getElementById("cursor_3").hidden=true;
183
    document.getElementById("cursor_4").hidden=true;
184
    if(maxCursor == 2){
185
      document.getElementById("cursor_2").hidden=false;    
186
    }
187
    if(maxCursor == 3){
188
      document.getElementById("cursor_2").hidden=false;
189
      document.getElementById("cursor_3").hidden=false;
190
    }
191
    if(maxCursor>=4)
192
    {
193
      document.getElementById("cursor_2").hidden=false;
194
      document.getElementById("cursor_3").hidden=false;
195
      document.getElementById("cursor_4").hidden=false;
196
    }
197
198
  }, [meterList]);
199
200
  useEffect(() => {
201
    setSelectMeterList(meterList.slice(cursor * len - 8, cursor * len));
202
   
203
204
  }, [cursor, meterList]);
205
206
  function getCursor(location){
207
    switch (location){
208
      case 1:
209
            return cursor > maxCursor-3&&maxCursor - 3 >= 0 ? maxCursor-3 : cursor;
210
      case 2:
211
            return cursor > maxCursor-3&&maxCursor - 3 >= 0 ? maxCursor -2 : cursor +1;
212
      case 3:
213
            return cursor > maxCursor-3&&maxCursor - 3 >= 0 ? maxCursor -1: cursor +2;  
214
      case 4:
215
            return cursor > maxCursor-3&&maxCursor - 3 >= 0 ? maxCursor  : cursor+3;
216
    }
217
  }
218
219
  return (
220
    <Fragment>
221
      <div>
222
        <Breadcrumb>
223
          <BreadcrumbItem>{t('Meter Data')}</BreadcrumbItem>
224
          <BreadcrumbItem active>{t('Meter Realtime')}</BreadcrumbItem>
225
        </Breadcrumb>
226
      </div>
227
      <Card className="bg-light mb-3">
228
        <CardBody className="p-3">
229
          <Form>
230
            <Row form>
231
              <Col xs={6} sm={3}>
232
                <FormGroup className="form-group">
233
                  <Label className={labelClasses} for="space">
234
                    {t('Space')}
235
                  </Label>
236
                  <br />
237
                  <Cascader
238
                    options={cascaderOptions}
239
                    onChange={onSpaceCascaderChange}
240
                    changeOnSelect
241
                    expandTrigger="hover"
242
                  >
243
                    <Input value={selectedSpaceName || ''} readOnly />
244
                  </Cascader>
245
                </FormGroup>
246
              </Col>
247
              <Col xs="auto">
248
                <FormGroup>
249
                  <br />
250
                  <Spinner color="primary" hidden={spinnerHidden} />
251
                </FormGroup>
252
              </Col>
253
            </Row>
254
          </Form>
255
        </CardBody>
256
      </Card>
257
      <Row noGutters>
258
        {selectMeterList.map(meter => (
259
          <Col lg="3" className="pr-lg-2" key={uuid()}>
260
            <RealtimeChart meterId={meter['id']} meterName={meter['name']} />
261
          </Col>
262
        ))}
263
      </Row>
264
      <Pagination>
265
        <PaginationItem>
266
          <PaginationLink first href="#" onClick={() => setCursor(1)} />
267
        </PaginationItem>
268
       
269
        <PaginationItem>
270
          <PaginationLink previous href="#" onClick={() => (cursor - 1 >= 1 ? setCursor(cursor - 1) : null)} />
271
        </PaginationItem>
272
        <PaginationItem>
273
          <PaginationLink href="#" onClick={() => (setCursor(getCursor(1)))}>{getCursor(1)}</PaginationLink>
274
        </PaginationItem>
275
        <PaginationItem id="cursor_2">
276
          <PaginationLink href="#" onClick={() => (setCursor(getCursor(2)))}>{getCursor(2)}</PaginationLink>
277
        </PaginationItem>
278
        <PaginationItem id="cursor_3">
279
          <PaginationLink href="#" onClick={() => (setCursor(getCursor(3)))}>{getCursor(3)}</PaginationLink>
280
        </PaginationItem>
281
        <PaginationItem id="cursor_4">
282
          <PaginationLink href="#" onClick={() => (setCursor(getCursor(4)))}>{getCursor(4)}</PaginationLink>
283
        </PaginationItem>
284
        <PaginationItem >
285
          <PaginationLink next href="#" onClick={() => (cursor + 1 <= maxCursor ? setCursor(cursor + 1) : null)} />
286
        </PaginationItem>
287
        <PaginationItem>
288
          <PaginationLink last href="#" onClick={() => setCursor(maxCursor)} />
289
        </PaginationItem>
290
      </Pagination>
291
    </Fragment>
292
  );
293
};
294
295
export default withTranslation()(withRedirect(MeterRealtime));