mirror of
				https://github.com/TheAnachronism/docspell.git
				synced 2025-11-04 12:30:12 +00:00 
			
		
		
		
	Outline share detail page
This commit is contained in:
		@@ -83,6 +83,7 @@ module Api exposing
 | 
			
		||||
    , initOtp
 | 
			
		||||
    , itemBasePreviewURL
 | 
			
		||||
    , itemDetail
 | 
			
		||||
    , itemDetailShare
 | 
			
		||||
    , itemIndexSearch
 | 
			
		||||
    , itemSearch
 | 
			
		||||
    , itemSearchStats
 | 
			
		||||
@@ -2302,6 +2303,15 @@ searchShareStats flags token search receive =
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
itemDetailShare : Flags -> String -> String -> (Result Http.Error ItemDetail -> msg) -> Cmd msg
 | 
			
		||||
itemDetailShare flags token itemId receive =
 | 
			
		||||
    Http2.shareGet
 | 
			
		||||
        { url = flags.config.baseUrl ++ "/api/v1/share/item/" ++ itemId
 | 
			
		||||
        , token = token
 | 
			
		||||
        , expect = Http.expectJson receive Api.Model.ItemDetail.decoder
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
shareAttachmentPreviewURL : String -> String
 | 
			
		||||
shareAttachmentPreviewURL id =
 | 
			
		||||
    "/api/v1/share/attachment/" ++ id ++ "/preview?withFallback=true"
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@ import Page.NewInvite.Data
 | 
			
		||||
import Page.Queue.Data
 | 
			
		||||
import Page.Register.Data
 | 
			
		||||
import Page.Share.Data
 | 
			
		||||
import Page.ShareDetail.Data
 | 
			
		||||
import Page.Upload.Data
 | 
			
		||||
import Page.UserSettings.Data
 | 
			
		||||
import Url exposing (Url)
 | 
			
		||||
@@ -54,6 +55,7 @@ type alias Model =
 | 
			
		||||
    , newInviteModel : Page.NewInvite.Data.Model
 | 
			
		||||
    , itemDetailModel : Page.ItemDetail.Data.Model
 | 
			
		||||
    , shareModel : Page.Share.Data.Model
 | 
			
		||||
    , shareDetailModel : Page.ShareDetail.Data.Model
 | 
			
		||||
    , navMenuOpen : Bool
 | 
			
		||||
    , userMenuOpen : Bool
 | 
			
		||||
    , subs : Sub Msg
 | 
			
		||||
@@ -88,7 +90,10 @@ init key url flags_ settings =
 | 
			
		||||
            Page.Login.Data.init flags (Page.loginPageReferrer page)
 | 
			
		||||
 | 
			
		||||
        ( shm, shc ) =
 | 
			
		||||
            Page.Share.Data.init (Page.shareId page) flags
 | 
			
		||||
            Page.Share.Data.init (Page.pageShareId page) flags
 | 
			
		||||
 | 
			
		||||
        ( sdm, sdc ) =
 | 
			
		||||
            Page.ShareDetail.Data.init (Page.pageShareDetail page) flags
 | 
			
		||||
 | 
			
		||||
        homeViewMode =
 | 
			
		||||
            if settings.searchMenuVisible then
 | 
			
		||||
@@ -112,6 +117,7 @@ init key url flags_ settings =
 | 
			
		||||
      , newInviteModel = Page.NewInvite.Data.emptyModel
 | 
			
		||||
      , itemDetailModel = Page.ItemDetail.Data.emptyModel
 | 
			
		||||
      , shareModel = shm
 | 
			
		||||
      , shareDetailModel = sdm
 | 
			
		||||
      , navMenuOpen = False
 | 
			
		||||
      , userMenuOpen = False
 | 
			
		||||
      , subs = Sub.none
 | 
			
		||||
@@ -127,6 +133,7 @@ init key url flags_ settings =
 | 
			
		||||
        , Cmd.map CollSettingsMsg csc
 | 
			
		||||
        , Cmd.map LoginMsg loginc
 | 
			
		||||
        , Cmd.map ShareMsg shc
 | 
			
		||||
        , Cmd.map ShareDetailMsg sdc
 | 
			
		||||
        ]
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@@ -170,6 +177,7 @@ type Msg
 | 
			
		||||
    | NewInviteMsg Page.NewInvite.Data.Msg
 | 
			
		||||
    | ItemDetailMsg Page.ItemDetail.Data.Msg
 | 
			
		||||
    | ShareMsg Page.Share.Data.Msg
 | 
			
		||||
    | ShareDetailMsg Page.ShareDetail.Data.Msg
 | 
			
		||||
    | Logout
 | 
			
		||||
    | LogoutResp (Result Http.Error ())
 | 
			
		||||
    | SessionCheckResp (Result Http.Error AuthResult)
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,8 @@ import Page.Register.Data
 | 
			
		||||
