Passed
Push — master ( 183c79...49504c )
by
unknown
12:19 queued 13s
created

myems-web/src/components/MyEMS/dashboard/Dashboard.js   B

Complexity

Total Complexity 44
Complexity/F 0

Size

Lines of Code 847
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 44
eloc 726
dl 0
loc 847
rs 8.754
c 0
b 0
f 0
mnd 44
bc 44
fnc 0
bpm 0
cpm 0
noi 0

How to fix   Complexity   

Complexity

Complex classes like myems-web/src/components/MyEMS/dashboard/Dashboard.js 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, { Fragment, useEffect, useState } from 'react';
2
import CountUp from 'react-countup';
3
import { Col, Row, Spinner } from 'reactstrap';
4
import CardSummary from '../common/CardSummary';
5
import LineChart from '../common/LineChart';
6
import { toast } from 'react-toastify';
7
import SharePie from '../common/SharePie';
8
import loadable from '@loadable/component';
9
import { getCookieValue, createCookie, checkEmpty } from '../../../helpers/utils';
10
import withRedirect from '../../../hoc/withRedirect';
11
import { withTranslation } from 'react-i18next';
12
import moment from 'moment';
13
import { APIBaseURL, settings } from '../../../config';
14
import { v4 as uuid } from 'uuid';
15
import annotationPlugin from 'chartjs-plugin-annotation';
16
import { Chart as ChartJS } from 'chart.js';
17
import BarChart from '../common/BarChart';
18
import ChartSpacesStackBar from '../common/ChartSpacesStackBar';
19
import RealtimeSensor from '../common/RealtimeSensor';
20
import CustomizeMapBox from '../common/CustomizeMapBox';
21
22
ChartJS.register(annotationPlugin);
23
24
const ChildSpacesTable = loadable(() => import('../common/ChildSpacesTable'));
25
26
const Dashboard = ({ setRedirect, setRedirectUrl, t }) => {
27
  let current_moment = moment();
28
  const [isFetchDashboard, setIsFetchDashboard] = useState(true);
29
  const [periodType, setPeriodType] = useState('monthly');
30
  const [basePeriodBeginsDatetime, setBasePeriodBeginsDatetime] = useState(
31
    current_moment.clone().subtract(1, 'years').subtract(1, 'years').startOf('month')
32
  );
33
  const [basePeriodEndsDatetime, setBasePeriodEndsDatetime] = useState(current_moment.clone().subtract(1, 'years'));
34
  const [reportingPeriodBeginsDatetime, setReportingPeriodBeginsDatetime] = useState(
35
    current_moment.clone().subtract(1, 'years').startOf('month')
36
  );
37
  const [reportingPeriodEndsDatetime, setReportingPeriodEndsDatetime] = useState(current_moment);
38
39
  const [spinnerHidden, setSpinnerHidden] = useState(false);
40
41
  //Results
42
  const [costShareData, setCostShareData] = useState([]);
43
  const [timeOfUseShareData, setTimeOfUseShareData] = useState([]);
44
  const [TCEShareData, setTCEShareData] = useState([]);
45
  const [TCO2EShareData, setTCO2EShareData] = useState([]);
46
47
  const [thisYearBarList, setThisYearBarList] = useState([]);
48
  const [lastYearBarList, setLastYearBarList] = useState([]);
49
  const [thisMonthInputCardSummaryList, setThisMonthInputCardSummaryList] = useState([]);
50
  const [thisMonthCostCardSummaryList, setThisMonthCostCardSummaryList] = useState([]);
51
  const [thisMonthOutputCardSummaryList, setThisMonthOutputCardSummaryList] = useState([]);
52
  const [barLabels, setBarLabels] = useState([]);
53
  const [totalInTCE, setTotalInTCE] = useState({});
54
  const [totalInTCO2E, setTotalInTCO2E] = useState({});
55
56
  const [spaceInputLineChartLabels, setSpaceInputLineChartLabels] = useState([]);
57
  const [spaceInputLineChartData, setSpaceInputLineChartData] = useState({});
58
  const [spaceInputLineChartOptions, setSpaceInputLineChartOptions] = useState([]);
59
  const [spaceCostLineChartOptions, setSpaceCostLineChartOptions] = useState([]);
60
  const [spaceCostLineChartLabels, setSpaceCostLineChartLabels] = useState([]);
61
  const [spaceCostLineChartData, setSpaceCostLineChartData] = useState({});
62
63
  const [detailedDataTableData, setDetailedDataTableData] = useState([]);
64
  const [detailedDataTableColumns, setDetailedDataTableColumns] = useState([
65
    { dataField: 'startdatetime', text: t('Datetime'), sort: true }
66
  ]);
67
68
  const [childSpacesTableData, setChildSpacesTableData] = useState([]);
69
  const [childSpacesTableColumns, setChildSpacesTableColumns] = useState([
70
    { dataField: 'name', text: t('Child Spaces'), sort: true }
71
  ]);
72
73
  const [childSpacesInputData, setChildSpacesInputData] = useState([]);
74
  const [childSpacesCostData, setChildSpacesCostData] = useState([]);
75
  const [monthLabels, setMonthLabels] = useState([]);
76
  const [geojson, setGeojson] = useState({});
77
  const [rootLatitude, setRootLatitude] = useState('');
78
  const [rootLongitude, setRootLongitude] = useState('');
79
80
  const [sensor, setSensor] = useState({});
81
  const [pointList, setPointList] = useState({});
82
83
  useEffect(() => {
84
    let is_logged_in = getCookieValue('is_logged_in');
85
    let user_name = getCookieValue('user_name');
86
    let user_display_name = getCookieValue('user_display_name');
87
    let user_uuid = getCookieValue('user_uuid');
88
    let token = getCookieValue('token');
89
    if (checkEmpty(is_logged_in) || checkEmpty(token) || checkEmpty(user_uuid) || !is_logged_in) {
90
      setRedirectUrl(`/authentication/basic/login`);
91
      setRedirect(true);
92
    } else {
93
      //update expires time of cookies
94
      createCookie('is_logged_in', true, settings.cookieExpireTime);
95
      createCookie('user_name', user_name, settings.cookieExpireTime);
96
      createCookie('user_display_name', user_display_name, settings.cookieExpireTime);
97
      createCookie('user_uuid', user_uuid, settings.cookieExpireTime);
98
      createCookie('token', token, settings.cookieExpireTime);
99
100
      let isResponseOK = false;
101
      if (isFetchDashboard) {
102
        setIsFetchDashboard(false);
103
        toast(
104
          <Fragment>
105
            {t('Welcome to MyEMS')}
106
            <br />
107
            {t('An Industry Leading Open Source Energy Management System')}
108
          </Fragment>
109
        );
110
111
        fetch(APIBaseURL + '/reports/dashboard?' + 'useruuid=' + user_uuid + '&periodtype=' + periodType +
112
          '&baseperiodstartdatetime=' +
113
          (basePeriodBeginsDatetime != null ? basePeriodBeginsDatetime.format('YYYY-MM-DDTHH:mm:ss') : '') +
114
          '&baseperiodenddatetime=' +
115
          (basePeriodEndsDatetime != null ? basePeriodEndsDatetime.format('YYYY-MM-DDTHH:mm:ss') : '') +
116
          '&reportingperiodstartdatetime=' +
117
          reportingPeriodBeginsDatetime.format('YYYY-MM-DDTHH:mm:ss') +
118
          '&reportingperiodenddatetime=' +
119
          reportingPeriodEndsDatetime.format('YYYY-MM-DDTHH:mm:ss'),
120
          {
121
            method: 'GET',
122
            headers: {
123
              'Content-type': 'application/json',
124
              'User-UUID': getCookieValue('user_uuid'),
125
              Token: getCookieValue('token')
126
            },
127
            body: null
128
          }
129
        )
130
          .then(response => {
131
            if (response.ok) {
132
              isResponseOK = true;
133
            }
134
            return response.json();
135
          })
136
          .then(json => {
137
            if (isResponseOK) {
138
              // hide spinner
139
              setSpinnerHidden(true);
140
              let labels = [];
141
              let thisYearBarList = [];
142
              let lastYearBarList = [];
143
              json['reporting_period_input']['names'].forEach((currentValue, index) => {
144
                let cardSummaryItem = {};
145
                cardSummaryItem['name'] = json['reporting_period_input']['names'][index];
146
                cardSummaryItem['unit'] = json['reporting_period_input']['units'][index];
147
                cardSummaryItem['subtotal'] = json['reporting_period_input']['subtotals'][index];
148
                cardSummaryItem['increment_rate'] = parseFloat(json['reporting_period_input']['increment_rates'][index] * 100).toFixed(2) + '%';
149
                cardSummaryItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0;
150
                cardSummaryItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0;
151
                labels.push(
152
                  t('CATEGORY Consumption UNIT', { CATEGORY: null, UNIT: null }) +
153
                  cardSummaryItem['name'] +
154
                  cardSummaryItem['unit']
155
                );
156
                thisYearBarList.push(cardSummaryItem);
157
              });
158
159
              json['reporting_period_cost']['names'].forEach((currentValue, index) => {
160
                let cardSummaryItem = {};
161
                cardSummaryItem['name'] = json['reporting_period_cost']['names'][index];
162
                cardSummaryItem['unit'] = json['reporting_period_cost']['units'][index];
163
                cardSummaryItem['subtotal'] = json['reporting_period_cost']['subtotals'][index];
164
                cardSummaryItem['increment_rate'] = parseFloat(json['reporting_period_cost']['increment_rates'][index] * 100).toFixed(2) + '%';
165
                cardSummaryItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0;
166
                cardSummaryItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0;
167
                labels.push(
168
                  t('CATEGORY Costs UNIT', { CATEGORY: null, UNIT: null }) +
169
                  cardSummaryItem['name'] +
170
                  cardSummaryItem['unit']
171
                );
172
                thisYearBarList.push(cardSummaryItem);
173
              });
174
              setBarLabels(labels);
175
              setThisYearBarList(thisYearBarList);
176
177
              json['base_period_input']['names'].forEach((currentValue, index) => {
178
                let cardSummaryItem = {};
179
                cardSummaryItem['name'] = json['base_period_input']['names'][index];
180
                cardSummaryItem['unit'] = json['base_period_input']['units'][index];
181
                cardSummaryItem['subtotal'] = json['base_period_input']['subtotals'][index];
182
                cardSummaryItem['increment_rate'] = null;
183
                cardSummaryItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0;
184
                cardSummaryItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0;
185
                lastYearBarList.push(cardSummaryItem);
186
              });
187
188
              json['base_period_cost']['names'].forEach((currentValue, index) => {
189
                let cardSummaryItem = {};
190
                cardSummaryItem['name'] = json['base_period_cost']['names'][index];
191
                cardSummaryItem['unit'] = json['base_period_cost']['units'][index];
192
                cardSummaryItem['subtotal'] = json['base_period_cost']['subtotals'][index];
193
                cardSummaryItem['increment_rate'] = null;
194
                cardSummaryItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0;
195
                cardSummaryItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0;
196
                lastYearBarList.push(cardSummaryItem);
197
              });
198
              setLastYearBarList(lastYearBarList);
199
200
              let timeOfUseArray = [];
201
              json['reporting_period_input']['energy_category_ids'].forEach((currentValue, index) => {
202
                if (currentValue === 1) {
203
                  // energy_category_id 1 electricity
204
                  let timeOfUseItem = {};
205
                  timeOfUseItem['id'] = 1;
206
                  timeOfUseItem['name'] = t('Top-Peak');
207
                  timeOfUseItem['value'] = json['reporting_period_input']['toppeaks'][index];
208
                  timeOfUseItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16);
209
                  timeOfUseArray.push(timeOfUseItem);
210
211
                  timeOfUseItem = {};
212
                  timeOfUseItem['id'] = 2;
213
                  timeOfUseItem['name'] = t('On-Peak');
214
                  timeOfUseItem['value'] = json['reporting_period_input']['onpeaks'][index];
215
                  timeOfUseItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16);
216
                  timeOfUseArray.push(timeOfUseItem);
217
218
                  timeOfUseItem = {};
219
                  timeOfUseItem['id'] = 3;
220
                  timeOfUseItem['name'] = t('Mid-Peak');
221
                  timeOfUseItem['value'] = json['reporting_period_input']['midpeaks'][index];
222
                  timeOfUseItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16);
223
                  timeOfUseArray.push(timeOfUseItem);
224
225
                  timeOfUseItem = {};
226
                  timeOfUseItem['id'] = 4;
227
                  timeOfUseItem['name'] = t('Off-Peak');
228
                  timeOfUseItem['value'] = json['reporting_period_input']['offpeaks'][index];
229
                  timeOfUseItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16);
230
                  timeOfUseArray.push(timeOfUseItem);
231
232
                  timeOfUseItem = {};
233
                  timeOfUseItem['id'] = 5;
234
                  timeOfUseItem['name'] = t('Deep');
235
                  timeOfUseItem['value'] = json['reporting_period_input']['deeps'][index];
236
                  timeOfUseItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16);
237
                  timeOfUseArray.push(timeOfUseItem);
238
                }
239
              });
240
              setTimeOfUseShareData(timeOfUseArray);
241
              let totalInTCE = {};
242
              totalInTCE['value'] = json['reporting_period_input']['total_in_kgce'] / 1000; // convert from kg to t
243
              totalInTCE['increment_rate'] = parseFloat(json['reporting_period_input']['increment_rate_in_kgce'] * 100).toFixed(2) + '%';
244
              totalInTCE['value_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(totalInTCE['value'] / json['space']['area']).toFixed(3) : 0.0;
245
              totalInTCE['value_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(totalInTCE['value'] / json['space']['number_of_occupants']).toFixed(3) : 0.0;
246
              setTotalInTCE(totalInTCE);
247
248
              let costDataArray = [];
249
              json['reporting_period_cost']['names'].forEach((currentValue, index) => {
250
                let costDataItem = {};
251
                costDataItem['id'] = index;
252
                costDataItem['name'] = currentValue;
253
                costDataItem['value'] = json['reporting_period_cost']['subtotals'][index];
254
                costDataItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16);
255
                costDataArray.push(costDataItem);
256
              });
257
258
              setCostShareData(costDataArray);
259
              let totalInTCO2E = {};
260
              totalInTCO2E['value'] = json['reporting_period_input']['total_in_kgco2e'] / 1000; // convert from kg to t
261
              totalInTCO2E['increment_rate'] = parseFloat(json['reporting_period_input']['increment_rate_in_kgco2e'] * 100).toFixed(2) + '%';
262
              totalInTCO2E['value_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(totalInTCO2E['value'] / json['space']['area']).toFixed(3) : 0.0;
263
              totalInTCO2E['value_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(totalInTCO2E['value'] / json['space']['number_of_occupants']).toFixed(3) : 0.0;
264
              setTotalInTCO2E(totalInTCO2E);
265
266
              let TCEDataArray = [];
267
              json['reporting_period_input']['names'].forEach((currentValue, index) => {
268
                let TCEDataItem = {};
269
                TCEDataItem['id'] = index;
270
                TCEDataItem['name'] = currentValue;
271
                TCEDataItem['value'] = json['reporting_period_input']['subtotals_in_kgce'][index] / 1000;
272
                TCEDataItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16);
273
                TCEDataArray.push(TCEDataItem);
274
              });
275
              setTCEShareData(TCEDataArray);
276
277
              let TCO2EDataArray = [];
278
              json['reporting_period_input']['names'].forEach((currentValue, index) => {
279
                let TCO2EDataItem = {};
280
                TCO2EDataItem['id'] = index;
281
                TCO2EDataItem['name'] = currentValue;
282
                TCO2EDataItem['value'] = json['reporting_period_input']['subtotals_in_kgco2e'][index] / 1000; // convert from kg to t
283
                TCO2EDataItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16);
284
                TCO2EDataArray.push(TCO2EDataItem);
285
              });
286
              setTCO2EShareData(TCO2EDataArray);
287
288
              let timestamps = {};
289
              json['reporting_period_input']['timestamps'].forEach((currentValue, index) => {
290
                timestamps['a' + index] = currentValue;
291
              });
292
              setSpaceInputLineChartLabels(timestamps);
293
294
              let values = {};
295
              json['reporting_period_input']['values'].forEach((currentValue, index) => {
296
                values['a' + index] = currentValue;
297
              });
298
              setSpaceInputLineChartData(values);
299
300
              let names = [];
301
              let thisMonthInputArr = [];
302
              json['reporting_period_input']['names'].forEach((currentValue, index) => {
303
                let unit = json['reporting_period_input']['units'][index];
304
                let thisMonthItem = {};
305
                names.push({ value: 'a' + index, label: currentValue + ' (' + unit + ')' });
306
                thisMonthItem['name'] = json['reporting_period_input']['names'][index];
307
                thisMonthItem['unit'] = json['reporting_period_input']['units'][index];
308
                thisMonthItem['subtotal'] =
309
                  json['reporting_period_input']['values'][index][
310
                  json['reporting_period_input']['values'][index].length - 1
311
                  ];
312
                thisMonthItem['increment_rate'] =
313
                  parseFloat(json['reporting_period_input']['increment_rates'][index] * 100).toFixed(2) + '%';
314
                thisMonthItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0;
315
                thisMonthItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0;
316
                thisMonthInputArr.push(thisMonthItem);
317
              });
318
              setSpaceInputLineChartOptions(names);
319
              setThisMonthInputCardSummaryList(thisMonthInputArr);
320
321
              let thisMonthOutputArr = [];
322
              json['reporting_period_output']['names'].forEach((currentValue, index) => {
323
                let unit = json['reporting_period_output']['units'][index];
324
                let thisMonthItem = {};
325
                names.push({ value: 'a' + index, label: currentValue + ' (' + unit + ')' });
326
                thisMonthItem['name'] = json['reporting_period_output']['names'][index];
327
                thisMonthItem['unit'] = json['reporting_period_output']['units'][index];
328
                thisMonthItem['subtotal'] =
329
                  json['reporting_period_output']['values'][index][
330
                  json['reporting_period_output']['values'][index].length - 1
331
                  ];
332
                thisMonthItem['increment_rate'] = parseFloat(json['reporting_period_output']['increment_rates'][index] * 100).toFixed(2) + '%';
333
                thisMonthItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0;
334
                thisMonthItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0;
335
                thisMonthOutputArr.push(thisMonthItem);
336
              });
337
              setThisMonthOutputCardSummaryList(thisMonthOutputArr);
338
339
              timestamps = {};
340
              json['reporting_period_cost']['timestamps'].forEach((currentValue, index) => {
341
                timestamps['a' + index] = currentValue;
342
              });
343
              setSpaceCostLineChartLabels(timestamps);
344
345
              values = {};
346
              json['reporting_period_cost']['values'].forEach((currentValue, index) => {
347
                values['a' + index] = currentValue;
348
              });
349
              setSpaceCostLineChartData(values);
350
351
              names = [];
352
              let thisMonthCostArr = [];
353
              json['reporting_period_cost']['names'].forEach((currentValue, index) => {
354
                let thisMonthItem = {};
355
                let unit = json['reporting_period_cost']['units'][index];
356
                names.push({ value: 'a' + index, label: currentValue + ' (' + unit + ')' });
357
                thisMonthItem['name'] = json['reporting_period_cost']['names'][index];
358
                thisMonthItem['unit'] = json['reporting_period_cost']['units'][index];
359
                thisMonthItem['subtotal'] =
360
                  json['reporting_period_cost']['values'][index][
361
                  json['reporting_period_cost']['values'][index].length - 1
362
                  ];
363
                thisMonthItem['increment_rate'] =
364
                  parseFloat(json['reporting_period_cost']['increment_rates'][index] * 100).toFixed(2) + '%';
365
                thisMonthItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0;
366
                thisMonthItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0;
367
368
                thisMonthCostArr.push(thisMonthItem);
369
              });
370
              setSpaceCostLineChartOptions(names);
371
              setThisMonthCostCardSummaryList(thisMonthCostArr);
372
373
              let detailed_value_list = [];
374
              if (json['reporting_period_input']['timestamps'].length > 0) {
375
                json['reporting_period_input']['timestamps'][0].forEach((currentTimestamp, timestampIndex) => {
376
                  let detailed_value = {};
377
                  detailed_value['id'] = timestampIndex;
378
                  detailed_value['startdatetime'] = currentTimestamp;
379
                  json['reporting_period_input']['values'].forEach((currentValue, energyCategoryIndex) => {
380
                    detailed_value['a' + energyCategoryIndex] = json['reporting_period_input']['values'][
381
                      energyCategoryIndex
382
                    ][timestampIndex].toFixed(2);
383
                  });
384
                  detailed_value_list.push(detailed_value);
385
                });
386
              }
387
388
              let detailed_value = {};
389
              detailed_value['id'] = detailed_value_list.length;
390
              detailed_value['startdatetime'] = t('Subtotal');
391
              json['reporting_period_input']['subtotals'].forEach((currentValue, index) => {
392
                detailed_value['a' + index] = currentValue.toFixed(2);
393
              });
394
              detailed_value_list.push(detailed_value);
395
              setTimeout(() => {
396
                setDetailedDataTableData(detailed_value_list);
397
              }, 0);
398
399
              let detailed_column_list = [];
400
              detailed_column_list.push({
401
                dataField: 'startdatetime',
402
                text: t('Datetime'),
403
                sort: true
404
              });
405
              json['reporting_period_input']['names'].forEach((currentValue, index) => {
406
                let unit = json['reporting_period_cost']['units'][index];
407
                detailed_column_list.push({
408
                  dataField: 'a' + index,
409
                  text: currentValue + ' (' + unit + ')',
410
                  sort: true
411
                });
412
              });
413
              setDetailedDataTableColumns(detailed_column_list);
414
415
              let child_space_value_list = [];
416
              if (json['child_space_input']['child_space_names_array'].length > 0) {
417
                json['child_space_input']['child_space_names_array'][0].forEach((currentSpaceName, spaceIndex) => {
418
                  let child_space_value = {};
419
                  child_space_value['id'] = spaceIndex;
420
                  child_space_value['name'] = currentSpaceName;
421
                  json['child_space_input']['energy_category_names'].forEach((currentValue, energyCategoryIndex) => {
422
                    child_space_value['a' + energyCategoryIndex] =
423
                      json['child_space_input']['subtotals_array'][energyCategoryIndex][spaceIndex];
424
                    child_space_value['b' + energyCategoryIndex] =
425
                      json['child_space_cost']['subtotals_array'][energyCategoryIndex][spaceIndex];
426
                  });
427
                  child_space_value_list.push(child_space_value);
428
                });
429
              }
430
431
              setChildSpacesTableData(child_space_value_list);
432
433
              let child_space_column_list = [];
434
              child_space_column_list.push({
435
                dataField: 'name',
436
                text: t('Child Spaces'),
437
                sort: true
438
              });
439
              json['child_space_input']['energy_category_names'].forEach((currentValue, index) => {
440
                let unit = json['child_space_input']['units'][index];
441
                child_space_column_list.push({
442
                  dataField: 'a' + index,
443
                  text: t('CATEGORY Consumption UNIT', { CATEGORY: currentValue, UNIT: '(' + unit + ')' }),
444
                  sort: true,
445
                  formatter: function (decimalValue) {
446
                    if (typeof decimalValue === 'number') {
447
                      return decimalValue.toFixed(2);
448
                    } else {
449
                      return null;
450
                    }
451
                  }
452
                });
453
              });
454
              json['child_space_cost']['energy_category_names'].forEach((currentValue, index) => {
455
                let unit = json['child_space_cost']['units'][index];
456
                child_space_column_list.push({
457
                  dataField: 'b' + index,
458
                  text: t('CATEGORY Costs UNIT', { CATEGORY: currentValue, UNIT: '(' + unit + ')' }),
459
                  sort: true,
460
                  formatter: function (decimalValue) {
461
                    if (typeof decimalValue === 'number') {
462
                      return decimalValue.toFixed(2);
463
                    } else {
464
                      return null;
465
                    }
466
                  }
467
                });
468
              });
469
470
              setChildSpacesTableColumns(child_space_column_list);
471
              setChildSpacesInputData(json['child_space_input']);
472
              setChildSpacesCostData(json['child_space_cost']);
473
              setMonthLabels(json['reporting_period_cost']['timestamps'][0]);
474
              setSensor(json['sensor']);
475
              setPointList(json['point']);
476
            }
477
          });
478
      }
