From 43ab103b60647fd8834c24681bc3b7b184304daf Mon Sep 17 00:00:00 2001 From: Conrad Date: Thu, 22 Feb 2018 13:46:32 -0500 Subject: [PATCH 01/27] Initial impact view without deemed savings --- src/containers/BGroup/BGroup.js | 256 +++++++++++++++++++++++++++----- src/utils/restServices.js | 1 + 2 files changed, 216 insertions(+), 41 deletions(-) diff --git a/src/containers/BGroup/BGroup.js b/src/containers/BGroup/BGroup.js index 211dbeee..faa06156 100644 --- a/src/containers/BGroup/BGroup.js +++ b/src/containers/BGroup/BGroup.js @@ -3,7 +3,10 @@ import { connect } from 'react-redux'; import { Link, browserHistory } from 'react-router'; import { bindActionCreators } from 'redux'; import PropTypes from 'prop-types'; -import { Button, Nav, NavItem, NavLink } from 'reactstrap'; +import { + Button, Nav, NavItem, NavLink, Input, Collapse, + UncontrolledDropdown, DropdownToggle, DropdownMenu, DropdownItem, +} from 'reactstrap'; import ReactTable from 'react-table'; import 'react-table/react-table.css'; import { Icon } from 'react-fa'; @@ -24,7 +27,7 @@ import { loadProjects } from '../Project/actions'; import AddressSearch from '../../components/AddressSearch/AddressSearch'; import userPropType from '../User/propTypes'; import request from '../../utils/request'; -import { getHeaders, accountURL, gatewayURL, contactsURL } from '../../utils/restServices'; +import { getHeaders, accountURL, gatewayURL, contactsURL, sfBuildingImpactURL } from '../../utils/restServices'; const UTILITY_TYPES = { 1: 'electric', @@ -51,11 +54,18 @@ export class BGroup extends Component { projectStatusBreakdown: {}, contactAccounts: {}, contactParentAccounts: {}, - contactNames: {}, contactLoading: false, contactError: false, + impactLoading: false, + impactError: false, + impact: {}, numRows: -1, overviewTab: this.props.user.permissions['view::bgroupProjectsSummary'] ? 'projects' : 'buildings', + displayContact: false, + displayAnalysis: true, + displayProjects: true, + displayImpact: true, + recommendedRetrofitsToggle: {}, } componentDidMount() { @@ -79,6 +89,7 @@ export class BGroup extends Component { this.getGatewayDates(buildingIds); } this.getSimulationDates(buildingIds); + this.getSfBuildingImpact(buildingIds); } } if ( @@ -118,6 +129,27 @@ export class BGroup extends Component { clearTimeout(this.updateNumRows); } + getSfBuildingImpact = (buildingIds) => { + // A function to determine dates of gateway install + this.setState({ impactLoading: true }); + const filterString = buildingIds.reduce((acc, val) => ( + `${acc}building_id[]=${val}&` + ), ''); + request(`${sfBuildingImpactURL}?${filterString}`, { + method: 'GET', + headers: getHeaders(), + }).then((res) => { + this.setState({ impactLoading: false }); + const data = res.data; + if (!res.err && data) { + this.setState({ impact: data }); + } else { + this.setState({ impactError: true }); + } + }); + + } + getContacts = (projects) => { // A function to get all of the contact information for buildings this.setState({ contactLoading: true }); @@ -143,15 +175,13 @@ export class BGroup extends Component { if (!res.err && data) { const contactAccounts = {}; const contactParentAccounts = {}; - const contactNames = {}; data.map((val) => { const buildingId = salesForceToBuilding[val.sales_force_id]; contactAccounts[buildingId] = val.account_name; contactParentAccounts[buildingId] = val.parent_account_name; - contactNames[buildingId] = val.contacts.map(contact => contact.name); return val; }); - this.setState({ contactAccounts, contactParentAccounts, contactNames }); + this.setState({ contactAccounts, contactParentAccounts }); } else { this.setState({ contactError: true }); } @@ -291,9 +321,6 @@ export class BGroup extends Component { ); } - renderProjectSummary = () => { - } - renderDeleteBuildingButton = (id) => { if (this.props.bGroup.deleteBGroupBuildingLoading[id]) { return ( @@ -322,6 +349,18 @@ export class BGroup extends Component { : false ); + const listFilterMethod = (filter, row) => { + if (row[filter.id]) { + + return row[filter.id].reduce((acc, val) => ( + val && (acc || val.toLowerCase().indexOf( + filter.value.toLowerCase() + ) !== -1) + ), false); + } + return false; + }; + const utilityBillFilterMethod = (filter, row) => { if (filter.value === 'all') { return true; @@ -377,7 +416,7 @@ export class BGroup extends Component { ), }, ], - }, { + }, ...(!this.state.displayContact) ? [] : [{ Header: () => ( Contact Info{' '} @@ -397,30 +436,9 @@ export class BGroup extends Component { Header: 'Parent Company', filterMethod: genericFilterMethod, accessor: 'contact_parent_account', - }, { - Header: 'Contact Names', - filterMethod: (filter, row) => { - // Handle this one differently because it's a list - if (row[filter.id]) { - return row[filter.id].reduce((acc, val) => ( - val && (acc || val.toLowerCase().indexOf( - filter.value.toLowerCase() - ) !== -1) - ), false); - } - return false; - }, - accessor: 'contact_names', - Cell: row => (row.value ? ( - - ) : null), }, ], - }, { + }], ...(!this.state.displayAnalysis) ? [] : [{ Header: () => ( Analysis{' '} @@ -473,7 +491,7 @@ export class BGroup extends Component { Cell: row => (row.value ? : null), }, ], - }, { + }], ...(!this.state.displayProjects) ? [] : [{ Header: () => ( Projects{' '} @@ -538,29 +556,104 @@ export class BGroup extends Component { accessor: 'num_projects', }, { Header: 'Project Types', + filterMethod: listFilterMethod, + accessor: 'project_types', + Cell: row => (row.value ? ( +
    + {row.value.map((type, index) => ( +
  • {type}
  • + ))} +
+ ) : null), + }, + ], + }], ...(!this.state.displayImpact) ? [] : [{ + Header: () => ( + + Impact{' '} + + + ), + columns: [ + { + Header: 'Recommended Retrofits', + filterMethod: listFilterMethod, + accessor: 'recommended_retrofits', + Cell: (row) => { + if (row.value && row.value.length > 0) { + const buildingId = row.original.building_id; + const toggleButton = ( + /* eslint-disable jsx-a11y/no-static-element-interactions */ +
{ + this.setState({ recommendedRetrofitsToggle: { + ...this.state.recommendedRetrofitsToggle, + [buildingId]: !this.state.recommendedRetrofitsToggle[buildingId], + } }); + }} + style={{ textAlign: 'center', backgroundColor: '#f7f7f9' }} + > + {' '} + {this.state.recommendedRetrofitsToggle[buildingId] ? 'Hide' : 'Show'} +
+ ); + return ( +
+ {toggleButton} + +
    + {row.value.map((val, index) => ( +
  • {val}
  • + ))} +
+
+
+ ); + } + return null; + }, + }, { + Header: 'Deemed Savings (recommended)', + filterable: false, + style: { textAlign: 'center' }, + accessor: 'recommended_deemed_savings', + }, { + Header: 'Completed Retrofits', filterMethod: (filter, row) => { - // Handle this one differently because it's a list if (row[filter.id]) { - return row[filter.id].reduce((acc, val) => ( - val && (acc || val.toLowerCase().indexOf( + val && (acc || val.completed.toLowerCase().indexOf( filter.value.toLowerCase() ) !== -1) ), false); } return false; }, - accessor: 'project_types', + accessor: 'completed_retrofits', Cell: row => (row.value ? (
    - {row.value.map((type, index) => ( -
  • {type}
  • + {row.value.map((val, index) => ( +
  • {val.completed} ({(new Date(val.completed_date)).toLocaleDateString('en-US')})
  • ))}
) : null), + }, { + Header: 'Deemed Savings (completed)', + filterable: false, + style: { textAlign: 'center' }, + accessor: 'completed_deemed_savings', }, ], - }]; + }]]; if (this.state.edit) { columns.push({ Header: '', @@ -588,7 +681,21 @@ export class BGroup extends Component { val.building_simulation = this.state.simulationDates[val.building_id]; val.contact_account = this.state.contactAccounts[val.building_id]; val.contact_parent_account = this.state.contactParentAccounts[val.building_id]; - val.contact_names = this.state.contactNames[val.building_id]; + if (this.state.impact[val.building_id]) { + const impactObjects = this.state.impact[val.building_id]; + if (impactObjects.diagnostic_recommendations.length > 0) { + val.recommended_retrofits = impactObjects.diagnostic_recommendations; + } else { + val.recommended_retrofits = impactObjects.pns_recommendations; + } + val.completed_retrofits = impactObjects.complete; + } else { + val.recommended_retrofits = []; + val.completed_retrofits = []; + } + val.recommended_deemed_savings = undefined; + val.completed_deemed_savings = undefined; + return val; }); return ( @@ -607,6 +714,73 @@ export class BGroup extends Component {
{this.state.numRows} buildings
+ + + Toggle Columns + + + { + this.setState({ displayContact: !this.state.displayContact }); + }} + > + + {' '} + Contact Info + + + { + this.setState({ displayAnalysis: !this.state.displayAnalysis }); + }} + > + + {' '} + Analysis + + + { + this.setState({ displayProjects: !this.state.displayProjects }); + }} + > + + {' '} + Projects + + + { + this.setState({ displayImpact: !this.state.displayImpact }); + }} + > + + {' '} + Impact + + + +
diff --git a/src/utils/restServices.js b/src/utils/restServices.js index a292d8a7..95747f90 100644 --- a/src/utils/restServices.js +++ b/src/utils/restServices.js @@ -36,6 +36,7 @@ export const disaggregateMetaURL = `${utilityService}/disaggregatemeta/`; export const projectURL = `${projectService}/project/`; export const contactsURL = `${projectService}/contact/`; export const projectDocumentURL = `${projectService}/project/document/`; +export const sfBuildingImpactURL = `${projectService}/sfbuildingimpact/`; export const lightingReportURL = `${reportService}/kissflowlighting/`; -- GitLab From 74435b0041c8c02cc21a3f4868f09d197db77efb Mon Sep 17 00:00:00 2001 From: Conrad Date: Thu, 22 Feb 2018 17:29:49 -0500 Subject: [PATCH 02/27] Add deemed columns --- src/containers/BGroup/BGroup.js | 174 +++++++++++++++++++++++++++----- src/styles.css | 36 +++++++ 2 files changed, 184 insertions(+), 26 deletions(-) diff --git a/src/containers/BGroup/BGroup.js b/src/containers/BGroup/BGroup.js index faa06156..d4307bf6 100644 --- a/src/containers/BGroup/BGroup.js +++ b/src/containers/BGroup/BGroup.js @@ -62,10 +62,12 @@ export class BGroup extends Component { numRows: -1, overviewTab: this.props.user.permissions['view::bgroupProjectsSummary'] ? 'projects' : 'buildings', displayContact: false, - displayAnalysis: true, - displayProjects: true, + displayAnalysis: false, + displayProjects: false, displayImpact: true, recommendedRetrofitsToggle: {}, + recommendedDeemedToggle: {}, + completedDeemedToggle: {}, } componentDidMount() { @@ -412,7 +414,9 @@ export class BGroup extends Component { ), accessor: 'first_address', Cell: row => ( - {row.value} +
+ {row.value} +
), }, ], @@ -432,10 +436,20 @@ export class BGroup extends Component { Header: 'Owner', filterMethod: genericFilterMethod, accessor: 'contact_account', + Cell: row => ( +
+ {row.value} +
+ ), }, { Header: 'Parent Company', filterMethod: genericFilterMethod, accessor: 'contact_parent_account', + Cell: row => ( +
+ {row.value} +
+ ), }, ], }], ...(!this.state.displayAnalysis) ? [] : [{ @@ -456,14 +470,22 @@ export class BGroup extends Component { Filter: utilityBillFilter, accessor: 'electric_bill', style: { textAlign: 'center' }, - Cell: row => (row.value ? : null), + Cell: row => ( +
+ {row.value ? : null} +
+ ), }, { Header: 'Gas Bill', filterMethod: utilityBillFilterMethod, Filter: utilityBillFilter, accessor: 'gas_bill', style: { textAlign: 'center' }, - Cell: row => (row.value ? : null), + Cell: row => ( +
+ {row.value ? : null} +
+ ), }, { Header: 'Energy Simulation', filterMethod: (filter, row) => { @@ -488,7 +510,11 @@ export class BGroup extends Component { ), accessor: 'building_simulation', style: { textAlign: 'center' }, - Cell: row => (row.value ? : null), + Cell: row => ( +
+ {row.value ? : null} +
+ ), }, ], }], ...(!this.state.displayProjects) ? [] : [{ @@ -543,11 +569,13 @@ export class BGroup extends Component { return d1 > d2 ? 1 : -1; }, Cell: row => (row.value ? ( -
    - {row.value.map((installDate, index) => ( -
  • {installDate}
  • - ))} -
+
+
    + {row.value.map((installDate, index) => ( +
  • {installDate}
  • + ))} +
+
) : null), }], { Header: '# Projects', @@ -559,11 +587,13 @@ export class BGroup extends Component { filterMethod: listFilterMethod, accessor: 'project_types', Cell: row => (row.value ? ( -
    - {row.value.map((type, index) => ( -
  • {type}
  • - ))} -
+
+
    + {row.value.map((type, index) => ( +
  • {type}
  • + ))} +
+
) : null), }, ], @@ -604,13 +634,13 @@ export class BGroup extends Component {
); return ( -
+
{toggleButton} -
    +
      {row.value.map((val, index) => (
    • {val}
    • ))} @@ -625,7 +655,45 @@ export class BGroup extends Component { Header: 'Deemed Savings (recommended)', filterable: false, style: { textAlign: 'center' }, - accessor: 'recommended_deemed_savings', + accessor: 'projected_deemed_savings', + Cell: (row) => { + if (row.value && row.value.length > 0) { + const buildingId = row.original.building_id; + const toggleButton = ( + /* eslint-disable jsx-a11y/no-static-element-interactions */ +
      { + this.setState({ recommendedDeemedToggle: { + ...this.state.recommendedDeemedToggle, + [buildingId]: !this.state.recommendedDeemedToggle[buildingId], + } }); + }} + style={{ textAlign: 'center', backgroundColor: '#f7f7f9' }} + > + {' '} + {this.state.recommendedDeemedToggle[buildingId] ? 'Hide' : 'Show'} +
      + ); + return ( +
      + {toggleButton} + +
        + {row.value.map((val, index) => ( +
      • {val}
      • + ))} +
      +
      +
      + ); + } + return null; + }, }, { Header: 'Completed Retrofits', filterMethod: (filter, row) => { @@ -640,17 +708,57 @@ export class BGroup extends Component { }, accessor: 'completed_retrofits', Cell: row => (row.value ? ( -
        - {row.value.map((val, index) => ( -
      • {val.completed} ({(new Date(val.completed_date)).toLocaleDateString('en-US')})
      • - ))} -
      +
      +
        + {row.value.map((val, index) => ( +
      • {val.completed} ({(new Date(val.completed_date)).toLocaleDateString('en-US')})
      • + ))} +
      +
      ) : null), }, { Header: 'Deemed Savings (completed)', filterable: false, style: { textAlign: 'center' }, accessor: 'completed_deemed_savings', + Cell: (row) => { + if (row.value && row.value.length > 0) { + const buildingId = row.original.building_id; + const toggleButton = ( + /* eslint-disable jsx-a11y/no-static-element-interactions */ +
      { + this.setState({ completedDeemedToggle: { + ...this.state.completedDeemedToggle, + [buildingId]: !this.state.completedDeemedToggle[buildingId], + } }); + }} + style={{ textAlign: 'center', backgroundColor: '#f7f7f9' }} + > + {' '} + {this.state.completedDeemedToggle[buildingId] ? 'Hide' : 'Show'} +
      + ); + return ( +
      + {toggleButton} + +
        + {row.value.map((val, index) => ( +
      • {val}
      • + ))} +
      +
      +
      + ); + } + return null; + }, }, ], }]]; @@ -689,12 +797,26 @@ export class BGroup extends Component { val.recommended_retrofits = impactObjects.pns_recommendations; } val.completed_retrofits = impactObjects.complete; + // Create a list of all of the projected deemed values + val.projected_deemed_savings = Object.keys(impactObjects.deemed.projected).reduce( + (acc, key) => ([ + ...acc, + ...(impactObjects.deemed.projected[key]) ? [`${key}: ${impactObjects.deemed.projected[key]}`] : [], + ]), [] + ); + // Create a list of all of the completed deemed values + val.completed_deemed_savings = Object.keys(impactObjects.deemed.completed).reduce( + (acc, key) => ([ + ...acc, + ...(impactObjects.deemed.completed[key]) ? [`${key}: ${impactObjects.deemed.completed[key]}`] : [], + ]), [] + ); } else { val.recommended_retrofits = []; val.completed_retrofits = []; + val.projected_deemed_savings = []; + val.completed_deemed_savings = []; } - val.recommended_deemed_savings = undefined; - val.completed_deemed_savings = undefined; return val; }); diff --git a/src/styles.css b/src/styles.css index a0391599..ffb65d3c 100644 --- a/src/styles.css +++ b/src/styles.css @@ -57,3 +57,39 @@ h6 { right: 0; background-color: white; } + + +/* + * These two hovers work in conjunction to + * provide a more detailed view when + * you hover a list item in a react table, + * assuming the cell you are hovering over + * is surrounded by a div with the bp-cell-wrapper + * class + * */ +.rt-td:hover { + overflow: visible !important; + z-index: 1000; +} + +.bp-cell-wrapper:hover { + min-width: 100px; + width: fit-content; + background-color: white; + z-index: 1000; +} + +.rt-td { + padding: 0px !important; +} + +.bp-cell-wrapper { + padding: 7px 5px; + height: 100%; +} + +.bp-cell-table { + margin-bottom: 0; + padding-left: 0; + list-style-type: none; +} -- GitLab From 868ded59695c1579e00b79ada5a95fc0f6c7bbe5 Mon Sep 17 00:00:00 2001 From: Conrad Date: Fri, 23 Feb 2018 11:35:26 -0500 Subject: [PATCH 03/27] Improve hover affect for dropdown menus --- src/containers/BGroup/BGroup.js | 45 +++++++++++++++----------------- src/containers/BGroup/styles.css | 41 +++++++++++++++++++++++++++++ src/styles.css | 36 ------------------------- 3 files changed, 62 insertions(+), 60 deletions(-) create mode 100644 src/containers/BGroup/styles.css diff --git a/src/containers/BGroup/BGroup.js b/src/containers/BGroup/BGroup.js index d4307bf6..d8d403f6 100644 --- a/src/containers/BGroup/BGroup.js +++ b/src/containers/BGroup/BGroup.js @@ -28,6 +28,7 @@ import AddressSearch from '../../components/AddressSearch/AddressSearch'; import userPropType from '../User/propTypes'; import request from '../../utils/request'; import { getHeaders, accountURL, gatewayURL, contactsURL, sfBuildingImpactURL } from '../../utils/restServices'; +import './styles.css'; const UTILITY_TYPES = { 1: 'electric', @@ -62,8 +63,8 @@ export class BGroup extends Component { numRows: -1, overviewTab: this.props.user.permissions['view::bgroupProjectsSummary'] ? 'projects' : 'buildings', displayContact: false, - displayAnalysis: false, - displayProjects: false, + displayAnalysis: true, + displayProjects: true, displayImpact: true, recommendedRetrofitsToggle: {}, recommendedDeemedToggle: {}, @@ -471,9 +472,7 @@ export class BGroup extends Component { accessor: 'electric_bill', style: { textAlign: 'center' }, Cell: row => ( -
      - {row.value ? : null} -
      + row.value ? : null ), }, { Header: 'Gas Bill', @@ -482,9 +481,7 @@ export class BGroup extends Component { accessor: 'gas_bill', style: { textAlign: 'center' }, Cell: row => ( -
      - {row.value ? : null} -
      + row.value ? : null ), }, { Header: 'Energy Simulation', @@ -511,9 +508,7 @@ export class BGroup extends Component { accessor: 'building_simulation', style: { textAlign: 'center' }, Cell: row => ( -
      - {row.value ? : null} -
      + row.value ? : null ), }, ], @@ -625,7 +620,7 @@ export class BGroup extends Component { [buildingId]: !this.state.recommendedRetrofitsToggle[buildingId], } }); }} - style={{ textAlign: 'center', backgroundColor: '#f7f7f9' }} + className="bp-cell-dropdown" > ); return ( -
      +
      {toggleButton}
        {row.value.map((val, index) => ( @@ -668,7 +663,7 @@ export class BGroup extends Component { [buildingId]: !this.state.recommendedDeemedToggle[buildingId], } }); }} - style={{ textAlign: 'center', backgroundColor: '#f7f7f9' }} + className="bp-cell-dropdown" > ); return ( -
        +
        {toggleButton}
          {row.value.map((val, index) => ( @@ -733,7 +729,7 @@ export class BGroup extends Component { [buildingId]: !this.state.completedDeemedToggle[buildingId], } }); }} - style={{ textAlign: 'center', backgroundColor: '#f7f7f9' }} + className="bp-cell-dropdown" > ); return ( -
          +
          {toggleButton}
            {row.value.map((val, index) => ( @@ -851,7 +847,8 @@ export class BGroup extends Component { {}} />{' '} Contact Info @@ -866,7 +863,7 @@ export class BGroup extends Component { {}} />{' '} Analysis @@ -881,7 +878,7 @@ export class BGroup extends Component { {}} />{' '} Projects @@ -896,7 +893,7 @@ export class BGroup extends Component { {}} />{' '} Impact diff --git a/src/containers/BGroup/styles.css b/src/containers/BGroup/styles.css new file mode 100644 index 00000000..c6f7d8cb --- /dev/null +++ b/src/containers/BGroup/styles.css @@ -0,0 +1,41 @@ +/* + * These two hovers work in conjunction to + * provide a more detailed view when + * you hover a list item in a react table, + * assuming the cell you are hovering over + * is surrounded by a div with the bp-cell-wrapper + * class + * */ +.rt-td:hover { + overflow: visible !important; + z-index: 1000; +} + +.bp-cell-wrapper:hover { + min-width: 100px; + width: fit-content; + background-color: white; + z-index: 1000; +} + +.rt-td { + padding: 0px !important; +} + +.bp-cell-wrapper { + padding: 7px 5px; + height: 100%; +} + +.bp-cell-table { + margin-bottom: 0; + padding-left: 0; + list-style-type: none; + text-align: left; +} + +.bp-cell-dropdown { + text-align: center; + background-color: #f7f7f9; + cursor: pointer; +} diff --git a/src/styles.css b/src/styles.css index ffb65d3c..a0391599 100644 --- a/src/styles.css +++ b/src/styles.css @@ -57,39 +57,3 @@ h6 { right: 0; background-color: white; } - - -/* - * These two hovers work in conjunction to - * provide a more detailed view when - * you hover a list item in a react table, - * assuming the cell you are hovering over - * is surrounded by a div with the bp-cell-wrapper - * class - * */ -.rt-td:hover { - overflow: visible !important; - z-index: 1000; -} - -.bp-cell-wrapper:hover { - min-width: 100px; - width: fit-content; - background-color: white; - z-index: 1000; -} - -.rt-td { - padding: 0px !important; -} - -.bp-cell-wrapper { - padding: 7px 5px; - height: 100%; -} - -.bp-cell-table { - margin-bottom: 0; - padding-left: 0; - list-style-type: none; -} -- GitLab From 088eee281a8f831be501721b32d7d5073899de9a Mon Sep 17 00:00:00 2001 From: Conrad Date: Fri, 23 Feb 2018 13:01:42 -0500 Subject: [PATCH 04/27] Fix bp wrapper dropdown for all columns with the dropdown --- src/containers/BGroup/BGroup.js | 16 +++++++++------- src/containers/BGroup/styles.css | 8 ++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/containers/BGroup/BGroup.js b/src/containers/BGroup/BGroup.js index d8d403f6..c135f3ed 100644 --- a/src/containers/BGroup/BGroup.js +++ b/src/containers/BGroup/BGroup.js @@ -377,7 +377,7 @@ export class BGroup extends Component { const utilityBillFilter = ({ filter, onChange }) => ( onChange(event.target.value)} - style={{ width: '100%' }} + className="bp-dropdown-filter" value={filter ? filter.value : 'all'} > @@ -539,7 +539,7 @@ export class BGroup extends Component { Filter: ({ filter, onChange }) => ( onChange(event.target.value)} - className="bp-dropdown-filter" - value={filter ? filter.value : 'all'} - > - - - - - ); - const columns = [{ - Header: () => ( - - Building Info{' '} - - - ), - columns: [ - { - Header: 'Address', - filterMethod: (filter, row) => ( - row._original.address_list.toLowerCase().indexOf( // eslint-disable-line - filter.value.toLowerCase() - ) !== -1 - ), - Filter: ({ filter, onChange }) => ( - onChange(event.target.value)} - /> - ), - accessor: 'first_address', - Cell: row => ( -
            - {row.value} -
            - ), - }, - ], - }, ...(!this.state.displayContact) ? [] : [{ - Header: () => ( - - Contact Info{' '} - - - ), - columns: [ - { - Header: 'Owner', - filterMethod: genericFilterMethod, - accessor: 'contact_account', - Cell: row => ( -
            - {row.value} -
            - ), - }, { - Header: 'Parent Company', - filterMethod: genericFilterMethod, - accessor: 'contact_parent_account', - Cell: row => ( -
            - {row.value} -
            - ), - }, - ], - }], ...(!this.state.displayAnalysis) ? [] : [{ - Header: () => ( - - Analysis{' '} - - - ), - columns: [ - { - Header: 'Electric Bill', - filterMethod: utilityBillFilterMethod, - Filter: utilityBillFilter, - accessor: 'electric_bill', - style: { textAlign: 'center' }, - Cell: row => ( - row.value ? : null - ), - }, { - Header: 'Gas Bill', - filterMethod: utilityBillFilterMethod, - Filter: utilityBillFilter, - accessor: 'gas_bill', - style: { textAlign: 'center' }, - Cell: row => ( - row.value ? : null - ), - }, { - Header: 'Energy Simulation', - filterMethod: (filter, row) => { - if (filter.value === 'all') { - return true; - } - if (filter.value === 'complete') { - return row[filter.id]; - } - return !row[filter.id]; - }, - Filter: ({ filter, onChange }) => ( - - ), - accessor: 'building_simulation', - style: { textAlign: 'center' }, - Cell: row => ( - row.value ? : null - ), - }, - ], - }], ...(!this.state.displayProjects) ? [] : [{ - Header: () => ( - - Projects{' '} - - - ), - columns: [ - // Only show the sensor install column if the user has the correct permission - ...(!this.props.user.permissions['read::Gateway']) ? [] : [{ - Header: 'Sensor Install', - filterMethod: (filter, row) => { - if (filter.value === 'all') { - return true; - } - if (filter.value === 'installed') { - return row[filter.id]; - } - return !row[filter.id]; - }, - Filter: ({ filter, onChange }) => ( - - ), - accessor: 'gateway_install', - sortMethod: (a, b) => { - if (!b && a) { - return 1; - } else if (b && !a) { - return -1; - } else if (!b && !a) { - return 0; - } - const d1 = new Date(a[0]); - const d2 = new Date(b[0]); - if (d1.getTime() === d2.getTime()) { - return 0; - } - return d1 > d2 ? 1 : -1; - }, - Cell: row => (row.value ? ( -
            -
              - {row.value.map((installDate, index) => ( -
            • {installDate}
            • - ))} -
            -
            - ) : null), - }], { - Header: '# Projects', - filterable: false, - style: { textAlign: 'center' }, - accessor: 'num_projects', - }, { - Header: 'Project Types', - filterMethod: listFilterMethod, - accessor: 'project_types', - Cell: row => (row.value ? ( -
            -
              - {row.value.map((type, index) => ( -
            • {type}
            • - ))} -
            -
            - ) : null), - }, - ], - }], ...(!this.state.displayImpact) ? [] : [{ - Header: () => ( - - Impact{' '} - - - ), - columns: [ - { - Header: 'Recommended Retrofits', - filterMethod: listFilterMethod, - accessor: 'recommended_retrofits', - Cell: (row) => { - if (row.value && row.value.length > 0) { - const buildingId = row.original.building_id; - const toggleButton = ( - /* eslint-disable jsx-a11y/no-static-element-interactions */ -
            { - this.setState({ recommendedRetrofitsToggle: { - ...this.state.recommendedRetrofitsToggle, - [buildingId]: !this.state.recommendedRetrofitsToggle[buildingId], - } }); - }} - className="bp-cell-dropdown" - > - {' '} - {this.state.recommendedRetrofitsToggle[buildingId] ? 'Hide' : 'Show'} -
            - ); - return ( -
            - {toggleButton} - -
              - {row.value.map((val, index) => ( -
            • {val}
            • - ))} -
            -
            -
            - ); - } - return null; - }, - }, { - Header: 'Deemed Savings (recommended)', - filterable: false, - style: { textAlign: 'center' }, - accessor: 'projected_deemed_savings', - Cell: (row) => { - if (row.value && row.value.length > 0) { - const buildingId = row.original.building_id; - const toggleButton = ( - /* eslint-disable jsx-a11y/no-static-element-interactions */ -
            { - this.setState({ recommendedDeemedToggle: { - ...this.state.recommendedDeemedToggle, - [buildingId]: !this.state.recommendedDeemedToggle[buildingId], - } }); - }} - className="bp-cell-dropdown" - > - {' '} - {this.state.recommendedDeemedToggle[buildingId] ? 'Hide' : 'Show'} -
            - ); - return ( -
            - {toggleButton} - -
              - {row.value.map((val, index) => ( -
            • {val}
            • - ))} -
            -
            -
            - ); - } - return null; - }, - }, { - Header: 'Completed Retrofits', - filterMethod: (filter, row) => { - if (row[filter.id]) { - return row[filter.id].reduce((acc, val) => ( - val && (acc || val.completed.toLowerCase().indexOf( - filter.value.toLowerCase() - ) !== -1) - ), false); - } - return false; - }, - accessor: 'completed_retrofits', - Cell: row => (row.value ? ( -
            -
              - {row.value.map((val, index) => ( -
            • {val.completed} ({(new Date(val.completed_date)).toLocaleDateString('en-US')})
            • - ))} -
            -
            - ) : null), - }, { - Header: 'Deemed Savings (completed)', - filterable: false, - style: { textAlign: 'center' }, - accessor: 'completed_deemed_savings', - Cell: (row) => { - if (row.value && row.value.length > 0) { - const buildingId = row.original.building_id; - const toggleButton = ( - /* eslint-disable jsx-a11y/no-static-element-interactions */ -
            { - this.setState({ completedDeemedToggle: { - ...this.state.completedDeemedToggle, - [buildingId]: !this.state.completedDeemedToggle[buildingId], - } }); - }} - className="bp-cell-dropdown" - > - {' '} - {this.state.completedDeemedToggle[buildingId] ? 'Hide' : 'Show'} -
            - ); - return ( -
            - {toggleButton} - -
              - {row.value.map((val, index) => ( -
            • {val}
            • - ))} -
            -
            -
            - ); - } - return null; - }, - }, - ], - }]]; - if (this.state.edit) { - columns.push({ - Header: '', - filterable: false, - accessor: 'delete', - maxWidth: 35, - Cell: row => this.renderDeleteBuildingButton(row.original.id), - }); - } - bGroupBuildings = bGroupBuildings.map((val) => { - const projects = this.state.buildingIdProject[val.building_id]; - if (projects) { - val.num_projects = projects.length; - val.project_types = projects.map(proj => (proj.project_type)); - } else { - val.num_projects = 0; - val.project_types = []; - } - const utilityStatus = this.state.utilityAccountsStatus[val.building_id]; - if (utilityStatus) { - val.electric_bill = utilityStatus.electric; - val.gas_bill = utilityStatus.gas; - } - val.gateway_install = this.state.gatewayDates[val.building_id]; - val.building_simulation = this.state.simulationDates[val.building_id]; - val.contact_account = this.state.contactAccounts[val.building_id]; - val.contact_parent_account = this.state.contactParentAccounts[val.building_id]; - if (this.state.impact[val.building_id]) { - const impactObjects = this.state.impact[val.building_id]; - if (impactObjects.diagnostic_recommendations.length > 0) { - val.recommended_retrofits = impactObjects.diagnostic_recommendations; - } else { - val.recommended_retrofits = impactObjects.pns_recommendations; - } - val.completed_retrofits = impactObjects.complete; - // Create a list of all of the projected deemed values - val.projected_deemed_savings = Object.keys(impactObjects.deemed.projected).reduce( - (acc, key) => ([ - ...acc, - ...(impactObjects.deemed.projected[key]) ? [`${impactObjects.deemed.projected[key]} ${key.replace('Projected ', '')}`] : [], - ]), [] - ); - // Create a list of all of the completed deemed values - val.completed_deemed_savings = Object.keys(impactObjects.deemed.completed).reduce( - (acc, key) => ([ - ...acc, - ...(impactObjects.deemed.completed[key]) ? [`${impactObjects.deemed.completed[key]} ${key.replace('Completed ', '')}`] : [], - ]), [] - ); - } else { - val.recommended_retrofits = []; - val.completed_retrofits = []; - val.projected_deemed_savings = []; - val.completed_deemed_savings = []; - } - - return val; - }); - return ( -
            -
            -
            - - -
            -
            -
            = 0 ? '' : 'none' }}> -
            -
            {this.state.numRows} buildings
            -
            - - - Toggle Columns - - - { - this.setState({ displayContact: !this.state.displayContact }); - }} - > - - {}} - />{' '} - Contact Info - - - { - this.setState({ displayAnalysis: !this.state.displayAnalysis }); - }} - > - - {}} - />{' '} - Analysis - - - { - this.setState({ displayProjects: !this.state.displayProjects }); - }} - > - - {}} - />{' '} - Projects - - - { - this.setState({ displayImpact: !this.state.displayImpact }); - }} - > - - {}} - />{' '} - Impact - - - - -
            -
            -
            - { this.reactTable = reactTable; }} - onFilteredChange={(filter) => { - // Create a bounce function so as to not decrease the speed of the filter. - clearTimeout(this.updateNumRows); - this.updateNumRows = setTimeout( - () => { - ReactGA.event({ - category: 'Building Group', - action: 'Filter', - label: filter.reduce((acc, val) => { - return ( - `${acc}, ${val.id}: ${val.value}` - ); - }, `Building Group: ${this.props.bGroup.bGroupDetail.name}, # Results: ${this.reactTable.state.sortedData.length}`), - }); - this.setState({ - numRows: this.reactTable.state.sortedData.length, - }); - }, - 250, - ); - }} - noDataText={this.props.bGroup.bGroupDetailLoading ? 'Loading...' : 'No data'} - SubComponent={row => { - const addresses = bGroupBuildings - .filter(i => i.building_id === row.original.building_id) - .reduce((acc, val) => val.address_list, '') - .split(','); - return ( -
            - -
            -
            -

            - Address list{' '} - - - -

            -
              - {addresses.map(i =>
            • {i}
            • )} -
            -
            - {this.state.buildingIdProject[row.original.building_id] ? ( -
            -

            - Project list -

            -
              - {this.state.buildingIdProject[row.original.building_id].map((i) => { - let spanStatus = 'pending'; - if (i.state === 'constructed') { - spanStatus = 'claimed'; - } else if (i.state === 'cancelled') { - spanStatus = 'rejected'; - } - return ( -
            • - { i.state } - {' '} - { i.project_type } - {' '} - {i.name} -
            • - ); - })} -
            -
            - ) : null} -
            -
            - ); - }} - /> -
            -
            -
            - ); - } - render() { let content = ( @@ -1003,7 +311,28 @@ export class BGroup extends Component { ); break; case 'buildings': - content = this.renderBuildingGroup(); + content = ( + + ); break; default: content = 'There was an error'; @@ -1016,7 +345,7 @@ export class BGroup extends Component {
            -
            +
            View all groups {' '}

            -
          - {this.state.buildingIdProject[row.original.building_id] ? ( + {buildingIdProject[row.original.building_id] ? (

          Project list

            - {this.state.buildingIdProject[row.original.building_id].map((i) => { + {buildingIdProject[row.original.building_id].map((i) => { let spanStatus = 'pending'; if (i.state === 'constructed') { spanStatus = 'claimed'; @@ -745,5 +745,9 @@ BGroupBuildingTable.propTypes = { simulationLoading: PropTypes.bool, gatewayLoading: PropTypes.bool, impactLoading: PropTypes.bool, + displayToggleColumns: PropTypes.bool, + toggleContacts: PropTypes.bool, + toggleAnalysis: PropTypes.bool, + toggleProjects: PropTypes.bool, + toggleImpact: PropTypes.bool, }; - -- GitLab From d3d40cc8b07af95efd38c6ab16190a6ce44fcdec Mon Sep 17 00:00:00 2001 From: Conrad Date: Wed, 28 Feb 2018 11:52:44 -0500 Subject: [PATCH 15/27] Initial bgroup detail view --- .../Reports/components/BpImpact/index.js | 16 ++++++++++++++++ src/containers/Reports/index.js | 1 + 2 files changed, 17 insertions(+) diff --git a/src/containers/Reports/components/BpImpact/index.js b/src/containers/Reports/components/BpImpact/index.js index 564d91f9..2ff863b1 100644 --- a/src/containers/Reports/components/BpImpact/index.js +++ b/src/containers/Reports/components/BpImpact/index.js @@ -1,11 +1,25 @@ import React from 'react'; import ReactTooltip from 'react-tooltip'; +import PropTypes from 'prop-types'; import { bpImpactReportPropTypes } from '../../propTypes'; +import { BGroup } from '../../../../containers/BGroup'; +import userPropType from '../../../../containers/User/propTypes'; + export default function BpImpact({ bpImpactReports, + detail, + user, }) { + if (detail) { + return ( + + ); + } const dateCompareString = ` The blue number represents the difference between the last two generated reports
            @@ -63,4 +77,6 @@ export default function BpImpact({ BpImpact.propTypes = { bpImpactReports: bpImpactReportPropTypes, + detail: PropTypes.bool, + user: userPropType, }; diff --git a/src/containers/Reports/index.js b/src/containers/Reports/index.js index 410de7d0..e7253d78 100644 --- a/src/containers/Reports/index.js +++ b/src/containers/Reports/index.js @@ -60,6 +60,7 @@ class Reports extends Component { ); break; -- GitLab From c485f0d28eeb3116a9ea4d7604f6b1f75bcf3a5e Mon Sep 17 00:00:00 2001 From: Conrad Date: Wed, 28 Feb 2018 12:02:02 -0500 Subject: [PATCH 16/27] Display nav bar via props --- src/containers/BGroup/BGroup.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/containers/BGroup/BGroup.js b/src/containers/BGroup/BGroup.js index c218a416..ac3060f9 100644 --- a/src/containers/BGroup/BGroup.js +++ b/src/containers/BGroup/BGroup.js @@ -346,7 +346,7 @@ export class BGroup extends Component { return (
            - + {this.props.displayNavBar ? : null}
            @@ -417,6 +417,7 @@ BGroup.propTypes = { user: userPropType, projects: completeProjectPropTypes, loadProjects: PropTypes.func, + displayNavBar: PropTypes.bool, displayProjectOverview: PropTypes.bool, displayBuildingOverview: PropTypes.bool, displayOverviewTab: PropTypes.bool, @@ -430,6 +431,7 @@ BGroup.propTypes = { }; BGroup.defaultProps = { + displayNavBar: true, displayProjectOverview: true, displayBuildingOverview: true, displayOverviewTab: true, -- GitLab From 0d39a0492fee0fe0c92bbd30f9edda834e08faee Mon Sep 17 00:00:00 2001 From: Conrad Date: Wed, 28 Feb 2018 12:37:47 -0500 Subject: [PATCH 17/27] Add loading to bpimpact --- .../Reports/components/BpImpact/index.js | 20 ++++++ .../Reports/components/Lighting/index.js | 9 +++ src/containers/Reports/index.js | 72 +++++++++---------- 3 files changed, 65 insertions(+), 36 deletions(-) diff --git a/src/containers/Reports/components/BpImpact/index.js b/src/containers/Reports/components/BpImpact/index.js index 2ff863b1..ff0ca037 100644 --- a/src/containers/Reports/components/BpImpact/index.js +++ b/src/containers/Reports/components/BpImpact/index.js @@ -1,6 +1,7 @@ import React from 'react'; import ReactTooltip from 'react-tooltip'; import PropTypes from 'prop-types'; +import { Icon } from 'react-fa'; import { bpImpactReportPropTypes } from '../../propTypes'; import { BGroup } from '../../../../containers/BGroup'; @@ -11,12 +12,30 @@ export default function BpImpact({ bpImpactReports, detail, user, + loading, }) { + if (loading) { + return ( +
            + +
            + ); + } if (detail) { return ( ); } @@ -78,5 +97,6 @@ export default function BpImpact({ BpImpact.propTypes = { bpImpactReports: bpImpactReportPropTypes, detail: PropTypes.bool, + loading: PropTypes.bool, user: userPropType, }; diff --git a/src/containers/Reports/components/Lighting/index.js b/src/containers/Reports/components/Lighting/index.js index af7c8840..4d2012e5 100644 --- a/src/containers/Reports/components/Lighting/index.js +++ b/src/containers/Reports/components/Lighting/index.js @@ -8,7 +8,15 @@ import { lightingReportPropTypes } from '../../propTypes'; export default function Lighting({ lightingReports, detail, + loading, }) { + if (loading) { + return ( +
            + +
            + ); + } const dateCompareString = ` The blue number represents the difference between the last two generated reports
            @@ -76,4 +84,5 @@ export default function Lighting({ Lighting.propTypes = { lightingReports: lightingReportPropTypes, detail: PropTypes.bool, + loading: PropTypes.bool, }; diff --git a/src/containers/Reports/index.js b/src/containers/Reports/index.js index e7253d78..937d6c6c 100644 --- a/src/containers/Reports/index.js +++ b/src/containers/Reports/index.js @@ -5,7 +5,6 @@ import { connect } from 'react-redux'; import { Link } from 'react-router'; import { bindActionCreators } from 'redux'; import { Nav, NavItem, NavLink } from 'reactstrap'; -import { Icon } from 'react-fa'; import ReactTooltip from 'react-tooltip'; import { @@ -36,45 +35,45 @@ class Reports extends Component { } } if (this.props.user.permissions['read::BpImpact']) { - console.log('Loading report'); this.props.loadBpImpactReports(2); } } render() { - let content = ( -
            - -
            - ); - const loading = ( - this.props.report.lightingReports.length === 0 || - this.props.report.loadingLighting || - this.props.report.bpImpactReports.length === 0 || - this.props.report.loadingBpImpact - ); - if (!loading) { - switch (this.state.reportTab) { - case 'bpimpact': - content = ( - - ); - break; - case 'lighting': - content = ( - - ); - break; - default: - content = 'There was an error'; - } + let content = null; + let loading = false; + switch (this.state.reportTab) { + case 'bpimpact': + loading = ( + this.state.mode === 'summary' && ( + this.props.report.bpImpactReports.length === 0 || + this.props.report.loadingBpImpact + ) + ); + content = ( + + ); + break; + case 'lighting': + loading = ( + this.props.report.lightingReports.length === 0 || + this.props.report.loadingLighting + ); + content = ( + + ); + break; + default: + content = 'There was an error'; } if (this.props.report.error) { content = 'There was an error'; @@ -85,6 +84,7 @@ class Reports extends Component { ) { content = 'You do not have the permission to view this report'; } + return ( // create a simple report that is engaged, out to bid, complete, total active, total inactive
            @@ -112,7 +112,7 @@ class Reports extends Component { ) : null } -
            +
            {content}
            -- GitLab From 153cb8741dc7b0df7787b2af2410fbb28e04efdc Mon Sep 17 00:00:00 2001 From: Conrad Date: Wed, 28 Feb 2018 13:33:44 -0500 Subject: [PATCH 18/27] Update readme with new env variable --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ee44ae3a..4cba54a1 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ REACT_APP_AUTH0_CALLBACK_URL REACT_APP_AUTH0_CLAIMS_NAMESPACE REACT_APP_AUTH0_AUDIENCE REACT_APP_FEEDBACK_LINK +REACT_APP_BP_BGROUP_ID ``` ### Optional - [React Devtools](https://github.com/facebook/react-devtools) -- GitLab From 418a7c019f91f14658d090f2e7d516e9e07b77b6 Mon Sep 17 00:00:00 2001 From: Conrad Date: Thu, 1 Mar 2018 10:58:47 -0500 Subject: [PATCH 19/27] USe env variable for bgroup id --- src/containers/Reports/components/BpImpact/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/Reports/components/BpImpact/index.js b/src/containers/Reports/components/BpImpact/index.js index ff0ca037..45bfe860 100644 --- a/src/containers/Reports/components/BpImpact/index.js +++ b/src/containers/Reports/components/BpImpact/index.js @@ -24,7 +24,7 @@ export default function BpImpact({ if (detail) { return ( Date: Thu, 1 Mar 2018 14:49:43 -0500 Subject: [PATCH 20/27] Add overal impact report to report detail --- .../Reports/components/BpImpact/index.js | 36 +++++++++---------- src/containers/Reports/index.js | 6 ++-- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/containers/Reports/components/BpImpact/index.js b/src/containers/Reports/components/BpImpact/index.js index 45bfe860..ec4656e5 100644 --- a/src/containers/Reports/components/BpImpact/index.js +++ b/src/containers/Reports/components/BpImpact/index.js @@ -21,24 +21,6 @@ export default function BpImpact({
            ); } - if (detail) { - return ( - - ); - } const dateCompareString = ` The blue number represents the difference between the last two generated reports
            @@ -90,6 +72,24 @@ export default function BpImpact({ } + { + detail ? ( + + ) : null + }
            ); } diff --git a/src/containers/Reports/index.js b/src/containers/Reports/index.js index 937d6c6c..4729ff54 100644 --- a/src/containers/Reports/index.js +++ b/src/containers/Reports/index.js @@ -45,10 +45,8 @@ class Reports extends Component { switch (this.state.reportTab) { case 'bpimpact': loading = ( - this.state.mode === 'summary' && ( - this.props.report.bpImpactReports.length === 0 || - this.props.report.loadingBpImpact - ) + this.props.report.bpImpactReports.length === 0 || + this.props.report.loadingBpImpact ); content = ( Date: Thu, 1 Mar 2018 15:46:32 -0500 Subject: [PATCH 21/27] Increase width of detail to 100% --- src/containers/Reports/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/containers/Reports/index.js b/src/containers/Reports/index.js index 4729ff54..c9ae3b62 100644 --- a/src/containers/Reports/index.js +++ b/src/containers/Reports/index.js @@ -85,7 +85,7 @@ class Reports extends Component { return ( // create a simple report that is engaged, out to bid, complete, total active, total inactive -
            +
            -
            +
            {content}
            -- GitLab From ee655fb55f956da9dcabf84199b24f4f7e08a78e Mon Sep 17 00:00:00 2001 From: Conrad Date: Thu, 1 Mar 2018 16:04:29 -0500 Subject: [PATCH 22/27] Add impact report for each bgroup --- src/containers/BGroup/BGroup.js | 34 +++++++++++++++++-- .../BGroup/BGroupProjectOverview.js | 15 ++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/containers/BGroup/BGroup.js b/src/containers/BGroup/BGroup.js index ac3060f9..0ccdffbb 100644 --- a/src/containers/BGroup/BGroup.js +++ b/src/containers/BGroup/BGroup.js @@ -24,7 +24,10 @@ import completeProjectPropTypes from '../Project/propTypes'; import { loadProjects } from '../Project/actions'; import userPropType from '../User/propTypes'; import request from '../../utils/request'; -import { getHeaders, accountURL, gatewayURL, contactsURL, sfBuildingImpactURL } from '../../utils/restServices'; +import { + getHeaders, accountURL, gatewayURL, + contactsURL, sfBuildingImpactURL, bpImpactReportURL, +} from '../../utils/restServices'; import './styles.css'; const UTILITY_TYPES = { @@ -56,6 +59,9 @@ export class BGroup extends Component { impactLoading: false, impactError: false, impact: {}, + impactSummaryLoading: false, + impactSummaryError: false, + impactSummary: {}, overviewTab: this.props.user.permissions['view::bgroupProjectsSummary'] && this.props.displayProjectOverview ? 'projects' : 'buildings', } @@ -80,6 +86,7 @@ export class BGroup extends Component { } this.getSimulationDates(buildingIds); this.getSfBuildingImpact(buildingIds); + this.getImpactSummary(buildingIds); } } if ( @@ -120,7 +127,7 @@ export class BGroup extends Component { } getSfBuildingImpact = (buildingIds) => { - // A function to determine dates of gateway install + // A function to get impat data for each building this.setState({ impactLoading: true }); const filterString = buildingIds.reduce((acc, val) => ( `${acc}building_id[]=${val}&` @@ -137,6 +144,26 @@ export class BGroup extends Component { this.setState({ impactError: true }); } }); + } + + getImpactSummary = (buildingIds) => { + // A function to get impact data for the whole bgroup + this.setState({ impactSummaryLoading: true }); + const filterString = buildingIds.reduce((acc, val) => ( + `${acc}building_id=${val}&` + ), ''); + request(`${bpImpactReportURL}?generate=true&${filterString}`, { + method: 'GET', + headers: getHeaders(), + }).then((res) => { + this.setState({ impactSummaryLoading: false }); + const data = res.data; + if (!res.err && data) { + this.setState({ impactSummary: data }); + } else { + this.setState({ impactSummaryError: true }); + } + }); } @@ -307,6 +334,9 @@ export class BGroup extends Component { projects={this.props.projects} projectStatusBreakdown={this.state.projectStatusBreakdown} projectTypeBreakdown={this.state.projectTypeBreakdown} + impactSummary={this.state.impactSummary} + impactSummaryLoading={this.state.impactSummaryLoading} + impactSummaryError={this.state.impactSummaryError} /> ); break; diff --git a/src/containers/BGroup/BGroupProjectOverview.js b/src/containers/BGroup/BGroupProjectOverview.js index eccb35e9..60281ce3 100644 --- a/src/containers/BGroup/BGroupProjectOverview.js +++ b/src/containers/BGroup/BGroupProjectOverview.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import userPropTypes from '../User/propTypes'; import completeProjectPropTypes from '../Project/propTypes'; import Loading from '../../components/Loading'; +import BpImpact from '../../containers/Reports/components/BpImpact'; export default class BGroupProjectOverview extends Component { state = { }; @@ -12,6 +13,8 @@ export default class BGroupProjectOverview extends Component { user, projects, projectStatusBreakdown, projectTypeBreakdown, + impactSummary, + impactSummaryLoading, } = this.props; if (projects.loading) { return ; @@ -27,6 +30,16 @@ export default class BGroupProjectOverview extends Component { return (
            +
            + +
            +
            +

            Project Type Summary

            @@ -92,5 +105,7 @@ BGroupProjectOverview.propTypes = { projects: completeProjectPropTypes, projectTypeBreakdown: PropTypes.object, // eslint-disable-line projectStatusBreakdown: PropTypes.object, // eslint-disable-line + impactSummary: PropTypes.array, // eslint-disable-line + impactSummaryLoading: PropTypes.bool, }; -- GitLab From 3565408f05c8274a758c1a60a8319827982e0702 Mon Sep 17 00:00:00 2001 From: Conrad Date: Thu, 1 Mar 2018 16:34:15 -0500 Subject: [PATCH 23/27] Clearly display errors on project overview --- src/containers/BGroup/BGroup.js | 7 ++----- src/containers/BGroup/BGroupProjectOverview.js | 13 +++++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/containers/BGroup/BGroup.js b/src/containers/BGroup/BGroup.js index 0ccdffbb..069b5bcb 100644 --- a/src/containers/BGroup/BGroup.js +++ b/src/containers/BGroup/BGroup.js @@ -61,7 +61,7 @@ export class BGroup extends Component { impact: {}, impactSummaryLoading: false, impactSummaryError: false, - impactSummary: {}, + impactSummary: [], overviewTab: this.props.user.permissions['view::bgroupProjectsSummary'] && this.props.displayProjectOverview ? 'projects' : 'buildings', } @@ -89,10 +89,7 @@ export class BGroup extends Component { this.getImpactSummary(buildingIds); } } - if ( - nextProps.projects.projects.length > 0 && - nextProps.projects.projects !== this.props.projects.project - ) { + if (nextProps.projects.projects !== this.props.projects.project) { const projectTypeBreakdown = {}; const projectStatusBreakdown = {}; const buildingIdProject = nextProps.projects.projects.reduce( diff --git a/src/containers/BGroup/BGroupProjectOverview.js b/src/containers/BGroup/BGroupProjectOverview.js index 60281ce3..42b9b25e 100644 --- a/src/containers/BGroup/BGroupProjectOverview.js +++ b/src/containers/BGroup/BGroupProjectOverview.js @@ -16,14 +16,14 @@ export default class BGroupProjectOverview extends Component { impactSummary, impactSummaryLoading, } = this.props; - if (projects.loading) { + if (projects.loading || impactSummaryLoading) { return ; } - if ( - !user.permissions['view::bgroupProjectsSummary'] || - Object.keys(projectTypeBreakdown).length === 0 - ) { - return null; + if (!user.permissions['view::bgroupProjectsSummary']) { + return
            Incorrect permissions
            ; + } + if (Object.keys(projectTypeBreakdown).length === 0) { + return
            Insufficient project data
            ; } let numProjects = 0; const stageOrder = ['Engaged', 'Out to Bid', 'In Construction', 'Complete', 'HPD Pipeline']; @@ -31,6 +31,7 @@ export default class BGroupProjectOverview extends Component {
            +

            Project Impact Summary

            Date: Thu, 1 Mar 2018 17:02:53 -0500 Subject: [PATCH 24/27] Don't show report if no report --- src/containers/BGroup/BGroup.js | 2 +- src/containers/Reports/components/BpImpact/index.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/containers/BGroup/BGroup.js b/src/containers/BGroup/BGroup.js index 069b5bcb..20fe9260 100644 --- a/src/containers/BGroup/BGroup.js +++ b/src/containers/BGroup/BGroup.js @@ -153,13 +153,13 @@ export class BGroup extends Component { method: 'GET', headers: getHeaders(), }).then((res) => { - this.setState({ impactSummaryLoading: false }); const data = res.data; if (!res.err && data) { this.setState({ impactSummary: data }); } else { this.setState({ impactSummaryError: true }); } + this.setState({ impactSummaryLoading: false }); }); } diff --git a/src/containers/Reports/components/BpImpact/index.js b/src/containers/Reports/components/BpImpact/index.js index ec4656e5..a549ff23 100644 --- a/src/containers/Reports/components/BpImpact/index.js +++ b/src/containers/Reports/components/BpImpact/index.js @@ -21,6 +21,9 @@ export default function BpImpact({
            ); } + if (bpImpactReports.length < 1) { + return
            No report
            + } const dateCompareString = ` The blue number represents the difference between the last two generated reports
            -- GitLab From e7745517a9c1f89360856ac39567e689a08c5f13 Mon Sep 17 00:00:00 2001 From: Conrad Date: Thu, 1 Mar 2018 17:03:30 -0500 Subject: [PATCH 25/27] Add missing semicolan --- src/containers/Reports/components/BpImpact/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/Reports/components/BpImpact/index.js b/src/containers/Reports/components/BpImpact/index.js index a549ff23..601e0982 100644 --- a/src/containers/Reports/components/BpImpact/index.js +++ b/src/containers/Reports/components/BpImpact/index.js @@ -22,7 +22,7 @@ export default function BpImpact({ ); } if (bpImpactReports.length < 1) { - return
            No report
            + return
            No report
            ; } const dateCompareString = ` The blue number represents the difference between the last two generated reports -- GitLab From 5befa7221cb5c8461aa56ca9f97ead77c5137f2e Mon Sep 17 00:00:00 2001 From: Conrad Date: Fri, 2 Mar 2018 14:47:22 -0500 Subject: [PATCH 26/27] Add a report that responds to filter on report detail --- src/containers/BGroup/BGroup.js | 50 +++---- src/containers/BGroup/BGroupBuildingTable.js | 6 + .../BGroup/BGroupProjectOverview.js | 5 +- src/containers/Reports/actions.js | 30 +++++ .../Reports/components/BpImpact/BpImpact.js | 81 ++++++++++++ .../components/BpImpact/BpImpactWrapper.js | 122 ++++++++++++++++++ .../Reports/components/BpImpact/index.js | 105 --------------- .../Reports/components/Lighting/index.js | 9 +- src/containers/Reports/constants.js | 4 + src/containers/Reports/index.js | 14 +- src/containers/Reports/reducer.js | 28 +++- src/containers/Reports/sagas.js | 23 ++++ 12 files changed, 321 insertions(+), 156 deletions(-) create mode 100644 src/containers/Reports/components/BpImpact/BpImpact.js create mode 100644 src/containers/Reports/components/BpImpact/BpImpactWrapper.js delete mode 100644 src/containers/Reports/components/BpImpact/index.js diff --git a/src/containers/BGroup/BGroup.js b/src/containers/BGroup/BGroup.js index 20fe9260..84361e66 100644 --- a/src/containers/BGroup/BGroup.js +++ b/src/containers/BGroup/BGroup.js @@ -22,11 +22,13 @@ import BGroupProjectOverview from './BGroupProjectOverview'; import BGroupBuildingTable from './BGroupBuildingTable'; import completeProjectPropTypes from '../Project/propTypes'; import { loadProjects } from '../Project/actions'; +import { loadCustomBpImpactReport } from '../Reports/actions'; +import reportsPropTypes from '../Reports/propTypes'; import userPropType from '../User/propTypes'; import request from '../../utils/request'; import { getHeaders, accountURL, gatewayURL, - contactsURL, sfBuildingImpactURL, bpImpactReportURL, + contactsURL, sfBuildingImpactURL, } from '../../utils/restServices'; import './styles.css'; @@ -59,9 +61,6 @@ export class BGroup extends Component { impactLoading: false, impactError: false, impact: {}, - impactSummaryLoading: false, - impactSummaryError: false, - impactSummary: [], overviewTab: this.props.user.permissions['view::bgroupProjectsSummary'] && this.props.displayProjectOverview ? 'projects' : 'buildings', } @@ -86,7 +85,7 @@ export class BGroup extends Component { } this.getSimulationDates(buildingIds); this.getSfBuildingImpact(buildingIds); - this.getImpactSummary(buildingIds); + this.props.loadCustomBpImpactReport(buildingIds); } } if (nextProps.projects.projects !== this.props.projects.project) { @@ -119,10 +118,6 @@ export class BGroup extends Component { } } - componentWillUnmount() { - clearTimeout(this.updateNumRows); - } - getSfBuildingImpact = (buildingIds) => { // A function to get impat data for each building this.setState({ impactLoading: true }); @@ -143,27 +138,6 @@ export class BGroup extends Component { }); } - getImpactSummary = (buildingIds) => { - // A function to get impact data for the whole bgroup - this.setState({ impactSummaryLoading: true }); - const filterString = buildingIds.reduce((acc, val) => ( - `${acc}building_id=${val}&` - ), ''); - request(`${bpImpactReportURL}?generate=true&${filterString}`, { - method: 'GET', - headers: getHeaders(), - }).then((res) => { - const data = res.data; - if (!res.err && data) { - this.setState({ impactSummary: data }); - } else { - this.setState({ impactSummaryError: true }); - } - this.setState({ impactSummaryLoading: false }); - }); - - } - getContacts = (projects) => { // A function to get all of the contact information for buildings this.setState({ contactLoading: true }); @@ -322,7 +296,7 @@ export class BGroup extends Component { let content = ( ); - if (!this.props.bGroup.bGroupDetailLoading) { + if (!this.props.bGroup.bGroupDetailLoading && this.props.bGroup.bGroupDetail.name !== '') { switch (this.state.overviewTab) { case 'projects': content = ( @@ -331,9 +305,8 @@ export class BGroup extends Component { projects={this.props.projects} projectStatusBreakdown={this.state.projectStatusBreakdown} projectTypeBreakdown={this.state.projectTypeBreakdown} - impactSummary={this.state.impactSummary} - impactSummaryLoading={this.state.impactSummaryLoading} - impactSummaryError={this.state.impactSummaryError} + impactSummary={this.props.report.customBpImpactReport} + impactSummaryLoading={this.props.report.loadingCustomBpImpact} /> ); break; @@ -363,6 +336,7 @@ export class BGroup extends Component { toggleAnalysis={this.props.toggleAnalysis} toggleProjects={this.props.toggleProjects} toggleImpact={this.props.toggleImpact} + onBuildingFilter={this.props.onBuildingFilter} /> ); break; @@ -375,7 +349,7 @@ export class BGroup extends Component {
            {this.props.displayNavBar ? : null}
            -
            +
            View all groups @@ -443,6 +417,8 @@ BGroup.propTypes = { deleteBuildingFromBGroup: PropTypes.func, user: userPropType, projects: completeProjectPropTypes, + report: reportsPropTypes, + loadCustomBpImpactReport: PropTypes.func, loadProjects: PropTypes.func, displayNavBar: PropTypes.bool, displayProjectOverview: PropTypes.bool, @@ -455,6 +431,7 @@ BGroup.propTypes = { toggleAnalysis: PropTypes.bool, toggleProjects: PropTypes.bool, toggleImpact: PropTypes.bool, + onBuildingFilter: PropTypes.func, }; BGroup.defaultProps = { @@ -469,12 +446,14 @@ BGroup.defaultProps = { toggleAnalysis: true, toggleProjects: true, toggleImpact: true, + onBuildingFilter: () => { }, }; const mapStateToProps = state => ( { bGroup: state.bGroup, projects: state.projectList, + report: state.report, } ); @@ -486,6 +465,7 @@ const mapDispatchToProps = dispatch => ( deleteBuildingFromBGroup, deleteBGroup, loadProjects, + loadCustomBpImpactReport, }, dispatch) ); diff --git a/src/containers/BGroup/BGroupBuildingTable.js b/src/containers/BGroup/BGroupBuildingTable.js index 0dec97fb..ab26d832 100644 --- a/src/containers/BGroup/BGroupBuildingTable.js +++ b/src/containers/BGroup/BGroupBuildingTable.js @@ -29,6 +29,10 @@ export default class BGroupBuildingTable extends Component { completedDeemedToggle: {}, }; + componentWillUnmount() { + clearTimeout(this.updateNumRows); + } + handleAddBuilding = (item) => { this.props.addBuildingToBGroup( this.props.bGroupId, @@ -667,6 +671,7 @@ export default class BGroupBuildingTable extends Component { }, 250, ); + this.props.onBuildingFilter(filter, this.reactTable.state); }} noDataText={this.props.bGroup.bGroupDetailLoading ? 'Loading...' : 'No data'} SubComponent={row => { @@ -750,4 +755,5 @@ BGroupBuildingTable.propTypes = { toggleAnalysis: PropTypes.bool, toggleProjects: PropTypes.bool, toggleImpact: PropTypes.bool, + onBuildingFilter: PropTypes.func, }; diff --git a/src/containers/BGroup/BGroupProjectOverview.js b/src/containers/BGroup/BGroupProjectOverview.js index 42b9b25e..cb9e4933 100644 --- a/src/containers/BGroup/BGroupProjectOverview.js +++ b/src/containers/BGroup/BGroupProjectOverview.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import userPropTypes from '../User/propTypes'; import completeProjectPropTypes from '../Project/propTypes'; import Loading from '../../components/Loading'; -import BpImpact from '../../containers/Reports/components/BpImpact'; +import BpImpact from '../../containers/Reports/components/BpImpact/BpImpact'; export default class BGroupProjectOverview extends Component { state = { }; @@ -34,9 +34,6 @@ export default class BGroupProjectOverview extends Component {

            Project Impact Summary

            diff --git a/src/containers/Reports/actions.js b/src/containers/Reports/actions.js index adfb21b4..8941c605 100644 --- a/src/containers/Reports/actions.js +++ b/src/containers/Reports/actions.js @@ -6,6 +6,9 @@ import { LOAD_BP_IMPACT_REPORT, LOAD_BP_IMPACT_REPORT_SUCCESS, LOAD_BP_IMPACT_REPORT_ERROR, + LOAD_CUSTOM_BP_IMPACT_REPORT, + LOAD_CUSTOM_BP_IMPACT_REPORT_SUCCESS, + LOAD_CUSTOM_BP_IMPACT_REPORT_ERROR, } from './constants'; /** @@ -62,3 +65,30 @@ export function bpImpactReportsLoadingError(error) { error, }; } + +/** + * Load custom bp impact reports + * + * @returns {object} An action object with a type of LOAD_CUSTOM_BP_IMPACT_REPORT + */ + +export function loadCustomBpImpactReport(buildingIds) { + return { + type: LOAD_CUSTOM_BP_IMPACT_REPORT, + buildingIds, + }; +} + +export function customBpImpactReportsLoaded(bpImpactReport) { + return { + type: LOAD_CUSTOM_BP_IMPACT_REPORT_SUCCESS, + payload: bpImpactReport.data, + }; +} + +export function customBpImpactReportsLoadingError(error) { + return { + type: LOAD_CUSTOM_BP_IMPACT_REPORT_ERROR, + error, + }; +} diff --git a/src/containers/Reports/components/BpImpact/BpImpact.js b/src/containers/Reports/components/BpImpact/BpImpact.js new file mode 100644 index 00000000..45d60702 --- /dev/null +++ b/src/containers/Reports/components/BpImpact/BpImpact.js @@ -0,0 +1,81 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ReactTooltip from 'react-tooltip'; + +import { bpImpactReportPropTypes } from '../../propTypes'; +import Loading from '../../../../components/Loading'; + + +export default class BpImpact extends Component { + + state = {} + + render() { + if (this.props.loading) { + return ; + } + const bpImpactReports = this.props.bpImpactReports; + if (!this.props.bpImpactReports) { + return null; + } + const dateCompareString = ` + The blue number represents the difference between the last two generated reports +
            + The last reports were generated on + ${bpImpactReports[0].created} and ${bpImpactReports.length > 1 ? bpImpactReports[1].created : 'n/a'} + `; + return ( +
            + +
            + + { + bpImpactReports[0].report.map((val, index) => { + let change = 0; + if (bpImpactReports.length > 1) { + const previousReport = bpImpactReports[1]; + change = val.value - previousReport.report[index].value; + } + let changeString = ''; + if (change > 0) { + changeString = ` +${change}`; + } + if (change < 0) { + changeString = ` ${change}`; + } + const changeEl = ( + + {changeString} + + ); + let trStyling = {}; + if (val.col === 'Total Buildings') { + trStyling = { + backgroundColor: 'rgba(176, 167, 167, 0.41)', + pointerEvents: 'none', + }; + } + return ( + + + + + ); + }) + } + +
            {val.col}{val.value}{changeEl}
            +
            + ); + + } +} + +BpImpact.propTypes = { + bpImpactReports: bpImpactReportPropTypes, + loading: PropTypes.bool, +}; diff --git a/src/containers/Reports/components/BpImpact/BpImpactWrapper.js b/src/containers/Reports/components/BpImpact/BpImpactWrapper.js new file mode 100644 index 00000000..eb48e2d4 --- /dev/null +++ b/src/containers/Reports/components/BpImpact/BpImpactWrapper.js @@ -0,0 +1,122 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import ReactTooltip from 'react-tooltip'; +import { Icon } from 'react-fa'; + +import { bpImpactReportPropTypes } from '../../propTypes'; +import { BGroup } from '../../../../containers/BGroup'; +import userPropType from '../../../../containers/User/propTypes'; +import BpImpact from './BpImpact'; + + +export default class BpImpactWrapper extends Component { + + state = { + filterReport: null, + } + + componentWillReceiveProps(nextProps) { + if ( + nextProps.customBpImpactReport !== this.props.customBpImpactReport + ) { + this.setState({ filterReport: [nextProps.customBpImpactReport[0]] }); + } + } + + componentWillUnmount() { + clearTimeout(this.updateFilterReportTimeout); + } + + updateFilterReport = (filter, tableState) => { + const buildingIds = tableState.sortedData.map(val => ( + val._original.building_id // eslint-disable-line + )); + clearTimeout(this.updateFilterReportTimeout); + this.updateFilterReportTimeout = setTimeout( + () => { + this.props.loadCustomBpImpactReport(buildingIds); + }, + 250, + ); + } + + render() { + if (this.props.bpImpactReports !== null && this.props.bpImpactReports.length < 1) { + return
            No report
            ; + } + if (!this.props.detail) { + return ( + + ); + } + const filterDescriptionString = ` + Filter buildings below to see a new report generated +
            + for the subset of buildings that pass the filter + `; + return ( +
            + +
            +
            +

            Overall Report

            + +
            + +
            +
            +
            +
            +

            BlocPower Buildings

            + +
            +
            +
            + ); + } +} + +BpImpactWrapper.propTypes = { + bpImpactReports: bpImpactReportPropTypes, + loadCustomBpImpactReport: PropTypes.func, + customBpImpactReport: PropTypes.array, // eslint-disable-line + loadingCustomBpImpact: PropTypes.bool, + detail: PropTypes.bool, + loading: PropTypes.bool, + user: userPropType, +}; diff --git a/src/containers/Reports/components/BpImpact/index.js b/src/containers/Reports/components/BpImpact/index.js deleted file mode 100644 index 601e0982..00000000 --- a/src/containers/Reports/components/BpImpact/index.js +++ /dev/null @@ -1,105 +0,0 @@ -import React from 'react'; -import ReactTooltip from 'react-tooltip'; -import PropTypes from 'prop-types'; -import { Icon } from 'react-fa'; - -import { bpImpactReportPropTypes } from '../../propTypes'; -import { BGroup } from '../../../../containers/BGroup'; -import userPropType from '../../../../containers/User/propTypes'; - - -export default function BpImpact({ - bpImpactReports, - detail, - user, - loading, -}) { - if (loading) { - return ( -
            - -
            - ); - } - if (bpImpactReports.length < 1) { - return
            No report
            ; - } - const dateCompareString = ` - The blue number represents the difference between the last two generated reports -
            - The last reports were generated on - ${bpImpactReports[0].created} and ${bpImpactReports.length > 1 ? bpImpactReports[1].created : 'n/a'} - `; - return ( -
            - - - - { - bpImpactReports[0].report.map((val, index) => { - let change = 0; - if (bpImpactReports.length > 1) { - const previousReport = bpImpactReports[1]; - change = val.value - previousReport.report[index].value; - } - let changeString = ''; - if (change > 0) { - changeString = ` +${change}`; - } - if (change < 0) { - changeString = ` ${change}`; - } - const changeEl = ( - - {changeString} - - ); - let trStyling = {}; - if (val.col === 'Total Buildings') { - trStyling = { - backgroundColor: 'rgba(176, 167, 167, 0.41)', - pointerEvents: 'none', - }; - } - return ( - - - - - ); - }) - } - -
            {val.col}{val.value}{changeEl}
            - { - detail ? ( - - ) : null - } -
            - ); -} - -BpImpact.propTypes = { - bpImpactReports: bpImpactReportPropTypes, - detail: PropTypes.bool, - loading: PropTypes.bool, - user: userPropType, -}; diff --git a/src/containers/Reports/components/Lighting/index.js b/src/containers/Reports/components/Lighting/index.js index 4d2012e5..aa378975 100644 --- a/src/containers/Reports/components/Lighting/index.js +++ b/src/containers/Reports/components/Lighting/index.js @@ -1,9 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Icon } from 'react-fa'; import ReactTooltip from 'react-tooltip'; +import { Icon } from 'react-fa'; import { lightingReportPropTypes } from '../../propTypes'; +import Loading from '../../../../components/Loading'; export default function Lighting({ lightingReports, @@ -11,11 +12,7 @@ export default function Lighting({ loading, }) { if (loading) { - return ( -
            - -
            - ); + return ; } const dateCompareString = ` The blue number represents the difference between the last two generated reports diff --git a/src/containers/Reports/constants.js b/src/containers/Reports/constants.js index 9d7936f4..1ba142cb 100644 --- a/src/containers/Reports/constants.js +++ b/src/containers/Reports/constants.js @@ -4,3 +4,7 @@ export const LOAD_LIGHTING_REPORT_ERROR = 'LOAD_LIGHTING_REPORT_ERROR'; export const LOAD_BP_IMPACT_REPORT = 'LOAD_BP_IMPACT_REPORT'; export const LOAD_BP_IMPACT_REPORT_SUCCESS = 'LOAD_BP_IMPACT_REPORT_SUCCESS'; export const LOAD_BP_IMPACT_REPORT_ERROR = 'LOAD_BP_IMPACT_REPORT_ERROR'; +// A bp impact report for a subset of buildings +export const LOAD_CUSTOM_BP_IMPACT_REPORT = 'LOAD_CUSTOM_BP_IMPACT_REPORT'; +export const LOAD_CUSTOM_BP_IMPACT_REPORT_SUCCESS = 'LOAD_CUSTOM_BP_IMPACT_REPORT_SUCCESS'; +export const LOAD_CUSTOM_BP_IMPACT_REPORT_ERROR = 'LOAD_CUSTOM_BP_IMPACT_REPORT_ERROR'; diff --git a/src/containers/Reports/index.js b/src/containers/Reports/index.js index c9ae3b62..d45cd6f9 100644 --- a/src/containers/Reports/index.js +++ b/src/containers/Reports/index.js @@ -10,9 +10,10 @@ import ReactTooltip from 'react-tooltip'; import { loadLightingReports, loadBpImpactReports, + loadCustomBpImpactReport, } from './actions'; import reportsPropTypes from './propTypes'; -import BpImpact from './components/BpImpact'; +import BpImpactWrapper from './components/BpImpact/BpImpactWrapper'; import Lighting from './components/Lighting'; import userPropType from '../../containers/User/propTypes'; @@ -45,12 +46,15 @@ class Reports extends Component { switch (this.state.reportTab) { case 'bpimpact': loading = ( - this.props.report.bpImpactReports.length === 0 || + this.props.report.bpImpactReports === null || this.props.report.loadingBpImpact ); content = ( - ( + `${acc}building_id=${val}&` + ), ''); + const res = yield call( + request, + `${bpImpactReportURL}?generate=true&${filterString}`, { + method: 'GET', + headers: getHeaders(), + } + ); + + if (!res.err) { + yield put(customBpImpactReportsLoaded(res)); + } else { + yield put(customBpImpactReportsLoadingError(res.err)); + } +} + /** * Watches for LOAD_LIGHTING_REPORT and LOAD_BP_IMPACT * actions and calls the appropriate handler function. @@ -69,6 +91,7 @@ function* getBpImpactReports(action) { function* reportWatcher() { yield takeLatest(LOAD_LIGHTING_REPORT, getLightingReports); yield takeLatest(LOAD_BP_IMPACT_REPORT, getBpImpactReports); + yield takeLatest(LOAD_CUSTOM_BP_IMPACT_REPORT, getCustomBpImpactReport); } export default reportWatcher; -- GitLab From 31e6fcfe7009f907cf83908c2a1354ff3c0a2a0c Mon Sep 17 00:00:00 2001 From: Jose Contreras Date: Thu, 8 Mar 2018 17:31:15 -0500 Subject: [PATCH 27/27] Add `REACT_APP_BP_BGROUP_ID` parameter to `env.default` --- .env.default | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.env.default b/.env.default index 9460ac93..a31cc652 100644 --- a/.env.default +++ b/.env.default @@ -25,3 +25,6 @@ REACT_APP_AUTH0_CLIENT_ID REACT_APP_AUTH0_CALLBACK_URL REACT_APP_AUTH0_CLAIMS_NAMESPACE REACT_APP_AUTH0_AUDIENCE + +# BlocPower Building Group ID +REACT_APP_BP_BGROUP_ID -- GitLab