import Page.Register.Update
 | 
			
		||||
import Page.Share.Data
 | 
			
		||||
import Page.Share.Update
 | 
			
		||||
import Page.ShareDetail.Data
 | 
			
		||||
import Page.ShareDetail.Update
 | 
			
		||||
import Page.Upload.Data
 | 
			
		||||
import Page.Upload.Update
 | 
			
		||||
import Page.UserSettings.Data
 | 
			
		||||
@@ -119,6 +121,9 @@ updateWithSub msg model =
 | 
			
		||||
        ShareMsg lm ->
 | 
			
		||||
            updateShare lm model
 | 
			
		||||
 | 
			
		||||
        ShareDetailMsg lm ->
 | 
			
		||||
            updateShareDetail lm model
 | 
			
		||||
 | 
			
		||||
        LoginMsg lm ->
 | 
			
		||||
            updateLogin lm model
 | 
			
		||||
 | 
			
		||||
@@ -318,9 +323,26 @@ applyClientSettings model settings =
 | 
			
		||||
        { model | uiSettings = settings }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
updateShareDetail : Page.ShareDetail.Data.Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
 | 
			
		||||
updateShareDetail lmsg model =
 | 
			
		||||
    case Page.pageShareDetail model.page of
 | 
			
		||||
        Just ( shareId, itemId ) ->
 | 
			
		||||
            let
 | 
			
		||||
                ( m, c ) =
 | 
			
		||||
                    Page.ShareDetail.Update.update shareId itemId model.flags lmsg model.shareDetailModel
 | 
			
		||||
            in
 | 
			
		||||
            ( { model | shareDetailModel = m }
 | 
			
		||||
            , Cmd.map ShareDetailMsg c
 | 
			
		||||
            , Sub.none
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        Nothing ->
 | 
			
		||||
            ( model, Cmd.none, Sub.none )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
updateShare : Page.Share.Data.Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
 | 
			
		||||
updateShare lmsg model =
 | 
			
		||||
    case Page.shareId model.page of
 | 
			
		||||
    case Page.pageShareId model.page of
 | 
			
		||||
        Just id ->
 | 
			
		||||
            let
 | 
			
		||||
                result =
 | 
			
		||||
@@ -593,3 +615,15 @@ initPage model_ page =
 | 
			
		||||
 | 
			
		||||
        SharePage _ ->
 | 
			
		||||
            ( model, Cmd.none, Sub.none )
 | 
			
		||||
 | 
			
		||||
        ShareDetailPage _ _ ->
 | 
			
		||||
            case model_.page of
 | 
			
		||||
                SharePage _ ->
 | 
			
		||||
                    let
 | 
			
		||||
                        verifyResult =
 | 
			
		||||
                            model.shareModel.verifyResult
 | 
			
		||||
                    in
 | 
			
		||||
                    updateShareDetail (Page.ShareDetail.Data.VerifyResp (Ok verifyResult)) model
 | 
			
		||||
 | 
			
		||||
                _ ->
 | 
			
		||||
                    ( model, Cmd.none, Sub.none )
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,7 @@ import Page.NewInvite.View2 as NewInvite
 | 
			
		||||
import Page.Queue.View2 as Queue
 | 
			
		||||
import Page.Register.View2 as Register
 | 
			
		||||
import Page.Share.View as Share
 | 
			
		||||
import Page.ShareDetail.View as ShareDetail
 | 
			
		||||
import Page.Upload.View2 as Upload
 | 
			
		||||
import Page.UserSettings.View2 as UserSettings
 | 
			
		||||
import Styles as S
 | 
			
		||||
@@ -166,6 +167,9 @@ mainContent model =
 | 
			
		||||
 | 
			
		||||
            SharePage id ->
 | 
			
		||||
                viewShare texts id model
 | 
			
		||||
 | 
			
		||||
            ShareDetailPage shareId itemId ->
 | 
			
		||||
                viewShareDetail texts shareId itemId model
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -434,11 +438,33 @@ viewShare texts shareId model =
 | 
			
		||||
            model.flags
 | 
			
		||||
            model.version
 | 
			
		||||
            model.uiSettings
 | 
			
		||||
            shareId
 | 
			
		||||
            model.shareModel
 | 
			
		||||
        )
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
viewShareDetail : Messages -> String -> String -> Model -> List (Html Msg)
 | 
			
		||||
