diff --git a/ChangeLog.md b/ChangeLog.md index abd105b..2216817 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -3,6 +3,7 @@ ## current - Ask for database to load on start-up - Add page break to report file +- Implemented player/goalie deletion ## 0.14.0 - Fixed a bug that was causing shutouts to not be recorded diff --git a/src/Mtlstats/Control/EditGoalie.hs b/src/Mtlstats/Control/EditGoalie.hs index 595b35a..7632084 100644 --- a/src/Mtlstats/Control/EditGoalie.hs +++ b/src/Mtlstats/Control/EditGoalie.hs @@ -23,10 +23,13 @@ along with this program. If not, see . module Mtlstats.Control.EditGoalie (editGoalieC) where +import Control.Monad.Trans.State (gets, modify) import Data.Maybe (fromMaybe) -import Lens.Micro ((^.)) +import Lens.Micro ((^.), (.~), (%~)) import UI.NCurses as C +import Mtlstats.Actions +import Mtlstats.Handlers import Mtlstats.Helpers.Goalie import Mtlstats.Menu import Mtlstats.Menu.EditGoalie @@ -52,6 +55,7 @@ editC cb = EGName -> nameC EGYtd -> ytdMenuC EGLifetime -> lifetimeMenuC + EGDelete -> deleteC EGYtdGames b -> ytdGamesC b EGYtdMins b -> ytdMinsC b EGYtdGoals b -> ytdGoalsC b @@ -83,6 +87,38 @@ ytdMenuC _ = menuControllerWith header editGoalieYtdMenu lifetimeMenuC :: Action () -> Controller lifetimeMenuC _ = menuControllerWith header editGoalieLtMenu +deleteC :: Action () -> Controller +deleteC _ = Controller + + { drawController = \s -> do + + C.drawString $ let + + hdr = fromMaybe [] $ do + gid <- s^.progMode.editGoalieStateL.egsSelectedGoalie + goalie <- nth gid $ s^.database.dbGoalies + Just $ "Goalie: " ++ goalieDetails goalie ++ "\n\n" + + in hdr ++ "Are you sure you want to delete this goalie? (Y/N)" + + return C.CursorInvisible + + , handleController = \e -> do + + case ynHandler e of + + Just True -> do + gets (^.progMode.editGoalieStateL.egsSelectedGoalie) >>= mapM_ + (\gid -> modify $ database.dbGoalies %~ dropNth gid) + modify edit + + Just False -> modify $ progMode.editGoalieStateL.egsMode .~ EGMenu + Nothing -> return () + + return True + + } + ytdGamesC :: Bool -> Action () -> Controller ytdGamesC = curry $ promptController . uncurry editGoalieYtdGamesPrompt diff --git a/src/Mtlstats/Control/EditPlayer.hs b/src/Mtlstats/Control/EditPlayer.hs index c31340b..5fe1d96 100644 --- a/src/Mtlstats/Control/EditPlayer.hs +++ b/src/Mtlstats/Control/EditPlayer.hs @@ -21,10 +21,13 @@ along with this program. If not, see . module Mtlstats.Control.EditPlayer (editPlayerC) where +import Control.Monad.Trans.State (gets, modify) import Data.Maybe (fromMaybe) -import Lens.Micro ((^.)) +import Lens.Micro ((^.), (.~), (%~)) import qualified UI.NCurses as C +import Mtlstats.Actions +import Mtlstats.Handlers import Mtlstats.Helpers.Player import Mtlstats.Menu import Mtlstats.Menu.EditPlayer @@ -45,6 +48,7 @@ editPlayerC eps EPPosition -> positionC EPYtd -> ytdC EPLifetime -> lifetimeC + EPDelete -> deleteC EPYtdGoals b -> ytdGoalsC b EPYtdAssists b -> ytdAssistsC b EPYtdPMin -> ytdPMinC @@ -74,6 +78,38 @@ ytdC _ = menuControllerWith header editPlayerYtdMenu lifetimeC :: Action () -> Controller lifetimeC _ = menuControllerWith header editPlayerLtMenu +deleteC :: Action () -> Controller +deleteC _ = Controller + + { drawController = \s -> do + + C.drawString $ let + + hdr = fromMaybe [] $ do + pid <- s^.progMode.editPlayerStateL.epsSelectedPlayer + player <- nth pid $ s^.database.dbPlayers + Just $ "Player: " ++ playerDetails player ++ "\n\n" + + in hdr ++ "Are you sure you want to delete this player? (Y/N)" + + return C.CursorInvisible + + , handleController = \e -> do + + case ynHandler e of + + Just True -> do + gets (^.progMode.editPlayerStateL.epsSelectedPlayer) >>= mapM_ + (\pid -> modify $ database.dbPlayers %~ dropNth pid) + modify edit + + Just False -> modify $ progMode.editPlayerStateL.epsMode .~ EPMenu + Nothing -> return () + + return True + + } + ytdGoalsC :: Bool -> Action () -> Controller ytdGoalsC batchMode callback = promptController $ editPlayerYtdGoalsPrompt batchMode callback diff --git a/src/Mtlstats/Menu/EditGoalie.hs b/src/Mtlstats/Menu/EditGoalie.hs index 0859b83..f8bec65 100644 --- a/src/Mtlstats/Menu/EditGoalie.hs +++ b/src/Mtlstats/Menu/EditGoalie.hs @@ -44,6 +44,7 @@ editGoalieMenu = Menu "EDIT GOALTENDER" () $ map , ( 'D', "ACTIVE FLAG", toggleActive ) , ( 'E', "YTD STATS", set EGYtd ) , ( 'F', "LIFETIME STATS", set EGLifetime ) + , ( 'G', "DELETE RECORD", set EGDelete ) , ( 'R', "RETURN TO EDIT MENU", edit ) ] diff --git a/src/Mtlstats/Menu/EditPlayer.hs b/src/Mtlstats/Menu/EditPlayer.hs index 0a5f8cc..42512ee 100644 --- a/src/Mtlstats/Menu/EditPlayer.hs +++ b/src/Mtlstats/Menu/EditPlayer.hs @@ -45,6 +45,7 @@ editPlayerMenu = Menu "EDIT PLAYER" () $ map , ( 'E', "ACTIVE FLAG", toggleActive ) , ( 'F', "YTD STATS", set EPYtd ) , ( 'G', "LIFETIME STATS", set EPLifetime ) + , ( 'H', "DELETE RECORD", set EPDelete ) , ( 'R', "RETURN TO EDIT MENU", edit ) ] diff --git a/src/Mtlstats/Types.hs b/src/Mtlstats/Types.hs index 6185a8c..b64f46a 100644 --- a/src/Mtlstats/Types.hs +++ b/src/Mtlstats/Types.hs @@ -378,6 +378,7 @@ data EditPlayerMode | EPPosition | EPYtd | EPLifetime + | EPDelete | EPYtdGoals Bool | EPYtdAssists Bool | EPYtdPMin @@ -403,6 +404,7 @@ data EditGoalieMode | EGName | EGYtd | EGLifetime + | EGDelete | EGYtdGames Bool | EGYtdMins Bool | EGYtdGoals Bool diff --git a/src/Mtlstats/Util.hs b/src/Mtlstats/Util.hs index 951859c..02249f9 100644 --- a/src/Mtlstats/Util.hs +++ b/src/Mtlstats/Util.hs @@ -22,6 +22,7 @@ along with this program. If not, see . module Mtlstats.Util ( nth , modifyNth + , dropNth , updateMap , slice , capitalizeName @@ -56,6 +57,18 @@ modifyNth n f = zipWith (\i x -> if i == n then f x else x) [0..] +-- | Attempt to drop the nth element from a list +dropNth + :: Int + -- ^ The index of the element to drop + -> [a] + -- ^ The list to be modified + -> [a] + -- ^ The modified list +dropNth n = foldr + (\(i, x) acc -> if i == n then acc else x : acc) + [] . zip [0..] + -- | Modify a value indexed by a given key in a map using a default -- initial value if not present updateMap diff --git a/test/UtilSpec.hs b/test/UtilSpec.hs index 13d9a39..b0c49f1 100644 --- a/test/UtilSpec.hs +++ b/test/UtilSpec.hs @@ -30,6 +30,7 @@ spec :: Spec spec = describe "Mtlstats.Util" $ do nthSpec modifyNthSpec + dropNthSpec updateMapSpec sliceSpec capitalizeNameSpec @@ -64,6 +65,20 @@ modifyNthSpec = describe "modifyNth" $ do it "should not modify the value" $ modifyNth (-1) succ list `shouldBe` [1, 2, 3] +dropNthSpec :: Spec +dropNthSpec = describe "dropNth" $ mapM_ + + (\(label, n, expected) -> + context label $ + it ("should be " ++ show expected) $ + dropNth n list `shouldBe` expected) + + [ ( "out of bounds", 1, ["foo", "baz"] ) + , ( "in bounds", 3, list ) + ] + + where list = ["foo", "bar", "baz"] + updateMapSpec :: Spec updateMapSpec = describe "updateMap" $ do let