479
    }
480
  });
481
482
  useEffect(() => {
483
    let timer = setInterval(() => {
484
      let is_logged_in = getCookieValue('is_logged_in');
485
      if (is_logged_in === null || !is_logged_in) {
486
        setRedirectUrl(`/authentication/basic/login`);
487
        setRedirect(true);
488
      }
489
    }, 1000);
490
    return () => clearInterval(timer);
491
  }, [setRedirect, setRedirectUrl]);
492
493
  useEffect(() => {
494
    let is_logged_in = getCookieValue('is_logged_in');
495
    let user_name = getCookieValue('user_name');
496
    let user_display_name = getCookieValue('user_display_name');
497
    let user_uuid = getCookieValue('user_uuid');
498
    let token = getCookieValue('token');
499
    if (checkEmpty(is_logged_in) || checkEmpty(token) || checkEmpty(user_uuid) || !is_logged_in) {
500
      setRedirectUrl(`/authentication/basic/login`);
501
      setRedirect(true);
502
    } else {
503
      //update expires time of cookies
504
      createCookie('is_logged_in', true, settings.cookieExpireTime);
505
      createCookie('user_name', user_name, settings.cookieExpireTime);
506
      createCookie('user_display_name', user_display_name, settings.cookieExpireTime);
507
      createCookie('user_uuid', user_uuid, settings.cookieExpireTime);
508
      createCookie('token', token, settings.cookieExpireTime);
509
510
      let isResponseOK = false;
511
      fetch(APIBaseURL + '/spaces/tree', {
512
        method: 'GET',
513
        headers: {
514
          'Content-type': 'application/json',
515
          'User-UUID': getCookieValue('user_uuid'),
516
          Token: getCookieValue('token')
517
        },
518
        body: null
519
      })
520
        .then(response => {
521
          if (response.ok) {
522
            isResponseOK = true;
523
          }
524
          return response.json();
525
        })
526
        .then(json => {
527
          if (isResponseOK) {
528
            // rename keys
529
            json = JSON.parse(
530
              JSON.stringify([json])
531
                .split('"id":')
532
                .join('"value":')
533
                .split('"name":')
534
                .join('"label":')
535
            );
536
            // get chiildren of root Space
537
            let isResponseOK = false;
538
            fetch(APIBaseURL + '/spaces/' + [json[0]].map(o => o.value) + '/children', {
539
              method: 'GET',
540
              headers: {
541
                'Content-type': 'application/json',
542
                'User-UUID': getCookieValue('user_uuid'),
543
                Token: getCookieValue('token')
544
              },
545
              body: null
546
            })
547
              .then(response => {
548
                if (response.ok) {
549
                  isResponseOK = true;
550
                }
551
                return response.json();
552
              })
553
              .then(json => {
554
                if (isResponseOK) {
555
                  json = JSON.parse(
556
                    JSON.stringify([json])
557
                      .split('"id":')
558
                      .join('"value":')
559
                      .split('"name":')
560
                      .join('"label":')
561
                  );
562
                  setRootLongitude(json[0]['current']['longitude']);
563
                  setRootLatitude(json[0]['current']['latitude']);
564
                  let geojson = {};
565
                  geojson['type'] = 'FeatureCollection';
566
                  let geojsonData = [];
567
                  for (const childSpace of json[0]['children']) {
568
                    if (childSpace['latitude'] && childSpace['longitude']) {
569
                      geojsonData.push({
570
                        type: 'Feature',
571
                        geometry: {
572
                          type: 'Point',
573
                          coordinates: [childSpace['longitude'], childSpace['latitude']]
574
                        },
575
                        properties: {
576
                          title: childSpace['label'],
577
                          description: childSpace['description'],
578
                          uuid: childSpace['uuid'],
579
                          url: '/space/energycategory'
580
                        }
581
                      });
582
                    }
583
                  }
584
                  geojson['features'] = geojsonData;
585
                  setGeojson(geojson);
586
                } else {
587
                  toast.error(t(json.description));
588
                }
589
              })
590
              .catch(err => {
591
                console.log(err);
592
              });
593
            // end of get children of root Space
594
          } else {
595
            toast.error(t(json.description));
596
          }
597
        })
598
        .catch(err => {
599
          console.log(err);
600
        });
601
    }
602
  }, [setRedirect, setRedirectUrl, t]);