viewShareDetail texts shareId itemId model =
 | 
			
		||||
    [ Html.map ShareDetailMsg
 | 
			
		||||
        (ShareDetail.viewSidebar texts.shareDetail
 | 
			
		||||
            model.sidebarVisible
 | 
			
		||||
            model.flags
 | 
			
		||||
            model.uiSettings
 | 
			
		||||
            model.shareDetailModel
 | 
			
		||||
        )
 | 
			
		||||
    , Html.map ShareDetailMsg
 | 
			
		||||
        (ShareDetail.viewContent texts.shareDetail
 | 
			
		||||
            model.flags
 | 
			
		||||
            model.uiSettings
 | 
			
		||||
            model.version
 | 
			
		||||
            shareId
 | 
			
		||||
            itemId
 | 
			
		||||
            model.shareDetailModel
 | 
			
		||||
        )
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
viewHome : Messages -> Model -> List (Html Msg)
 | 
			
		||||
viewHome texts model =
 | 
			
		||||
    [ Html.map HomeMsg
 | 
			
		||||
 
 | 
			
		||||
@@ -59,6 +59,7 @@ type alias ViewConfig =
 | 
			
		||||
    , previewUrl : AttachmentLight -> String
 | 
			
		||||
    , previewUrlFallback : ItemLight -> String
 | 
			
		||||
    , attachUrl : AttachmentLight -> String
 | 
			
		||||
    , detailPage : ItemLight -> Page
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -174,7 +175,7 @@ view2 texts cfg settings model item =
 | 
			
		||||
        cardAction =
 | 
			
		||||
            case cfg.selection of
 | 
			
		||||
                Data.ItemSelection.Inactive ->
 | 
			
		||||
                    [ Page.href (ItemDetailPage item.id)
 | 
			
		||||
                    [ Page.href (cfg.detailPage item)
 | 
			
		||||
                    ]
 | 
			
		||||
 | 
			
		||||
                Data.ItemSelection.Active ids ->
 | 
			
		||||
@@ -530,7 +531,7 @@ previewMenu2 texts settings cfg model item mainAttach =
 | 
			
		||||
        , a
 | 
			
		||||
            [ class S.secondaryBasicButtonPlain
 | 
			
		||||
            , class "px-2 py-1 border rounded ml-2"
 | 
			
		||||
            , Page.href (ItemDetailPage item.id)
 | 
			
		||||
            , Page.href (cfg.detailPage item)
 | 
			
		||||
            , title texts.gotoDetail
 | 
			
		||||
            ]
 | 
			
		||||
            [ i [ class "fa fa-edit" ] []
 | 
			
		||||
 
 | 
			
		||||
@@ -165,6 +165,7 @@ type alias ViewConfig =
 | 
			
		||||
    , previewUrl : AttachmentLight -> String
 | 
			
		||||
    , previewUrlFallback : ItemLight -> String
 | 
			
		||||
    , attachUrl : AttachmentLight -> String
 | 
			
		||||
    , detailPage : ItemLight -> Page
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -220,7 +221,7 @@ viewItem2 texts model cfg settings item =
 | 
			
		||||
                ""
 | 
			
		||||
 | 
			
		||||
        vvcfg =
 | 
			
		||||
            Comp.ItemCard.ViewConfig cfg.selection currentClass cfg.previewUrl cfg.previewUrlFallback cfg.attachUrl
 | 
			
		||||
            Comp.ItemCard.ViewConfig cfg.selection currentClass cfg.previewUrl cfg.previewUrlFallback cfg.attachUrl cfg.detailPage
 | 
			
		||||
 | 
			
		||||
        cardModel =
 | 
			
		||||
            Dict.get item.id model.itemCards
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										156
									
								
								modules/webapp/src/main/elm/Comp/SharePasswordForm.elm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								modules/webapp/src/main/elm/Comp/SharePasswordForm.elm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,156 @@
 | 
			
		||||
module Comp.SharePasswordForm exposing (Model, Msg, init, update, view)
 | 
			
		||||
 | 
			
		||||
import Api
 | 
			
		||||
import Api.Model.ShareVerifyResult exposing (ShareVerifyResult)
 | 
			
		||||
import Api.Model.VersionInfo exposing (VersionInfo)
 | 
			
		||||
import Data.Flags exposing (Flags)
 | 
			
		||||
import Html exposing (..)
 | 
			
		||||
import Html.Attributes exposing (..)
 | 
			
		||||
import Html.Events exposing (onInput, onSubmit)
 | 
			
		||||
import Http
 | 
			
		||||
import Messages.Comp.SharePasswordForm exposing (Texts)
 | 
			
		||||
import Styles as S
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type CompError
 | 
			
		||||
    = CompErrorNone
 | 
			
		||||
    | CompErrorPasswordFailed
 | 
			
		||||
    | CompErrorHttp Http.Error
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type alias Model =
 | 
			
		||||
    { password : String
 | 
			
		||||
    , compError : CompError
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
init : Model
 | 
			
		||||
init =
 | 
			
		||||
    { password = ""
 | 
			
		||||
    , compError = CompErrorNone
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type Msg
 | 
			
		||||
    = SetPassword String
 | 
			
		||||
    | SubmitPassword
 | 
			
		||||
    | VerifyResp (Result Http.Error ShareVerifyResult)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--- update
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
update : String -> Flags -> Msg -> Model -> ( Model, Cmd Msg, Maybe ShareVerifyResult )
 | 
			
		||||
update shareId flags msg model =
 | 
			
		||||
    case msg of
 | 
			
		||||
        SetPassword pw ->
 | 
			
		||||
            ( { model | password = pw }, Cmd.none, Nothing )
 | 
			
		||||
 | 
			
		||||
        SubmitPassword ->
 | 
			
		||||
            let
 | 
			
		||||
                secret =
 | 
			
		||||
                    { shareId = shareId
 | 
			
		||||
                    , password = Just model.password
 | 
			
		||||
                    }
 | 
			
		||||
            in
 | 
			
		||||
            ( model, Api.verifyShare flags secret VerifyResp, Nothing )
 | 
			
		||||
 | 
			
		||||
        VerifyResp (Ok res) ->
 | 
			
		||||
            if res.success then
 | 
			
		||||
                ( { model | password = "", compError = CompErrorNone }, Cmd.none, Just res )
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
                ( { model | password = "", compError = CompErrorPasswordFailed }, Cmd.none, Nothing )
 | 
			
		||||
 | 
			
		||||
        VerifyResp (Err err) ->
 | 
			
		||||
            ( { model | password = "", compError = CompErrorHttp err }, Cmd.none, Nothing )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--- view
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
view : Texts -> Flags -> VersionInfo -> Model -> Html Msg
 | 
			
		||||
view texts flags versionInfo model =
 | 
			
		||||
    div [ class "flex flex-col items-center" ]
 | 
			
		||||
        [ 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.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
 | 
			
		||||
                        ]
 | 
			
		||||
                    ]
 | 
			
		||||
                , case model.compError of
 | 
			
		||||
                    CompErrorNone ->
 | 
			
		||||
                        span [ class "hidden" ] []
 | 
			
		||||
 | 
			
		||||
                    CompErrorHttp err ->
 | 
			
		||||
                        div [ class S.errorMessage ]
 | 
			
		||||
                            [ text (texts.httpError err)
 | 
			
		||||
                            ]
 | 
			
		||||
 | 
			
		||||
                    CompErrorPasswordFailed ->
 | 
			
		||||
                        div [ class S.errorMessage ]
 | 
			
		||||
                            [ 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
 | 
			
		||||
                ]
 | 
			
		||||
            ]
 | 
			
		||||
        ]
 | 
			
		||||
@@ -22,6 +22,7 @@ import Messages.Page.NewInvite
 | 
			
		||||
import Messages.Page.Queue
 | 
			
		||||
import Messages.Page.Register
 | 
			
		||||
import Messages.Page.Share
 | 
			
		||||
import Messages.Page.ShareDetail
 | 
			
		||||
import Messages.Page.Upload
 | 
			
		||||
import Messages.Page.UserSettings
 | 
			
		||||
import Messages.UiLanguage exposing (UiLanguage(..))
 | 
			
		||||
@@ -46,6 +47,7 @@ type alias Messages =
 | 
			
		||||
    , manageData : Messages.Page.ManageData.Texts
 | 
			
		||||
    , home : Messages.Page.Home.Texts
 | 
			
		||||
    , share : Messages.Page.Share.Texts
 | 
			
		||||
    , shareDetail : Messages.Page.ShareDetail.Texts
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -112,6 +114,7 @@ gb =
 | 
			
		||||
    , manageData = Messages.Page.ManageData.gb
 | 
			
		||||
    , home = Messages.Page.Home.gb
 | 
			
		||||
    , share = Messages.Page.Share.gb
 | 
			
		||||
    , shareDetail = Messages.Page.ShareDetail.gb
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -133,4 +136,5 @@ de =
 | 
			
		||||
    , manageData = Messages.Page.ManageData.de
 | 
			
		||||
    , home = Messages.Page.Home.de
 | 
			
		||||
    , share = Messages.Page.Share.de
 | 
			
		||||
    , shareDetail = Messages.Page.ShareDetail.de
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
module Messages.Comp.SharePasswordForm exposing (Texts, de, gb)
 | 
			
		||||
 | 
			
		||||
import Http
 | 
			
		||||
import Messages.Comp.HttpError
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type alias Texts =
 | 
			
		||||
    { httpError : Http.Error -> String
 | 
			
		||||
    , passwordRequired : String
 | 
			
		||||
    , password : String
 | 
			
		||||
    , passwordSubmitButton : String
 | 
			
		||||
    , passwordFailed : String
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
gb : Texts
 | 
			
		||||
gb =
 | 
			
		||||
    { httpError = Messages.Comp.HttpError.gb
 | 
			
		||||
    , passwordRequired = "Password required"
 | 
			
		||||
    , password = "Password"
 | 
			
		||||
    , passwordSubmitButton = "Submit"
 | 
			
		||||
    , passwordFailed = "Das Passwort ist falsch"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
de : Texts
 | 
			
		||||
de =
 | 
			
		||||
    { httpError = Messages.Comp.HttpError.de
 | 
			
		||||
    , passwordRequired = "Passwort benötigt"
 | 
			
		||||
    , password = "Passwort"
 | 
			
		||||
    , passwordSubmitButton = "Submit"
 | 
			
		||||
    , passwordFailed = "Password is wrong"
 | 
			
		||||
    }
 | 
			
		||||
@@ -10,16 +10,14 @@ module Messages.Page.Share exposing (..)
 | 
			
		||||
import Messages.Basics
 | 
			
		||||
import Messages.Comp.ItemCardList
 | 
			
		||||
import Messages.Comp.SearchMenu
 | 
			
		||||
import Messages.Comp.SharePasswordForm
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type alias Texts =
 | 
			
		||||
    { searchMenu : Messages.Comp.SearchMenu.Texts
 | 
			
		||||
    , basics : Messages.Basics.Texts
 | 
			
		||||
    , itemCardList : Messages.Comp.ItemCardList.Texts
 | 
			
		||||
    , passwordRequired : String
 | 
			
		||||
    , password : String
 | 
			
		||||
    , passwordSubmitButton : String
 | 
			
		||||
    , passwordFailed : String
 | 
			
		||||
    , passwordForm : Messages.Comp.SharePasswordForm.Texts
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -28,10 +26,7 @@ gb =
 | 
			
		||||
    { searchMenu = Messages.Comp.SearchMenu.gb
 | 
			
		||||
    , basics = Messages.Basics.gb
 | 
			
		||||
    , itemCardList = Messages.Comp.ItemCardList.gb
 | 
			
		||||
    , passwordRequired = "Password required"
 | 
			
		||||
    , password = "Password"
 | 
			
		||||
    , passwordSubmitButton = "Submit"
 | 
			
		||||
    , passwordFailed = "Das Passwort ist falsch"
 | 
			
		||||
    , passwordForm = Messages.Comp.SharePasswordForm.gb
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -40,8 +35,5 @@ de =
 | 
			
		||||
    { searchMenu = Messages.Comp.SearchMenu.de
 | 
			
		||||
    , basics = Messages.Basics.de
 | 
			
		||||
    , itemCardList = Messages.Comp.ItemCardList.de
 | 
			
		||||
    , passwordRequired = "Passwort benötigt"
 | 
			
		||||
    , password = "Passwort"
 | 
			
		||||
    , passwordSubmitButton = "Submit"
 | 
			
		||||
    , passwordFailed = "Password is wrong"
 | 
			
		||||
    , passwordForm = Messages.Comp.SharePasswordForm.de
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								modules/webapp/src/main/elm/Messages/Page/ShareDetail.elm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								modules/webapp/src/main/elm/Messages/Page/ShareDetail.elm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
module Messages.Page.ShareDetail exposing (..)
 | 
			
		||||
 | 
			
		||||
import Messages.Comp.SharePasswordForm
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type alias Texts =
 | 
			
		||||
    { passwordForm : Messages.Comp.SharePasswordForm.Texts
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
gb : Texts
 | 
			
		||||
gb =
 | 
			
		||||
    { passwordForm = Messages.Comp.SharePasswordForm.gb
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
de : Texts
 | 
			
		||||
de =
 | 
			
		||||
    { passwordForm = Messages.Comp.SharePasswordForm.de
 | 
			
		||||
    }
 | 
			
		||||
@@ -19,9 +19,10 @@ module Page exposing
 | 
			
		||||
    , loginPageReferrer
 | 
			
		||||
    , pageFromString
 | 
			
		||||
    , pageName
 | 
			
		||||
    , pageShareDetail
 | 
			
		||||
    , pageShareId
 | 
			
		||||
    , pageToString
 | 
			
		||||
    , set
 | 
			
		||||
    , shareId
 | 
			
		||||
    , uploadId
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@@ -61,6 +62,7 @@ type Page
 | 
			
		||||
    | NewInvitePage
 | 
			
		||||
    | ItemDetailPage String
 | 
			
		||||
    | SharePage String
 | 
			
		||||
    | ShareDetailPage String String
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
isSecured : Page -> Bool
 | 
			
		||||
@@ -99,6 +101,9 @@ isSecured page =
 | 
			
		||||
        SharePage _ ->
 | 
			
		||||
            False
 | 
			
		||||
 | 
			
		||||
        ShareDetailPage _ _ ->
 | 
			
		||||
            False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{-| Currently, all secured pages have a sidebar, except UploadPage.
 | 
			
		||||
-}
 | 
			
		||||
@@ -171,6 +176,9 @@ pageName page =
 | 
			
		||||
        SharePage _ ->
 | 
			
		||||
            "Share"
 | 
			
		||||
 | 
			
		||||
        ShareDetailPage _ _ ->
 | 
			
		||||
            "Share Detail"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
loginPageReferrer : Page -> LoginData
 | 
			
		||||
loginPageReferrer page =
 | 
			
		||||
@@ -182,8 +190,8 @@ loginPageReferrer page =
 | 
			
		||||
            emptyLoginData
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
shareId : Page -> Maybe String
 | 
			
		||||
shareId page =
 | 
			
		||||
pageShareId : Page -> Maybe String
 | 
			
		||||
pageShareId page =
 | 
			
		||||
    case page of
 | 
			
		||||
        SharePage id ->
 | 
			
		||||
            Just id
 | 
			
		||||
@@ -192,6 +200,16 @@ shareId page =
 | 
			
		||||
            Nothing
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pageShareDetail : Page -> Maybe ( String, String )
 | 
			
		||||
pageShareDetail page =
 | 
			
		||||
    case page of
 | 
			
		||||
        ShareDetailPage shareId itemId ->
 | 
			
		||||
            Just ( shareId, itemId )
 | 
			
		||||
 | 
			
		||||
        _ ->
 | 
			
		||||
            Nothing
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uploadId : Page -> Maybe String
 | 
			
		||||
uploadId page =
 | 
			
		||||
    case page of
 | 
			
		||||
@@ -248,6 +266,9 @@ pageToString page =
 | 
			
		||||
        SharePage id ->
 | 
			
		||||
            "/app/share/" ++ id
 | 
			
		||||
 | 
			
		||||
        ShareDetailPage shareId itemId ->
 | 
			
		||||
            "/app/share/" ++ shareId ++ "/" ++ itemId
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pageFromString : String -> Maybe Page
 | 
			
		||||
pageFromString str =
 | 
			
		||||
@@ -304,6 +325,7 @@ parser =
 | 
			
		||||
        , Parser.map (UploadPage Nothing) (s pathPrefix </> s "upload")
 | 
			
		||||
        , Parser.map NewInvitePage (s pathPrefix </> s "newinvite")
 | 
			
		||||
        , Parser.map ItemDetailPage (s pathPrefix </> s "item" </> string)
 | 
			
		||||
        , Parser.map ShareDetailPage (s pathPrefix </> s "share" </> string </> string)
 | 
			
		||||
        , Parser.map SharePage (s pathPrefix </> s "share" </> string)
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
        ]
 | 
			
		||||
@@ -14,6 +14,7 @@ module Util.Http exposing
 | 
			
		||||
    , authTask
 | 
			
		||||
    , executeIn
 | 
			
		||||
    , jsonResolver
 | 
			
		||||
    , shareGet
 | 
			
		||||
    , sharePost
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@@ -167,6 +168,24 @@ authGet req =
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
shareGet :
 | 
			
		||||
    { url : String
 | 
			
		||||
    , token : String
 | 
			
		||||
    , expect : Http.Expect msg
 | 
			
		||||
    }
 | 
			
		||||
    -> Cmd msg
 | 
			
		||||
shareGet req =
 | 
			
		||||
    shareReq
 | 
			
		||||
        { url = req.url
 | 
			
		||||
        , token = req.token
 | 
			
		||||
        , body = Http.emptyBody
 | 
			
		||||
        , expect = req.expect
 | 
			
		||||
        , method = "GET"
 | 
			
		||||
        , headers = []
 | 
			
		||||
        , tracker = Nothing
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
authDelete :
 | 
			
		||||
    { url : String
 | 
			
		||||
    , account : AuthResult
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user