Passed
Push — master ( b2b1e2...669be3 )
by Guangyu
13:22 queued 10s
created

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

Complexity

Total Complexity 10
Complexity/F 0

Size

Lines of Code 443
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 10
eloc 395
mnd 10
bc 10
fnc 0
dl 0
loc 443
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
            if (json['reporting_period_input']['timestamps'].length > 0 ) {
271
              json['reporting_period_input']['timestamps'][0].forEach((currentTimestamp, timestampIndex) => {
272
                let detailed_value = {};
273
                detailed_value['id'] = timestampIndex;
274
                detailed_value['startdatetime'] = currentTimestamp;
275
                json['reporting_period_input']['values'].forEach((currentValue, energyCategoryIndex) => {
276
                  detailed_value['a' + energyCategoryIndex] = json['reporting_period_input']['values'][energyCategoryIndex][timestampIndex].toFixed(2);
277
                });
278
                detailed_value_list.push(detailed_value);
279
              });
280
            }
281
282
            let detailed_value = {};
283
            detailed_value['id'] = detailed_value_list.length;
284
            detailed_value['startdatetime'] = t('Subtotal');
285
            json['reporting_period_input']['subtotals'].forEach((currentValue, index) => {
286
                detailed_value['a' + index] = currentValue.toFixed(2);
287
              });
288
            detailed_value_list.push(detailed_value);
289
            setDetailedDataTableData(detailed_value_list);
290
            
291
            let detailed_column_list = [];
292
            detailed_column_list.push({
293
              dataField: 'startdatetime',
294
              text: t('Datetime'),
295
              sort: true
296
            })
297
            json['reporting_period_input']['names'].forEach((currentValue, index) => {
298
              let unit = json['reporting_period_input']['units'][index];
299
              detailed_column_list.push({
300
                dataField: 'a' + index,
301
                text: currentValue + ' (' + unit + ')',
302
                sort: true
303
              })
304
            });
305
            setDetailedDataTableColumns(detailed_column_list);
306
307
            let child_space_value_list = [];
308
            if (json['child_space_input']['child_space_names_array'].length > 0) {
309
              json['child_space_input']['child_space_names_array'][0].forEach((currentSpaceName, spaceIndex) => {
310
                let child_space_value = {};
311
                child_space_value['id'] = spaceIndex;
312
                child_space_value['name'] = currentSpaceName;
313
                json['child_space_input']['energy_category_names'].forEach((currentValue, energyCategoryIndex) => {
314
                  child_space_value['a' + energyCategoryIndex] = json['child_space_input']['subtotals_array'][energyCategoryIndex][spaceIndex].toFixed(2);
315
                  child_space_value['b' + energyCategoryIndex] = json['child_space_cost']['subtotals_array'][energyCategoryIndex][spaceIndex].toFixed(2);
316
                });
317
                child_space_value_list.push(child_space_value);
318
              });
319
            }
320
321
            setChildSpacesTableData(child_space_value_list);
322
323
            let child_space_column_list = [];
324
            child_space_column_list.push({
325
              dataField: 'name',
326
              text: t('Child Spaces'),
327
              sort: true
328
            });
329
            json['child_space_input']['energy_category_names'].forEach((currentValue, index) => {
330
              let unit = json['child_space_input']['units'][index];
331
              child_space_column_list.push({
332
                dataField: 'a' + index,
333
                text: currentValue + ' (' + unit + ')',
334
                sort: true
335
              });
336
            });
337
            json['child_space_cost']['energy_category_names'].forEach((currentValue, index) => {
338
              let unit = json['child_space_cost']['units'][index];
339
              child_space_column_list.push({
340
                dataField: 'b' + index,
341
                text: currentValue + ' (' + unit + ')',
342
                sort: true
343
              });
344
            });
345
346
            setChildSpacesTableColumns(child_space_column_list);
347
          }
348
        });
349
      };
350
351
    };
352
  }, );
353
  
