[UNSTBLE] Fixed optimistic crop creation bug
parent
a1a61ae197
commit
c9154e90f3
|
@ -7,11 +7,9 @@
|
|||
component: 'PlantInventory',
|
||||
tab: 'Plants'
|
||||
},
|
||||
middleMenu: {
|
||||
global: {
|
||||
plants: <%= raw(current_user.device.plants.to_json) %>,
|
||||
selectedCrop: {}
|
||||
},
|
||||
rightMenu: {
|
||||
selectedPlant: {}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -7,7 +7,7 @@ export class CropInfo extends React.Component {
|
|||
|
||||
removeCrop() {
|
||||
this.props.dispatch({type: "CROP_REMOVE_REQUEST",
|
||||
payload: this.props.crop });
|
||||
payload: this.props.plant });
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -18,7 +18,7 @@ export class CropInfo extends React.Component {
|
|||
<a href="#" onClick={ this.goBack.bind(this) }>
|
||||
<i className="fa fa-arrow-left"></i>
|
||||
</a>
|
||||
Crop { this.props.crop._id || "" }
|
||||
Crop { this.props.plant._id || "" }
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,7 +26,7 @@ export class CropInfo extends React.Component {
|
|||
<div className="crop-drag-info-tile">
|
||||
<h6>Photos of this Crop</h6>
|
||||
<img className="crop-drag-info-image"
|
||||
src={this.props.crop.imgUrl || '/designer_icons/placeholder_berries.jpg'} />
|
||||
src={this.props.plant.imgUrl || '/designer_icons/placeholder_berries.jpg'} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -9,7 +9,7 @@ const LEFT_MENU_CHOICES = {PlantInventory, PlantCatalog, PlantInfo, CropInfo}
|
|||
|
||||
export class DesignerMain extends React.Component {
|
||||
transferableProps(name){
|
||||
return _.merge({}, {dispatch: this.props.dispatch}, this.props[name]);
|
||||
return _.merge({}, this.props.global, {dispatch: this.props.dispatch}, this.props[name]);
|
||||
};
|
||||
|
||||
// Dynamically determine what to render on the left side of the designer,
|
||||
|
@ -27,8 +27,8 @@ export class DesignerMain extends React.Component {
|
|||
}
|
||||
|
||||
renderMiddle(){
|
||||
let props = this.transferableProps("middleMenu");
|
||||
return React.createElement(GardenMap, props);
|
||||
return React.createElement(GardenMap,
|
||||
this.transferableProps("middleMenu"));
|
||||
}
|
||||
|
||||
render(){
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
export class MapPointView extends React.Component {
|
||||
select() {
|
||||
this.props.dispatch({type: "CROP_SELECT", payload: this.props.crop});
|
||||
this.props.dispatch({type: "CROP_SELECT", payload: this.props.plant});
|
||||
}
|
||||
render() {
|
||||
var style = {
|
||||
position: 'absolute',
|
||||
left: (this.props.crop.x - 20),
|
||||
top: (this.props.crop.y - 40)
|
||||
left: (this.props.plant.x - 20),
|
||||
top: (this.props.plant.y - 40)
|
||||
};
|
||||
if (!!this.props.selected) { style.border = "1px solid green"; };
|
||||
return <div onClick={ this.select.bind(this) }>
|
||||
|
@ -16,11 +16,11 @@ export class MapPointView extends React.Component {
|
|||
};
|
||||
|
||||
export class GardenMap extends React.Component {
|
||||
crops() {
|
||||
plants() {
|
||||
return this.props.plants.map(
|
||||
(p, k) => <MapPointView crop={ p }
|
||||
(p, k) => <MapPointView plant={ p }
|
||||
key={ k }
|
||||
selected={ p._id && (this.props.selectedCrop._id === p._id) }
|
||||
selected={ (this.props.selectedPlant._id === p._id) }
|
||||
dispatch={ this.props.dispatch }/>
|
||||
);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ export class GardenMap extends React.Component {
|
|||
render() {
|
||||
return <div>
|
||||
<div id="drop-area">
|
||||
{ this.crops() }
|
||||
{ this.plants() }
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ export class PlantCatalogTile extends React.Component {
|
|||
showPlantInfo(){
|
||||
this.props.dispatch({
|
||||
type: 'PLANT_INFO_SHOW',
|
||||
payload: this.props.crop
|
||||
payload: this.props.plant
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -14,14 +14,14 @@ export class PlantCatalogTile extends React.Component {
|
|||
<div className="row">
|
||||
<div className="small-12 columns">
|
||||
<div className="small-header-wrapper">
|
||||
<h5>{ this.props.crop.name }</h5>
|
||||
<h5>{ this.props.plant.name }</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="small-12 columns">
|
||||
<div className="content-wrapper">
|
||||
<p> <img src={this.props.crop.imgUrl} /> </p>
|
||||
<p> <img src={this.props.plant.imgUrl} /> </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -34,7 +34,7 @@ export class PlantCatalog extends React.Component {
|
|||
back() { this.props.dispatch({type: "INVENTORY_SHOW"}) }
|
||||
render() {
|
||||
var crops = Plant.fakePlants.map(
|
||||
(crop, k) => <PlantCatalogTile crop={ crop }
|
||||
(plant, k) => <PlantCatalogTile plant={ plant }
|
||||
key={ k }
|
||||
dispatch={ this.props.dispatch } />
|
||||
);
|
||||
|
|
|
@ -18,7 +18,7 @@ export class PlantInfo extends React.Component {
|
|||
<a href="#" onClick={ this.showCatalog.bind(this) }>
|
||||
<i className="fa fa-arrow-left"></i>
|
||||
</a>
|
||||
{ this.props.crop.name }
|
||||
{ this.props.plant.name }
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,7 +26,7 @@ export class PlantInfo extends React.Component {
|
|||
<div className="crop-drag-info-tile">
|
||||
<h6>Plant Image</h6>
|
||||
<img className="crop-drag-info-image"
|
||||
src={this.props.crop.imgUrl}
|
||||
src={this.props.plant.imgUrl}
|
||||
onDragEnd={ this.drop.bind(this) }/>
|
||||
<div className="crop-info-overlay">
|
||||
To plant, drag and drop into map
|
||||
|
|
|
@ -109,8 +109,8 @@ export class Item extends React.Component {
|
|||
render() {
|
||||
return(
|
||||
<li>
|
||||
<a href="#"> {this.props.crop.name} </a>
|
||||
<div>{this.props.crop.age} days old</div>
|
||||
<a href="#"> {this.props.plant.name} </a>
|
||||
<div>{this.props.plant.age} days old</div>
|
||||
</li>);
|
||||
}
|
||||
};
|
||||
|
@ -118,7 +118,7 @@ export class Item extends React.Component {
|
|||
export class List extends React.Component {
|
||||
render() {
|
||||
var crops = this.props.plants.map(
|
||||
(crop, k) => <Item crop={crop} key={ k } />
|
||||
(plant, k) => <Item plant={plant} key={ k } />
|
||||
);
|
||||
|
||||
return(<ul className="crop-inventory"> { crops } </ul>);
|
||||
|
|
|
@ -18,7 +18,7 @@ export class SpeciesInfo extends React.Component {
|
|||
<a href="#" onClick={ this.showCatalog.bind(this) }>
|
||||
<i className="fa fa-arrow-left"></i>
|
||||
</a>
|
||||
{ this.props.crop.name }
|
||||
{ this.props.plant.name }
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,7 +26,7 @@ export class SpeciesInfo extends React.Component {
|
|||
<div className="crop-drag-info-tile">
|
||||
<h6>Species Image</h6>
|
||||
<img className="crop-drag-info-image"
|
||||
src={this.props.crop.imgUrl}
|
||||
src={this.props.plant.imgUrl}
|
||||
onDragEnd={ this.drop.bind(this) }/>
|
||||
<div className="crop-info-overlay">
|
||||
To plant, drag and drop into map
|
||||
|
|
|
@ -13,18 +13,23 @@ actions.DEFAULT = function (s, a) {
|
|||
};
|
||||
|
||||
actions.CROP_SELECT = function(s, a) {
|
||||
var select_crop = update(s, {middleMenu: {selectedCrop: a.payload}});
|
||||
var select_crop = update(s, {global: {selectedPlant: a.payload}});
|
||||
var change_menu = actions.CROP_INFO_SHOW(select_crop, a);
|
||||
return change_menu;
|
||||
return _.merge({}, select_crop, change_menu);
|
||||
};
|
||||
|
||||
actions.CROP_ADD_REQUEST = function (s, a) {
|
||||
var req = $.ajax({method: "POST", url: "/api/plants", data: a.payload})
|
||||
.done(function (plant) {
|
||||
store.dispatch({type: "CROP_ADD_SUCCESS", payload: plant});
|
||||
})
|
||||
$.ajax({method: "POST", url: "/api/plants", data: a.payload})
|
||||
.fail(function (a, b, c) { store.dispatch({type: "CROP_ADD_FAILURE"}) });
|
||||
return s;
|
||||
var plants = _.cloneDeep(s.global.plants);
|
||||
var selectedPlant = _.cloneDeep(a.payload);
|
||||
plants.push(selectedPlant);
|
||||
return update(s, {
|
||||
global: {
|
||||
plants: plants,
|
||||
selectedPlant: selectedPlant
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
actions.CROP_ADD_FAILURE = function (s = store.getState(), a) {
|
||||
|
@ -32,18 +37,27 @@ actions.CROP_ADD_FAILURE = function (s = store.getState(), a) {
|
|||
return s;
|
||||
};
|
||||
|
||||
actions.CROP_ADD_SUCCESS = function (s = store.getState(), a) {
|
||||
var new_array = s.middleMenu.plants.concat(a.payload);
|
||||
return update(s, {middleMenu: {plants: new_array}});
|
||||
actions.CROP_ADD_SUCCESS = function (s, a) {
|
||||
var plants = _.cloneDeep(s.global.plants);
|
||||
var selectedPlant = _.cloneDeep(a.payload);
|
||||
plants.push(selectedPlant);
|
||||
return update(s, {
|
||||
global: {
|
||||
plants: plants,
|
||||
selectedPlant: selectedPlant
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
actions.CROP_REMOVE_REQUEST = function (s, a) {
|
||||
$.ajax({
|
||||
method: "DELETE",
|
||||
url: "/api/plants/" + a.payload._id
|
||||
}).fail(function () {
|
||||
store.dispatch({type: "CROP_REMOVE_FAILURE"});
|
||||
}).done(function () {
|
||||
store.dispatch({type: "CROP_REMOVE_SUCCESS", payload: a.payload});
|
||||
}).fail(function (a, b, c) { store.dispatch({type: "CROP_REMOVE_FAILURE"}) });
|
||||
});
|
||||
return s;
|
||||
};
|
||||
|
||||
|
@ -53,18 +67,19 @@ actions.CROP_REMOVE_FAILURE = function (s = store.getState(), a) {
|
|||
};
|
||||
|
||||
actions.CROP_REMOVE_SUCCESS = function (s = store.getState(), a) {
|
||||
let oldArray = s.middleMenu.plants;
|
||||
var newArray = _.filter(oldArray, (c) => c._id !== a.payload._id);
|
||||
return update(s, {middleMenu: {plants: newArray}});
|
||||
return update(s, {
|
||||
global: {
|
||||
plants: _.filter(s.global.plants, a.payload)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
actions.PLANT_INFO_SHOW = function(s, a) {
|
||||
// TODO: add type system to check for presence of `crop` Object?
|
||||
let fragment = {
|
||||
leftMenu: {
|
||||
component: 'PlantInfo',
|
||||
crop: a.payload
|
||||
plant: a.payload
|
||||
}
|
||||
};
|
||||
return update(s, fragment);
|
||||
|
@ -72,13 +87,12 @@ actions.PLANT_INFO_SHOW = function(s, a) {
|
|||
|
||||
actions.CROP_INFO_SHOW = function(s, a) {
|
||||
// TODO: add type system to check for presence of `crop` Object?
|
||||
let fragment = {
|
||||
leftMenu: {
|
||||
component: 'CropInfo',
|
||||
crop: a.payload
|
||||
}
|
||||
};
|
||||
return update(s, fragment);
|
||||
return update(s, {
|
||||
leftMenu: {
|
||||
component: 'CropInfo',
|
||||
plant: a.payload
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
actions.CATALOG_SHOW = function(s, a){
|
||||
|
|
|
@ -3,6 +3,8 @@ import { isFSA } from 'flux-standard-action';
|
|||
|
||||
export function reducer(state, action) {
|
||||
if (isFSA(action)){
|
||||
console.log(action.type);
|
||||
console.dir(state);
|
||||
return (actions[action.type] || actions.DEFAULT)(state, action);
|
||||
} else {
|
||||
console.error("Action does not conform to 'flux-standard-action", action);
|
||||
|
|
Loading…
Reference in New Issue