Add a qr code to the link of an item or attachment

This commit is contained in:
eikek 2021-08-17 02:15:14 +02:00
parent 2d2f9e3e87
commit 8f23b68587
14 changed files with 307 additions and 41 deletions

View File

@ -38,6 +38,6 @@ update =
Comp.ItemDetail.Update.update
view2 : Texts -> ItemNav -> UiSettings -> Model -> Html Msg
view2 : Texts -> Flags -> ItemNav -> UiSettings -> Model -> Html Msg
view2 =
Comp.ItemDetail.View2.view

View File

@ -18,7 +18,10 @@ module Comp.ItemDetail.Model exposing
, ViewMode(..)
, emptyModel
, initSelectViewModel
, initShowQrModel
, isEditNotes
, isShowQrAttach
, isShowQrItem
, personMatchesOrg
, resultModel
, resultModelCmd
@ -40,7 +43,6 @@ import Api.Model.SentMails exposing (SentMails)
import Api.Model.Tag exposing (Tag)
import Api.Model.TagList exposing (TagList)
import Comp.AttachmentMeta
import Comp.ConfirmModal
import Comp.CustomFieldMultiInput
import Comp.DatePicker
import Comp.DetailEdit
@ -118,9 +120,33 @@ type alias Model =
, attachmentDropdownOpen : Bool
, editMenuTabsOpen : Set String
, viewMode : ViewMode
, showQrModel : ShowQrModel
}
type alias ShowQrModel =
{ item : Bool
, attach : Bool
}
initShowQrModel : ShowQrModel
initShowQrModel =
{ item = False
, attach = False
}
isShowQrItem : ShowQrModel -> Bool
isShowQrItem model =
model.item
isShowQrAttach : ShowQrModel -> Bool
isShowQrAttach model =
model.attach
type ConfirmModalValue
= ConfirmModalReprocessItem Msg
| ConfirmModalReprocessFile Msg
@ -230,6 +256,7 @@ emptyModel =
, attachmentDropdownOpen = False
, editMenuTabsOpen = Set.empty
, viewMode = SimpleView
, showQrModel = initShowQrModel
}
@ -340,6 +367,9 @@ type Msg
| ReprocessItemConfirmed
| ToggleSelectView
| RestoreItem
| ToggleShowQrItem String
| ToggleShowQrAttach String
| PrintElement String
type SaveNameState

View File

@ -0,0 +1,117 @@
{-
Copyright 2020 Docspell Contributors
SPDX-License-Identifier: GPL-3.0-or-later
-}
module Comp.ItemDetail.ShowQrCode exposing (UrlId(..), qrCodeElementId, view, view1)
import Api
import Comp.Basic as B
import Comp.ItemDetail.Model exposing (Model, Msg(..), isShowQrAttach, isShowQrItem)
import Comp.MenuBar as MB
import Data.Flags exposing (Flags)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import QRCode
import Styles as S
view : Flags -> String -> Model -> UrlId -> Html Msg
view flags classes model urlId =
case urlId of
Attach _ ->
if isShowQrAttach model.showQrModel then
view1 flags classes urlId
else
span [ class "hidden" ] []
Item _ ->
if isShowQrItem model.showQrModel then
view1 flags classes urlId
else
span [ class "hidden" ] []
view1 : Flags -> String -> UrlId -> Html Msg
view1 flags classes urlId =
let
docUrl =
case urlId of
Attach str ->
flags.config.baseUrl ++ Api.fileURL str
Item str ->
flags.config.baseUrl ++ "/app/item/" ++ str
elementId =
qrCodeElementId urlId
toggleShowQr =
case urlId of
Attach id ->
ToggleShowQrAttach id
Item id ->
ToggleShowQrItem id
in
div
[ class "flex flex-col py-2 px-2 items-center"
, class classes
]
[ MB.view
{ start =
[ MB.PrimaryButton
{ tagger = PrintElement elementId
, title = "Print this QR code"
, icon = Just "fa fa-print"
, label = "Print"
}
]
, end =
[ MB.SecondaryButton
{ tagger = toggleShowQr
, title = "Close"
, icon = Just "fa fa-times"
, label = "Close"
}
]
, rootClasses = "w-full mt-2 mb-4"
}
, div [ class "flex flex-col sm:flex-row sm:space-x-2" ]
[ div
[ class S.border
, class S.qrCode
, id elementId
]
[ qrCodeView docUrl
]
]
]
qrCodeElementId : UrlId -> String
qrCodeElementId urlId =
case urlId of
Attach str ->
"qr-attach-" ++ str
Item str ->
"qr-item-" ++ str
type UrlId
= Attach String
| Item String
qrCodeView : String -> Html msg
qrCodeView message =
QRCode.encode message
|> Result.map QRCode.toSvg
|> Result.withDefault
(text "Error generating QR code")