354
355
  return (
356
    <Fragment>
357
      <div className="card-deck">
358
      {inputCardSummaryList.map(cardSummaryItem => (
359
          <CardSummary key={uuid()}
360
            rate={cardSummaryItem['increment_rate']}
361
            title={t("This Month's Consumption CATEGORY VALUE UNIT", { 'CATEGORY': cardSummaryItem['name'], 'VALUE': null, 'UNIT': '(' + cardSummaryItem['unit'] + ')' })}
362
            color="success" 
363
            footnote={t('Per Unit Area')} 
364
            footvalue={cardSummaryItem['subtotal_per_unit_area']}
365
            footunit={"(" + cardSummaryItem['unit'] + "/M²)"} >
366
            {cardSummaryItem['subtotal'] && <CountUp end={cardSummaryItem['subtotal']} duration={2} prefix="" separator="," decimal="." decimals={2} />}
367
          </CardSummary>
368
        ))}
369
        {costCardSummaryList.map(cardSummaryItem => (
370
          <CardSummary key={uuid()}
371
            rate={cardSummaryItem['increment_rate']}
372
            title={t("This Month's Costs CATEGORY VALUE UNIT", { 'CATEGORY': cardSummaryItem['name'], 'VALUE': null, 'UNIT': '(' + cardSummaryItem['unit'] + ')' })}
373
            color="success" 
374
            footnote={t('Per Unit Area')} 
375
            footvalue={cardSummaryItem['subtotal_per_unit_area']}
376
            footunit={"(" + cardSummaryItem['unit'] + "/M²)"} >
377
            {cardSummaryItem['subtotal'] && <CountUp end={cardSummaryItem['subtotal']} duration={2} prefix="" separator="," decimal="." decimals={2} />}
378
          </CardSummary>
379
        ))}
380
        <CardSummary 
381
          rate={totalInTCE['increment_rate'] || ''} 
382
          title={t("This Month's Consumption CATEGORY VALUE UNIT", { 'CATEGORY': t('Ton of Standard Coal'), 'UNIT': '(TCE)' })}
383
          color="warning" 
384
          footnote={t('Per Unit Area')} 
385
          footvalue={totalInTCE['value_per_unit_area']} 
386
          footunit="(TCE/M²)">
387
          {totalInTCE['value'] && <CountUp end={totalInTCE['value']} duration={2} prefix="" separator="," decimal="." decimals={2} />}
388
        </CardSummary>
389
        <CardSummary 
390
          rate={totalInTCO2E['increment_rate'] || ''} 
391
          title={t("This Month's Consumption CATEGORY VALUE UNIT", { 'CATEGORY': t('Ton of Carbon Dioxide Emissions'), 'UNIT': '(TCO2E)' })}
392
          color="warning" 
393
          footnote={t('Per Unit Area')} 
394
          footvalue={totalInTCO2E['value_per_unit_area']} 
395
          footunit="(TCO2E/M²)">
396
          {totalInTCO2E['value'] && <CountUp end={totalInTCO2E['value']} duration={2} prefix="" separator="," decimal="." decimals={2} />}
397
        </CardSummary>
398
      </div>
399
      <Row noGutters>
400
        <Col className="mb-3 pr-lg-2 mb-3">
401
          <SharePie data={timeOfUseShareData} title={t('Electricity Consumption by Time-Of-Use')} />
402
        </Col>
403
        <Col className="mb-3 pr-lg-2 mb-3">
404
          <SharePie data={costShareData} title={t('Costs by Energy Category')} />
405
        </Col>
406
        <Col className="mb-3 pr-lg-2 mb-3">
407
          <SharePie data={TCEShareData} title={t('Ton of Standard Coal by Energy Category')} />
408
        </Col>
409
        <Col className="mb-3 pr-lg-2 mb-3">
410
          <SharePie data={TCO2EShareData} title={t('Ton of Carbon Dioxide Emissions by Energy Category')} />
411
        </Col>
412
      </Row>
413
      <LineChart reportingTitle={t("This Month's Consumption CATEGORY VALUE UNIT", { 'CATEGORY': null, 'VALUE': null, 'UNIT': null })}
414
        baseTitle=''
415
        labels={spaceInputLineChartLabels}
416
        data={spaceInputLineChartData}
417
        options={spaceInputLineChartOptions}>
418
      </LineChart>
419
      <LineChart reportingTitle={t("This Month's Costs CATEGORY VALUE UNIT", { 'CATEGORY': null, 'VALUE': null, 'UNIT': null })}
420
        baseTitle=''
421
        labels={spaceCostLineChartLabels}
422
        data={spaceCostLineChartData}
423
        options={spaceCostLineChartOptions}>
424
      </LineChart>
425
426
      <LineChart reportingTitle={t('Related Parameters')}
427
        baseTitle=''
428
        labels={parameterLineChartLabels}
429
        data={parameterLineChartData}
430
        options={parameterLineChartOptions}>
431
      </LineChart>
432
433
      <ChildSpacesTable data={childSpacesTableData}
434
        title={t('Child Spaces Data of This Month')}
435
        columns={childSpacesTableColumns}>
436
      </ChildSpacesTable>
437
438
    </Fragment>
439
  );
440
};
441
442
export default withTranslation()(withRedirect(Dashboard));
443