implement reactjs history
This commit is contained in:
174
client/dashboard/state_manager.js
Normal file
174
client/dashboard/state_manager.js
Normal file
@@ -0,0 +1,174 @@
|
||||
import query_string from 'query-string';
|
||||
|
||||
import ObjectUtil from './../../shared/utils/object';
|
||||
import ArrayUtil from './../../shared/utils/array';
|
||||
|
||||
const ROUTES = [
|
||||
{
|
||||
path: /houses\/(\d+)\/?$/,
|
||||
parameters: {1: 'house_id'}
|
||||
}, {
|
||||
path: /houses\/(\d+)\/(energy)\/(\d+)\/([^\/]+)\/([^\/]+)\/?$/,
|
||||
parameters: { 1: 'house_id', 2: 'dataset', 3: 'year', 4: 'graph_attr', 5: 'view' }
|
||||
}, {
|
||||
path: /houses\/(\d+)\/(power)\/([^\/]+)\/(\d+)\/([^\/]+)\/?$/,
|
||||
parameters: { 1: 'house_id', 2: 'dataset', 3: 'month', 4: 'year', 5: 'view' }
|
||||
}
|
||||
];
|
||||
|
||||
class StateManager {
|
||||
|
||||
constructor(createHistory, houses){
|
||||
var state_manager = this;
|
||||
|
||||
state_manager.houses = houses;
|
||||
|
||||
state_manager.state = {
|
||||
loading_energy_data: false,
|
||||
loading_power_data: false,
|
||||
graph_attr: 'consumption',
|
||||
view: 'graph',
|
||||
dataset: 'power',
|
||||
house_id: null,
|
||||
house: null,
|
||||
month: null,
|
||||
year: null,
|
||||
power_range: null };
|
||||
|
||||
state_manager.history = createHistory();
|
||||
state_manager.update_in_progress = false;
|
||||
}
|
||||
|
||||
get date_params(){
|
||||
return ObjectUtil.filterKeys(this.state, ['year', 'month', 'power_range']);
|
||||
}
|
||||
|
||||
// This will update the house state acccording to passed update parameters.
|
||||
updateHouseFromState(component){
|
||||
var state_manager = this,
|
||||
house = state_manager.state.house,
|
||||
promise;
|
||||
if (!house) {
|
||||
promise = Promise.resolve();
|
||||
} else if (state_manager.state.dataset === 'energy' && (!house.energy_data || !house.matchesEnergyState(state_manager.state))){
|
||||
house.setMonthState(state_manager.state);
|
||||
promise = state_manager.setHouseEnergyFromState(component);
|
||||
} else if (state_manager.state.dataset === 'power' && !house.power_data || !house.matchesPowerState(state_manager.state)){
|
||||
house.setMonthState(state_manager.state);
|
||||
promise = state_manager.setHousePowerFromState(component);
|
||||
} else {
|
||||
promise = new Promise((fnResolve, fnReject)=>{
|
||||
component.syncFromStateManager(fnResolve);
|
||||
});
|
||||
}
|
||||
return promise.then(()=>{ state_manager.update_in_progress = false; })
|
||||
}
|
||||
|
||||
setHouseEnergyFromState(component){
|
||||
var state_manager = this;
|
||||
state_manager.power_data_updated = true;
|
||||
return new Promise((fnResolve, fnReject)=>{
|
||||
component.setState({
|
||||
loading_energy_data: true
|
||||
}, ()=>{
|
||||
state_manager.state.house.setEnergyData()
|
||||
.then(()=>{
|
||||
component.syncFromStateManager(fnResolve);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
powerDataRendered(){
|
||||
var state_manager = this;
|
||||
state_manager.power_data_updated = false;
|
||||
}
|
||||
|
||||
setHousePowerFromState(component){
|
||||
var state_manager = this,
|
||||
house = state_manager.state.house;
|
||||
return new Promise((fnResolve, fnReject)=>{
|
||||
component.setState({
|
||||
loading_power_data: true
|
||||
}, ()=>{
|
||||
house.setPowerData()
|
||||
.then(()=>{
|
||||
component.syncFromStateManager(fnResolve);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Change Params -> Change Url
|
||||
*/
|
||||
|
||||
setParams(params){
|
||||
var state_manager = this,
|
||||
url;
|
||||
if (state_manager.update_in_progress) return false;
|
||||
state_manager.update_in_progress = true;
|
||||
params = Object.assign({}, state_manager.state, params);
|
||||
if (!params.house_id){
|
||||
url = '/';
|
||||
} else {
|
||||
var house = state_manager.houses.find((h)=>{ return h.data.id == params.house_id; })
|
||||
|
||||
house.verifyMonthState(params);
|
||||
if (params.dataset === 'energy'){
|
||||
url = `/houses/${params.house_id}/energy/${params.year}/${params.graph_attr}/${params.view}`;
|
||||
} else if (params.dataset === 'power'){
|
||||
house.verifyPowerRange(params);
|
||||
url = `/houses/${params.house_id}/power/${params.month}/${params.year}/${params.view}?${query_string.stringify({dates: params.power_range})}`;
|
||||
} else {
|
||||
url = `/houses/${house.house_id}`;
|
||||
}
|
||||
}
|
||||
state_manager.history.push(url);
|
||||
}
|
||||
|
||||
/*
|
||||
* Url Changed -> Change State
|
||||
*/
|
||||
|
||||
updateStateFromUrl(location, component){
|
||||
var state_manager = this;
|
||||
return new Promise((fnResolve, fnReject)=>{
|
||||
var params = state_manager.parseUrl(location.pathname),
|
||||
house = null;
|
||||
if (params.dataset === 'power' && location.query.dates) {
|
||||
params.power_range = [+location.query.dates[0], +location.query.dates[1]];
|
||||
}
|
||||
if (params.house_id || params.house_id != state_manager.state.house_id){
|
||||
house = state_manager.houses.find((h)=>{ return h.data.id == params.house_id; });
|
||||
}
|
||||
state_manager.state.house = house;
|
||||
Object.assign(state_manager.state, params);
|
||||
if (state_manager.state.house_id) {
|
||||
state_manager.updateHouseFromState(component);
|
||||
} else {
|
||||
component.syncFromStateManager(()=>{
|
||||
state_manager.update_in_progress = false;
|
||||
fnResolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
parseUrl(url, query){
|
||||
for (var route of ROUTES){
|
||||
var match = url.match(route.path);
|
||||
if (match){
|
||||
var parsed = {};
|
||||
for (var index in route.parameters){
|
||||
parsed[route.parameters[index]] = match[index];
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default StateManager;
|
||||
Reference in New Issue
Block a user