View File

@ -11,8 +11,19 @@ import Api
import Api.Model.Attachment exposing (Attachment)
import Comp.AttachmentMeta
import Comp.ItemDetail.ConfirmModalView
import Comp.ItemDetail.Model exposing (Model, Msg(..), NotesField(..), SaveNameState(..), ViewMode(..))
import Comp.ItemDetail.Model
exposing
( Model
, Msg(..)
, NotesField(..)
, SaveNameState(..)
, ViewMode(..)
, isShowQrAttach
)
import Comp.ItemDetail.ShowQrCode
import Comp.MenuBar as MB
import Data.Flags exposing (Flags)
import Data.Icons as Icons
import Data.UiSettings exposing (UiSettings)
import Dict
import Html exposing (..)
@ -27,8 +38,8 @@ import Util.Size
import Util.String
view : Texts -> UiSettings -> Model -> Int -> Attachment -> Html Msg
view texts settings model pos attach =
view : Texts -> Flags -> UiSettings -> Model -> Int -> Attachment -> Html Msg
view texts flags settings model pos attach =
let
fileUrl =
Api.fileURL attach.id
@ -61,6 +72,11 @@ view texts settings model pos attach =
Nothing ->
span [ class "hidden" ] []
else if isShowQrAttach model.showQrModel then
Comp.ItemDetail.ShowQrCode.view1 flags
"border-r border-l border-b dark:border-bluegray-600 h-full"
(Comp.ItemDetail.ShowQrCode.Attach attach.id)
else
div
[ class "flex flex-col relative px-2 pt-2 h-full"
@ -269,6 +285,13 @@ attachHeader texts settings model _ attach =
, href "#"
]
}
, { icon = Icons.showQr
, label = texts.showQrCode
, attrs =
[ onClick (ToggleShowQrAttach attach.id)
, href "#"
]
}
, { icon = "fa fa-trash"
, label = texts.deleteThisFile
, attrs =

View File

@ -42,7 +42,10 @@ import Comp.ItemDetail.Model
, UpdateResult
, ViewMode(..)
, initSelectViewModel
, initShowQrModel
, isEditNotes
, isShowQrAttach
, isShowQrItem
, resultModel
, resultModelCmd
, resultModelCmdSub
@ -66,6 +69,7 @@ import Dict
import Html5.DragDrop as DD
import Http
import Page exposing (Page(..))
import Ports
import Set exposing (Set)
import Throttle
import Time
@ -1607,6 +1611,29 @@ update key flags inav settings msg model =
RestoreItem ->
resultModelCmd ( model, Api.restoreItem flags model.item.id SaveResp )
ToggleShowQrItem id ->
let
sqm =
model.showQrModel
next =
{ sqm | item = not sqm.item }
in
resultModel { model | showQrModel = next }
ToggleShowQrAttach id ->
let
sqm =
model.showQrModel
next =
{ sqm | attach = not sqm.attach }
in
resultModel { model | attachmentDropdownOpen = False, showQrModel = next }
PrintElement id ->
resultModelCmd ( model, Ports.printElement id )
--- Helper

View File

@ -19,12 +19,15 @@ import Comp.ItemDetail.Model
, Msg(..)
, NotesField(..)
, SaveNameState(..)
, isShowQrItem
)
import Comp.ItemDetail.Notes
import Comp.ItemDetail.ShowQrCode
import Comp.ItemDetail.SingleAttachment
import Comp.ItemMail
import Comp.MenuBar as MB
import Comp.SentMails
import Data.Flags exposing (Flags)
import Data.Icons as Icons
import Data.ItemNav exposing (ItemNav)
import Data.UiSettings exposing (UiSettings)
@ -36,12 +39,12 @@ import Page exposing (Page(..))
import Styles as S
view : Texts -> ItemNav -> UiSettings -> Model -> Html Msg
view texts inav settings model =
view : Texts -> Flags -> ItemNav -> UiSettings -> Model -> Html Msg
view texts flags inav settings model =
div [ class "flex flex-col h-full" ]
[ header texts settings model
, menuBar texts inav settings model
, body texts inav settings model
, body texts flags inav settings model
, itemModal texts model
]
@ -146,7 +149,7 @@ menuBar texts inav settings model =
[ ( "bg-gray-200 dark:bg-bluegray-600", model.addFilesOpen )
]
, if model.addFilesOpen then
title "Close"
title texts.close
else
title texts.addMoreFiles
@ -156,6 +159,22 @@ menuBar texts inav settings model =
]
[ Icons.addFilesIcon2 ""
]
, MB.CustomElement <|
a
[ classList
[ ( "bg-gray-200 dark:bg-bluegray-600", isShowQrItem model.showQrModel )
]
, if isShowQrItem model.showQrModel then
title texts.close
else
title texts.showQrCode
, onClick (ToggleShowQrItem model.item.id)
, class S.secondaryBasicButton
, href "#"
]
[ Icons.showQrIcon ""
]
, MB.CustomElement <|
a
[ class S.primaryButton
@ -214,20 +233,24 @@ menuBar texts inav settings model =
}
body : Texts -> ItemNav -> UiSettings -> Model -> Html Msg
body texts _ settings model =
body : Texts -> Flags -> ItemNav -> UiSettings -> Model -> Html Msg
body texts flags _ settings model =
div [ class "grid gap-2 grid-cols-1 md:grid-cols-3 h-full" ]
[ leftArea texts settings model
, rightArea texts settings model
[ leftArea texts flags settings model
, rightArea texts flags settings model
]
leftArea : Texts -> UiSettings -> Model -> Html Msg
leftArea texts settings model =
leftArea : Texts -> Flags -> UiSettings -> Model -> Html Msg
leftArea texts flags settings model =
div [ class "w-full md:order-first md:mr-2 flex flex-col" ]
[ addDetailForm texts settings model
, sendMailForm texts settings model
, Comp.ItemDetail.AddFilesForm.view texts.addFilesForm model
, Comp.ItemDetail.ShowQrCode.view flags
(S.border ++ " mb-4")
model
(Comp.ItemDetail.ShowQrCode.Item model.item.id)
, Comp.ItemDetail.Notes.view texts.notes model
, div
[ classList
@ -245,15 +268,15 @@ leftArea texts settings model =
]
rightArea : Texts -> UiSettings -> Model -> Html Msg
rightArea texts settings model =
rightArea : Texts -> Flags -> UiSettings -> Model -> Html Msg
rightArea texts flags settings model =
div [ class "md:col-span-2 h-full" ]
(attachmentsBody texts settings model)
(attachmentsBody texts flags settings model)
attachmentsBody : Texts -> UiSettings -> Model -> List (Html Msg)
attachmentsBody texts settings model =
List.indexedMap (Comp.ItemDetail.SingleAttachment.view texts.singleAttachment settings model)
attachmentsBody : Texts -> Flags -> UiSettings -> Model -> List (Html Msg)
attachmentsBody texts flags settings model =
List.indexedMap (Comp.ItemDetail.SingleAttachment.view texts.singleAttachment flags settings model)
model.item.attachments

View File

@ -279,9 +279,6 @@ viewLinks2 texts flags _ source =
styleUrl =
"truncate px-2 py-2 border-0 border-t border-b border-r font-mono text-sm my-auto rounded-r border-gray-400 dark:border-bluegray-500"
styleQr =
"max-w-min dark:bg-bluegray-400 bg-gray-50 mx-auto md:mx-0"
in
div
[]
@ -350,7 +347,7 @@ viewLinks2 texts flags _ source =
, div [ class "py-2" ]
[ div
[ class S.border
, class styleQr
, class S.qrCode
]
[ qrCodeView texts appUrl
]
@ -386,7 +383,7 @@ viewLinks2 texts flags _ source =
, div [ class "py-2" ]
[ div
[ class S.border
, class styleQr
, class S.qrCode
]
[ qrCodeView texts apiUrl
]

View File

@ -6,9 +6,7 @@
module Data.Icons exposing
( addFiles
, addFiles2
, addFilesIcon
( addFiles2
, addFilesIcon2
, concerned
, concerned2
@ -60,6 +58,8 @@ module Data.Icons exposing
, personIcon2
, search
, searchIcon
, showQr
, showQrIcon
, source
, source2
, sourceIcon
@ -321,26 +321,26 @@ editNotesIcon =
i [ class editNotes ] []
addFiles : String
addFiles =
"file plus icon"
addFiles2 : String
addFiles2 =
"fa fa-file-upload"
addFilesIcon : Html msg
addFilesIcon =
i [ class addFiles ] []
addFilesIcon2 : String -> Html msg
addFilesIcon2 classes =
i [ class addFiles2, class classes ] []
showQr : String
showQr =
"fa fa-qrcode"
showQrIcon : String -> Html msg
showQrIcon classes =
i [ class showQr, class classes ] []
tag : String
tag =
"tag icon"

View File

@ -55,6 +55,8 @@ type alias Texts =
, sendingMailNow : String
, formatDateTime : Int -> String
, mailSendSuccessful : String
, showQrCode : String
, close : String
}
@ -89,6 +91,8 @@ gb =
, sendingMailNow = "Sending e-mail"
, formatDateTime = DF.formatDateTimeLong Messages.UiLanguage.English
, mailSendSuccessful = "Mail sent."
, showQrCode = "Show the URL to this page as QR code"
, close = "Close"
}
@ -123,4 +127,6 @@ de =
, sendingMailNow = "E-Mail wird gesendet"
, formatDateTime = DF.formatDateTimeLong Messages.UiLanguage.German
, mailSendSuccessful = "E-Mail wurde versendet."
, showQrCode = "Den Link zu dieser Seite als QR code anzeigen"
, close = "Schließen"
}

View File

@ -31,6 +31,7 @@ type alias Texts =
, selectModeTitle : String
, exitSelectMode : String
, deleteAttachments : String
, showQrCode : String
}
@ -51,6 +52,7 @@ gb =
, selectModeTitle = "Select Mode"
, exitSelectMode = "Exit Select Mode"
, deleteAttachments = "Delete attachments"
, showQrCode = "Show URL as QR code"
}
@ -71,4 +73,5 @@ de =
, selectModeTitle = "Auswahlmodus"
, exitSelectMode = "Auswahlmodus beenden"
, deleteAttachments = "Anhänge löschen"
, showQrCode = "Link als QR Code anzeigen"
}

