From 1f2a940968ead9a8aa2a9b8fc13dd74feddd4079 Mon Sep 17 00:00:00 2001 From: Artus Date: Mon, 28 Oct 2019 16:08:05 +0100 Subject: [PATCH] adds reactivity when undoing an event --- lootalot_db/src/lib.rs | 27 +++++++-------------- lootalot_db/src/models/claim.rs | 2 +- lootalot_db/src/models/history.rs | 23 ++++++++++++++---- lootalot_front/src/components/PlayerView.js | 5 ++-- src/api.rs | 11 ++++++--- 5 files changed, 39 insertions(+), 29 deletions(-) diff --git a/lootalot_db/src/lib.rs b/lootalot_db/src/lib.rs index 0a7d0b2..3f420d0 100644 --- a/lootalot_db/src/lib.rs +++ b/lootalot_db/src/lib.rs @@ -20,7 +20,7 @@ pub use models::{ claim::{Claim, Claims}, item::{Item, LootManager, Inventory}, player::{Player, Wealth, Players, AsPlayer}, - history::Event, + history::{Event, UpdateList}, }; /// The connection used @@ -54,22 +54,21 @@ pub enum Update { impl Update { /// Change back what has been updated - fn undo(&self, conn: &DbConnection, id: i32) -> QueryResult<()> { - match self { + fn undo(&self, conn: &DbConnection, id: i32) -> QueryResult { + Ok(match self { Update::Wealth(diff) => { - AsPlayer(conn, id).update_wealth(-diff.to_gp())?; + Update::Wealth(AsPlayer(conn, id).update_wealth(-diff.to_gp())?) }, Update::ItemAdded(item) => { - LootManager(conn, id).remove(item.id)?; + Update::ItemRemoved(LootManager(conn, id).remove(item.id)?) }, Update::ItemRemoved(item) => { - LootManager(conn, id).add_from(&item)?; + Update::ItemAdded(LootManager(conn, id).add_from(&item)?) }, // Unused for now - Update::ClaimAdded(claim) => {}, - Update::ClaimRemoved(claim) => {}, - }; - Ok(()) + Update::ClaimAdded(claim) => { Update::ClaimRemoved(*claim) }, + Update::ClaimRemoved(claim) => { Update::ClaimAdded(*claim) }, + }) } } @@ -198,14 +197,6 @@ pub fn split_and_share(conn: &DbConnection, amount: i32, players: Vec) -> Q }) } - -/// Reverts the last action stored for player -pub fn undo_last_action(conn: &DbConnection, id: i32) -> QueryResult { - let last_event = models::history::get_last_of_player(conn, id)?; - last_event.undo(conn) -} - - #[cfg(none)] mod tests_old { use super::*; diff --git a/lootalot_db/src/models/claim.rs b/lootalot_db/src/models/claim.rs index 11bfe6d..76d7d81 100644 --- a/lootalot_db/src/models/claim.rs +++ b/lootalot_db/src/models/claim.rs @@ -5,7 +5,7 @@ use crate::models::{self, item::Loot}; use crate::schema::claims; /// 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)] pub struct Claim { /// DB Identifier diff --git a/lootalot_db/src/models/history.rs b/lootalot_db/src/models/history.rs index 94e465c..d23681b 100644 --- a/lootalot_db/src/models/history.rs +++ b/lootalot_db/src/models/history.rs @@ -9,6 +9,16 @@ use crate::{DbConnection, QueryResult, Update}; #[derive(Debug, FromSqlRow)] pub struct UpdateList(Vec); +impl UpdateList { + pub fn inner(&self) -> &Vec { + &self.0 + } + + pub fn into_inner(self) -> Vec { + self.0 + } +} + // TODO: decide if updates is really optionnal or not // (like if storing an event without update is usefull ?) @@ -29,15 +39,18 @@ impl Event { /// TODO: why a move here ?? /// Undo all updates in a single transaction - pub fn undo(self, conn: &DbConnection) -> QueryResult { + pub fn undo(self, conn: &DbConnection) -> QueryResult { conn.transaction(move || { if let Some(ref updates) = self.updates { - for update in updates.0.iter() { - update.undo(conn, self.player_id)?; - } + let undone = updates.0.iter() + // TODO: swallow errors ! + .filter_map(|u| u.undo(conn, self.player_id).ok()) + .collect(); diesel::delete(history::table.find(self.id)).execute(conn)?; + Ok(UpdateList(undone)) + } else { + Ok(UpdateList(vec![])) } - Ok(self) }) } } diff --git a/lootalot_front/src/components/PlayerView.js b/lootalot_front/src/components/PlayerView.js index 2947d1c..d53b95a 100644 --- a/lootalot_front/src/components/PlayerView.js +++ b/lootalot_front/src/components/PlayerView.js @@ -39,8 +39,9 @@ export default { this.loot.push(i); } else if (update.ItemRemoved) { - var i = update.ItemRemoved; - this.loot.splice(this.loot.indexOf(i), 1); + var removed = update.ItemRemoved; + var idx = this.loot.findIndex(item => item.id == removed.id); + this.loot.splice(idx, 1); } else if (update.ClaimAdded) { var c = update.ClaimAdded; diff --git a/src/api.rs b/src/api.rs index 4b8ee42..4eb2bca 100644 --- a/src/api.rs +++ b/src/api.rs @@ -198,9 +198,14 @@ pub fn execute( None } ApiActions::UndoLastAction(id) => { - match db::undo_last_action(conn, id) { - Ok(ev) => response.notify(format!("'{}' annulé(e)", ev.name())), - Err(e) => response.push_error(format!("Erreur : {:?}", e)), + if let Ok(event) = db::models::history::get_last_of_player(conn, id) { + let name = String::from(event.name()); + 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 }