603
604
  return (
605
    <Fragment>
606
      <div className="card-deck">
607
        <Spinner color="primary" hidden={spinnerHidden} />
608
        {thisMonthInputCardSummaryList.map(cardSummaryItem => (
609
          <CardSummary
610
            key={uuid()}
611
            rate={cardSummaryItem['increment_rate']}
612
            title={t("This Month's Consumption CATEGORY VALUE UNIT", {
613
              CATEGORY: cardSummaryItem['name'],
614
              VALUE: null,
615
              UNIT: '(' + cardSummaryItem['unit'] + ')'
616
            })}
617
            color="success"
618
            footnote={t('Per Unit Area')}
619
            footvalue={cardSummaryItem['subtotal_per_unit_area']}
620
            footunit={'(' + cardSummaryItem['unit'] + '/m²)'}
621
            secondfootnote={t('Per Capita')}
622
            secondfootvalue={cardSummaryItem['subtotal_per_capita']}
623
            secondfootunit={'(' + cardSummaryItem['unit'] + ')'}
624
          >
625
            {cardSummaryItem['subtotal'] && (
626
              <CountUp
627
                end={cardSummaryItem['subtotal']}
628
                duration={2}
629
                prefix=""
630
                separator=","
631
                decimal="."
632
                decimals={0}
633
              />
634
            )}
635
          </CardSummary>
636
        ))}
637
        {thisMonthCostCardSummaryList.map(cardSummaryItem => (
638
          <CardSummary
639
            key={uuid()}
640
            rate={cardSummaryItem['increment_rate']}
641
            title={t("This Month's Costs CATEGORY VALUE UNIT", {
642
              CATEGORY: cardSummaryItem['name'],
643
              VALUE: null,
644
              UNIT: '(' + cardSummaryItem['unit'] + ')'
645
            })}
646
            color="success"
647
            footnote={t('Per Unit Area')}
648
            footvalue={cardSummaryItem['subtotal_per_unit_area']}
649
            footunit={'(' + cardSummaryItem['unit'] + '/m²)'}
650
            secondfootnote={t('Per Capita')}
651
            secondfootvalue={cardSummaryItem['subtotal_per_capita']}
652
            secondfootunit={'(' + cardSummaryItem['unit'] + ')'}
653
          >
654
            {cardSummaryItem['subtotal'] && (
655
              <CountUp
656
                end={cardSummaryItem['subtotal']}
657
                duration={2}
658
                prefix=""
659
                separator=","
660
                decimal="."
661
                decimals={0}
662
              />
663
            )}
664
          </CardSummary>
665
        ))}
666
        {thisMonthOutputCardSummaryList.map(cardSummaryItem => (
667
          <CardSummary
668
            key={uuid()}
669
            rate={cardSummaryItem['increment_rate']}
670
            title={t("This Month's Generation CATEGORY VALUE UNIT", {
671
              CATEGORY: cardSummaryItem['name'],
672
              VALUE: null,
673
              UNIT: '(' + cardSummaryItem['unit'] + ')'
674
            })}
675
            color="success"
676
            footnote={t('Per Unit Area')}
677
            footvalue={cardSummaryItem['subtotal_per_unit_area']}
678
            footunit={'(' + cardSummaryItem['unit'] + '/m²)'}
679
            secondfootnote={t('Per Capita')}
680
            secondfootvalue={cardSummaryItem['subtotal_per_capita']}
681
            secondfootunit={'(' + cardSummaryItem['unit'] + ')'}
682
          >
683
            {cardSummaryItem['subtotal'] && (
684
              <CountUp
685
                end={cardSummaryItem['subtotal']}
686
                duration={2}
687
                prefix=""
688
                separator=","
689
                decimal="."
690
                decimals={0}
691
              />
692
            )}
693
          </CardSummary>
694
        ))}
695
      </div>
696
      <div className="card-deck">
697
        {settings.showTCEData ? (
698
          <CardSummary
699
            rate={totalInTCE['increment_rate'] || ''}
700
            title={t("This Year's Consumption CATEGORY VALUE UNIT", {
701
              CATEGORY: t('Ton of Standard Coal'),
702
              UNIT: '(TCE)'
703
            })}
704
            color="warning"
705
            footnote={t('Per Unit Area')}
706
            footvalue={totalInTCE['value_per_unit_area']}
707
            footunit="(TCE/m²)"
708
            secondfootnote={t('Per Capita')}
709
            secondfootvalue={totalInTCE['value_per_capita']}
710
            secondfootunit="(TCE)"
711
          >
712
            {totalInTCE['value'] && (
713
              <CountUp end={totalInTCE['value']} duration={2} prefix="" separator="," decimal="." decimals={2} />
714
            )}
715
          </CardSummary>
716
        ) : (
717
          <></>
718
        )}
719
        <CardSummary
720
          rate={totalInTCO2E['increment_rate'] || ''}
721
          title={t("This Year's Consumption CATEGORY VALUE UNIT", {
722
            CATEGORY: t('Ton of Carbon Dioxide Emissions'),
723
            UNIT: '(TCO2E)'
724
          })}
725
          color="warning"
726
          footnote={t('Per Unit Area')}
727
          footvalue={totalInTCO2E['value_per_unit_area']}
728
          footunit="(TCO2E/m²)"
729
          secondfootnote={t('Per Capita')}
730
          secondfootvalue={totalInTCO2E['value_per_capita']}
731
          secondfootunit="(TCO2E)"
732
        >
733
          {totalInTCO2E['value'] && (
734
            <CountUp end={totalInTCO2E['value']} duration={2} prefix="" separator="," decimal="." decimals={2} />
735
          )}
736
        </CardSummary>
737
        <CardSummary
738
          rate={
739
            totalInTCE['value'] && totalInTCE['value'] !== 0 && totalInTCO2E['value'] && totalInTCO2E['increment_rate'] && totalInTCE['increment_rate']
740
              ? ((parseFloat(totalInTCO2E['increment_rate']) / parseFloat(totalInTCE['increment_rate'])).toFixed(2) + '%')
741
              : ''
742
          }
743
          title={t("This Year's Consumption CATEGORY VALUE UNIT", {
744
            CATEGORY: t('Carbon Emissions Per Unit Of Energy Consumption'),
745
            UNIT: '(TCO2E/TCE)'
746
          })}
747
          color="warning"
748
          footnote={t('Per Unit Area')}
749
          footvalue={
750
            totalInTCE['value_per_unit_area'] && totalInTCE['value_per_unit_area'] !== 0 && totalInTCO2E['value_per_unit_area']
751
              ? (totalInTCO2E['value_per_unit_area'] / totalInTCE['value_per_unit_area']).toFixed(3)
752
              : '--'
753
          }
754
          footunit={t('(TCO2E/TCE/m²)')}
755
          secondfootnote={t('Per Capita')}
756
          secondfootvalue={
757
            totalInTCE['value_per_capita'] && totalInTCE['value_per_capita'] !== 0 && totalInTCO2E['value_per_capita']
758
              ? (totalInTCO2E['value_per_capita'] / totalInTCE['value_per_capita']).toFixed(3)
759
              : '--'
760
          }
761
          secondfootunit={t('(TCO2E/TCE)')}
762
        >
763
          {totalInTCE['value'] && totalInTCE['value'] !== 0 && totalInTCO2E['value'] ? (
764
            <CountUp
765
              end={totalInTCO2E['value'] / totalInTCE['value']}
766
              duration={2}
767
              prefix=""
768
              separator=","
769
              decimal="."
770
              decimals={3}
771
            />
772
          ) : (
773
            '--'
774
          )}
775
        </CardSummary>
776
      </div>
777
      <div className="card-deck">
778
        <BarChart
779
          labels={barLabels}
780
          data={lastYearBarList}
781
          compareData={thisYearBarList}
782
          title={t('The Same Period Last Year')}
783
          compareTitle={t('This Year')}
784
          footnote={t('Per Unit Area')}
785
          footunit={'/m²'}
786
        />
787
        <LineChart
788
          reportingTitle={t("This Year's Consumption CATEGORY VALUE UNIT", { CATEGORY: null, VALUE: null, UNIT: null })}
789
          baseTitle=""
790
          labels={spaceInputLineChartLabels}
791
          data={spaceInputLineChartData}
792
          options={spaceInputLineChartOptions}
793
        />
794
        <LineChart
795
          reportingTitle={t("This Year's Costs CATEGORY VALUE UNIT", { CATEGORY: null, VALUE: null, UNIT: null })}
796
          baseTitle=""
797
          labels={spaceCostLineChartLabels}
798
          data={spaceCostLineChartData}
799
          options={spaceCostLineChartOptions}
800
        />
801
      </div>
802
      <div className="wrapper" />
803
      <div className="card-deck">
804
        {settings.showOnlineMap ? (
805
          <div className="mb-3 card" style={{ height: '400px' }}>
806
            <CustomizeMapBox Latitude={rootLatitude} Longitude={rootLongitude} Zoom={10} Geojson={geojson['features']} />
807
          </div>
808
        ) : (
809
          <></>
810
        )}
811
        {Object.keys(sensor).map(item => (
812
          <RealtimeSensor key={uuid()} sensor={sensor[item]} pointList={pointList} />
813
        ))}
814
      </div>
815
      <Row noGutters>
816
        <Col className="mb-3 pr-lg-2 mb-3">
817
          <SharePie data={timeOfUseShareData} title={t('Electricity Consumption by Time-Of-Use')} />
818
        </Col>
819
        <Col className="mb-3 pr-lg-2 mb-3">
820
          <SharePie data={costShareData} title={t('Costs by Energy Category')} />
821
        </Col>
822
823
        {settings.showTCEData ? (
824
          <Col className="mb-3 pr-lg-2 mb-3">
825
            <SharePie data={TCEShareData} title={t('Ton of Standard Coal by Energy Category')} />
826
          </Col>
827
        ) : (
828
          <></>
829
        )}
830
831
        <Col className="mb-3 pr-lg-2 mb-3">
832
          <SharePie data={TCO2EShareData} title={t('Ton of Carbon Dioxide Emissions by Energy Category')} />
833
        </Col>
834
      </Row>
835
      <ChartSpacesStackBar
836
        title={t('Child Spaces Data')}
837
        labels={monthLabels}
838
        inputData={childSpacesInputData}
839
        costData={childSpacesCostData}
840
        childSpaces={spaceInputLineChartOptions}
841
      />
842
    </Fragment>
843
  );
844
};
845
846
export default withTranslation()(withRedirect(Dashboard));
847