View File

@ -61,11 +61,11 @@ viewSidebar texts visible flags settings model =
viewContent : Texts -> ItemNav -> Flags -> UiSettings -> Model -> Html Msg
viewContent texts inav _ settings model =
viewContent texts inav flags settings model =
div
[ id "content"
, class S.content
]
[ Html.map ItemDetailMsg
(Comp.ItemDetail.view2 texts.itemDetail inav settings model.detail)
(Comp.ItemDetail.view2 texts.itemDetail flags inav settings model.detail)
]

View File

@ -8,6 +8,7 @@
port module Ports exposing
( checkSearchQueryString
, initClipboard
, printElement
, receiveCheckQueryResult
, receiveUiSettings
, removeAccount
@ -48,6 +49,12 @@ port receiveUiSettings : (StoredUiSettings -> msg) -> Sub msg
port requestUiSettings : AuthResult -> Cmd msg
{-| Creates a new window/tab, writes the contents of the given element
and calls the print dialog.
-}
port printElement : String -> Cmd msg
setUiTheme : UiTheme -> Cmd msg
setUiTheme theme =
internalSetUiTheme (Data.UiTheme.toString theme)

View File

@ -351,3 +351,8 @@ tableMain =
tableRow : String
tableRow =
"border-t dark:border-bluegray-600"
qrCode : String
qrCode =
"max-w-min dark:bg-bluegray-400 bg-gray-50 mx-auto md:mx-0"

View File

@ -105,3 +105,31 @@ elmApp.ports.checkSearchQueryString.subscribe(function(args) {
elmApp.ports.receiveCheckQueryResult.send(answer);
}
});
elmApp.ports.printElement.subscribe(function(id) {
if (id) {
var el = document.getElementById(id);
var head = document.getElementsByTagName('head');
if (head && head.length > 0) {
head = head[0];
}
if (el) {
var w = window.open();
w.document.write('<html>');
if (head) {
w.document.write('<head>');
['title', 'meta'].forEach(function(el) {
var headEls = head.getElementsByTagName(el);
for (var i=0; i<headEls.length; i++) {
w.document.write(headEls.item(i).outerHTML);
}
});
w.document.write('</head>');
}
w.document.write('<body>');
w.document.write(el.outerHTML);
w.document.write('<script type="application/javascript">window.print(); window.close();</script>');
w.document.write('</body></html>');
}
}
});