Navigate items using keyboard

- previous/next item with `.,`
- confirm with `c`
- unconfirm with `u`
This commit is contained in:
Eike Kettner
2020-09-22 00:27:32 +02:00
parent dc0e05bc20
commit 60b8dc2134
10 changed files with 107 additions and 41 deletions

View File

@ -195,7 +195,7 @@ updateItemDetail lmsg model =
Page.ItemDetail.Update.update
model.key
model.flags
inav.next
inav
model.uiSettings
lmsg
model.itemDetailModel

View File

@ -10,6 +10,7 @@ import Comp.ItemDetail.Model exposing (Msg(..))
import Comp.ItemDetail.Update
import Comp.ItemDetail.View exposing (..)
import Data.Flags exposing (Flags)
import Data.ItemNav exposing (ItemNav)
import Data.UiSettings exposing (UiSettings)
import Html exposing (..)
import Page exposing (Page(..))
@ -24,11 +25,11 @@ emptyModel =
Comp.ItemDetail.Model.emptyModel
update : Nav.Key -> Flags -> Maybe String -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
update : Nav.Key -> Flags -> ItemNav -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
update =
Comp.ItemDetail.Update.update
view : { prev : Maybe String, next : Maybe String } -> UiSettings -> Model -> Html Msg
view : ItemNav -> UiSettings -> Model -> Html Msg
view =
Comp.ItemDetail.View.view

View File

@ -40,6 +40,7 @@ import Http
import Page exposing (Page(..))
import Set exposing (Set)
import Throttle exposing (Throttle)
import Util.Html exposing (KeyCode)
import Util.Tag
@ -265,6 +266,7 @@ type Msg
| ResetHiddenMsg Field (Result Http.Error BasicResult)
| SaveNameResp (Result Http.Error BasicResult)
| UpdateThrottle
| KeyPress (Maybe KeyCode)
type SaveNameState

View File

