Skip to content

Commit

Permalink
Merge branch 'multi-province'
Browse files Browse the repository at this point in the history
  • Loading branch information
gilyes committed Sep 29, 2019
2 parents 4f506f3 + 6d82a38 commit af7952a
Show file tree
Hide file tree
Showing 22 changed files with 598 additions and 110 deletions.
60 changes: 60 additions & 0 deletions app/app/components/ProvinceSelector/ProvinceSelector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react';
import Select from 'react-select';
import PropTypes from 'prop-types';
import './style.scss'

const ProvinceSelector = (props) => {
const selectStyles = {
control: (styles, state) => ({
...styles,
backgroundColor: '#1c1c1c',
}),
option: (styles, state) => {
return {
...styles,
backgroundColor: state.isFocused ? '#4c4c4c' : '#3c3c3c',
color: '#c0c0c0',
':active': {
backgroundColor: '#5c5c5c'
}
};
},
singleValue: (provided, state) => {
const color = '#c0c0c0';
return { ...provided, color };
},
menu: base => ({
...base,
borderRadius: 0,
marginTop: 0
}),
menuList: base => ({
...base,
padding: 0
})
};
return (
<div className="province-selector">
<Select
options={props.provinces}
styles={selectStyles}
onChange={props.onSelectedProvinceChanged}
value={props.selectedProvince}
getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.name}
isSearchable={false}
maxMenuHeight={500}
noOptionsMessage={() => props.error ? "Load error." : "Loading..."}
placeholder={props.placeholder} />
</div>
)
};

ProvinceSelector.propTypes = {
provinces: PropTypes.array,
onSelectedProvinceChanged: PropTypes.func,
selectedProvince: PropTypes.object,
placeholder: PropTypes.string
};

export default ProvinceSelector;
1 change: 1 addition & 0 deletions app/app/components/ProvinceSelector/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './ProvinceSelector';
9 changes: 9 additions & 0 deletions app/app/components/ProvinceSelector/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.province-selector {
margin-top: auto;
margin-bottom: auto;
padding-left: 10px;
padding-right: 10px;
padding-top: 10px;
padding-bottom: 10px;
width: 50%;
}
11 changes: 11 additions & 0 deletions app/app/components/ProvinceSelector/tests/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import { shallow } from 'enzyme';
import Select from 'react-select';
import ProvinceSelector from '../index';

describe('<ProvinceSelector />', () => {
it('should render a Select', () => {
const renderedComponent = shallow(<ProvinceSelector />);
expect(renderedComponent.find(Select)).toHaveLength(1);
});
});
17 changes: 16 additions & 1 deletion app/app/components/TNGChart/TNGChart.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,26 @@ const TNGChart = (props) => {
backgroundColor: "transparent",
fontSize: "14",
pieHole: 0.45,
sliceVisibilityThreshold: 0.0001,
legend: { textStyle: { color: '#eeeeee', fontSize: "15" } },
chartArea: { top: 9, bottom: 9, left: 5, right: 5 },
tooltip: { text: 'percentage', showColorCode: true }
}} />
<div className="tng-update-time">Last updated: {props.tng.time}</div>
{props.tng.type === 'live' &&
<div className="tng-update-info-container">
<div className="tng-update-time">Last updated: {props.tng.time}</div>
<a href={props.tng.sourceUrl} target="_blank">
<div className="tng-type-live">Live</div>
</a>
</div>
}
{props.tng.type === 'historical' &&
<div className="tng-update-info-container">
<a href={props.tng.sourceUrl} target="_blank">
<div className="tng-type-historical">Historical data</div>
</a>
</div>
}
</div>
);
};
Expand Down
34 changes: 34 additions & 0 deletions app/app/components/TNGChart/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,37 @@ svg[aria-label="A chart."]>g>g:last-child {
// HACK: working around a bug in Google Pie Chart that causes flickering tooltip. from https://stackoverflow.com/a/39775254/573447
pointer-events: none
}

.tng-update-info-container {
text-align: right;
margin-right: 9px;
}

.tng-type-live,
.tng-type-historical {
display: inline-block;
}

.tng-type-live{
color: black;
background-color: green;
padding-top: 1px;
padding-bottom: 1px;
padding-left: 6px;
padding-right: 6px;
border-radius: 4px;
}

.tng-type-historical {
color: black;
background-color: gray;
padding-top: 1px;
padding-bottom: 1px;
padding-left: 6px;
padding-right: 6px;
border-radius: 4px
}

.tng-update-time {
display: inline-block;
}
33 changes: 30 additions & 3 deletions app/app/containers/App/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ const createConfigSelector = () => createSelector(
(globalState) => globalState.getIn(['data', 'config'])
);

const createProvincesSelector = () => createSelector(
createConfigSelector(),
(config) => config ? config.provinces : []
);

