Passed
Push — master ( 919ab1...b5c0a2 )
by Guangyu
07:58 queued 13s
created

myems-web/src/components/MyEMS/Equipment/EquipmentCarbon.js   A

Complexity

Total Complexity 30
Complexity/F 0

Size

Lines of Code 708
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 30
eloc 619
dl 0
loc 708
rs 9.981
c 0
b 0
f 0
mnd 30
bc 30
fnc 0
bpm 0
cpm 0
noi 0
1
import React, { Fragment, useEffect, useState } from 'react';
2
import {
3
  Breadcrumb,
4
  BreadcrumbItem,
5
  Row,
6
  Col,
7
  Card,
8
  CardBody,
9
  Button,
10
  ButtonGroup,
11
  Form,
12
  FormGroup,
13
  Input,
14
  Label,
15
  CustomInput,
16
  Spinner
17
} from 'reactstrap';
18
import CountUp from 'react-countup';
19
import moment from 'moment';
20
import loadable from '@loadable/component';
21
import Cascader from 'rc-cascader';
22
import CardSummary from '../common/CardSummary';
23
import LineChart from '../common/LineChart';
24
import SharePie from '../common/SharePie';
25
import { getCookieValue, createCookie } from '../../../helpers/utils';
26
import withRedirect from '../../../hoc/withRedirect';
27
import { withTranslation } from 'react-i18next';
28
import { toast } from 'react-toastify';
29
import ButtonIcon from '../../common/ButtonIcon';
30
import { APIBaseURL } from '../../../config';
31
import { periodTypeOptions } from '../common/PeriodTypeOptions';
32
import { comparisonTypeOptions } from '../common/ComparisonTypeOptions';
33
import { DateRangePicker } from 'rsuite';
34
import { endOfDay} from 'date-fns';
35
36
const DetailedDataTable = loadable(() => import('../common/DetailedDataTable'));
37
38
const EquipmentCarbon = ({ setRedirect, setRedirectUrl, t }) => {
39
  let current_moment = moment();
40
  useEffect(() => {
41
    let is_logged_in = getCookieValue('is_logged_in');
42
    let user_name = getCookieValue('user_name');
43
    let user_display_name = getCookieValue('user_display_name');
44
    let user_uuid = getCookieValue('user_uuid');
45
    let token = getCookieValue('token');
46
    if (is_logged_in === null || !is_logged_in) {
47
      setRedirectUrl(`/authentication/basic/login`);
48
      setRedirect(true);
49
    } else {
50
      //update expires time of cookies
51
      createCookie('is_logged_in', true, 1000 * 60 * 60 * 8);
52
      createCookie('user_name', user_name, 1000 * 60 * 60 * 8);
53
      createCookie('user_display_name', user_display_name, 1000 * 60 * 60 * 8);
54
      createCookie('user_uuid', user_uuid, 1000 * 60 * 60 * 8);
55
      createCookie('token', token, 1000 * 60 * 60 * 8);
56
    }
57
  });
58
59
60
  // State
61
  // Query Parameters
62
  const [selectedSpaceName, setSelectedSpaceName] = useState(undefined);
63
  const [selectedSpaceID, setSelectedSpaceID] = useState(undefined);
64
  const [equipmentList, setEquipmentList] = useState([]);
65
  const [selectedEquipment, setSelectedEquipment] = useState(undefined);
66
  const [comparisonType, setComparisonType] = useState('month-on-month');
67
  const [periodType, setPeriodType] = useState('daily');
68
  const [cascaderOptions, setCascaderOptions] = useState(undefined);
69
  const [basePeriodDateRange, setBasePeriodDateRange] = useState([current_moment.clone().subtract(1, 'months').startOf('month').toDate(), current_moment.clone().subtract(1, 'months').toDate()]);
70
  const [basePeriodDateRangePickerDisabled, setBasePeriodDateRangePickerDisabled] = useState(true);
71
  const [reportingPeriodDateRange, setReportingPeriodDateRange] = useState([current_moment.clone().startOf('month').toDate(), current_moment.toDate()]);
72
  const dateRangePickerLocale = {
73
    sunday: t('sunday'),
74
    monday: t('monday'),
75
    tuesday: t('tuesday'),
76
    wednesday: t('wednesday'),
77
    thursday: t('thursday'),
78
    friday: t('friday'),
79
    saturday: t('saturday'),
80
    ok: t('ok'),
81
    today: t('today'),
82
    yesterday: t('yesterday'),
83
    hours: t('hours'),
84
    minutes: t('minutes'),
85
    seconds: t('seconds'),
86
    last7Days: t('last7Days')
87
  };
88
  const dateRangePickerStyle = { display: 'block', zIndex: 10};
89
90
  // buttons
91
  const [submitButtonDisabled, setSubmitButtonDisabled] = useState(true);
92
  const [spinnerHidden, setSpinnerHidden] = useState(true);
93
  const [exportButtonHidden, setExportButtonHidden] = useState(true);
94
95
  //Results
96
  const [timeOfUseShareData, setTimeOfUseShareData] = useState([]);
97
  const [carbonShareData, setCarbonShareData] = useState([]);
98
99
  const [cardSummaryList, setCardSummaryList] = useState([]);
100
  const [equipmentLineChartLabels, setEquipmentLineChartLabels] = useState([]);
101
  const [equipmentLineChartData, setEquipmentLineChartData] = useState({});
102
  const [equipmentLineChartOptions, setEquipmentLineChartOptions] = useState([]);
103
104
  const [parameterLineChartLabels, setParameterLineChartLabels] = useState([]);
105
  const [parameterLineChartData, setParameterLineChartData] = useState({});
106
  const [parameterLineChartOptions, setParameterLineChartOptions] = useState([]);
107
108
  const [detailedDataTableData, setDetailedDataTableData] = useState([]);
109
  const [detailedDataTableColumns, setDetailedDataTableColumns] = useState([{dataField: 'startdatetime', text: t('Datetime'), sort: true}]);
110
  const [excelBytesBase64, setExcelBytesBase64] = useState(undefined);
111
112
  useEffect(() => {
113
    let isResponseOK = false;
114
    fetch(APIBaseURL + '/spaces/tree', {
115
      method: 'GET',
116
      headers: {
117
        "Content-type": "application/json",
118
        "User-UUID": getCookieValue('user_uuid'),
119
        "Token": getCookieValue('token')
120
      },
121
      body: null,
122
123
    }).then(response => {
124
      console.log(response);
125
      if (response.ok) {
126
        isResponseOK = true;
127
      }
128
      return response.json();
129
    }).then(json => {
130
      console.log(json);
131
      if (isResponseOK) {
132
        // rename keys 
133
        json = JSON.parse(JSON.stringify([json]).split('"id":').join('"value":').split('"name":').join('"label":'));
134
        setCascaderOptions(json);
135
        setSelectedSpaceName([json[0]].map(o => o.label));
136
        setSelectedSpaceID([json[0]].map(o => o.value));
137
        // get Equipments by root Space ID
138
        let isResponseOK = false;
139
        fetch(APIBaseURL + '/spaces/' + [json[0]].map(o => o.value) + '/equipments', {
140
          method: 'GET',
141
          headers: {
142
            "Content-type": "application/json",
143
            "User-UUID": getCookieValue('user_uuid'),
144
            "Token": getCookieValue('token')
145
          },
146
          body: null,
147
148
        }).then(response => {
149
          if (response.ok) {
150
            isResponseOK = true;
151
          }
152
          return response.json();
153
        }).then(json => {
154
          if (isResponseOK) {
155
            json = JSON.parse(JSON.stringify([json]).split('"id":').join('"value":').split('"name":').join('"label":'));
156
            console.log(json);
157
            setEquipmentList(json[0]);
158
            if (json[0].length > 0) {
159
              setSelectedEquipment(json[0][0].value);
160
              // enable submit button
161
              setSubmitButtonDisabled(false);
162
            } else {
163
              setSelectedEquipment(undefined);
164
              // disable submit button
165
              setSubmitButtonDisabled(true);
166
            }
167
          } else {
168
            toast.error(json.description)
169
          }
170
        }).catch(err => {
171
          console.log(err);
172
        });
173
        // end of get Equipments by root Space ID
174
      } else {
175
        toast.error(json.description);
176
      }
177
    }).catch(err => {
178
      console.log(err);
179
    });
180
181
  }, []);
182
183
  const labelClasses = 'ls text-uppercase text-600 font-weight-semi-bold mb-0';
184
185
  let onSpaceCascaderChange = (value, selectedOptions) => {
186
    setSelectedSpaceName(selectedOptions.map(o => o.label).join('/'));
187
    setSelectedSpaceID(value[value.length - 1]);
188
189
    let isResponseOK = false;
190
    fetch(APIBaseURL + '/spaces/' + value[value.length - 1] + '/equipments', {
191
      method: 'GET',
192
      headers: {
193
        "Content-type": "application/json",
194
        "User-UUID": getCookieValue('user_uuid'),
195
        "Token": getCookieValue('token')
196
      },
197
      body: null,
198
199
    }).then(response => {
200
      if (response.ok) {
201
        isResponseOK = true;
202
      }
203
      return response.json();
204
    }).then(json => {
205
      if (isResponseOK) {
206
        json = JSON.parse(JSON.stringify([json]).split('"id":').join('"value":').split('"name":').join('"label":'));
207
        console.log(json)
208
        setEquipmentList(json[0]);
209
        if (json[0].length > 0) {
210
          setSelectedEquipment(json[0][0].value);
211
          // enable submit button
212
          setSubmitButtonDisabled(false);
213
        } else {
214
          setSelectedEquipment(undefined);
215
          // disable submit button
216
          setSubmitButtonDisabled(true);
217
        }
218
      } else {
219
        toast.error(json.description)
220
      }
221
    }).catch(err => {
222
      console.log(err);
223
    });
224
  }
225
226
227
  let onComparisonTypeChange = ({ target }) => {
228
    console.log(target.value);
229
    setComparisonType(target.value);
230
    if (target.value === 'year-over-year') {
231
      setBasePeriodDateRangePickerDisabled(true);
232
      setBasePeriodDateRange([moment(reportingPeriodDateRange[0]).subtract(1, 'years').toDate(),
233
        moment(reportingPeriodDateRange[1]).subtract(1, 'years').toDate()]);
234
    } else if (target.value === 'month-on-month') {
235
      setBasePeriodDateRangePickerDisabled(true);
236
      setBasePeriodDateRange([moment(reportingPeriodDateRange[0]).subtract(1, 'months').toDate(),
237
        moment(reportingPeriodDateRange[1]).subtract(1, 'months').toDate()]);
238
    } else if (target.value === 'free-comparison') {
239
      setBasePeriodDateRangePickerDisabled(false);
240
    } else if (target.value === 'none-comparison') {
241
      setBasePeriodDateRange([null, null]);
242
      setBasePeriodDateRangePickerDisabled(true);
243
    }
244
  };
245
246
  // Callback fired when value changed
247
  let onBasePeriodChange = (DateRange) => {
248
    if(DateRange == null) {
249
      setBasePeriodDateRange([null, null]);
250
    } else {
251
      if (moment(DateRange[1]).format('HH:mm:ss') == '00:00:00') {
252
        // if the user did not change time value, set the default time to the end of day
253
        DateRange[1] = endOfDay(DateRange[1]);
254
      }
255
      setBasePeriodDateRange([DateRange[0], DateRange[1]]);
256
    }
257
  };
258
259
  // Callback fired when value changed
260
  let onReportingPeriodChange = (DateRange) => {
261
    if(DateRange == null) {
262
      setReportingPeriodDateRange([null, null]);
263
    } else {
264
      if (moment(DateRange[1]).format('HH:mm:ss') == '00:00:00') {
265
        // if the user did not change time value, set the default time to the end of day
266
        DateRange[1] = endOfDay(DateRange[1]);
267
      }
268
      setReportingPeriodDateRange([DateRange[0], DateRange[1]]);
269
      if (comparisonType === 'year-over-year') {
270
        setBasePeriodDateRange([moment(DateRange[0]).clone().subtract(1, 'years').toDate(), moment(DateRange[1]).clone().subtract(1, 'years').toDate()]);
271
      } else if (comparisonType === 'month-on-month') {
272
        setBasePeriodDateRange([moment(DateRange[0]).clone().subtract(1, 'months').toDate(), moment(DateRange[1]).clone().subtract(1, 'months').toDate()]);
273
      }
274
    }
275
  };
276
277
  // Callback fired when value clean
278
  let onBasePeriodClean = event => {
279
    setBasePeriodDateRange([null, null]);
280
  };
281
282
  // Callback fired when value clean
283
  let onReportingPeriodClean = event => {
284
    setReportingPeriodDateRange([null, null]);
285
  };
286
287
  // Handler
288
  const handleSubmit = e => {
289
    e.preventDefault();
290
    console.log('handleSubmit');
291
    console.log(selectedSpaceID);
292
    console.log(selectedEquipment);
293
    console.log(comparisonType);
294
    console.log(periodType);
295
    console.log(basePeriodDateRange[0] != null ? moment(basePeriodDateRange[0]).format('YYYY-MM-DDTHH:mm:ss') : null)
296
    console.log(basePeriodDateRange[1] != null ? moment(basePeriodDateRange[1]).format('YYYY-MM-DDTHH:mm:ss') : null)
297
    console.log(moment(reportingPeriodDateRange[0]).format('YYYY-MM-DDTHH:mm:ss'))
298
    console.log(moment(reportingPeriodDateRange[1]).format('YYYY-MM-DDTHH:mm:ss'));
299
300
    // disable submit button
301
    setSubmitButtonDisabled(true);
302
    // show spinner
303
    setSpinnerHidden(false);
304
    // hide export button
305
    setExportButtonHidden(true)
306
307
    // Reinitialize tables
308
    setDetailedDataTableData([]);
309
    
310
    let isResponseOK = false;
311
    fetch(APIBaseURL + '/reports/equipmentcarbon?' +
312
      'equipmentid=' + selectedEquipment +
313
      '&periodtype=' + periodType +
314
      '&baseperiodstartdatetime=' + (basePeriodDateRange[0] != null ? moment(basePeriodDateRange[0]).format('YYYY-MM-DDTHH:mm:ss') : '') +
315
      '&baseperiodenddatetime=' + (basePeriodDateRange[1] != null ? moment(basePeriodDateRange[1]).format('YYYY-MM-DDTHH:mm:ss') : '') +
316
      '&reportingperiodstartdatetime=' + moment(reportingPeriodDateRange[0]).format('YYYY-MM-DDTHH:mm:ss') +
317
      '&reportingperiodenddatetime=' + moment(reportingPeriodDateRange[1]).format('YYYY-MM-DDTHH:mm:ss'), {
318
      method: 'GET',
319
      headers: {
320
        "Content-type": "application/json",
321
        "User-UUID": getCookieValue('user_uuid'),
322
        "Token": getCookieValue('token')
323
      },
324
      body: null,
325
326
    }).then(response => {
327
      if (response.ok) {
328
        isResponseOK = true;
329
      };
330
      return response.json();
331
    }).then(json => {
332
      if (isResponseOK) {
333
        console.log(json)
334
335
        let cardSummaryList = []
336
        json['reporting_period']['names'].forEach((currentValue, index) => {
337
          let cardSummaryItem = {}
338
          cardSummaryItem['name'] = json['reporting_period']['names'][index];
339
          cardSummaryItem['unit'] = json['reporting_period']['units'][index];
340
          cardSummaryItem['subtotal'] = json['reporting_period']['subtotals'][index];
341
          cardSummaryItem['increment_rate'] = parseFloat(json['reporting_period']['increment_rates'][index] * 100).toFixed(2) + "%";
342
          cardSummaryList.push(cardSummaryItem);
343
        });
344
        let cardSummaryItem = {}
345
        cardSummaryItem['name'] = t('Total');
346
        cardSummaryItem['unit'] = json['reporting_period']['total_unit'];
347
        cardSummaryItem['subtotal'] = json['reporting_period']['total'];
348
        cardSummaryItem['increment_rate'] = parseFloat(json['reporting_period']['total_increment_rate'] * 100).toFixed(2) + "%";
349
        cardSummaryList.push(cardSummaryItem);
350
        setCardSummaryList(cardSummaryList);
351
352
        let timeOfUseArray = [];
353
        json['reporting_period']['energy_category_ids'].forEach((currentValue, index) => {
354
          if(currentValue === 1) {
355
            // energy_category_id 1 electricity
356
            let timeOfUseItem = {}
357
            timeOfUseItem['id'] = 1;
358
            timeOfUseItem['name'] =  t('Top-Peak');
359
            timeOfUseItem['value'] = json['reporting_period']['toppeaks'][index];
360
            timeOfUseItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
361
            timeOfUseArray.push(timeOfUseItem);
362
            
363
            timeOfUseItem = {}
364
            timeOfUseItem['id'] = 2;
365
            timeOfUseItem['name'] =  t('On-Peak');
366
            timeOfUseItem['value'] = json['reporting_period']['onpeaks'][index];
367
            timeOfUseItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
368
            timeOfUseArray.push(timeOfUseItem);
369
370
            timeOfUseItem = {}
371
            timeOfUseItem['id'] = 3;
372
            timeOfUseItem['name'] =  t('Mid-Peak');
373
            timeOfUseItem['value'] = json['reporting_period']['midpeaks'][index];
374
            timeOfUseItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
375
            timeOfUseArray.push(timeOfUseItem);
376
377
            timeOfUseItem = {}
378
            timeOfUseItem['id'] = 4;
379
            timeOfUseItem['name'] =  t('Off-Peak');
380
            timeOfUseItem['value'] = json['reporting_period']['offpeaks'][index];
381
            timeOfUseItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
382
            timeOfUseArray.push(timeOfUseItem);
383
          }
384
        });
385
        setTimeOfUseShareData(timeOfUseArray);
386
387
        let carbonDataArray = [];
388
        json['reporting_period']['names'].forEach((currentValue, index) => {
389
          let carbonDataItem = {}
390
          carbonDataItem['id'] = index;
391
          carbonDataItem['name'] = currentValue;
392
          carbonDataItem['value'] = json['reporting_period']['subtotals'][index];
393
          carbonDataItem['color'] = "#"+((1<<24)*Math.random()|0).toString(16);
394
          carbonDataArray.push(carbonDataItem);
395
        });
396
        setCarbonShareData(carbonDataArray);
397
398
        let timestamps = {}
399
        json['reporting_period']['timestamps'].forEach((currentValue, index) => {
400
          timestamps['a' + index] = currentValue;
401
        });
402
        setEquipmentLineChartLabels(timestamps);
403
404
        let values = {}
405
        json['reporting_period']['values'].forEach((currentValue, index) => {
406
          values['a' + index] = currentValue;
407
        });
408
        setEquipmentLineChartData(values);
409
        
410
        let names = Array();
411
        json['reporting_period']['names'].forEach((currentValue, index) => {
412
          let unit = json['reporting_period']['units'][index];
413
          names.push({ 'value': 'a' + index, 'label': currentValue + ' (' + unit + ')'});
414
        });
415
        setEquipmentLineChartOptions(names);
416
417
        timestamps = {}
418
        json['parameters']['timestamps'].forEach((currentValue, index) => {
419
          timestamps['a' + index] = currentValue;
420
        });
421
        setParameterLineChartLabels(timestamps);
422
423
        values = {}
424
        json['parameters']['values'].forEach((currentValue, index) => {
425
          values['a' + index] = currentValue;
426
        });
427
        setParameterLineChartData(values);
428
      
429
        names = Array();
430
        json['parameters']['names'].forEach((currentValue, index) => {
431
          if (currentValue.startsWith('TARIFF-')) {
432
            currentValue = t('Tariff') + currentValue.replace('TARIFF-', '-');
433
          }
434
          
435
          names.push({ 'value': 'a' + index, 'label': currentValue });
436
        });
437
        setParameterLineChartOptions(names);
438
439
        let detailed_value_list = [];
440
        if (json['reporting_period']['timestamps'].length > 0) {
441
          json['reporting_period']['timestamps'][0].forEach((currentTimestamp, timestampIndex) => {
442
            let detailed_value = {};
443
            detailed_value['id'] = timestampIndex;
444
            detailed_value['startdatetime'] = currentTimestamp;
445
            let total_current_timstamp = 0.0;
446
            json['reporting_period']['values'].forEach((currentValue, energyCategoryIndex) => {
447
              detailed_value['a' + energyCategoryIndex] = json['reporting_period']['values'][energyCategoryIndex][timestampIndex];
448
              total_current_timstamp += json['reporting_period']['values'][energyCategoryIndex][timestampIndex];
449
            });
450
            detailed_value['total'] = total_current_timstamp;
451
            detailed_value_list.push(detailed_value);
452
          });
453
        };
454
455
        let detailed_value = {};
456
        detailed_value['id'] = detailed_value_list.length;
457
        detailed_value['startdatetime'] = t('Subtotal');
458
        let total_of_subtotals = 0.0;
459
        json['reporting_period']['subtotals'].forEach((currentValue, index) => {
460
            detailed_value['a' + index] = currentValue;
461
            total_of_subtotals += currentValue
462
          });
463
        detailed_value['total'] = total_of_subtotals;
464
        detailed_value_list.push(detailed_value);
465
        setDetailedDataTableData(detailed_value_list);
466
        
467
        let detailed_column_list = [];
468
        detailed_column_list.push({
469
          dataField: 'startdatetime',
470
          text: t('Datetime'),
471
          sort: true
472
        });
473
        json['reporting_period']['names'].forEach((currentValue, index) => {
474
          let unit = json['reporting_period']['units'][index];
475
          detailed_column_list.push({
476
            dataField: 'a' + index,
477
            text: currentValue + ' (' + unit + ')',
478
            sort: true,
479
            formatter: function (decimalValue) {
480
              if (typeof decimalValue === 'number') {
481
                return decimalValue.toFixed(2);
482
              } else {
483
                return null;
484
              }
485
            }
486
          });
487
        });
488
        detailed_column_list.push({
489
          dataField: 'total',
490
          text: t('Total') + ' (' + json['reporting_period']['total_unit'] + ')',
491
          sort: true,
492
          formatter: function (decimalValue) {
493
            if (typeof decimalValue === 'number') {
494
              return decimalValue.toFixed(2);
495
            } else {
496
              return null;
497
            }
498
          }
499
        });
500
        setDetailedDataTableColumns(detailed_column_list);
501
        
502
        setExcelBytesBase64(json['excel_bytes_base64']);
503
504
        // enable submit button
505
        setSubmitButtonDisabled(false);
506
        // hide spinner
507
        setSpinnerHidden(true);
508
        // show export button
509
        setExportButtonHidden(false);
510
      } else {
511
        toast.error(json.description)
512
      }
513
    }).catch(err => {
514
      console.log(err);
515
    });
516
  };
517
518
  const handleExport = e => {
519
    e.preventDefault();
520
    const mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
521
    const fileName = 'equipmentcarbon.xlsx'
522
    var fileUrl = "data:" + mimeType + ";base64," + excelBytesBase64;
523
    fetch(fileUrl)
524
        .then(response => response.blob())
525
        .then(blob => {
526
            var link = window.document.createElement("a");
527
            link.href = window.URL.createObjectURL(blob, { type: mimeType });
528
            link.download = fileName;
529
            document.body.appendChild(link);
530
            link.click();
531
            document.body.removeChild(link);
532
        });
533
  };
534
535
  return (
536
    <Fragment>
537
      <div>
538
        <Breadcrumb>
539
          <BreadcrumbItem>{t('Equipment Data')}</BreadcrumbItem><BreadcrumbItem active>{t('Carbon')}</BreadcrumbItem>
540
        </Breadcrumb>
541
      </div>
542
      <Card className="bg-light mb-3">
543
        <CardBody className="p-3">
544
          <Form onSubmit={handleSubmit}>
545
            <Row form>
546
              <Col xs={6} sm={3}>
547
                <FormGroup className="form-group">
548
                  <Label className={labelClasses} for="space">
549
                    {t('Space')}
550
                  </Label>
551
                  <br />
552
                  <Cascader options={cascaderOptions}
553
                    onChange={onSpaceCascaderChange}
554
                    changeOnSelect
555
                    expandTrigger="hover">
556
                    <Input value={selectedSpaceName || ''} readOnly />
557
                  </Cascader>
558
                </FormGroup>
559
              </Col>
560
              <Col xs="auto">
561
                <FormGroup>
562
                  <Label className={labelClasses} for="equipmentSelect">
563
                    {t('Equipment')}
564
                  </Label>
565
                  <CustomInput type="select" id="equipmentSelect" name="equipmentSelect" onChange={({ target }) => setSelectedEquipment(target.value)}
566
                  >
567
                    {equipmentList.map((equipment, index) => (
568
                      <option value={equipment.value} key={equipment.value}>
569
                        {equipment.label}
570
                      </option>
571
                    ))}
572
                  </CustomInput>
573
                </FormGroup>
574
              </Col>
575
              <Col xs="auto">
576
                <FormGroup>
577
                  <Label className={labelClasses} for="comparisonType">
578
                    {t('Comparison Types')}
579
                  </Label>
580
                  <CustomInput type="select" id="comparisonType" name="comparisonType"
581
                    defaultValue="month-on-month"
582
                    onChange={onComparisonTypeChange}
583
                  >
584
                    {comparisonTypeOptions.map((comparisonType, index) => (
585
                      <option value={comparisonType.value} key={comparisonType.value} >
586
                        {t(comparisonType.label)}
587
                      </option>
588
                    ))}
589
                  </CustomInput>
590
                </FormGroup>
591
              </Col>
592
              <Col xs="auto">
593
                <FormGroup>
594
                  <Label className={labelClasses} for="periodType">
595
                    {t('Period Types')}
596
                  </Label>
597
                  <CustomInput type="select" id="periodType" name="periodType" defaultValue="daily" onChange={({ target }) => setPeriodType(target.value)}
598
                  >
599
                    {periodTypeOptions.map((periodType, index) => (
600
                      <option value={periodType.value} key={periodType.value} >
601
                        {t(periodType.label)}
602
                      </option>
603
                    ))}
604
                  </CustomInput>
605
                </FormGroup>
606
              </Col>
607
              <Col xs={6} sm={3}>
608
                <FormGroup className="form-group">
609
                  <Label className={labelClasses} for="basePeriodDateRangePicker">{t('Base Period')}{t('(Optional)')}</Label>
610
                  <DateRangePicker 
611
                    id='basePeriodDateRangePicker'
612
                    readOnly={basePeriodDateRangePickerDisabled}
613
                    format="yyyy-MM-dd HH:mm:ss"
614
                    value={basePeriodDateRange}
615
                    onChange={onBasePeriodChange}
616
                    size="md"
617
                    style={dateRangePickerStyle}
618
                    onClean={onBasePeriodClean}
619
                    locale={dateRangePickerLocale}
620
                    placeholder={t("Select Date Range")}
621
                   />
622
                </FormGroup>
623
              </Col>
624
              <Col xs={6} sm={3}>
625
                <FormGroup className="form-group">
626
                  <Label className={labelClasses} for="reportingPeriodDateRangePicker">{t('Reporting Period')}</Label>
627
                  <br/>
628
                  <DateRangePicker
629
                    id='reportingPeriodDateRangePicker'
630
                    format="yyyy-MM-dd HH:mm:ss"
631
                    value={reportingPeriodDateRange}
632
                    onChange={onReportingPeriodChange}
633
                    size="md"
634
                    style={dateRangePickerStyle}
635
                    onClean={onReportingPeriodClean}
636
                    locale={dateRangePickerLocale}
637
                    placeholder={t("Select Date Range")}
638
                  />
639
                </FormGroup>
640
              </Col>
641
              <Col xs="auto">
642
                <FormGroup>
643
                  <br></br>
644
                  <ButtonGroup id="submit">
645
                    <Button color="success" disabled={submitButtonDisabled} >{t('Submit')}</Button>
646
                  </ButtonGroup>
647
                </FormGroup>
648
              </Col>
649
              <Col xs="auto">
650
                <FormGroup>
651
                  <br></br>
652
                  <Spinner color="primary" hidden={spinnerHidden}  />
653
                </FormGroup>
654
              </Col>
655
              <Col xs="auto">
656
                  <br></br>
657
                  <ButtonIcon icon="external-link-alt" transform="shrink-3 down-2" color="falcon-default" 
658
                  hidden={exportButtonHidden}
659
                  onClick={handleExport} >
660
                    {t('Export')}
661
                  </ButtonIcon>
662
              </Col>
663
            </Row>
664
          </Form>
665
        </CardBody>
666
      </Card>
667
      <div className="card-deck">
668
        {cardSummaryList.map(cardSummaryItem => (
669
          <CardSummary key={cardSummaryItem['name']}
670
            rate={cardSummaryItem['increment_rate']}
671
            title={t('Reporting Period Carbon Dioxide Emissions CATEGORY UNIT', { 'CATEGORY': cardSummaryItem['name'], 'UNIT': '(' + cardSummaryItem['unit'] + ')' })}
672
            color="success" >
673
            {cardSummaryItem['subtotal'] && <CountUp end={cardSummaryItem['subtotal']} duration={2} prefix="" separator="," decimal="." decimals={2} />}
674
          </CardSummary>
675
        ))}
676
      </div>
677
      <Row noGutters>
678
        <Col className="mb-3 pr-lg-2 mb-3">
679
          <SharePie data={timeOfUseShareData} title={t('Electricity Carbon Dioxide Emissions by Time-Of-Use')} />
680
        </Col>
681
        <Col className="mb-3 pr-lg-2 mb-3">
682
          <SharePie data={carbonShareData} title={t('Carbon Dioxide Emissions by Energy Category')} />
683
        </Col>
684
      </Row>
685
      <LineChart reportingTitle={t('Reporting Period Carbon Dioxide Emissions CATEGORY VALUE UNIT', { 'CATEGORY': null, 'VALUE': null, 'UNIT': null })}
686
        baseTitle=''
687
        labels={equipmentLineChartLabels}
688
        data={equipmentLineChartData}
689
        options={equipmentLineChartOptions}>
690
      </LineChart>
691
692
      <LineChart reportingTitle={t('Related Parameters')}
693
        baseTitle=''
694
        labels={parameterLineChartLabels}
695
        data={parameterLineChartData}
696
        options={parameterLineChartOptions}>
697
      </LineChart>
698
699
      <br />
700
      <DetailedDataTable data={detailedDataTableData} title={t('Detailed Data')} columns={detailedDataTableColumns} pagesize={50} >
701
      </DetailedDataTable>
702
703
    </Fragment>
704
  );
705
};
706
707
export default withTranslation()(withRedirect(EquipmentCarbon));
708