@ -36,6 +36,7 @@ import Comp.YesNoDimmer
import Data.Direction exposing (Direction)
import Data.Fields exposing (Field)
import Data.Flags exposing (Flags)
import Data.ItemNav exposing (ItemNav)
import Data.UiSettings exposing (UiSettings)
import DatePicker
import Dict
@ -50,14 +51,15 @@ import Throttle
import Time
import Util.File exposing (makeFileId)
import Util.Folder exposing (mkFolderOption)
import Util.Html exposing (KeyCode(..))
import Util.Http
import Util.List
import Util.Maybe
import Util.String
update : Nav.Key -> Flags -> Maybe String -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
update key flags next settings msg model =
update : Nav.Key -> Flags -> ItemNav -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
update key flags inav settings msg model =
case msg of
Init ->
let
@ -83,7 +85,7 @@ update key flags next settings msg model =
( m1, c1, s1 ) =
update key
flags
next
inav
settings
(TagDropdownMsg (Comp.Dropdown.SetSelection item.tags))
model
@ -91,7 +93,7 @@ update key flags next settings msg model =
( m2, c2, s2 ) =
update key
flags
next
inav
settings
(DirDropdownMsg
(Comp.Dropdown.SetSelection
@ -106,7 +108,7 @@ update key flags next settings msg model =
( m3, c3, s3 ) =
update key
flags
next
inav
settings
(OrgDropdownMsg
(Comp.Dropdown.SetSelection
@ -121,7 +123,7 @@ update key flags next settings msg model =
( m4, c4, s4 ) =
update key
flags
next
inav
settings
(CorrPersonMsg
(Comp.Dropdown.SetSelection
@ -136,7 +138,7 @@ update key flags next settings msg model =
( m5, c5, s5 ) =
update key
flags
next
inav
settings
(ConcPersonMsg
(Comp.Dropdown.SetSelection
@ -151,7 +153,7 @@ update key flags next settings msg model =
( m6, c6, s6 ) =
update key
flags
next
inav
settings
(ConcEquipMsg
(Comp.Dropdown.SetSelection
@ -164,12 +166,12 @@ update key flags next settings msg model =
m5
( m7, c7, s7 ) =
update key flags next settings AddFilesReset m6
update key flags inav settings AddFilesReset m6
( m8, c8, s8 ) =
update key
flags
next
inav
settings
(FolderDropdownMsg
(Comp.Dropdown.SetSelection
@ -498,7 +500,7 @@ update key flags next settings msg model =
noSub ( { model | deleteItemConfirm = cm }, cmd )
RequestDelete ->
update key flags next settings (DeleteItemConfirm Comp.YesNoDimmer.activate) model
update key flags inav settings (DeleteItemConfirm Comp.YesNoDimmer.activate) model
SetCorrOrgSuggestion idname ->
noSub ( model, setCorrOrg flags model (Just idname) )
@ -537,7 +539,7 @@ update key flags next settings msg model =
|> List.map mkIdName
|> Comp.Dropdown.SetOptions
in
update key flags next settings (FolderDropdownMsg opts) model_
update key flags inav settings (FolderDropdownMsg opts) model_
GetFolderResp (Err _) ->
noSub ( model, Cmd.none )
@ -548,7 +550,7 @@ update key flags next settings msg model =
Comp.Dropdown.SetOptions tags.items
( m1, c1, s1 ) =
update key flags next settings (TagDropdownMsg tagList) model
update key flags inav settings (TagDropdownMsg tagList) model
in
( m1, c1, s1 )
@ -560,7 +562,7 @@ update key flags next settings msg model =
opts =
Comp.Dropdown.SetOptions orgs.items
in
update key flags next settings (OrgDropdownMsg opts) model
update key flags inav settings (OrgDropdownMsg opts) model
GetOrgResp (Err _) ->
noSub ( model, Cmd.none )
@ -571,10 +573,10 @@ update key flags next settings msg model =
Comp.Dropdown.SetOptions ps.items
( m1, c1, s1 ) =
update key flags next settings (CorrPersonMsg opts) model
update key flags inav settings (CorrPersonMsg opts) model
( m2, c2, s2 ) =
update key flags next settings (ConcPersonMsg opts) m1
update key flags inav settings (ConcPersonMsg opts) m1
in
( m2, Cmd.batch [ c1, c2 ], Sub.batch [ s1, s2 ] )
@ -589,7 +591,7 @@ update key flags next settings msg model =
equips.items
)
in
update key flags next settings (ConcEquipMsg opts) model
update key flags inav settings (ConcEquipMsg opts) model
GetEquipResp (Err _) ->
noSub ( model, Cmd.none )
@ -625,7 +627,7 @@ update key flags next settings msg model =
DeleteResp (Ok res) ->
if res.success then
case next of
case inav.next of
Just id ->
noSub ( model, Page.set key (ItemDetailPage id) )
@ -639,7 +641,7 @@ update key flags next settings msg model =
noSub ( model, Cmd.none )
GetItemResp (Ok item) ->
update key flags next settings (SetItem item) model
update key flags inav settings (SetItem item) model
GetItemResp (Err _) ->
noSub ( model, Cmd.none )
@ -834,7 +836,7 @@ update key flags next settings msg model =
DeleteAttachResp (Ok res) ->
if res.success then
update key flags next settings ReloadItem model
update key flags inav settings ReloadItem model
else
noSub ( model, Cmd.none )
@ -845,7 +847,7 @@ update key flags next settings msg model =
RequestDeleteAttachment id ->
update key
flags
next
inav
settings
(DeleteAttachConfirm id Comp.YesNoDimmer.activate)
model
@ -1228,6 +1230,41 @@ update key flags next settings msg model =
in
withSub ( { model | nameSaveThrottle = newThrottle }, cmd )
KeyPress n ->
case n of
Just Letter_C ->
if model.item.state == "created" then
update key flags inav settings ConfirmItem model
else
noSub ( model, Cmd.none )
Just Letter_U ->
if model.item.state /= "created" then
update key flags inav settings UnconfirmItem model
else
noSub ( model, Cmd.none )
Just Point ->
case inav.next of
Just id ->
noSub ( model, Page.set key (ItemDetailPage id) )
Nothing ->
noSub ( model, Cmd.none )
Just Comma ->
case inav.prev of
Just id ->
noSub ( model, Page.set key (ItemDetailPage id) )
Nothing ->
noSub ( model, Cmd.none )
_ ->
noSub ( model, Cmd.none )
--- Helper

View File

@ -14,6 +14,7 @@ import Comp.YesNoDimmer
import Data.Direction
import Data.Fields
import Data.Icons as Icons
import Data.ItemNav exposing (ItemNav)
import Data.UiSettings exposing (UiSettings)
import DatePicker
import Dict
@ -27,6 +28,7 @@ import Page exposing (Page(..))
import Set
import Util.File exposing (makeFileId)
import Util.Folder
import Util.Html exposing (onKeyUpCode)
import Util.List
import Util.Maybe
import Util.Size
@ -34,9 +36,11 @@ import Util.String
import Util.Time
view : { prev : Maybe String, next : Maybe String } -> UiSettings -> Model -> Html Msg
view : ItemNav -> UiSettings -> Model -> Html Msg
view inav settings model =
div []
div
[ onKeyUpCode KeyPress
]
[ renderItemInfo settings model
, renderDetailMenu inav model
, renderMailForm settings model
@ -87,7 +91,7 @@ view inav settings model =
--- Helper
renderDetailMenu : { prev : Maybe String, next : Maybe String } -> Model -> Html Msg
renderDetailMenu : ItemNav -> Model -> Html Msg
renderDetailMenu inav model =
div
[ classList
@ -109,6 +113,7 @@ renderDetailMenu inav model =
, Maybe.map ItemDetailPage inav.prev
|> Maybe.map Page.href
|> Maybe.withDefault (href "#")
, title "Previous item. Key ','"
]
[ i [ class "caret square left outline icon" ] []
]
@ -120,6 +125,7 @@ renderDetailMenu inav model =
, Maybe.map ItemDetailPage inav.next
|> Maybe.map Page.href
|> Maybe.withDefault (href "#")
, title "Next item. Key '.'"
]
[ i [ class "caret square right outline icon" ] []
]
@ -718,7 +724,7 @@ renderEditButtons model =
[ ( "borderless item", True )
, ( "invisible", model.item.state /= "created" )
]
, title "Confirm metadata"
, title "Confirm metadata. Key 'c'."
, href "#"
, onClick ConfirmItem
]
@ -730,7 +736,7 @@ renderEditButtons model =
, ( "invisible", model.item.state /= "confirmed" )
]
, href "#"
, title "Unconfirm metadata"
, title "Unconfirm metadata. Key 'u'."
, onClick UnconfirmItem
]
[ i [ class "eye slash outline icon" ] []

View File

@ -0,0 +1,7 @@
module Data.ItemNav exposing (ItemNav)
type alias ItemNav =
{ prev : Maybe String
, next : Maybe String
}

View File

@ -18,6 +18,7 @@ import Comp.FixedDropdown
import Comp.ItemCardList
import Comp.SearchMenu
import Data.Flags exposing (Flags)
import Data.ItemNav exposing (ItemNav)
import Data.Items
import Data.UiSettings exposing (UiSettings)
import Http
@ -119,7 +120,7 @@ searchTypeString st =
"Contents Only"
itemNav : String -> Model -> { prev : Maybe String, next : Maybe String }
itemNav : String -> Model -> ItemNav
itemNav id model =
let
prev =

View File

@ -5,21 +5,22 @@ import Browser.Navigation as Nav
import Comp.ItemDetail
import Comp.ItemDetail.Model
import Data.Flags exposing (Flags)
import Data.ItemNav exposing (ItemNav)
import Data.UiSettings exposing (UiSettings)
import Page.ItemDetail.Data exposing (Model, Msg(..))
import Scroll
import Task
update : Nav.Key -> Flags -> Maybe String -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
update key flags next settings msg model =
update : Nav.Key -> Flags -> ItemNav -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
update key flags inav settings msg model =
case msg of
Init id ->
let
( lm, lc, ls ) =
Comp.ItemDetail.update key
flags
next
inav
settings
Comp.ItemDetail.Model.Init
model.detail
@ -39,7 +40,7 @@ update key flags next settings msg model =
ItemDetailMsg lmsg ->
let
( lm, lc, ls ) =
Comp.ItemDetail.update key flags next settings lmsg model.detail
Comp.ItemDetail.update key flags inav settings lmsg model.detail
in
( { model | detail = lm }
, Cmd.map ItemDetailMsg lc
@ -51,7 +52,7 @@ update key flags next settings msg model =
lmsg =
Comp.ItemDetail.Model.SetItem item
in
update key flags next settings (ItemDetailMsg lmsg) model
update key flags inav settings (ItemDetailMsg lmsg) model
ItemResp (Err _) ->
( model, Cmd.none, Sub.none )

View File

@ -1,18 +1,13 @@
module Page.ItemDetail.View exposing (view)
import Comp.ItemDetail
import Data.ItemNav exposing (ItemNav)
import Data.UiSettings exposing (UiSettings)
import Html exposing (..)
import Html.Attributes exposing (..)
import Page.ItemDetail.Data exposing (Model, Msg(..))
type alias ItemNav =
{ prev : Maybe String
, next : Maybe String
}
view : ItemNav -> UiSettings -> Model -> Html Msg
view inav settings model =
div [ class "ui fluid container item-detail-page" ]

View File

@ -46,12 +46,16 @@ type KeyCode
| Enter
| Space
| ESC
| Letter_C
| Letter_N
| Letter_P
| Letter_H
| Letter_J
| Letter_K
| Letter_L
| Letter_U
| Point
| Comma
| Code Int
@ -79,6 +83,9 @@ intToKeyCode code =
27 ->
Just ESC
67 ->
Just Letter_C
72 ->
Just Letter_H
@ -97,6 +104,15 @@ intToKeyCode code =
80 ->
Just Letter_P
85 ->
Just Letter_U
188 ->
Just Comma
190 ->
Just Point
n ->
Just (Code n)