const createTNGForDisplaySelector = () => createSelector(
createTNGSelector(),
(tng) => {
Expand All @@ -46,20 +51,42 @@ const createTNGForDisplaySelector = () => createSelector(
}

const tngForDisplay = {
tng: { "Coal": tng.coal, "Gas": tng.gas, "Hydro": tng.hydro, "Wind": tng.wind, "Solar/Other": tng.other },
time: tng.time
tng: {
"Coal": tng.coal,
"Gas": tng.gas,
"Nuclear": tng.nuclear,
"Hydro": tng.hydro,
"Wind": tng.wind,
"Solar": tng.solar,
"Biomass": tng.biomass,
"Diesel": tng.diesel,
// if there is explicit Solar entry then skip Solar/Other
"Solar/Other": tng.solar ? 0 : tng.other,
// if there is explicit Solar entry then add explicit Other (if present)
"Imports": tng.imports,
"Other": tng.solar ? tng.other : 0
},
time: tng.time,
type: tng.type,
sourceUrl: tng.sourceUrl
};

tngForDisplay.tng = Object.entries(tngForDisplay.tng)
tngForDisplay.tng.sort((x, y) => (y[1] ? y[1] : 0) - (x[1] ? x[1] : 0));

return tngForDisplay;
}
);

export {
selectGlobal,
selectRoute,
createLoadingSelector,
createErrorSelector,
createElectricVehicleSelector,
createIceVehicleSelector,
createTNGSelector,
createTNGForDisplaySelector,
createConfigSelector
createConfigSelector,
createProvincesSelector
};
13 changes: 12 additions & 1 deletion app/app/containers/HomePage/HomePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ReactMarkdown from 'react-markdown';
import CostComparisonForm from '../../components/CostComparisonForm';
import TNGChart from '../../components/TNGChart';
import VehicleSelector from '../../components/VehicleSelector';
import ProvinceSelector from '../../components/ProvinceSelector';
import AnnualCostChart from '../../components/AnnualCostChart';
import VehicleDetails from '../../components/VehicleDetails';
import VehicleCost from '../../components/VehicleCost';
Expand Down Expand Up @@ -45,6 +46,12 @@ export default class HomePage extends React.PureComponent { // eslint-disable-li
<div className="home-page">
<section>
<div>
<ProvinceSelector
provinces={this.props.provinces}
selectedProvince={this.props.selectedProvince}
onSelectedProvinceChanged={this.props.onSelectedProvinceChanged}
placeholder="Select province..."
/>
<div className="tng-chart-container">
<TNGChart tng={this.props.tng} />
</div>
Expand Down Expand Up @@ -121,6 +128,7 @@ HomePage.propTypes = {
PropTypes.object,
PropTypes.bool,
]),
config: PropTypes.object,
onInitialLoad: PropTypes.func,
onReloadTNGRequested: PropTypes.func,
electricVehicles: PropTypes.array,
Expand All @@ -139,5 +147,8 @@ HomePage.propTypes = {
iceVehicleAnnualCost: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
])
]),
provinces: PropTypes.array,
selectedProvince: PropTypes.object,
onSelectedProvinceChanged: PropTypes.func
};
19 changes: 18 additions & 1 deletion app/app/containers/HomePage/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
* }
*/

import { CHANGE_SELECTED_ICE_VEHICLE, CHANGE_SELECTED_ELECTRIC_VEHICLE, SET_DEFAULT_SELECTED_ELECTRIC_VEHICLE, SET_DEFAULT_SELECTED_ICE_VEHICLE } from './constants';
import {
CHANGE_SELECTED_ICE_VEHICLE, CHANGE_SELECTED_ELECTRIC_VEHICLE, SET_DEFAULT_SELECTED_ELECTRIC_VEHICLE, SET_DEFAULT_SELECTED_ICE_VEHICLE,
CHANGE_SELECTED_PROVINCE, SET_DEFAULT_SELECTED_PROVINCE
} from './constants';

