ui: register: reduce "warping", keep selection at nearest txn

When the transaction list changes, eg due to toggling a query filter,
and the previously selected item has disappeared, instead of moving
the selection to the end, we now select the nearest transaction by
date (and if several have the same date, by journal order).
This commit is contained in:
Simon Michael 2017-06-30 19:08:51 +01:00
parent eab17c8edb
commit f666d5fc25

View File

@ -17,7 +17,7 @@ import Data.List.Split (splitOn)
import Data.Monoid import Data.Monoid
import Data.Maybe import Data.Maybe
import qualified Data.Text as T import qualified Data.Text as T
import Data.Time.Calendar (Day) import Data.Time.Calendar
import qualified Data.Vector as V import qualified Data.Vector as V
import Graphics.Vty (Event(..),Key(..),Modifier(..)) import Graphics.Vty (Event(..),Key(..),Modifier(..))
import Brick import Brick
@ -25,6 +25,7 @@ import Brick.Widgets.List
import Brick.Widgets.Edit import Brick.Widgets.Edit
import Brick.Widgets.Border (borderAttr) import Brick.Widgets.Border (borderAttr)
import Lens.Micro.Platform import Lens.Micro.Platform
import Safe
import System.Console.ANSI import System.Console.ANSI
@ -101,15 +102,27 @@ rsInit d reset ui@UIState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}, ajo
-- build the List -- build the List
newitems = list RegisterList (V.fromList $ displayitems ++ blankitems) 1 newitems = list RegisterList (V.fromList $ displayitems ++ blankitems) 1
-- keep the selection on the previously selected transaction if possible, -- decide which transaction is selected.
-- (eg after toggling nonzero mode), otherwise select the last element. -- if reset is true, select the last (latest) transaction;
-- otherwise, select the previously selected transaction if possible;
-- otherwise, select the transaction nearest in date to it;
-- or if there's several with the same date, the nearest in journal order;
-- otherwise, select the last (latest) transaction.
newitems' = listMoveTo newselidx newitems newitems' = listMoveTo newselidx newitems
where where
newselidx = case (reset, listSelectedElement rsList) of newselidx =
(True, _) -> endidx case (reset, listSelectedElement rsList) of
(_, Nothing) -> endidx (True, _) -> endidx
(_, Just (_,RegisterScreenItem{rsItemTransaction=Transaction{tindex=ti}})) (_, Nothing) -> endidx
-> fromMaybe endidx $ findIndex ((==ti) . tindex . rsItemTransaction) displayitems (_, Just (_, RegisterScreenItem{rsItemTransaction=Transaction{tindex=prevselidx, tdate=prevseld}})) ->
headDef endidx $ catMaybes [
findIndex ((==prevselidx) . tindex . rsItemTransaction) displayitems
,findIndex ((==nearestidbydatethenid) . Just . tindex . rsItemTransaction) displayitems
]
where
nearestidbydatethenid = third3 <$> (headMay $ sort
[(abs $ diffDays (tdate t) prevseld, abs (tindex t - prevselidx), tindex t) | t <- ts])
ts = map rsItemTransaction displayitems
endidx = length displayitems - 1 endidx = length displayitems - 1
rsInit _ _ _ = error "init function called with wrong screen type, should not happen" rsInit _ _ _ = error "init function called with wrong screen type, should not happen"