adds reactivity when undoing an event

This commit is contained in:
2019-10-28 16:08:05 +01:00
parent 8d1344e0b6
commit 1f2a940968
5 changed files with 39 additions and 29 deletions

View File

@@ -20,7 +20,7 @@ pub use models::{
claim::{Claim, Claims}, claim::{Claim, Claims},
item::{Item, LootManager, Inventory}, item::{Item, LootManager, Inventory},
player::{Player, Wealth, Players, AsPlayer}, player::{Player, Wealth, Players, AsPlayer},
history::Event, history::{Event, UpdateList},
}; };
/// The connection used /// The connection used
@@ -54,22 +54,21 @@ pub enum Update {
impl Update { impl Update {
/// Change back what has been updated /// Change back what has been updated
fn undo(&self, conn: &DbConnection, id: i32) -> QueryResult<()> { fn undo(&self, conn: &DbConnection, id: i32) -> QueryResult<Self> {
match self { Ok(match self {
Update::Wealth(diff) => { Update::Wealth(diff) => {
AsPlayer(conn, id).update_wealth(-diff.to_gp())?; Update::Wealth(AsPlayer(conn, id).update_wealth(-diff.to_gp())?)
}, },
Update::ItemAdded(item) => { Update::ItemAdded(item) => {
LootManager(conn, id).remove(item.id)?; Update::ItemRemoved(LootManager(conn, id).remove(item.id)?)
}, },
Update::ItemRemoved(item) => { Update::ItemRemoved(item) => {
LootManager(conn, id).add_from(&item)?; Update::ItemAdded(LootManager(conn, id).add_from(&item)?)
}, },
// Unused for now // Unused for now
Update::ClaimAdded(claim) => {}, Update::ClaimAdded(claim) => { Update::ClaimRemoved(*claim) },
Update::ClaimRemoved(claim) => {}, Update::ClaimRemoved(claim) => { Update::ClaimAdded(*claim) },
}; })
Ok(())
} }
} }
@@ -198,14 +197,6 @@ pub fn split_and_share(conn: &DbConnection, amount: i32, players: Vec<i32>) -> Q
}) })
} }
/// Reverts the last action stored for player
pub fn undo_last_action(conn: &DbConnection, id: i32) -> QueryResult<Event> {
let last_event = models::history::get_last_of_player(conn, id)?;
last_event.undo(conn)
}
#[cfg(none)] #[cfg(none)]
mod tests_old { mod tests_old {
use super::*; use super::*;

View File

@@ -5,7 +5,7 @@ use crate::models::{self, item::Loot};
use crate::schema::claims; use crate::schema::claims;
/// A Claim is a request by a single player on an item from group chest. /// A Claim is a request by a single player on an item from group chest.
#[derive(Identifiable, Queryable, Associations, Serialize, Deserialize, Debug)] #[derive(Identifiable, Queryable, Associations, Serialize, Deserialize, Clone, Copy, Debug)]
#[belongs_to(Loot)] #[belongs_to(Loot)]
pub struct Claim { pub struct Claim {
/// DB Identifier /// DB Identifier

View File

@@ -9,6 +9,16 @@ use crate::{DbConnection, QueryResult, Update};
#[derive(Debug, FromSqlRow)] #[derive(Debug, FromSqlRow)]
pub struct UpdateList(Vec<Update>); pub struct UpdateList(Vec<Update>);
impl UpdateList {
pub fn inner(&self) -> &Vec<Update> {
&self.0
}
pub fn into_inner(self) -> Vec<Update> {
self.0
}
}
// TODO: decide if updates is really optionnal or not // TODO: decide if updates is really optionnal or not
// (like if storing an event without update is usefull ?) // (like if storing an event without update is usefull ?)
@@ -29,15 +39,18 @@ impl Event {
/// TODO: why a move here ?? /// TODO: why a move here ??
/// Undo all updates in a single transaction /// Undo all updates in a single transaction
pub fn undo(self, conn: &DbConnection) -> QueryResult<Self> { pub fn undo(self, conn: &DbConnection) -> QueryResult<UpdateList> {
conn.transaction(move || { conn.transaction(move || {
if let Some(ref updates) = self.updates { if let Some(ref updates) = self.updates {
for update in updates.0.iter() { let undone = updates.0.iter()
update.undo(conn, self.player_id)?; // TODO: swallow errors !
} .filter_map(|u| u.undo(conn, self.player_id).ok())
.collect();
diesel::delete(history::table.find(self.id)).execute(conn)?; diesel::delete(history::table.find(self.id)).execute(conn)?;
Ok(UpdateList(undone))
} else {
Ok(UpdateList(vec![]))
} }
Ok(self)
}) })
} }
} }

View File

@@ -39,8 +39,9 @@ export default {
this.loot.push(i); this.loot.push(i);
} }
else if (update.ItemRemoved) { else if (update.ItemRemoved) {
var i = update.ItemRemoved; var removed = update.ItemRemoved;
this.loot.splice(this.loot.indexOf(i), 1); var idx = this.loot.findIndex(item => item.id == removed.id);
this.loot.splice(idx, 1);
} }
else if (update.ClaimAdded) { else if (update.ClaimAdded) {
var c = update.ClaimAdded; var c = update.ClaimAdded;

View File

@@ -198,9 +198,14 @@ pub fn execute(
None None
} }
ApiActions::UndoLastAction(id) => { ApiActions::UndoLastAction(id) => {
match db::undo_last_action(conn, id) { if let Ok(event) = db::models::history::get_last_of_player(conn, id) {
Ok(ev) => response.notify(format!("'{}' annulé(e)", ev.name())), let name = String::from(event.name());
Err(e) => response.push_error(format!("Erreur : {:?}", e)), for undone in event.undo(conn)?.into_inner().into_iter() {
response.push_update(undone);
}
response.notify(format!("'{}' annulé(e)", name));
} else {
response.push_error("Aucune action trouvée")
}; };
None None
} }