mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-22 02:18:26 +00:00
Add a load-more button to item list
This commit is contained in:
@ -2,13 +2,19 @@ module Page.Home.Data exposing
|
||||
( Model
|
||||
, Msg(..)
|
||||
, ViewMode(..)
|
||||
, emptyModel
|
||||
, doSearchCmd
|
||||
, init
|
||||
, itemNav
|
||||
, resultsBelowLimit
|
||||
, searchLimit
|
||||
)
|
||||
|
||||
import Api
|
||||
import Api.Model.ItemLightList exposing (ItemLightList)
|
||||
import Comp.ItemCardList
|
||||
import Comp.SearchMenu
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Items
|
||||
import Http
|
||||
|
||||
|
||||
@ -18,16 +24,22 @@ type alias Model =
|
||||
, searchInProgress : Bool
|
||||
, viewMode : ViewMode
|
||||
, menuCollapsed : Bool
|
||||
, searchOffset : Int
|
||||
, moreAvailable : Bool
|
||||
, moreInProgress : Bool
|
||||
}
|
||||
|
||||
|
||||
emptyModel : Model
|
||||
emptyModel =
|
||||
init : Flags -> Model
|
||||
init _ =
|
||||
{ searchMenuModel = Comp.SearchMenu.emptyModel
|
||||
, itemListModel = Comp.ItemCardList.init
|
||||
, searchInProgress = False
|
||||
, viewMode = Listing
|
||||
, menuCollapsed = False
|
||||
, searchOffset = 0
|
||||
, moreAvailable = True
|
||||
, moreInProgress = False
|
||||
}
|
||||
|
||||
|
||||
@ -39,6 +51,7 @@ type Msg
|
||||
| ItemSearchResp (Result Http.Error ItemLightList)
|
||||
| DoSearch
|
||||
| ToggleSearchMenu
|
||||
| LoadMore
|
||||
|
||||
|
||||
type ViewMode
|
||||
@ -58,3 +71,32 @@ itemNav id model =
|
||||
{ prev = Maybe.map .id prev
|
||||
, next = Maybe.map .id next
|
||||
}
|
||||
|
||||
|
||||
searchLimit : Int
|
||||
searchLimit =
|
||||
90
|
||||
|
||||
|
||||
doSearchCmd : Flags -> Int -> Comp.SearchMenu.Model -> Cmd Msg
|
||||
doSearchCmd flags offset model =
|
||||
let
|
||||
smask =
|
||||
Comp.SearchMenu.getItemSearch model
|
||||
|
||||
mask =
|
||||
{ smask
|
||||
| limit = searchLimit
|
||||
, offset = offset
|
||||
}
|
||||
in
|
||||
Api.itemSearch flags mask ItemSearchResp
|
||||
|
||||
|
||||
resultsBelowLimit : Model -> Bool
|
||||
resultsBelowLimit model =
|
||||
let
|
||||
len =
|
||||
Data.Items.length model.itemListModel.results
|
||||
in
|
||||
len < searchLimit
|
||||
|
@ -1,6 +1,5 @@
|
||||
module Page.Home.Update exposing (update)
|
||||
|
||||
import Api
|
||||
import Browser.Navigation as Nav
|
||||
import Comp.ItemCardList
|
||||
import Comp.SearchMenu
|
||||
@ -21,7 +20,11 @@ update key flags msg model =
|
||||
model
|
||||
|
||||
ResetSearch ->
|
||||
update key flags (SearchMenuMsg Comp.SearchMenu.ResetForm) model
|
||||
let
|
||||
nm =
|
||||
{ model | searchOffset = 0 }
|
||||
in
|
||||
update key flags (SearchMenuMsg Comp.SearchMenu.ResetForm) nm
|
||||
|
||||
SearchMenuMsg m ->
|
||||
let
|
||||
@ -57,32 +60,71 @@ update key flags msg model =
|
||||
|
||||
ItemSearchResp (Ok list) ->
|
||||
let
|
||||
noff =
|
||||
model.searchOffset + searchLimit
|
||||
|
||||
m =
|
||||
{ model | searchInProgress = False, viewMode = Listing }
|
||||
{ model
|
||||
| searchInProgress = False
|
||||
, moreInProgress = False
|
||||
, searchOffset = noff
|
||||
, viewMode = Listing
|
||||
, moreAvailable = list.groups /= []
|
||||
}
|
||||
in
|
||||
update key flags (ItemCardListMsg (Comp.ItemCardList.SetResults list)) m
|
||||
if list.groups == [] then
|
||||
( m, Cmd.none )
|
||||
|
||||
else if model.searchOffset == 0 then
|
||||
update key flags (ItemCardListMsg (Comp.ItemCardList.SetResults list)) m
|
||||
|
||||
else
|
||||
update key flags (ItemCardListMsg (Comp.ItemCardList.AddResults list)) m
|
||||
|
||||
ItemSearchResp (Err _) ->
|
||||
( { model | searchInProgress = False }, Cmd.none )
|
||||
( { model
|
||||
| searchInProgress = False
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
DoSearch ->
|
||||
doSearch flags model
|
||||
let
|
||||
nm =
|
||||
{ model | searchOffset = 0 }
|
||||
in
|
||||
doSearch flags nm
|
||||
|
||||
ToggleSearchMenu ->
|
||||
( { model | menuCollapsed = not model.menuCollapsed }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
LoadMore ->
|
||||
if model.moreAvailable then
|
||||
doSearchMore flags model
|
||||
|
||||
else
|
||||
( model, Cmd.none )
|
||||
|
||||
|
||||
doSearch : Flags -> Model -> ( Model, Cmd Msg )
|
||||
doSearch flags model =
|
||||
let
|
||||
smask =
|
||||
Comp.SearchMenu.getItemSearch model.searchMenuModel
|
||||
|
||||
mask =
|
||||
{ smask | limit = 100 }
|
||||
cmd =
|
||||
doSearchCmd flags model.searchOffset model.searchMenuModel
|
||||
in
|
||||
( { model | searchInProgress = True, viewMode = Listing }
|
||||
, Api.itemSearch flags mask ItemSearchResp
|
||||
, cmd
|
||||
)
|
||||
|
||||
|
||||
doSearchMore : Flags -> Model -> ( Model, Cmd Msg )
|
||||
doSearchMore flags model =
|
||||
let
|
||||
cmd =
|
||||
doSearchCmd flags model.searchOffset model.searchMenuModel
|
||||
in
|
||||
( { model | moreInProgress = True, viewMode = Listing }
|
||||
, cmd
|
||||
)
|
||||
|
@ -61,6 +61,7 @@ view model =
|
||||
, not model.menuCollapsed
|
||||
)
|
||||
, ( "sixteen wide column", model.menuCollapsed )
|
||||
, ( "item-card-list", True )
|
||||
]
|
||||
]
|
||||
[ div
|
||||
@ -90,6 +91,36 @@ view model =
|
||||
Detail ->
|
||||
div [] []
|
||||
]
|
||||
, div
|
||||
[ classList
|
||||
[ ( "sixteen wide column", True )
|
||||
]
|
||||
]
|
||||
[ div [ class "ui basic center aligned segment" ]
|
||||
[ button
|
||||
[ classList
|
||||
[ ( "ui basic tiny button", True )
|
||||
, ( "disabled", not model.moreAvailable )
|
||||
, ( "hidden invisible", resultsBelowLimit model )
|
||||
]
|
||||
, disabled (not model.moreAvailable || model.moreInProgress || model.searchInProgress)
|
||||
, title "Load more items"
|
||||
, href "#"
|
||||
, onClick LoadMore
|
||||
]
|
||||
[ if model.moreInProgress then
|
||||
i [ class "loading spinner icon" ] []
|
||||
|
||||
else
|
||||
i [ class "angle double down icon" ] []
|
||||
, if model.moreAvailable then
|
||||
text "Load more…"
|
||||
|
||||
else
|
||||
text "That's all"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user