mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-09-30 00:28:23 +00:00
Download multiple files as zip
This commit is contained in:
@@ -33,6 +33,7 @@ import Api.Model.ItemLightList exposing (ItemLightList)
|
||||
import Api.Model.SearchStats exposing (SearchStats)
|
||||
import Browser.Dom as Dom
|
||||
import Comp.BookmarkQueryManage
|
||||
import Comp.DownloadAll
|
||||
import Comp.ItemCardList
|
||||
import Comp.ItemDetail.FormChange exposing (FormChange)
|
||||
import Comp.ItemDetail.MultiEditMenu exposing (SaveNameState(..))
|
||||
@@ -76,6 +77,7 @@ type alias Model =
|
||||
|
||||
type TopWidgetModel
|
||||
= TopWidgetHidden
|
||||
| DownloadAll Comp.DownloadAll.Model
|
||||
| BookmarkQuery Comp.BookmarkQueryManage.Model
|
||||
|
||||
|
||||
@@ -239,7 +241,9 @@ type Msg
|
||||
| ToggleArrange ItemArrange
|
||||
| ToggleExpandCollapseRows
|
||||
| ToggleBookmarkCurrentQueryView
|
||||
| ToggleDownloadAllView
|
||||
| BookmarkQueryMsg Comp.BookmarkQueryManage.Msg
|
||||
| DownloadAllMsg Comp.DownloadAll.Msg
|
||||
| ItemSelectionChanged
|
||||
|
||||
|
||||
|
@@ -13,6 +13,7 @@ module Page.Search.Update exposing
|
||||
import Api
|
||||
import Api.Model.ItemLightList exposing (ItemLightList)
|
||||
import Comp.BookmarkQueryManage
|
||||
import Comp.DownloadAll
|
||||
import Comp.ItemCardList
|
||||
import Comp.ItemDetail.FormChange exposing (FormChange(..))
|
||||
import Comp.ItemDetail.MultiEditMenu exposing (SaveNameState(..))
|
||||
@@ -892,14 +893,46 @@ update texts bookmarkId lastViewedItemId env msg model =
|
||||
Nothing ->
|
||||
resultModelCmd env.selectedItems ( model, Cmd.none )
|
||||
|
||||
ToggleDownloadAllView ->
|
||||
case createQuery env.selectedItems model of
|
||||
Just q ->
|
||||
case model.topWidgetModel of
|
||||
DownloadAll _ ->
|
||||
resultModelCmd env.selectedItems
|
||||
( { model
|
||||
| topWidgetModel = TopWidgetHidden
|
||||
, viewMenuOpen = False
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
_ ->
|
||||
let
|
||||
( qm, qc ) =
|
||||
Comp.DownloadAll.init Comp.DownloadAll.AccessUser env.flags (Q.render q)
|
||||
in
|
||||
resultModelCmd env.selectedItems
|
||||
( { model | topWidgetModel = DownloadAll qm, viewMenuOpen = False }
|
||||
, Cmd.map DownloadAllMsg qc
|
||||
)
|
||||
|
||||
Nothing ->
|
||||
resultModelCmd env.selectedItems ( model, Cmd.none )
|
||||
|
||||
ToggleBookmarkCurrentQueryView ->
|
||||
case createQuery env.selectedItems model of
|
||||
Just q ->
|
||||
case model.topWidgetModel of
|
||||
BookmarkQuery _ ->
|
||||
resultModelCmd env.selectedItems ( { model | topWidgetModel = TopWidgetHidden, viewMenuOpen = False }, Cmd.none )
|
||||
resultModelCmd env.selectedItems
|
||||
( { model
|
||||
| topWidgetModel = TopWidgetHidden
|
||||
, viewMenuOpen = False
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
TopWidgetHidden ->
|
||||
_ ->
|
||||
let
|
||||
( qm, qc ) =
|
||||
Comp.BookmarkQueryManage.init (Q.render q)
|
||||
@@ -947,7 +980,30 @@ update texts bookmarkId lastViewedItemId env msg model =
|
||||
, Sub.map BookmarkQueryMsg res.sub
|
||||
)
|
||||
|
||||
TopWidgetHidden ->
|
||||
_ ->
|
||||
resultModelCmd env.selectedItems ( model, Cmd.none )
|
||||
|
||||
DownloadAllMsg lm ->
|
||||
case model.topWidgetModel of
|
||||
DownloadAll bm ->
|
||||
let
|
||||
res =
|
||||
Comp.DownloadAll.update env.flags lm bm
|
||||
|
||||
nextModel =
|
||||
if res.closed then
|
||||
TopWidgetHidden
|
||||
|
||||
else
|
||||
DownloadAll res.model
|
||||
in
|
||||
makeResult env.selectedItems
|
||||
( { model | topWidgetModel = nextModel }
|
||||
, Cmd.map DownloadAllMsg res.cmd
|
||||
, Sub.none
|
||||
)
|
||||
|
||||
_ ->
|
||||
resultModelCmd env.selectedItems ( model, Cmd.none )
|
||||
|
||||
PublishViewMsg lmsg ->
|
||||
|
@@ -11,6 +11,7 @@ import Api
|
||||
import Comp.Basic as B
|
||||
import Comp.BookmarkQueryManage
|
||||
import Comp.ConfirmModal
|
||||
import Comp.DownloadAll
|
||||
import Comp.ItemCardList
|
||||
import Comp.ItemMerge
|
||||
import Comp.MenuBar as MB
|
||||
@@ -108,7 +109,7 @@ mainView texts env model =
|
||||
|
||||
|
||||
bookmarkQueryWidget : Texts -> UiSettings -> Flags -> Model -> List (Html Msg)
|
||||
bookmarkQueryWidget texts _ _ model =
|
||||
bookmarkQueryWidget texts _ flags model =
|
||||
case model.topWidgetModel of
|
||||
BookmarkQuery m ->
|
||||
[ div [ class "px-2 mb-4 border-l border-r border-b dark:border-slate-600" ]
|
||||
@@ -116,6 +117,12 @@ bookmarkQueryWidget texts _ _ model =
|
||||
]
|
||||
]
|
||||
|
||||
DownloadAll m ->
|
||||
[ div [ class "mb-4 border-l border-r border-b dark:border-slate-600" ]
|
||||
[ Html.map DownloadAllMsg (Comp.DownloadAll.view flags texts.downloadAllComp m)
|
||||
]
|
||||
]
|
||||
|
||||
TopWidgetHidden ->
|
||||
[]
|
||||
|
||||
@@ -437,6 +444,24 @@ defaultMenuBar texts env model =
|
||||
onClick ToggleBookmarkCurrentQueryView
|
||||
]
|
||||
}
|
||||
, { label = texts.downloadAll
|
||||
, icon = i [ class "fa fa-download" ] []
|
||||
, disabled = createQuery env.selectedItems model == Nothing
|
||||
, attrs =
|
||||
[ title <|
|
||||
if createQuery env.selectedItems model == Nothing then
|
||||
texts.downloadAllQueryNeeded
|
||||
|
||||
else
|
||||
texts.downloadAll
|
||||
, href "#"
|
||||
, if createQuery env.selectedItems model == Nothing then
|
||||
class ""
|
||||
|
||||
else
|
||||
onClick ToggleDownloadAllView
|
||||
]
|
||||
}
|
||||
, { label =
|
||||
if env.settings.cardPreviewFullWidth then
|
||||
texts.fullHeightPreviewTitle
|
||||
|
@@ -5,13 +5,23 @@
|
||||
-}
|
||||
|
||||
|
||||
module Page.Share.Data exposing (Mode(..), Model, Msg(..), PageError(..), SearchBarMode(..), init, initCmd)
|
||||
module Page.Share.Data exposing
|
||||
( Mode(..)
|
||||
, Model
|
||||
, Msg(..)
|
||||
, PageError(..)
|
||||
, SearchBarMode(..)
|
||||
, TopContentModel(..)
|
||||
, init
|
||||
, initCmd
|
||||
)
|
||||
|
||||
import Api
|
||||
import Api.Model.ItemLightList exposing (ItemLightList)
|
||||
import Api.Model.SearchStats exposing (SearchStats)
|
||||
import Api.Model.ShareSecret exposing (ShareSecret)
|
||||
import Api.Model.ShareVerifyResult exposing (ShareVerifyResult)
|
||||
import Comp.DownloadAll
|
||||
import Comp.ItemCardList
|
||||
import Comp.PowerSearchInput
|
||||
import Comp.SearchMenu
|
||||
@@ -42,6 +52,11 @@ type SearchBarMode
|
||||
| SearchBarContent
|
||||
|
||||
|
||||
type TopContentModel
|
||||
= TopContentHidden
|
||||
| TopContentDownload Comp.DownloadAll.Model
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ mode : Mode
|
||||
, verifyResult : ShareVerifyResult
|
||||
@@ -61,6 +76,7 @@ type alias Model =
|
||||
, arrange : ItemArrange
|
||||
, rowsOpen : Set String
|
||||
}
|
||||
, topContent : TopContentModel
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +100,7 @@ emptyModel flags =
|
||||
, arrange = Data.ItemArrange.Cards
|
||||
, rowsOpen = Set.empty
|
||||
}
|
||||
, topContent = TopContentHidden
|
||||
}
|
||||
|
||||
|
||||
@@ -122,3 +139,5 @@ type Msg
|
||||
| ToggleViewMenu
|
||||
| ToggleArrange ItemArrange
|
||||
| ToggleShowGroups
|
||||
| DownloadAllMsg Comp.DownloadAll.Msg
|
||||
| ToggleDownloadAll
|
||||
|
@@ -146,6 +146,15 @@ view texts flags model =
|
||||
, onClick (ToggleArrange Data.ItemArrange.Cards)
|
||||
]
|
||||
}
|
||||
, { label = texts.downloadAllLabel
|
||||
, icon = i [ class "fa fa-download" ] []
|
||||
, disabled = False
|
||||
, attrs =
|
||||
[ title texts.downloadAllLabel
|
||||
, href "#"
|
||||
, onClick ToggleDownloadAll
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
28
modules/webapp/src/main/elm/Page/Share/TopContent.elm
Normal file
28
modules/webapp/src/main/elm/Page/Share/TopContent.elm
Normal file
@@ -0,0 +1,28 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Page.Share.TopContent exposing (view)
|
||||
|
||||
import Comp.DownloadAll
|
||||
import Data.Flags exposing (Flags)
|
||||
import Html exposing (Html, div, span, text)
|
||||
import Html.Attributes exposing (class)
|
||||
import Messages.Page.Share exposing (Texts)
|
||||
import Page.Share.Data exposing (Model, Msg(..), TopContentModel(..))
|
||||
|
||||
|
||||
view : Texts -> Flags -> Model -> Html Msg
|
||||
view texts flags model =
|
||||
case model.topContent of
|
||||
TopContentHidden ->
|
||||
span [ class "hidden" ] []
|
||||
|
||||
TopContentDownload dm ->
|
||||
div [ class "mb-4 border-l border-r border-b dark:border-slate-600" ]
|
||||
[ Html.map DownloadAllMsg
|
||||
(Comp.DownloadAll.view flags texts.downloadAll dm)
|
||||
]
|
@@ -8,6 +8,7 @@
|
||||
module Page.Share.Update exposing (UpdateResult, update)
|
||||
|
||||
import Api
|
||||
import Comp.DownloadAll
|
||||
import Comp.ItemCardList
|
||||
import Comp.LinkTarget exposing (LinkTarget)
|
||||
import Comp.PowerSearchInput
|
||||
@@ -19,7 +20,10 @@ import Data.ItemQuery as Q
|
||||
import Data.SearchMode
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Page.Share.Data exposing (..)
|
||||
import Process
|
||||
import Set
|
||||
import Task
|
||||
import Time
|
||||
import Util.Html
|
||||
import Util.Maybe
|
||||
import Util.Update
|
||||
@@ -252,30 +256,97 @@ update flags settings shareId msg model =
|
||||
UiSettingsResp (Err _) ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
DownloadAllMsg lm ->
|
||||
case model.topContent of
|
||||
TopContentDownload dm ->
|
||||
let
|
||||
res =
|
||||
Comp.DownloadAll.update flags lm dm
|
||||
|
||||
nextModel =
|
||||
if res.closed then
|
||||
TopContentHidden
|
||||
|
||||
else
|
||||
TopContentDownload res.model
|
||||
|
||||
-- The share page can't use websockets (not authenticated) so need to poll
|
||||
-- for new download state
|
||||
checkSub =
|
||||
if Comp.DownloadAll.isPreparing res.model then
|
||||
Process.sleep 3500
|
||||
|> Task.perform (always (DownloadAllMsg Comp.DownloadAll.checkDownload))
|
||||
|
||||
else
|
||||
Cmd.none
|
||||
in
|
||||
{ model = { model | topContent = nextModel }
|
||||
, cmd =
|
||||
Cmd.batch
|
||||
[ Cmd.map DownloadAllMsg res.cmd
|
||||
, checkSub
|
||||
]
|
||||
, sub = Sub.none
|
||||
}
|
||||
|
||||
_ ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
ToggleDownloadAll ->
|
||||
let
|
||||
vm =
|
||||
model.viewMode
|
||||
|
||||
nextVm =
|
||||
{ vm | menuOpen = False }
|
||||
in
|
||||
case model.topContent of
|
||||
TopContentHidden ->
|
||||
let
|
||||
query =
|
||||
createQuery flags model
|
||||
|> Maybe.withDefault (Q.DateMs Q.Gt 0)
|
||||
|
||||
am =
|
||||
Comp.DownloadAll.AccessShare shareId
|
||||
|
||||
( dm, dc ) =
|
||||
Comp.DownloadAll.init am flags (Q.render query)
|
||||
in
|
||||
noSub ( { model | topContent = TopContentDownload dm, viewMode = nextVm }, Cmd.map DownloadAllMsg dc )
|
||||
|
||||
TopContentDownload _ ->
|
||||
noSub ( { model | topContent = TopContentHidden, viewMode = nextVm }, Cmd.none )
|
||||
|
||||
|
||||
noSub : ( Model, Cmd Msg ) -> UpdateResult
|
||||
noSub ( m, c ) =
|
||||
UpdateResult m c Sub.none
|
||||
|
||||
|
||||
createQuery : Flags -> Model -> Maybe Q.ItemQuery
|
||||
createQuery flags model =
|
||||
Q.and
|
||||
[ Comp.SearchMenu.getItemQuery Data.ItemIds.empty model.searchMenuModel
|
||||
, Maybe.map Q.Fragment <|
|
||||
case model.searchMode of
|
||||
SearchBarNormal ->
|
||||
Comp.PowerSearchInput.getSearchString model.powerSearchInput
|
||||
|
||||
SearchBarContent ->
|
||||
if flags.config.fullTextSearchEnabled then
|
||||
Maybe.map (Q.Contents >> Q.render) model.contentSearch
|
||||
|
||||
else
|
||||
Maybe.map (Q.AllNames >> Q.render) model.contentSearch
|
||||
]
|
||||
|
||||
|
||||
makeSearchCmd : Flags -> Bool -> Model -> Cmd Msg
|
||||
makeSearchCmd flags doInit model =
|
||||
let
|
||||
xq =
|
||||
Q.and
|
||||
[ Comp.SearchMenu.getItemQuery Data.ItemIds.empty model.searchMenuModel
|
||||
, Maybe.map Q.Fragment <|
|
||||
case model.searchMode of
|
||||
SearchBarNormal ->
|
||||
Comp.PowerSearchInput.getSearchString model.powerSearchInput
|
||||
|
||||
SearchBarContent ->
|
||||
if flags.config.fullTextSearchEnabled then
|
||||
Maybe.map (Q.Contents >> Q.render) model.contentSearch
|
||||
|
||||
else
|
||||
Maybe.map (Q.AllNames >> Q.render) model.contentSearch
|
||||
]
|
||||
createQuery flags model
|
||||
|
||||
request mq =
|
||||
{ offset = Nothing
|
||||
|
@@ -19,6 +19,7 @@ import Page.Share.Data exposing (..)
|
||||
import Page.Share.Menubar as Menubar
|
||||
import Page.Share.Results as Results
|
||||
import Page.Share.Sidebar as Sidebar
|
||||
import Page.Share.TopContent as TopContent
|
||||
import Styles as S
|
||||
|
||||
|
||||
@@ -80,6 +81,7 @@ mainContent texts flags shareId model =
|
||||
]
|
||||
, Menubar.view texts flags model
|
||||
, errorMessage texts model
|
||||
, TopContent.view texts flags model
|
||||
, Results.view texts model.uiSettings flags shareId model
|
||||
]
|
||||
|
||||
|
Reference in New Issue
Block a user