Passed
Push — master ( 4f3f28...c5d2bd )
by Guangyu
04:38 queued 11s
created

src/components/MyEMS/dashboard/Dashboard.js   A

Complexity

Total Complexity 8
Complexity/F 0

Size

Lines of Code 439
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 8
eloc 393
mnd 8
bc 8
fnc 0
dl 0
loc 439
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import React, { Fragment, useEffect, useState } from 'react';
2
import CountUp from 'react-countup';
3
import { Col, Row } 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 } from '../../../helpers/utils';
10
import withRedirect from '../../../hoc/withRedirect';
11
import { withTranslation } from 'react-i18next';
12
import moment from 'moment';
13
import { APIBaseURL } from '../../../config';
14
import uuid from 'uuid/v1';
15
16
const ChildSpacesTable = loadable(() => import('../common/ChildSpacesTable'));
17
18
const Dashboard = ({ setRedirect, setRedirectUrl, t }) => {
19
  let current_moment = moment();
20
  const [fetchSuccess, setFetchSuccess] = useState(false);
21
  const [periodType, setPeriodType] = useState('daily');
22
  const [basePeriodBeginsDatetime, setBasePeriodBeginsDatetime] = useState(current_moment.clone().subtract(1, 'months').startOf('month'));
23
  const [basePeriodEndsDatetime, setBasePeriodEndsDatetime] = useState(current_moment.clone().subtract(1, 'months'));
24
  const [reportingPeriodBeginsDatetime, setReportingPeriodBeginsDatetime] = useState(current_moment.clone().startOf('month'));
25
  const [reportingPeriodEndsDatetime, setReportingPeriodEndsDatetime] = useState(current_moment);
26
  //Results
27
  const [costShareData, setCostShareData] = useState([]);
28
  const [timeOfUseShareData, setTimeOfUseShareData] = useState([]);
29
  const [TCEShareData, setTCEShareData] = useState([]);
30
  const [TCO2EShareData, setTCO2EShareData] = useState([]);
31
32
  const [inputCardSummaryList, setInputCardSummaryList] = useState([]);
33
  const [costCardSummaryList, setCostCardSummaryList] = useState([]);
34
  const [totalInTCE, setTotalInTCE] = useState({});
35
  const [totalInTCO2E, setTotalInTCO2E] = useState({});
36
37
  const [spaceInputLineChartLabels, setSpaceInputLineChartLabels] = useState([]);
38
  const [spaceInputLineChartData, setSpaceInputLineChartData] = useState({});
39
  const [spaceInputLineChartOptions, setSpaceInputLineChartOptions] = useState([]);
40
  const [spaceCostLineChartLabels, setSpaceCostLineChartLabels] = useState([]);
41
  const [spaceCostLineChartData, setSpaceCostLineChartData] = useState({});
42
  const [spaceCostLineChartOptions, setSpaceCostLineChartOptions] = useState([]);
43
  
44
  const [parameterLineChartLabels, setParameterLineChartLabels] = useState([]);
45
  const [parameterLineChartData, setParameterLineChartData] = useState({});
46
  const [parameterLineChartOptions, setParameterLineChartOptions] = useState([]);
47
  
48
  const [detailedDataTableData, setDetailedDataTableData] = useState([]);
49
  const [detailedDataTableColumns, setDetailedDataTableColumns] = useState([{dataField: 'startdatetime', text: t('Datetime'), sort: true}]);
50
  
51
  const [childSpacesTableData, setChildSpacesTableData] = useState([]);
52
  const [childSpacesTableColumns, setChildSpacesTableColumns] = useState([{dataField: 'name', text: t('Child Spaces'), sort: true }]);
53
  
54
55
  useEffect(() => {
56
    let is_logged_in = getCookieValue('is_logged_in');
57
    let user_name = getCookieValue('user_name');
58
    let user_display_name = getCookieValue('user_display_name');
59
    let user_uuid = getCookieValue('user_uuid');
60
    let token = getCookieValue('token');
61
    console.log(is_logged_in);
62
    if (is_logged_in === null || !is_logged_in) {
63
      setRedirectUrl(`/authentication/basic/login`);
64
      setRedirect(true);
65
    } else {
66
      //update expires time of cookies
67
      createCookie('is_logged_in', true, 1000 * 60 * 60 * 8);
68
      createCookie('user_name', user_name, 1000 * 60 * 60 * 8);
69
      createCookie('user_display_name', user_display_name, 1000 * 60 * 60 * 8);
70
      createCookie('user_uuid', user_uuid, 1000 * 60 * 60 * 8);
71
      createCookie('token', token, 1000 * 60 * 60 * 8);
72
73
    let isResponseOK = false;
74
    if (!fetchSuccess) { 
75
      toast(
76
        <Fragment>
77
          {t("Welcome to MyEMS")}!<br />
78
          {t("An Industry Leading Open Source Energy Management System")}
79
        </Fragment>
80
      );
81
     
82
      fetch(APIBaseURL + '/reports/dashboard?' +
83
        'useruuid=' + user_uuid +
84
        '&periodtype=' + periodType +
85
        '&baseperiodstartdatetime=' + (basePeriodBeginsDatetime != null ? basePeriodBeginsDatetime.format('YYYY-MM-DDTHH:mm:ss') : '') +
86
        '&baseperiodenddatetime=' + (basePeriodEndsDatetime != null ? basePeriodEndsDatetime.format('YYYY-MM-DDTHH:mm:ss') : '') +
87
        '&reportingperiodstartdatetime=' + reportingPeriodBeginsDatetime.format('YYYY-MM-DDTHH:mm:ss') +
88
        '&reportingperiodenddatetime=' + reportingPeriodEndsDatetime.format('YYYY-MM-DDTHH:mm:ss'), {
89
        method: 'GET',
90
        headers: {
91
          "Content-type": "application/json",
92
          "User-UUID": getCookieValue('user_uuid'),
93
          "Token": getCookieValue('token')
94
        },
95
        body: null,
96
97
      }).then(response => {
98
        if (response.ok) {
99
          isResponseOK = true;
100
        }
101
        return response.json();
102
      }).then(json => {
103
        if (isResponseOK) {
104
          console.log(json);
105
          setFetchSuccess(true);
106
          let inputCardSummaryArray = []
107
          json['reporting_period_input']['names'].forEach((currentValue, index) => {
108
            let cardSummaryItem = {}
109
            cardSummaryItem['name'] = json['reporting_period_input']['names'][index];
110
            cardSummaryItem['unit'] = json['reporting_period_input']['units'][index];
111
            cardSummaryItem['subtotal'] = json['reporting_period_input']['subtotals'][index];
112
            cardSummaryItem['increment_rate'] = parseFloat(json['reporting_period_input']['increment_rates'][index] * 100).toFixed(2) + "%";
113
            cardSummaryItem['subtotal_per_unit_area'] = json['reporting_period_input']['subtotals_per_unit_area'][index];
114
            inputCardSummaryArray.push(cardSummaryItem);
115
          });
116
          setInputCardSummaryList(inputCardSummaryArray);
117
118
          let costCardSummaryArray = []
119
          json['reporting_period_cost']['names'].forEach((currentValue, index) => {
120
            let cardSummaryItem = {}
121
            cardSummaryItem['name'] = json['reporting_period_cost']['names'][index];
122
            cardSummaryItem['unit'] = json['reporting_period_cost']['units'][index];
123
            cardSummaryItem['subtotal'] = json['reporting_period_cost']['subtotals'][index];
124
            cardSummaryItem['increment_rate'] = parseFloat(json['reporting_period_cost']['increment_rates'][index] * 100).toFixed(2) + "%";
125
            cardSummaryItem['subtotal_per_unit_area'] = json['reporting_period_cost']['subtotals_per_unit_area'][index];
126
            costCardSummaryArray.push(cardSummaryItem);
127
          });
128
          setCostCardSummaryList(costCardSummaryArray);
129
130
          let timeOfUseArray = [];
131
          json['reporting_period_input']['energy_category_ids'].forEach((currentValue, index) => {
132
            if(currentValue == 1) {
133
              // energy_category_id 1 electricity
134
              let timeOfUseItem = {}
135
              timeOfUseItem['id'] = 1;
136
              timeOfUseItem['name'] =  t('Top-Peak');
137
              timeOfUseItem['value'] = json['reporting_period_input']['toppeaks'][index];
138
              timeOfUseItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
139
              timeOfUseArray.push(timeOfUseItem);
140
              
141
              timeOfUseItem = {}
142
              timeOfUseItem['id'] = 2;
143
              timeOfUseItem['name'] =  t('On-Peak');
144
              timeOfUseItem['value'] = json['reporting_period_input']['onpeaks'][index];
145
              timeOfUseItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
146
              timeOfUseArray.push(timeOfUseItem);
147
148
              timeOfUseItem = {}
149
              timeOfUseItem['id'] = 3;
150
              timeOfUseItem['name'] =  t('Mid-Peak');
151
              timeOfUseItem['value'] = json['reporting_period_input']['midpeaks'][index];
152
              timeOfUseItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
153
              timeOfUseArray.push(timeOfUseItem);
154
155
              timeOfUseItem = {}
156
              timeOfUseItem['id'] = 4;
157
              timeOfUseItem['name'] =  t('Off-Peak');
158
              timeOfUseItem['value'] = json['reporting_period_input']['offpeaks'][index];
159
              timeOfUseItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
160
              timeOfUseArray.push(timeOfUseItem);
161
            }
162
          });
163
          setTimeOfUseShareData(timeOfUseArray);
164
          let totalInTCE = {}; 
165
          totalInTCE['value'] = json['reporting_period_input']['total_in_kgce'] / 1000; // convert from kg to t
166
          totalInTCE['increment_rate'] = parseFloat(json['reporting_period_input']['increment_rate_in_kgce'] * 100).toFixed(2) + "%";
167
          totalInTCE['value_per_unit_area'] = json['reporting_period_input']['total_in_kgce_per_unit_area'] / 1000; // convert from kg to t
168
          setTotalInTCE(totalInTCE);
169
170
          let costDataArray = [];
171
          json['reporting_period_cost']['names'].forEach((currentValue, index) => {
172
            let costDataItem = {}
173
            costDataItem['id'] = index;
174
            costDataItem['name'] = currentValue;
175
            costDataItem['value'] = json['reporting_period_cost']['subtotals'][index];
176
            costDataItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
177
            costDataArray.push(costDataItem);
178
          });
179
180
          setCostShareData(costDataArray);
181
          let totalInTCO2E = {}; 
182
          totalInTCO2E['value'] = json['reporting_period_input']['total_in_kgco2e'] / 1000; // convert from kg to t
183
          totalInTCO2E['increment_rate'] = parseFloat(json['reporting_period_input']['increment_rate_in_kgco2e'] * 100).toFixed(2) + "%";
184
          totalInTCO2E['value_per_unit_area'] = json['reporting_period_input']['total_in_kgco2e_per_unit_area'] / 1000; // convert from kg to t
185
          setTotalInTCO2E(totalInTCO2E);
186
187
          let TCEDataArray = [];
188
          json['reporting_period_input']['names'].forEach((currentValue, index) => {
189
            let TCEDataItem = {}
190
            TCEDataItem['id'] = index;
191
            TCEDataItem['name'] = currentValue;
192
            TCEDataItem['value'] = json['reporting_period_input']['subtotals_in_kgce'][index] / 1000;
193
            TCEDataItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
194
            TCEDataArray.push(TCEDataItem);
195
          });
196
          setTCEShareData(TCEDataArray);
197
198
          let TCO2EDataArray = [];
199
          json['reporting_period_input']['names'].forEach((currentValue, index) => {
200
            let TCO2EDataItem = {}
201
            TCO2EDataItem['id'] = index;
202
            TCO2EDataItem['name'] = currentValue;
203
            TCO2EDataItem['value'] = json['reporting_period_input']['subtotals_in_kgco2e'][index] / 1000; // convert from kg to t
204
            TCO2EDataItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
205
            TCO2EDataArray.push(TCO2EDataItem);
206
          });
207
          setTCO2EShareData(TCO2EDataArray);
208
209
          let timestamps = {}
210
          json['reporting_period_input']['timestamps'].forEach((currentValue, index) => {
211
            timestamps['a' + index] = currentValue;
212
          });
213
          setSpaceInputLineChartLabels(timestamps);
214
          
215
          let values = {}
216
          json['reporting_period_input']['values'].forEach((currentValue, index) => {
217
            values['a' + index] = currentValue;
218
          });
219
          setSpaceInputLineChartData(values);
220
          
221
          let names = Array();
222
          json['reporting_period_input']['names'].forEach((currentValue, index) => {
223
            let unit = json['reporting_period_input']['units'][index];
224
            names.push({ 'value': 'a' + index, 'label': currentValue + ' (' + unit + ')'});
225
          });
226
          setSpaceInputLineChartOptions(names);
227
228
          timestamps = {}
229
          json['reporting_period_cost']['timestamps'].forEach((currentValue, index) => {
230
            timestamps['a' + index] = currentValue;
231
          });
232
          setSpaceCostLineChartLabels(timestamps);
233
          
234
          values = {}
235
          json['reporting_period_cost']['values'].forEach((currentValue, index) => {
236
            values['a' + index] = currentValue;
237
          });
238
          setSpaceCostLineChartData(values);
239
          
240
          names = Array();
241
          json['reporting_period_cost']['names'].forEach((currentValue, index) => {
242
            let unit = json['reporting_period_cost']['units'][index];
243
            names.push({ 'value': 'a' + index, 'label': currentValue + ' (' + unit + ')'});
244
          });
245
          setSpaceCostLineChartOptions(names);
246
247
          timestamps = {}
248
          json['parameters']['timestamps'].forEach((currentValue, index) => {
249
            timestamps['a' + index] = currentValue;
250
          });
251
          setParameterLineChartLabels(timestamps);
252
253
          values = {}
254
          json['parameters']['values'].forEach((currentValue, index) => {
255
            values['a' + index] = currentValue;
256
          });
257
          setParameterLineChartData(values);
258
        
259
          names = Array();
260
          json['parameters']['names'].forEach((currentValue, index) => {
261
            if (currentValue.startsWith('TARIFF-')) {
262
              currentValue = t('Tariff') + currentValue.replace('TARIFF-', '-');
263
            }
264
            
265
            names.push({ 'value': 'a' + index, 'label': currentValue });
266
          });
267
          setParameterLineChartOptions(names);
268
          
269
          let detailed_value_list = [];
270
          json['reporting_period_input']['timestamps'][0].forEach((currentTimestamp, timestampIndex) => {
271
            let detailed_value = {};
272
            detailed_value['id'] = timestampIndex;
273
            detailed_value['startdatetime'] = currentTimestamp;
274
            json['reporting_period_input']['values'].forEach((currentValue, energyCategoryIndex) => {
275
              detailed_value['a' + energyCategoryIndex] = json['reporting_period_input']['values'][energyCategoryIndex][timestampIndex].toFixed(2);
276
            });
277
            detailed_value_list.push(detailed_value);
278
          });
279
280
          let detailed_value = {};
281
          detailed_value['id'] = detailed_value_list.length;
282
          detailed_value['startdatetime'] = t('Subtotal');
283
          json['reporting_period_input']['subtotals'].forEach((currentValue, index) => {
284
              detailed_value['a' + index] = currentValue.toFixed(2);
285
            });
286
          detailed_value_list.push(detailed_value);
287
          setDetailedDataTableData(detailed_value_list);
288
          
289
          let detailed_column_list = [];
290
          detailed_column_list.push({
291
            dataField: 'startdatetime',
292
            text: t('Datetime'),
293
            sort: true
294
          })
295
          json['reporting_period_input']['names'].forEach((currentValue, index) => {
296
            let unit = json['reporting_period_input']['units'][index];
297
            detailed_column_list.push({
298
              dataField: 'a' + index,
299
              text: currentValue + ' (' + unit + ')',
300
              sort: true
301
            })
302
          });
303
          setDetailedDataTableColumns(detailed_column_list);
304
305
          let child_space_value_list = [];
306
          json['child_space_input']['child_space_names_array'][0].forEach((currentSpaceName, spaceIndex) => {
307
            let child_space_value = {};
308
            child_space_value['id'] = spaceIndex;
309
            child_space_value['name'] = currentSpaceName;
310
            json['child_space_input']['energy_category_names'].forEach((currentValue, energyCategoryIndex) => {
311
              child_space_value['a' + energyCategoryIndex] = json['child_space_input']['subtotals_array'][energyCategoryIndex][spaceIndex].toFixed(2);
312
              child_space_value['b' + energyCategoryIndex] = json['child_space_cost']['subtotals_array'][energyCategoryIndex][spaceIndex].toFixed(2);
313
            });
314
            child_space_value_list.push(child_space_value);
315
          });
316
317
          setChildSpacesTableData(child_space_value_list);
318
319
          let child_space_column_list = [];
320
          child_space_column_list.push({
321
            dataField: 'name',
322
            text: t('Child Spaces'),
323
            sort: true
324
          });
325
          json['child_space_input']['energy_category_names'].forEach((currentValue, index) => {
326
            let unit = json['child_space_input']['units'][index];
327
            child_space_column_list.push({
328
              dataField: 'a' + index,
329
              text: currentValue + ' (' + unit + ')',
330
              sort: true
331
            });
332
          });
333
          json['child_space_cost']['energy_category_names'].forEach((currentValue, index) => {
334
            let unit = json['child_space_cost']['units'][index];
335
            child_space_column_list.push({
336
              dataField: 'b' + index,
337
              text: currentValue + ' (' + unit + ')',
338
              sort: true
339
            });
340
          });
341
342
          setChildSpacesTableColumns(child_space_column_list);
343
        }
344
      });
345
    };
346
347
  };
348
  }, );
349
  
350
351
  return (
352
    <Fragment>
353
      <div className="card-deck">
354
      {inputCardSummaryList.map(cardSummaryItem => (
355
          <CardSummary key={uuid()}
356
            rate={cardSummaryItem['increment_rate']}
357
            title={t("This Month's Consumption CATEGORY VALUE UNIT", { 'CATEGORY': cardSummaryItem['name'], 'VALUE': null, 'UNIT': '(' + cardSummaryItem['unit'] + ')' })}
358
            color="success" 
359
            footnote={t('Per Unit Area')} 
360
            footvalue={cardSummaryItem['subtotal_per_unit_area']}
361
            footunit={"(" + cardSummaryItem['unit'] + "/M²)"} >
362
            {cardSummaryItem['subtotal'] && <CountUp end={cardSummaryItem['subtotal']} duration={2} prefix="" separator="," decimal="." decimals={2} />}
363
          </CardSummary>
364
        ))}
365
        {costCardSummaryList.map(cardSummaryItem => (
366
          <CardSummary key={uuid()}
367
            rate={cardSummaryItem['increment_rate']}
368
            title={t("This Month's Costs CATEGORY VALUE UNIT", { 'CATEGORY': cardSummaryItem['name'], 'VALUE': null, 'UNIT': '(' + cardSummaryItem['unit'] + ')' })}
369
            color="success" 
370
            footnote={t('Per Unit Area')} 
371
            footvalue={cardSummaryItem['subtotal_per_unit_area']}
372
            footunit={"(" + cardSummaryItem['unit'] + "/M²)"} >
373
            {cardSummaryItem['subtotal'] && <CountUp end={cardSummaryItem['subtotal']} duration={2} prefix="" separator="," decimal="." decimals={2} />}
374
          </CardSummary>
375
        ))}
376
        <CardSummary 
377
          rate={totalInTCE['increment_rate'] || ''} 
378
          title={t("This Month's Consumption CATEGORY VALUE UNIT", { 'CATEGORY': t('Ton of Standard Coal'), 'UNIT': '(TCE)' })}
379
          color="warning" 
380
          footnote={t('Per Unit Area')} 
381
          footvalue={totalInTCE['value_per_unit_area']} 
382
          footunit="(TCE/M²)">
383
          {totalInTCE['value'] && <CountUp end={totalInTCE['value']} duration={2} prefix="" separator="," decimal="." decimals={2} />}
384
        </CardSummary>
385
        <CardSummary 
386
          rate={totalInTCO2E['increment_rate'] || ''} 
387
          title={t("This Month's Consumption CATEGORY VALUE UNIT", { 'CATEGORY': t('Ton of Carbon Dioxide Emissions'), 'UNIT': '(TCO2E)' })}
388
          color="warning" 
389
          footnote={t('Per Unit Area')} 
390
          footvalue={totalInTCO2E['value_per_unit_area']} 
391
          footunit="(TCO2E/M²)">
392
          {totalInTCO2E['value'] && <CountUp end={totalInTCO2E['value']} duration={2} prefix="" separator="," decimal="." decimals={2} />}
393
        </CardSummary>
394
      </div>
395
      <Row noGutters>
396
        <Col className="mb-3 pr-lg-2 mb-3">
397
          <SharePie data={timeOfUseShareData} title={t('Electricity Consumption by Time-Of-Use')} />
398
        </Col>
399
        <Col className="mb-3 pr-lg-2 mb-3">
400
          <SharePie data={costShareData} title={t('Costs by Energy Category')} />
401
        </Col>
402
        <Col className="mb-3 pr-lg-2 mb-3">
403
          <SharePie data={TCEShareData} title={t('Ton of Standard Coal by Energy Category')} />
404
        </Col>
405
        <Col className="mb-3 pr-lg-2 mb-3">
406
          <SharePie data={TCO2EShareData} title={t('Carbon Dioxide Emissions by Energy Category')} />
407
        </Col>
408
      </Row>
409
      <LineChart reportingTitle={t("This Month's Consumption CATEGORY VALUE UNIT", { 'CATEGORY': null, 'VALUE': null, 'UNIT': null })}
410
        baseTitle=''
411
        labels={spaceInputLineChartLabels}
412
        data={spaceInputLineChartData}
413
        options={spaceInputLineChartOptions}>
414
      </LineChart>
415
      <LineChart reportingTitle={t("This Month's Costs CATEGORY VALUE UNIT", { 'CATEGORY': null, 'VALUE': null, 'UNIT': null })}
416
        baseTitle=''
417
        labels={spaceCostLineChartLabels}
418
        data={spaceCostLineChartData}
419
        options={spaceCostLineChartOptions}>
420
      </LineChart>
421
422
      <LineChart reportingTitle={t('Related Parameters')}
423
        baseTitle=''
424
        labels={parameterLineChartLabels}
425
        data={parameterLineChartData}
426
        options={parameterLineChartOptions}>
427
      </LineChart>
428
429
      <ChildSpacesTable data={childSpacesTableData}
430
        title={t('Child Spaces Data of This Month')}
431
        columns={childSpacesTableColumns}>
432
      </ChildSpacesTable>
433
434
    </Fragment>
435
  );
436
};
437
438
export default withTranslation()(withRedirect(Dashboard));
439