mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-09-30 00:28:23 +00:00
Outline share detail page
This commit is contained in:
@@ -468,23 +468,22 @@ itemCardList texts _ settings model =
|
||||
previewUrlFallback item =
|
||||
Api.itemBasePreviewURL item.id
|
||||
|
||||
viewCfg sel =
|
||||
Comp.ItemCardList.ViewConfig
|
||||
model.scrollToCard
|
||||
sel
|
||||
previewUrl
|
||||
previewUrlFallback
|
||||
(.id >> Api.fileURL)
|
||||
(.id >> ItemDetailPage)
|
||||
|
||||
itemViewCfg =
|
||||
case model.viewMode of
|
||||
SelectView svm ->
|
||||
Comp.ItemCardList.ViewConfig
|
||||
model.scrollToCard
|
||||
(Data.ItemSelection.Active svm.ids)
|
||||
previewUrl
|
||||
previewUrlFallback
|
||||
(.id >> Api.fileURL)
|
||||
viewCfg (Data.ItemSelection.Active svm.ids)
|
||||
|
||||
_ ->
|
||||
Comp.ItemCardList.ViewConfig
|
||||
model.scrollToCard
|
||||
Data.ItemSelection.Inactive
|
||||
previewUrl
|
||||
previewUrlFallback
|
||||
(.id >> Api.fileURL)
|
||||
viewCfg Data.ItemSelection.Inactive
|
||||
in
|
||||
[ Html.map ItemCardListMsg
|
||||
(Comp.ItemCardList.view2 texts.itemCardList
|
||||
|
@@ -15,6 +15,7 @@ import Api.Model.ShareVerifyResult exposing (ShareVerifyResult)
|
||||
import Comp.ItemCardList
|
||||
import Comp.PowerSearchInput
|
||||
import Comp.SearchMenu
|
||||
import Comp.SharePasswordForm
|
||||
import Data.Flags exposing (Flags)
|
||||
import Http
|
||||
|
||||
@@ -31,16 +32,10 @@ type PageError
|
||||
| PageErrorAuthFail
|
||||
|
||||
|
||||
type alias PasswordModel =
|
||||
{ password : String
|
||||
, passwordFailed : Bool
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ mode : Mode
|
||||
, verifyResult : ShareVerifyResult
|
||||
, passwordModel : PasswordModel
|
||||
, passwordModel : Comp.SharePasswordForm.Model
|
||||
, pageError : PageError
|
||||
, searchMenuModel : Comp.SearchMenu.Model
|
||||
, powerSearchInput : Comp.PowerSearchInput.Model
|
||||
@@ -53,10 +48,7 @@ emptyModel : Flags -> Model
|
||||
emptyModel flags =
|
||||
{ mode = ModeInitial
|
||||
, verifyResult = Api.Model.ShareVerifyResult.empty
|
||||
, passwordModel =
|
||||
{ password = ""
|
||||
, passwordFailed = False
|
||||
}
|
||||
, passwordModel = Comp.SharePasswordForm.init
|
||||
, pageError = PageErrorNone
|
||||
, searchMenuModel = Comp.SearchMenu.init flags
|
||||
, powerSearchInput = Comp.PowerSearchInput.init
|
||||
@@ -79,8 +71,7 @@ type Msg
|
||||
= VerifyResp (Result Http.Error ShareVerifyResult)
|
||||
| SearchResp (Result Http.Error ItemLightList)
|
||||
| StatsResp (Result Http.Error SearchStats)
|
||||
| SetPassword String
|
||||
| SubmitPassword
|
||||
| PasswordMsg Comp.SharePasswordForm.Msg
|
||||
| SearchMenuMsg Comp.SearchMenu.Msg
|
||||
| PowerSearchMsg Comp.PowerSearchInput.Msg
|
||||
| ResetSearch
|
||||
|
@@ -14,11 +14,12 @@ import Data.UiSettings exposing (UiSettings)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Messages.Page.Share exposing (Texts)
|
||||
import Page exposing (Page(..))
|
||||
import Page.Share.Data exposing (Model, Msg(..))
|
||||
|
||||
|
||||
view : Texts -> UiSettings -> Model -> Html Msg
|
||||
view texts settings model =
|
||||
view : Texts -> UiSettings -> String -> Model -> Html Msg
|
||||
view texts settings shareId model =
|
||||
let
|
||||
viewCfg =
|
||||
{ current = Nothing
|
||||
@@ -26,6 +27,7 @@ view texts settings model =
|
||||
, previewUrl = \attach -> Api.shareAttachmentPreviewURL attach.id
|
||||
, previewUrlFallback = \item -> Api.shareItemBasePreviewURL item.id
|
||||
, attachUrl = .id >> Api.shareFileURL
|
||||
, detailPage = \item -> ShareDetailPage shareId item.id
|
||||
}
|
||||
in
|
||||
div []
|
||||
|
@@ -13,6 +13,7 @@ import Comp.ItemCardList
|
||||
import Comp.LinkTarget exposing (LinkTarget)
|
||||
import Comp.PowerSearchInput
|
||||
import Comp.SearchMenu
|
||||
import Comp.SharePasswordForm
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.ItemQuery as Q
|
||||
import Data.SearchMode
|
||||
@@ -51,26 +52,13 @@ update flags settings shareId msg model =
|
||||
)
|
||||
|
||||
else if res.passwordRequired then
|
||||
if model.mode == ModePassword then
|
||||
noSub
|
||||
( { model
|
||||
| pageError = PageErrorNone
|
||||
, passwordModel =
|
||||
{ password = ""
|
||||
, passwordFailed = True
|
||||
}
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
else
|
||||
noSub
|
||||
( { model
|
||||
| pageError = PageErrorNone
|
||||
, mode = ModePassword
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
noSub
|
||||
( { model
|
||||
| pageError = PageErrorNone
|
||||
, mode = ModePassword
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
else
|
||||
noSub
|
||||
@@ -101,21 +89,21 @@ update flags settings shareId msg model =
|
||||
StatsResp (Err err) ->
|
||||
noSub ( { model | pageError = PageErrorHttp err }, Cmd.none )
|
||||
|
||||
SetPassword pw ->
|
||||
PasswordMsg lmsg ->
|
||||
let
|
||||
pm =
|
||||
model.passwordModel
|
||||
( m, c, res ) =
|
||||
Comp.SharePasswordForm.update shareId flags lmsg model.passwordModel
|
||||
in
|
||||
noSub ( { model | passwordModel = { pm | password = pw } }, Cmd.none )
|
||||
case res of
|
||||
Just verifyResult ->
|
||||
update flags
|
||||
settings
|
||||
shareId
|
||||
(VerifyResp (Ok verifyResult))
|
||||
model
|
||||
|
||||
SubmitPassword ->
|
||||
let
|
||||
secret =
|
||||
{ shareId = shareId
|
||||
, password = Just model.passwordModel.password
|
||||
}
|
||||
in
|
||||
noSub ( model, Api.verifyShare flags secret VerifyResp )
|
||||
Nothing ->
|
||||
noSub ( { model | passwordModel = m }, Cmd.map PasswordMsg c )
|
||||
|
||||
SearchMenuMsg lm ->
|
||||
let
|
||||
|
@@ -9,6 +9,7 @@ module Page.Share.View exposing (viewContent, viewSidebar)
|
||||
|
||||
import Api.Model.VersionInfo exposing (VersionInfo)
|
||||
import Comp.Basic as B
|
||||
import Comp.SharePasswordForm
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Items
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
@@ -35,8 +36,8 @@ viewSidebar texts visible flags settings model =
|
||||
]
|
||||
|
||||
|
||||
viewContent : Texts -> Flags -> VersionInfo -> UiSettings -> Model -> Html Msg
|
||||
viewContent texts flags versionInfo uiSettings model =
|
||||
viewContent : Texts -> Flags -> VersionInfo -> UiSettings -> String -> Model -> Html Msg
|
||||
viewContent texts flags versionInfo uiSettings shareId model =
|
||||
case model.mode of
|
||||
ModeInitial ->
|
||||
div
|
||||
@@ -54,15 +55,15 @@ viewContent texts flags versionInfo uiSettings model =
|
||||
passwordContent texts flags versionInfo model
|
||||
|
||||
ModeShare ->
|
||||
mainContent texts flags uiSettings model
|
||||
mainContent texts flags uiSettings shareId model
|
||||
|
||||
|
||||
|
||||
--- Helpers
|
||||
|
||||
|
||||
mainContent : Texts -> Flags -> UiSettings -> Model -> Html Msg
|
||||
mainContent texts _ settings model =
|
||||
mainContent : Texts -> Flags -> UiSettings -> String -> Model -> Html Msg
|
||||
mainContent texts _ settings shareId model =
|
||||
div
|
||||
[ id "content"
|
||||
, class "h-full flex flex-col"
|
||||
@@ -75,7 +76,7 @@ mainContent texts _ settings model =
|
||||
[ text <| Maybe.withDefault "" model.verifyResult.name
|
||||
]
|
||||
, Menubar.view texts model
|
||||
, Results.view texts settings model
|
||||
, Results.view texts settings shareId model
|
||||
]
|
||||
|
||||
|
||||
@@ -86,76 +87,6 @@ passwordContent texts flags versionInfo model =
|
||||
, class "h-full flex flex-col items-center justify-center w-full"
|
||||
, class S.content
|
||||
]
|
||||
[ div [ class ("flex flex-col px-4 sm:px-6 md:px-8 lg:px-10 py-8 rounded-md " ++ S.box) ]
|
||||
[ div [ class "self-center" ]
|
||||
[ img
|
||||
[ class "w-16 py-2"
|
||||
, src (flags.config.docspellAssetPath ++ "/img/logo-96.png")
|
||||
]
|
||||
[]
|
||||
]
|
||||
, div [ class "font-medium self-center text-xl sm:text-2xl" ]
|
||||
[ text texts.passwordRequired
|
||||
]
|
||||
, Html.form
|
||||
[ action "#"
|
||||
, onSubmit SubmitPassword
|
||||
, autocomplete False
|
||||
]
|
||||
[ div [ class "flex flex-col my-3" ]
|
||||
[ label
|
||||
[ for "password"
|
||||
, class S.inputLabel
|
||||
]
|
||||
[ text texts.password
|
||||
]
|
||||
, div [ class "relative" ]
|
||||
[ div [ class S.inputIcon ]
|
||||
[ i [ class "fa fa-lock" ] []
|
||||
]
|
||||
, input
|
||||
[ type_ "password"
|
||||
, name "password"
|
||||
, autocomplete False
|
||||
, autofocus True
|
||||
, tabindex 1
|
||||
, onInput SetPassword
|
||||
, value model.passwordModel.password
|
||||
, class ("pl-10 pr-4 py-2 rounded-lg" ++ S.textInput)
|
||||
, placeholder texts.password
|
||||
]
|
||||
[]
|
||||
]
|
||||
]
|
||||
, div [ class "flex flex-col my-3" ]
|
||||
[ button
|
||||
[ type_ "submit"
|
||||
, class S.primaryButton
|
||||
]
|
||||
[ text texts.passwordSubmitButton
|
||||
]
|
||||
]
|
||||
, div
|
||||
[ class S.errorMessage
|
||||
, classList [ ( "hidden", not model.passwordModel.passwordFailed ) ]
|
||||
]
|
||||
[ text texts.passwordFailed
|
||||
]
|
||||
]
|
||||
]
|
||||
, a
|
||||
[ class "inline-flex items-center mt-4 text-xs opacity-50 hover:opacity-90"
|
||||
, href "https://docspell.org"
|
||||
, target "_new"
|
||||
]
|
||||
[ img
|
||||
[ src (flags.config.docspellAssetPath ++ "/img/logo-mc-96.png")
|
||||
, class "w-3 h-3 mr-1"
|
||||
]
|
||||
[]
|
||||
, span []
|
||||
[ text "Docspell "
|
||||
, text versionInfo.version
|
||||
]
|
||||
]
|
||||
[ Html.map PasswordMsg
|
||||
(Comp.SharePasswordForm.view texts.passwordForm flags versionInfo model.passwordModel)
|
||||
]
|
||||
|
56
modules/webapp/src/main/elm/Page/ShareDetail/Data.elm
Normal file
56
modules/webapp/src/main/elm/Page/ShareDetail/Data.elm
Normal file
@@ -0,0 +1,56 @@
|
||||
module Page.ShareDetail.Data exposing (Model, Msg(..), PageError(..), ViewMode(..), init)
|
||||
|
||||
import Api
|
||||
import Api.Model.ItemDetail exposing (ItemDetail)
|
||||
import Api.Model.ShareSecret exposing (ShareSecret)
|
||||
import Api.Model.ShareVerifyResult exposing (ShareVerifyResult)
|
||||
import Comp.SharePasswordForm
|
||||
import Data.Flags exposing (Flags)
|
||||
import Http
|
||||
|
||||
|
||||
type ViewMode
|
||||
= ViewNormal
|
||||
| ViewPassword
|
||||
| ViewLoading
|
||||
|
||||
|
||||
type PageError
|
||||
= PageErrorNone
|
||||
| PageErrorHttp Http.Error
|
||||
| PageErrorAuthFail
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ item : ItemDetail
|
||||
, verifyResult : ShareVerifyResult
|
||||
, passwordModel : Comp.SharePasswordForm.Model
|
||||
, viewMode : ViewMode
|
||||
, pageError : PageError
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= VerifyResp (Result Http.Error ShareVerifyResult)
|
||||
| GetItemResp (Result Http.Error ItemDetail)
|
||||
| PasswordMsg Comp.SharePasswordForm.Msg
|
||||
|
||||
|
||||
emptyModel : ViewMode -> Model
|
||||
emptyModel vm =
|
||||
{ item = Api.Model.ItemDetail.empty
|
||||
, verifyResult = Api.Model.ShareVerifyResult.empty
|
||||
, passwordModel = Comp.SharePasswordForm.init
|
||||
, viewMode = vm
|
||||
, pageError = PageErrorNone
|
||||
}
|
||||
|
||||
|
||||
init : Maybe ( String, String ) -> Flags -> ( Model, Cmd Msg )
|
||||
init mids flags =
|
||||
case mids of
|
||||
Just ( shareId, _ ) ->
|
||||
( emptyModel ViewLoading, Api.verifyShare flags (ShareSecret shareId Nothing) VerifyResp )
|
||||
|
||||
Nothing ->
|
||||
( emptyModel ViewLoading, Cmd.none )
|
64
modules/webapp/src/main/elm/Page/ShareDetail/Update.elm
Normal file
64
modules/webapp/src/main/elm/Page/ShareDetail/Update.elm
Normal file
@@ -0,0 +1,64 @@
|
||||
module Page.ShareDetail.Update exposing (update)
|
||||
|
||||
import Api
|
||||
import Comp.SharePasswordForm
|
||||
import Data.Flags exposing (Flags)
|
||||
import Page.ShareDetail.Data exposing (..)
|
||||
|
||||
|
||||
update : String -> String -> Flags -> Msg -> Model -> ( Model, Cmd Msg )
|
||||
update shareId itemId flags msg model =
|
||||
case msg of
|
||||
VerifyResp (Ok res) ->
|
||||
if res.success then
|
||||
( { model
|
||||
| pageError = PageErrorNone
|
||||
, viewMode = ViewLoading
|
||||
, verifyResult = res
|
||||
}
|
||||
, Api.itemDetailShare flags res.token itemId GetItemResp
|
||||
)
|
||||
|
||||
else if res.passwordRequired then
|
||||
( { model
|
||||
| pageError = PageErrorNone
|
||||
, viewMode = ViewPassword
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
else
|
||||
( { model | pageError = PageErrorAuthFail }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
VerifyResp (Err err) ->
|
||||
( { model | pageError = PageErrorHttp err }, Cmd.none )
|
||||
|
||||
GetItemResp (Ok item) ->
|
||||
( { model
|
||||
| item = item
|
||||
, viewMode = ViewNormal
|
||||
, pageError = PageErrorNone
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
GetItemResp (Err err) ->
|
||||
( { model | viewMode = ViewNormal, pageError = PageErrorHttp err }, Cmd.none )
|
||||
|
||||
PasswordMsg lmsg ->
|
||||
let
|
||||
( m, c, res ) =
|
||||
Comp.SharePasswordForm.update shareId flags lmsg model.passwordModel
|
||||
in
|
||||
case res of
|
||||
Just verifyResult ->
|
||||
update shareId
|
||||
itemId
|
||||
flags
|
||||
(VerifyResp (Ok verifyResult))
|
||||
model
|
||||
|
||||
Nothing ->
|
||||
( { model | passwordModel = m }, Cmd.map PasswordMsg c )
|
108
modules/webapp/src/main/elm/Page/ShareDetail/View.elm
Normal file
108
modules/webapp/src/main/elm/Page/ShareDetail/View.elm
Normal file
@@ -0,0 +1,108 @@
|
||||
module Page.ShareDetail.View exposing (viewContent, viewSidebar)
|
||||
|
||||
import Api.Model.VersionInfo exposing (VersionInfo)
|
||||
import Comp.Basic as B
|
||||
import Comp.SharePasswordForm
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Messages.Page.ShareDetail exposing (Texts)
|
||||
import Page exposing (Page(..))
|
||||
import Page.ShareDetail.Data exposing (..)
|
||||
import Styles as S
|
||||
|
||||
|
||||
viewSidebar : Texts -> Bool -> Flags -> UiSettings -> Model -> Html Msg
|
||||
viewSidebar texts visible flags settings model =
|
||||
div
|
||||
[ id "sidebar"
|
||||
, class "hidden"
|
||||
]
|
||||
[]
|
||||
|
||||
|
||||
viewContent : Texts -> Flags -> UiSettings -> VersionInfo -> String -> String -> Model -> Html Msg
|
||||
viewContent texts flags uiSettings versionInfo shareId itemId model =
|
||||
case model.viewMode of
|
||||
ViewLoading ->
|
||||
div
|
||||
[ id "content"
|
||||
, class "h-full w-full flex flex-col text-5xl"
|
||||
, class S.content
|
||||
]
|
||||
[ B.loadingDimmer
|
||||
{ active = model.pageError == PageErrorNone
|
||||
, label = ""
|
||||
}
|
||||
]
|
||||
|
||||
ViewPassword ->
|
||||
passwordContent texts flags versionInfo model
|
||||
|
||||
ViewNormal ->
|
||||
mainContent texts flags uiSettings shareId model
|
||||
|
||||
|
||||
|
||||
--- Helper
|
||||
|
||||
|
||||
mainContent : Texts -> Flags -> UiSettings -> String -> Model -> Html Msg
|
||||
mainContent texts flags settings shareId model =
|
||||
div
|
||||
[ class "flex flex-col"
|
||||
, class S.content
|
||||
]
|
||||
[ itemHead texts shareId model
|
||||
, div [ class "flex flex-col sm:flex-row" ]
|
||||
[ itemData texts model
|
||||
, itemPreview texts flags settings model
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
itemData : Texts -> Model -> Html Msg
|
||||
itemData texts model =
|
||||
div [ class "flex" ]
|
||||
[]
|
||||
|
||||
|
||||
{-| Using ItemDetail Model to be able to reuse SingleAttachment component
|
||||
-}
|
||||
itemPreview : Texts -> Flags -> UiSettings -> Model -> Html Msg
|
||||
itemPreview texts flags settings model =
|
||||
div [ class "flex flex-grow" ]
|
||||
[]
|
||||
|
||||
|
||||
itemHead : Texts -> String -> Model -> Html Msg
|
||||
itemHead texts shareId model =
|
||||
div [ class "flex flex-col sm:flex-row" ]
|
||||
[ div [ class "flex flex-grow items-center" ]
|
||||
[ h1 [ class S.header1 ]
|
||||
[ text model.item.name
|
||||
]
|
||||
]
|
||||
, div [ class "flex flex-row items-center justify-end" ]
|
||||
[ B.secondaryBasicButton
|
||||
{ label = "Close"
|
||||
, icon = "fa fa-times"
|
||||
, disabled = False
|
||||
, handler = Page.href (SharePage shareId)
|
||||
, attrs = []
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
passwordContent : Texts -> Flags -> VersionInfo -> Model -> Html Msg
|
||||
passwordContent texts flags versionInfo model =
|
||||
div
|
||||
[ id "content"
|
||||
, class "h-full flex flex-col items-center justify-center w-full"
|
||||
, class S.content
|
||||
]
|
||||
[ Html.map PasswordMsg
|
||||
(Comp.SharePasswordForm.view texts.passwordForm flags versionInfo model.passwordModel)
|
||||
]
|
Reference in New Issue
Block a user