mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-05 22:55:58 +00:00
Show item detail for a shared item
This commit is contained in:
parent
006791deb4
commit
7cbdf919f4
@ -16,12 +16,13 @@
|
||||
"elm/html": "1.0.0",
|
||||
"elm/http": "2.0.0",
|
||||
"elm/json": "1.1.3",
|
||||
"elm/svg": "1.0.1",
|
||||
"elm/time": "1.0.0",
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"justinmimbs/date": "3.1.2",
|
||||
"norpan/elm-html5-drag-drop": "3.1.4",
|
||||
"pablohirafuji/elm-qrcode": "3.3.1",
|
||||
"pablohirafuji/elm-qrcode": "4.0.1",
|
||||
"ryannhg/date-format": "2.3.0",
|
||||
"truqu/elm-base64": "2.0.4",
|
||||
"ursi/elm-scroll": "1.0.0",
|
||||
@ -33,7 +34,6 @@
|
||||
"elm/bytes": "1.0.8",
|
||||
"elm/parser": "1.1.0",
|
||||
"elm/regex": "1.0.0",
|
||||
"elm/svg": "1.0.1",
|
||||
"elm/virtual-dom": "1.0.2",
|
||||
"elm-community/list-extra": "8.2.4",
|
||||
"folkertdev/elm-flate": "2.0.4",
|
||||
|
@ -613,8 +613,19 @@ initPage model_ page =
|
||||
]
|
||||
model
|
||||
|
||||
SharePage _ ->
|
||||
( model, Cmd.none, Sub.none )
|
||||
SharePage id ->
|
||||
let
|
||||
cmd =
|
||||
Cmd.map ShareMsg (Page.Share.Data.initCmd id model.flags)
|
||||
|
||||
shareModel =
|
||||
model.shareModel
|
||||
in
|
||||
if shareModel.initialized then
|
||||
( model, Cmd.none, Sub.none )
|
||||
|
||||
else
|
||||
( { model | shareModel = { shareModel | initialized = True } }, cmd, Sub.none )
|
||||
|
||||
ShareDetailPage _ _ ->
|
||||
case model_.page of
|
||||
|
@ -451,6 +451,8 @@ viewShareDetail texts shareId itemId model =
|
||||
model.sidebarVisible
|
||||
model.flags
|
||||
model.uiSettings
|
||||
shareId
|
||||
itemId
|
||||
model.shareDetailModel
|
||||
)
|
||||
, Html.map ShareDetailMsg
|
||||
|
@ -17,6 +17,7 @@ import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick)
|
||||
import QRCode
|
||||
import Styles as S
|
||||
import Svg.Attributes as SvgA
|
||||
|
||||
|
||||
view : Flags -> String -> Model -> UrlId -> Html Msg
|
||||
@ -111,7 +112,7 @@ type UrlId
|
||||
|
||||
qrCodeView : String -> Html msg
|
||||
qrCodeView message =
|
||||
QRCode.encode message
|
||||
|> Result.map QRCode.toSvg
|
||||
QRCode.fromString message
|
||||
|> Result.map (QRCode.toSvg [ SvgA.class "w-64 h-64" ])
|
||||
|> Result.withDefault
|
||||
(text "Error generating QR code")
|
||||
|
@ -23,6 +23,7 @@ import Markdown
|
||||
import Messages.Comp.OtpSetup exposing (Texts)
|
||||
import QRCode
|
||||
import Styles as S
|
||||
import Svg.Attributes as SvgA
|
||||
|
||||
|
||||
type Model
|
||||
@ -389,8 +390,8 @@ viewDisabled texts model =
|
||||
|
||||
qrCodeView : Texts -> String -> Html msg
|
||||
qrCodeView texts message =
|
||||
QRCode.encode message
|
||||
|> Result.map QRCode.toSvg
|
||||
QRCode.fromString message
|
||||
|> Result.map (QRCode.toSvg [ SvgA.class "w-64 h-64" ])
|
||||
|> Result.withDefault
|
||||
(Html.text texts.errorGeneratingQR)
|
||||
|
||||
|
@ -14,6 +14,7 @@ import Html.Attributes exposing (..)
|
||||
import Messages.Comp.ShareView exposing (Texts)
|
||||
import QRCode
|
||||
import Styles as S
|
||||
import Svg.Attributes as SvgA
|
||||
|
||||
|
||||
type alias ViewSettings =
|
||||
@ -178,7 +179,7 @@ viewDisabled cfg texts share =
|
||||
|
||||
qrCodeView : Texts -> String -> Html msg
|
||||
qrCodeView texts message =
|
||||
QRCode.encode message
|
||||
|> Result.map QRCode.toSvg
|
||||
QRCode.fromString message
|
||||
|> Result.map (QRCode.toSvg [ SvgA.class "w-64 h-64" ])
|
||||
|> Result.withDefault
|
||||
(Html.text texts.qrCodeError)
|
||||
|
@ -32,6 +32,7 @@ import Messages.Comp.SourceManage exposing (Texts)
|
||||
import Ports
|
||||
import QRCode
|
||||
import Styles as S
|
||||
import Svg.Attributes as SvgA
|
||||
|
||||
|
||||
type alias Model =
|
||||
@ -226,8 +227,8 @@ update flags msg model =
|
||||
|
||||
qrCodeView : Texts -> String -> Html msg
|
||||
qrCodeView texts message =
|
||||
QRCode.encode message
|
||||
|> Result.map QRCode.toSvg
|
||||
QRCode.fromString message
|
||||
|> Result.map (QRCode.toSvg [ SvgA.class "w-64 h-64" ])
|
||||
|> Result.withDefault
|
||||
(Html.text texts.errorGeneratingQR)
|
||||
|
||||
|
95
modules/webapp/src/main/elm/Comp/UrlCopy.elm
Normal file
95
modules/webapp/src/main/elm/Comp/UrlCopy.elm
Normal file
@ -0,0 +1,95 @@
|
||||
module Comp.UrlCopy exposing (..)
|
||||
|
||||
import Comp.Basic as B
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick)
|
||||
import Ports
|
||||
import QRCode
|
||||
import Styles as S
|
||||
import Svg.Attributes as SvgA
|
||||
|
||||
|
||||
type Msg
|
||||
= Print String
|
||||
|
||||
|
||||
update : Msg -> Cmd msg
|
||||
update msg =
|
||||
case msg of
|
||||
Print id ->
|
||||
Ports.printElement id
|
||||
|
||||
|
||||
initCopy : String -> Cmd msg
|
||||
initCopy data =
|
||||
Ports.initClipboard <| clipboardData data
|
||||
|
||||
|
||||
clipboardData : String -> ( String, String )
|
||||
clipboardData data =
|
||||
( "share-url", "#button-share-url" )
|
||||
|
||||
|
||||
view : String -> Html Msg
|
||||
view data =
|
||||
let
|
||||
( elementId, buttonId ) =
|
||||
clipboardData data
|
||||
|
||||
btnId =
|
||||
String.dropLeft 1 buttonId
|
||||
|
||||
printId =
|
||||
"print-qr-code"
|
||||
in
|
||||
div [ class "flex flex-col items-center" ]
|
||||
[ div
|
||||
[ class S.border
|
||||
, class S.qrCode
|
||||
, id printId
|
||||
]
|
||||
[ qrCodeView data
|
||||
]
|
||||
, div
|
||||
[ class "flex w-64"
|
||||
]
|
||||
[ p
|
||||
[ id elementId
|
||||
, class "font-mono text-xs py-2 mx-auto break-all"
|
||||
]
|
||||
[ text data
|
||||
]
|
||||
]
|
||||
, div [ class "flex flex-row mt-1 space-x-2 items-center w-full" ]
|
||||
[ B.primaryButton
|
||||
{ label = "Copy"
|
||||
, icon = "fa fa-copy"
|
||||
, handler = href "#"
|
||||
, disabled = False
|
||||
, attrs =
|
||||
[ id btnId
|
||||
, class "flex flex-grow items-center justify-center"
|
||||
, attribute "data-clipboard-target" ("#" ++ elementId)
|
||||
]
|
||||
}
|
||||
, B.primaryButton
|
||||
{ label = "Print"
|
||||
, icon = "fa fa-print"
|
||||
, handler = onClick (Print printId)
|
||||
, disabled = False
|
||||
, attrs =
|
||||
[ href "#"
|
||||
, class "flex flex-grow items-center justify-center"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
qrCodeView : String -> Html msg
|
||||
qrCodeView message =
|
||||
QRCode.fromString message
|
||||
|> Result.map (QRCode.toSvg [ SvgA.class "w-64 h-64" ])
|
||||
|> Result.withDefault
|
||||
(text "Error generating QR code")
|
@ -7,7 +7,9 @@
|
||||
|
||||
module Messages.Page.Share exposing (..)
|
||||
|
||||
import Http
|
||||
import Messages.Basics
|
||||
import Messages.Comp.HttpError
|
||||
import Messages.Comp.ItemCardList
|
||||
import Messages.Comp.SearchMenu
|
||||
import Messages.Comp.SharePasswordForm
|
||||
@ -18,6 +20,8 @@ type alias Texts =
|
||||
, basics : Messages.Basics.Texts
|
||||
, itemCardList : Messages.Comp.ItemCardList.Texts
|
||||
, passwordForm : Messages.Comp.SharePasswordForm.Texts
|
||||
, httpError : Http.Error -> String
|
||||
, authFailed : String
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +31,8 @@ gb =
|
||||
, basics = Messages.Basics.gb
|
||||
, itemCardList = Messages.Comp.ItemCardList.gb
|
||||
, passwordForm = Messages.Comp.SharePasswordForm.gb
|
||||
, authFailed = "This share does not exist."
|
||||
, httpError = Messages.Comp.HttpError.gb
|
||||
}
|
||||
|
||||
|
||||
@ -36,4 +42,6 @@ de =
|
||||
, basics = Messages.Basics.de
|
||||
, itemCardList = Messages.Comp.ItemCardList.de
|
||||
, passwordForm = Messages.Comp.SharePasswordForm.de
|
||||
, authFailed = "Diese Freigabe existiert nicht."
|
||||
, httpError = Messages.Comp.HttpError.de
|
||||
}
|
||||
|
@ -1,28 +1,54 @@
|
||||
module Messages.Page.ShareDetail exposing (..)
|
||||
|
||||
import Data.Fields exposing (Field)
|
||||
import Http
|
||||
import Messages.Basics
|
||||
import Messages.Comp.HttpError
|
||||
import Messages.Comp.SharePasswordForm
|
||||
import Messages.Data.Fields
|
||||
import Messages.DateFormat
|
||||
import Messages.UiLanguage exposing (UiLanguage(..))
|
||||
|
||||
|
||||
type alias Texts =
|
||||
{ passwordForm : Messages.Comp.SharePasswordForm.Texts
|
||||
, basics : Messages.Basics.Texts
|
||||
, field : Field -> String
|
||||
, formatDateLong : Int -> String
|
||||
, formatDateShort : Int -> String
|
||||
, httpError : Http.Error -> String
|
||||
, authFailed : String
|
||||
, tagsAndFields : String
|
||||
, noName : String
|
||||
, unconfirmed : String
|
||||
}
|
||||
|
||||
|
||||
gb : Texts
|
||||
gb =
|
||||
{ passwordForm = Messages.Comp.SharePasswordForm.gb
|
||||
, basics = Messages.Basics.gb
|
||||
, field = Messages.Data.Fields.gb
|
||||
, formatDateLong = Messages.DateFormat.formatDateLong English
|
||||
, formatDateShort = Messages.DateFormat.formatDateShort English
|
||||
, authFailed = "This share does not exist."
|
||||
, httpError = Messages.Comp.HttpError.gb
|
||||
, tagsAndFields = "Tags & Fields"
|
||||
, noName = "No name"
|
||||
, unconfirmed = "Unconfirmed"
|
||||
}
|
||||
|
||||
|
||||
de : Texts
|
||||
de =
|
||||
{ passwordForm = Messages.Comp.SharePasswordForm.de
|
||||
, basics = Messages.Basics.de
|
||||
, field = Messages.Data.Fields.de
|
||||
, formatDateLong = Messages.DateFormat.formatDateLong German
|
||||
, formatDateShort = Messages.DateFormat.formatDateShort German
|
||||
, authFailed = "Diese Freigabe existiert nicht."
|
||||
, httpError = Messages.Comp.HttpError.de
|
||||
, tagsAndFields = "Tags & Felder"
|
||||
, noName = "Kein Name"
|
||||
, unconfirmed = "Nicht bestätigt"
|
||||
}
|
||||
|
@ -116,6 +116,9 @@ hasSidebar page =
|
||||
SharePage _ ->
|
||||
True
|
||||
|
||||
ShareDetailPage _ _ ->
|
||||
True
|
||||
|
||||
_ ->
|
||||
isSecured page
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
-}
|
||||
|
||||
|
||||
module Page.Share.Data exposing (Mode(..), Model, Msg(..), PageError(..), init)
|
||||
module Page.Share.Data exposing (Mode(..), Model, Msg(..), PageError(..), init, initCmd)
|
||||
|
||||
import Api
|
||||
import Api.Model.ItemLightList exposing (ItemLightList)
|
||||
@ -41,6 +41,7 @@ type alias Model =
|
||||
, powerSearchInput : Comp.PowerSearchInput.Model
|
||||
, searchInProgress : Bool
|
||||
, itemListModel : Comp.ItemCardList.Model
|
||||
, initialized : Bool
|
||||
}
|
||||
|
||||
|
||||
@ -54,17 +55,27 @@ emptyModel flags =
|
||||
, powerSearchInput = Comp.PowerSearchInput.init
|
||||
, searchInProgress = False
|
||||
, itemListModel = Comp.ItemCardList.init
|
||||
, initialized = False
|
||||
}
|
||||
|
||||
|
||||
init : Maybe String -> Flags -> ( Model, Cmd Msg )
|
||||
init shareId flags =
|
||||
let
|
||||
em =
|
||||
emptyModel flags
|
||||
in
|
||||
case shareId of
|
||||
Just id ->
|
||||
( emptyModel flags, Api.verifyShare flags (ShareSecret id Nothing) VerifyResp )
|
||||
( { em | initialized = True }, Api.verifyShare flags (ShareSecret id Nothing) VerifyResp )
|
||||
|
||||
Nothing ->
|
||||
( emptyModel flags, Cmd.none )
|
||||
( em, Cmd.none )
|
||||
|
||||
|
||||
initCmd : String -> Flags -> Cmd Msg
|
||||
initCmd shareId flags =
|
||||
Api.verifyShare flags (ShareSecret shareId Nothing) VerifyResp
|
||||
|
||||
|
||||
type Msg
|
||||
|
@ -42,13 +42,18 @@ viewContent texts flags versionInfo uiSettings shareId model =
|
||||
ModeInitial ->
|
||||
div
|
||||
[ id "content"
|
||||
, class "h-full w-full flex flex-col text-5xl"
|
||||
, class "h-full w-full flex flex-col"
|
||||
, class S.content
|
||||
]
|
||||
[ B.loadingDimmer
|
||||
{ active = model.pageError == PageErrorNone
|
||||
, label = ""
|
||||
}
|
||||
[ div [ class " text-5xl" ]
|
||||
[ B.loadingDimmer
|
||||
{ active = model.pageError == PageErrorNone
|
||||
, label = ""
|
||||
}
|
||||
]
|
||||
, div [ class "my-4 text-lg" ]
|
||||
[ errorMessage texts model
|
||||
]
|
||||
]
|
||||
|
||||
ModePassword ->
|
||||
@ -76,10 +81,28 @@ mainContent texts flags settings shareId model =
|
||||
[ text <| Maybe.withDefault "" model.verifyResult.name
|
||||
]
|
||||
, Menubar.view texts model
|
||||
, errorMessage texts model
|
||||
, Results.view texts settings flags shareId model
|
||||
]
|
||||
|
||||
|
||||
errorMessage : Texts -> Model -> Html Msg
|
||||
errorMessage texts model =
|
||||
case model.pageError of
|
||||
PageErrorNone ->
|
||||
span [ class "hidden" ] []
|
||||
|
||||
PageErrorAuthFail ->
|
||||
div [ class S.errorMessage ]
|
||||
[ text texts.authFailed
|
||||
]
|
||||
|
||||
PageErrorHttp err ->
|
||||
div [ class S.errorMessage ]
|
||||
[ text (texts.httpError err)
|
||||
]
|
||||
|
||||
|
||||
passwordContent : Texts -> Flags -> VersionInfo -> Model -> Html Msg
|
||||
passwordContent texts flags versionInfo model =
|
||||
div
|
||||
|
@ -5,6 +5,7 @@ import Api.Model.ItemDetail exposing (ItemDetail)
|
||||
import Api.Model.ShareSecret exposing (ShareSecret)
|
||||
import Api.Model.ShareVerifyResult exposing (ShareVerifyResult)
|
||||
import Comp.SharePasswordForm
|
||||
import Comp.UrlCopy
|
||||
import Data.Flags exposing (Flags)
|
||||
import Http
|
||||
|
||||
@ -27,6 +28,8 @@ type alias Model =
|
||||
, passwordModel : Comp.SharePasswordForm.Model
|
||||
, viewMode : ViewMode
|
||||
, pageError : PageError
|
||||
, attachMenuOpen : Bool
|
||||
, visibleAttach : Int
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +37,9 @@ type Msg
|
||||
= VerifyResp (Result Http.Error ShareVerifyResult)
|
||||
| GetItemResp (Result Http.Error ItemDetail)
|
||||
| PasswordMsg Comp.SharePasswordForm.Msg
|
||||
| SelectActiveAttachment Int
|
||||
| ToggleSelectAttach
|
||||
| UrlCopyMsg Comp.UrlCopy.Msg
|
||||
|
||||
|
||||
emptyModel : ViewMode -> Model
|
||||
@ -43,14 +49,18 @@ emptyModel vm =
|
||||
, passwordModel = Comp.SharePasswordForm.init
|
||||
, viewMode = vm
|
||||
, pageError = PageErrorNone
|
||||
, attachMenuOpen = False
|
||||
, visibleAttach = 0
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
Just ( shareId, itemId ) ->
|
||||
( emptyModel ViewLoading
|
||||
, Api.verifyShare flags (ShareSecret shareId Nothing) VerifyResp
|
||||
)
|
||||
|
||||
Nothing ->
|
||||
( emptyModel ViewLoading, Cmd.none )
|
||||
|
@ -2,7 +2,9 @@ module Page.ShareDetail.Update exposing (update)
|
||||
|
||||
import Api
|
||||
import Comp.SharePasswordForm
|
||||
import Comp.UrlCopy
|
||||
import Data.Flags exposing (Flags)
|
||||
import Page exposing (Page(..))
|
||||
import Page.ShareDetail.Data exposing (..)
|
||||
|
||||
|
||||
@ -36,12 +38,16 @@ update shareId itemId flags msg model =
|
||||
( { model | pageError = PageErrorHttp err }, Cmd.none )
|
||||
|
||||
GetItemResp (Ok item) ->
|
||||
let
|
||||
url =
|
||||
Page.pageToString (ShareDetailPage shareId itemId)
|
||||
in
|
||||
( { model
|
||||
| item = item
|
||||
, viewMode = ViewNormal
|
||||
, pageError = PageErrorNone
|
||||
}
|
||||
, Cmd.none
|
||||
, Comp.UrlCopy.initCopy url
|
||||
)
|
||||
|
||||
GetItemResp (Err err) ->
|
||||
@ -62,3 +68,21 @@ update shareId itemId flags msg model =
|
||||
|
||||
Nothing ->
|
||||
( { model | passwordModel = m }, Cmd.map PasswordMsg c )
|
||||
|
||||
SelectActiveAttachment pos ->
|
||||
( { model
|
||||
| visibleAttach = pos
|
||||
, attachMenuOpen = False
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
ToggleSelectAttach ->
|
||||
( { model | attachMenuOpen = not model.attachMenuOpen }, Cmd.none )
|
||||
|
||||
UrlCopyMsg lm ->
|
||||
let
|
||||
cmd =
|
||||
Comp.UrlCopy.update lm
|
||||
in
|
||||
( model, cmd )
|
||||
|
@ -1,30 +1,41 @@
|
||||
module Page.ShareDetail.View exposing (viewContent, viewSidebar)
|
||||
|
||||
import Api
|
||||
import Api.Model.Attachment exposing (Attachment)
|
||||
import Api.Model.VersionInfo exposing (VersionInfo)
|
||||
import Comp.Basic as B
|
||||
import Comp.SharePasswordForm
|
||||
import Comp.UrlCopy
|
||||
import Data.Fields
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Icons as Icons
|
||||
import Data.ItemTemplate as IT exposing (ItemTemplate)
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick)
|
||||
import Messages.Page.ShareDetail exposing (Texts)
|
||||
import Page exposing (Page(..))
|
||||
import Page.ShareDetail.Data exposing (..)
|
||||
import Styles as S
|
||||
import Util.CustomField
|
||||
import Util.Item
|
||||
import Util.List
|
||||
import Util.Size
|
||||
import Util.String
|
||||
|
||||
|
||||
viewSidebar : Texts -> Bool -> Flags -> UiSettings -> Model -> Html Msg
|
||||
viewSidebar texts visible flags settings model =
|
||||
viewSidebar : Texts -> Bool -> Flags -> UiSettings -> String -> String -> Model -> Html Msg
|
||||
viewSidebar texts visible flags settings shareId itemId model =
|
||||
div
|
||||
[ id "sidebar"
|
||||
, class "hidden"
|
||||
, classList [ ( "hidden", not visible ) ]
|
||||
, class S.sidebar
|
||||
]
|
||||
[ div [ class "pt-2" ]
|
||||
[ itemData texts flags model shareId itemId
|
||||
]
|
||||
]
|
||||
[]
|
||||
|
||||
|
||||
viewContent : Texts -> Flags -> UiSettings -> VersionInfo -> String -> String -> Model -> Html Msg
|
||||
@ -36,10 +47,15 @@ viewContent texts flags uiSettings versionInfo shareId itemId model =
|
||||
, class "h-full w-full flex flex-col text-5xl"
|
||||
, class S.content
|
||||
]
|
||||
[ B.loadingDimmer
|
||||
{ active = model.pageError == PageErrorNone
|
||||
, label = ""
|
||||
}
|
||||
[ div [ class "text-5xl" ]
|
||||
[ B.loadingDimmer
|
||||
{ active = model.pageError == PageErrorNone
|
||||
, label = ""
|
||||
}
|
||||
]
|
||||
, div [ class "my-4 text-lg" ]
|
||||
[ errorMessage texts model
|
||||
]
|
||||
]
|
||||
|
||||
ViewPassword ->
|
||||
@ -60,18 +76,18 @@ mainContent texts flags settings shareId model =
|
||||
, class S.content
|
||||
]
|
||||
[ itemHead texts shareId model
|
||||
, div [ class "flex flex-col sm:flex-row sm:space-x-4 relative h-full" ]
|
||||
[ itemData texts model
|
||||
, itemPreview texts flags settings model
|
||||
, errorMessage texts model
|
||||
, div [ class "relative h-full" ]
|
||||
[ itemPreview texts flags settings model
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
itemData : Texts -> Model -> Html Msg
|
||||
itemData texts model =
|
||||
itemData : Texts -> Flags -> Model -> String -> String -> Html Msg
|
||||
itemData texts flags model shareId itemId =
|
||||
let
|
||||
boxStyle =
|
||||
"mb-4 sm:mb-6 max-w-sm"
|
||||
"mb-4 sm:mb-6"
|
||||
|
||||
headerStyle =
|
||||
"py-2 bg-blue-50 hover:bg-blue-100 dark:bg-bluegray-700 dark:hover:bg-opacity-100 dark:hover:bg-bluegray-600 text-lg font-medium rounded-lg"
|
||||
@ -92,11 +108,11 @@ itemData texts model =
|
||||
]
|
||||
Nothing
|
||||
in
|
||||
div [ class "flex flex-col pr-2 sm:w-1/3" ]
|
||||
div [ class "flex flex-col" ]
|
||||
[ div [ class boxStyle ]
|
||||
[ div [ class headerStyle ]
|
||||
[ Icons.dateIcon2 "mr-2 ml-2"
|
||||
, text "Date"
|
||||
, text (texts.field Data.Fields.Date)
|
||||
]
|
||||
, div [ class "text-lg ml-2" ]
|
||||
[ Util.Item.toItemLight model.item
|
||||
@ -104,10 +120,24 @@ itemData texts model =
|
||||
|> text
|
||||
]
|
||||
]
|
||||
, div
|
||||
[ class boxStyle
|
||||
, classList [ ( "hidden", model.item.dueDate == Nothing ) ]
|
||||
]
|
||||
[ div [ class headerStyle ]
|
||||
[ Icons.dueDateIcon2 "mr-2 ml-2"
|
||||
, text (texts.field Data.Fields.DueDate)
|
||||
]
|
||||
, div [ class "text-lg ml-2" ]
|
||||
[ Util.Item.toItemLight model.item
|
||||
|> IT.render IT.dueDateLong (templateCtx texts)
|
||||
|> text
|
||||
]
|
||||
]
|
||||
, div [ class boxStyle ]
|
||||
[ div [ class headerStyle ]
|
||||
[ Icons.tagsIcon2 "mr-2 ml-2"
|
||||
, text "Tags & Fields"
|
||||
, text texts.tagsAndFields
|
||||
]
|
||||
, div [ class "flex flex-row items-center flex-wrap font-medium my-1" ]
|
||||
(List.map showTag model.item.tags ++ List.map showField model.item.customfields)
|
||||
@ -115,7 +145,7 @@ itemData texts model =
|
||||
, div [ class boxStyle ]
|
||||
[ div [ class headerStyle ]
|
||||
[ Icons.correspondentIcon2 "mr-2 ml-2"
|
||||
, text "Correspondent"
|
||||
, text texts.basics.correspondent
|
||||
]
|
||||
, div [ class "text-lg ml-2" ]
|
||||
[ Util.Item.toItemLight model.item
|
||||
@ -126,7 +156,7 @@ itemData texts model =
|
||||
, div [ class boxStyle ]
|
||||
[ div [ class headerStyle ]
|
||||
[ Icons.concernedIcon2 "mr-2 ml-2"
|
||||
, text "Concerning"
|
||||
, text texts.basics.concerning
|
||||
]
|
||||
, div [ class "text-lg ml-2" ]
|
||||
[ Util.Item.toItemLight model.item
|
||||
@ -134,40 +164,110 @@ itemData texts model =
|
||||
|> text
|
||||
]
|
||||
]
|
||||
, div [ class boxStyle ]
|
||||
[ div [ class headerStyle ]
|
||||
[ i [ class "fa fa-copy mr-2 ml-2" ] []
|
||||
, text "Copy URL"
|
||||
]
|
||||
, div [ class "flex flex-col items-center py-2" ]
|
||||
[ Html.map UrlCopyMsg
|
||||
(Comp.UrlCopy.view
|
||||
(flags.config.baseUrl
|
||||
++ Page.pageToString
|
||||
(ShareDetailPage shareId itemId)
|
||||
)
|
||||
)
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
itemPreview : Texts -> Flags -> UiSettings -> Model -> Html Msg
|
||||
itemPreview texts flags settings model =
|
||||
let
|
||||
id =
|
||||
List.head model.item.attachments
|
||||
|> Maybe.map .id
|
||||
|> Maybe.withDefault ""
|
||||
attach =
|
||||
Util.List.get model.item.attachments model.visibleAttach
|
||||
|> Maybe.withDefault Api.Model.Attachment.empty
|
||||
|
||||
attachName =
|
||||
Maybe.withDefault (texts.noName ++ ".pdf") attach.name
|
||||
in
|
||||
div
|
||||
[ class "flex flex-grow"
|
||||
, style "min-height" "500px"
|
||||
[ class "flex flex-grow flex-col h-full border-t dark:border-bluegray-600"
|
||||
]
|
||||
[ embed
|
||||
[ src (Data.UiSettings.pdfUrl settings flags (Api.shareFileURL id))
|
||||
, class " h-full w-full mx-0 py-0"
|
||||
[ div [ class "flex flex-col sm:flex-row items-center py-1 px-1 border-l border-r dark:border-bluegray-600" ]
|
||||
[ div [ class "text-base font-bold flex-grow w-full text-center sm:text-left break-all" ]
|
||||
[ text attachName
|
||||
, text " ("
|
||||
, text (Util.Size.bytesReadable Util.Size.B (toFloat attach.size))
|
||||
, text ")"
|
||||
]
|
||||
, div [ class "flex flex-row space-x-2" ]
|
||||
[ B.secondaryBasicButton
|
||||
{ label = ""
|
||||
, icon = "fa fa-eye"
|
||||
, disabled = False
|
||||
, handler = href (Api.shareFileURL attach.id)
|
||||
, attrs =
|
||||
[ target "_new"
|
||||
]
|
||||
}
|
||||
, B.secondaryBasicButton
|
||||
{ label = ""
|
||||
, icon = "fa fa-download"
|
||||
, disabled = False
|
||||
, handler = href (Api.shareFileURL attach.id)
|
||||
, attrs =
|
||||
[ download attachName
|
||||
]
|
||||
}
|
||||
, B.secondaryBasicButton
|
||||
{ label = ""
|
||||
, icon = "fa fa-ellipsis-v"
|
||||
, disabled = False
|
||||
, handler = onClick ToggleSelectAttach
|
||||
, attrs =
|
||||
[ href "#"
|
||||
, classList [ ( "hidden", List.length model.item.attachments <= 1 ) ]
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
, attachmentSelect texts model
|
||||
, div
|
||||
[ class "flex w-full h-full mb-4 border-b border-l border-r dark:border-bluegray-600"
|
||||
, style "min-height" "500px"
|
||||
]
|
||||
[ embed
|
||||
[ src (Data.UiSettings.pdfUrl settings flags (Api.shareFileURL attach.id))
|
||||
, class " h-full w-full mx-0 py-0"
|
||||
]
|
||||
[]
|
||||
]
|
||||
[]
|
||||
]
|
||||
|
||||
|
||||
itemHead : Texts -> String -> Model -> Html Msg
|
||||
itemHead texts shareId model =
|
||||
div [ class "flex flex-col sm:flex-row" ]
|
||||
div [ class "flex flex-col sm:flex-row mt-1" ]
|
||||
[ div [ class "flex flex-grow items-center" ]
|
||||
[ h1 [ class S.header1 ]
|
||||
[ h1
|
||||
[ class S.header1
|
||||
, class "items-center flex flex-row"
|
||||
]
|
||||
[ text model.item.name
|
||||
, span
|
||||
[ classList [ ( "hidden", model.item.state /= "created" ) ]
|
||||
, class S.blueBasicLabel
|
||||
, class "inline ml-4 text-sm"
|
||||
]
|
||||
[ text texts.unconfirmed
|
||||
]
|
||||
]
|
||||
]
|
||||
, div [ class "flex flex-row items-center justify-end mb-2 sm:mb-0" ]
|
||||
[ B.secondaryBasicButton
|
||||
{ label = "Close"
|
||||
{ label = texts.basics.back
|
||||
, icon = "fa fa-times"
|
||||
, disabled = False
|
||||
, handler = Page.href (SharePage shareId)
|
||||
@ -189,6 +289,83 @@ passwordContent texts flags versionInfo model =
|
||||
]
|
||||
|
||||
|
||||
attachmentSelect : Texts -> Model -> Html Msg
|
||||
attachmentSelect texts model =
|
||||
div
|
||||
[ class "flex flex-row border-l border-t border-r px-2 py-2 dark:border-bluegray-600 "
|
||||
, class "overflow-x-auto overflow-y-none"
|
||||
, classList
|
||||
[ ( "hidden", not model.attachMenuOpen )
|
||||
]
|
||||
]
|
||||
(List.indexedMap (menuItem texts model) model.item.attachments)
|
||||
|
||||
|
||||
menuItem : Texts -> Model -> Int -> Attachment -> Html Msg
|
||||
menuItem texts model pos attach =
|
||||
let
|
||||
iconClass =
|
||||
"fa fa-circle ml-1"
|
||||
|
||||
visible =
|
||||
model.visibleAttach == pos
|
||||
in
|
||||
a
|
||||
[ classList <|
|
||||
[ ( "border-blue-500 dark:border-lightblue-500", pos == 0 )
|
||||
, ( "dark:border-bluegray-600", pos /= 0 )
|
||||
]
|
||||
, class "flex flex-col relative border rounded px-1 py-1 mr-2"
|
||||
, class " hover:shadow dark:hover:border-bluegray-500"
|
||||
, href "#"
|
||||
, onClick (SelectActiveAttachment pos)
|
||||
]
|
||||
[ div
|
||||
[ classList
|
||||
[ ( "hidden", not visible )
|
||||
]
|
||||
, class "absolute right-1 top-1 text-blue-400 dark:text-lightblue-400 text-xl"
|
||||
]
|
||||
[ i [ class iconClass ] []
|
||||
]
|
||||
, div [ class "flex-grow" ]
|
||||
[ img
|
||||
[ src (Api.shareAttachmentPreviewURL attach.id)
|
||||
, class "block w-20 mx-auto"
|
||||
]
|
||||
[]
|
||||
]
|
||||
, div [ class "mt-1 text-sm break-all w-28 text-center" ]
|
||||
[ Maybe.map (Util.String.ellipsis 36) attach.name
|
||||
|> Maybe.withDefault texts.noName
|
||||
|> text
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
errorMessage : Texts -> Model -> Html Msg
|
||||
errorMessage texts model =
|
||||
case model.pageError of
|
||||
PageErrorNone ->
|
||||
span [ class "hidden" ] []
|
||||
|
||||
PageErrorAuthFail ->
|
||||
div
|
||||
[ class S.errorMessage
|
||||
, class "my-4"
|
||||
]
|
||||
[ text texts.authFailed
|
||||
]
|
||||
|
||||
PageErrorHttp err ->
|
||||
div
|
||||
[ class S.errorMessage
|
||||
, class "my-4"
|
||||
]
|
||||
[ text (texts.httpError err)
|
||||
]
|
||||
|
||||
|
||||
templateCtx : Texts -> IT.TemplateContext
|
||||
templateCtx texts =
|
||||
{ dateFormatLong = texts.formatDateLong
|
||||
|
@ -10,7 +10,7 @@ module Styles exposing (..)
|
||||
|
||||
sidebar : String
|
||||
sidebar =
|
||||
" flex flex-col flex-none md:w-80 w-full min-h-max px-2 dark:text-gray-200 shadow overflow-y-auto h-full transition-opacity transition-duration-200 scrollbar-thin scrollbar-light-sidebar dark:scrollbar-dark-sidebar"
|
||||
" flex flex-col flex-none md:w-80 w-full min-h-max px-2 dark:text-gray-200 overflow-y-auto h-full transition-opacity transition-duration-200 scrollbar-thin scrollbar-light-sidebar dark:scrollbar-dark-sidebar"
|
||||
|
||||
|
||||
sidebarBg : String
|
||||
@ -100,6 +100,11 @@ basicLabel =
|
||||
" label border-gray-600 text-gray-600 dark:border-bluegray-300 dark:text-bluegray-300 "
|
||||
|
||||
|
||||
blueBasicLabel : String
|
||||
blueBasicLabel =
|
||||
" label border-blue-500 text-blue-500 dark:border-lightblue-200 dark:text-lightblue-200 "
|
||||
|
||||
|
||||
|
||||
--- Primary Button
|
||||
|
||||
|
@ -127,8 +127,10 @@ elmApp.ports.printElement.subscribe(function(id) {
|
||||
w.document.write('</head>');
|
||||
}
|
||||
w.document.write('<body>');
|
||||
w.document.write('<div id="print-qr" style="width: 300px; height: 300px; padding: 5px; border: 1px solid black;">');
|
||||
w.document.write(el.outerHTML);
|
||||
w.document.write('<script type="application/javascript">window.print(); window.close();</script>');
|
||||
w.document.write('</div>');
|
||||
w.document.write('<script type="application/javascript">window.print();</script>');
|
||||
w.document.write('</body></html>');
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user