export function changeSelectedElectricVehicle(vehicle) {
return {
Expand Down Expand Up @@ -44,3 +47,17 @@ export function setDefaultSelectedIceVehicle(vehicle) {
vehicle
};
}

export function changeSelectedProvince(province) {
return {
type: CHANGE_SELECTED_PROVINCE,
province
};
}

export function setDefaultSelectedProvince(province) {
return {
type: SET_DEFAULT_SELECTED_PROVINCE,
province
};
}
2 changes: 2 additions & 0 deletions app/app/containers/HomePage/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ export const CHANGE_SELECTED_ELECTRIC_VEHICLE = 'env-impact-comparison/Home/CHAN
export const CHANGE_SELECTED_ICE_VEHICLE = 'env-impact-comparison/Home/CHANGE_SELECTED_ICE_VEHICLE';
export const SET_DEFAULT_SELECTED_ELECTRIC_VEHICLE = 'env-impact-comparison/Home/SET_DEFAULT_SELECTED_ELECTRIC_VEHICLE';
export const SET_DEFAULT_SELECTED_ICE_VEHICLE = 'env-impact-comparison/Home/SET_DEFAULT_SELECTED_ICE_VEHICLE';
export const CHANGE_SELECTED_PROVINCE = 'env-impact-comparison/Home/CHANGE_SELECTED_PROVINCE';
export const SET_DEFAULT_SELECTED_PROVINCE = 'env-impact-comparison/Home/SET_DEFAULT_SELECTED_PROVINCE';
21 changes: 16 additions & 5 deletions app/app/containers/HomePage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { compose } from 'redux';
import { createStructuredSelector } from 'reselect';
import injectReducer from 'utils/injectReducer';
import injectSaga from 'utils/injectSaga';
import { createLoadingSelector, createErrorSelector, createElectricVehicleSelector, createIceVehicleSelector, createTNGForDisplaySelector } from 'containers/App/selectors';
import {
createLoadingSelector, createErrorSelector, createElectricVehicleSelector, createIceVehicleSelector,
createTNGForDisplaySelector, createConfigSelector, createProvincesSelector
} from 'containers/App/selectors';
import { loadElectricVehicles, loadIceVehicles, loadTNG, loadConfig } from '../App/actions';
import { changeSelectedElectricVehicle, changeSelectedIceVehicle } from './actions';
import { changeSelectedElectricVehicle, changeSelectedIceVehicle, changeSelectedProvince } from './actions';
import {
createSelectedElectricVehicleSelector,
createSelectedIceVehicleSelector,
Expand All @@ -21,18 +24,19 @@ import {
createIceVehicleAnnualCostSelector,
createDefaultElectricVehicleSelector,
createDefaultIceVehicleSelector,
createExplanationTextSelector
createExplanationTextSelector,
createSelectedProvinceSelector,
createDefaultSelectedProvinceSelector,
} from './selectors';
import reducer from './reducer';
import { electricVehiclesSaga, iceVehiclesSaga, tngSaga, configSaga } from './saga';
import HomePage from './HomePage';
import { createConfigSelector } from '../App/selectors';

const mapDispatchToProps = (dispatch) => ({
onInitialLoad: () => {
dispatch(loadTNG());
dispatch(loadElectricVehicles());
dispatch(loadIceVehicles());
// NOTE: loadConfig also triggers a loadTNG
dispatch(loadConfig());
},
onSelectedElectricVehicleChanged: (vehicle) => {
Expand All @@ -43,6 +47,10 @@ const mapDispatchToProps = (dispatch) => ({
},
onReloadTNGRequested: () => {
dispatch(loadTNG());
},
onSelectedProvinceChanged: (province) => {
dispatch(changeSelectedProvince(province))
dispatch(loadTNG());
}
});

Expand All @@ -66,6 +74,9 @@ const mapStateToProps = createStructuredSelector({
electricVehicleAnnualCost: createElectricVehicleAnnualCostSelector(),
iceVehicleAnnualCost: createIceVehicleAnnualCostSelector(),
explanationText: createExplanationTextSelector(),
provinces: createProvincesSelector(),
selectedProvince: createSelectedProvinceSelector(),
defaultSelectedProvince: createDefaultSelectedProvinceSelector(),
config: createConfigSelector(),
error: createErrorSelector(),
});
Expand Down
14 changes: 13 additions & 1 deletion app/app/containers/HomePage/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
*/
import { fromJS, toJS } from 'immutable';

import { CHANGE_SELECTED_ELECTRIC_VEHICLE, CHANGE_SELECTED_ICE_VEHICLE, SET_DEFAULT_SELECTED_ELECTRIC_VEHICLE, SET_DEFAULT_SELECTED_ICE_VEHICLE } from './constants';
import {
CHANGE_SELECTED_ELECTRIC_VEHICLE, CHANGE_SELECTED_ICE_VEHICLE, SET_DEFAULT_SELECTED_ELECTRIC_VEHICLE, SET_DEFAULT_SELECTED_ICE_VEHICLE,
CHANGE_SELECTED_PROVINCE, SET_DEFAULT_SELECTED_PROVINCE
} from './constants';

// The initial state of the App
const initialState = fromJS({
Expand All @@ -37,6 +40,15 @@ function homeReducer(state = initialState, action) {
}
return state;

case CHANGE_SELECTED_PROVINCE:
return state.set('selectedProvince', fromJS(action.province));

case SET_DEFAULT_SELECTED_PROVINCE:
if (action.province && !state.get('selectedProvince')) {
return state.set('selectedProvince', fromJS(action.province));
}
return state;

default:
return state;
}
Expand Down
Loading

0 comments on commit af7952a

Please sign in to comment.