mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-04 06:05:59 +00:00
Start with send-mail widget
This commit is contained in:
parent
4490a444a9
commit
51ce48997c
@ -1325,11 +1325,18 @@ components:
|
|||||||
schemas:
|
schemas:
|
||||||
SimpleMail:
|
SimpleMail:
|
||||||
description: |
|
description: |
|
||||||
A simple e-mail.
|
A simple e-mail related to an item.
|
||||||
|
|
||||||
|
The mail may contain the item attachments as mail attachments.
|
||||||
|
If all item attachments should be send, set
|
||||||
|
`addAllAttachments` to `true`. Otherwise set it to `false` and
|
||||||
|
specify a list of file-ids that you want to include.
|
||||||
required:
|
required:
|
||||||
- recipients
|
- recipients
|
||||||
- subject
|
- subject
|
||||||
- body
|
- body
|
||||||
|
- addAllAttachments
|
||||||
|
- attachmentIds
|
||||||
properties:
|
properties:
|
||||||
recipients:
|
recipients:
|
||||||
type: array
|
type: array
|
||||||
@ -1339,6 +1346,13 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
body:
|
body:
|
||||||
type: string
|
type: string
|
||||||
|
addAllAttachments:
|
||||||
|
type: boolean
|
||||||
|
attachemntIds:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
format: ident
|
||||||
EmailSettingsList:
|
EmailSettingsList:
|
||||||
description: |
|
description: |
|
||||||
A list of user email settings.
|
A list of user email settings.
|
||||||
|
@ -395,7 +395,9 @@ viewSingle model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
renderDefault =
|
renderDefault =
|
||||||
[ List.head model.selected |> Maybe.map renderClosed |> Maybe.withDefault (renderPlaceholder model)
|
[ List.head model.selected
|
||||||
|
|> Maybe.map renderClosed
|
||||||
|
|> Maybe.withDefault (renderPlaceholder model)
|
||||||
, renderMenu model
|
, renderMenu model
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -76,7 +76,10 @@ init ems =
|
|||||||
{ makeOption = \s -> { value = Data.SSLType.toString s, text = Data.SSLType.label s }
|
{ makeOption = \s -> { value = Data.SSLType.toString s, text = Data.SSLType.label s }
|
||||||
, placeholder = ""
|
, placeholder = ""
|
||||||
, options = Data.SSLType.all
|
, options = Data.SSLType.all
|
||||||
, selected = Data.SSLType.fromString ems.sslType
|
, selected =
|
||||||
|
Data.SSLType.fromString ems.sslType
|
||||||
|
|> Maybe.withDefault Data.SSLType.None
|
||||||
|
|> Just
|
||||||
}
|
}
|
||||||
, ignoreCertificates = ems.ignoreCertificates
|
, ignoreCertificates = ems.ignoreCertificates
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import Api.Model.TagList exposing (TagList)
|
|||||||
import Browser.Navigation as Nav
|
import Browser.Navigation as Nav
|
||||||
import Comp.DatePicker
|
import Comp.DatePicker
|
||||||
import Comp.Dropdown exposing (isDropdownChangeMsg)
|
import Comp.Dropdown exposing (isDropdownChangeMsg)
|
||||||
|
import Comp.ItemMail
|
||||||
import Comp.YesNoDimmer
|
import Comp.YesNoDimmer
|
||||||
import Data.Direction exposing (Direction)
|
import Data.Direction exposing (Direction)
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
@ -57,6 +58,8 @@ type alias Model =
|
|||||||
, itemProposals : ItemProposals
|
, itemProposals : ItemProposals
|
||||||
, dueDate : Maybe Int
|
, dueDate : Maybe Int
|
||||||
, dueDatePicker : DatePicker
|
, dueDatePicker : DatePicker
|
||||||
|
, itemMail : Comp.ItemMail.Model
|
||||||
|
, mailOpen : Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -116,6 +119,8 @@ emptyModel =
|
|||||||
, itemProposals = Api.Model.ItemProposals.empty
|
, itemProposals = Api.Model.ItemProposals.empty
|
||||||
, dueDate = Nothing
|
, dueDate = Nothing
|
||||||
, dueDatePicker = Comp.DatePicker.emptyModel
|
, dueDatePicker = Comp.DatePicker.emptyModel
|
||||||
|
, itemMail = Comp.ItemMail.emptyModel
|
||||||
|
, mailOpen = False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -158,6 +163,8 @@ type Msg
|
|||||||
| GetProposalResp (Result Http.Error ItemProposals)
|
| GetProposalResp (Result Http.Error ItemProposals)
|
||||||
| RemoveDueDate
|
| RemoveDueDate
|
||||||
| RemoveDate
|
| RemoveDate
|
||||||
|
| ItemMailMsg Comp.ItemMail.Msg
|
||||||
|
| ToggleMail
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -282,12 +289,16 @@ update key flags next msg model =
|
|||||||
let
|
let
|
||||||
( dp, dpc ) =
|
( dp, dpc ) =
|
||||||
Comp.DatePicker.init
|
Comp.DatePicker.init
|
||||||
|
|
||||||
|
( im, ic ) =
|
||||||
|
Comp.ItemMail.init flags
|
||||||
in
|
in
|
||||||
( { model | itemDatePicker = dp, dueDatePicker = dp }
|
( { model | itemDatePicker = dp, dueDatePicker = dp, itemMail = im }
|
||||||
, Cmd.batch
|
, Cmd.batch
|
||||||
[ getOptions flags
|
[ getOptions flags
|
||||||
, Cmd.map ItemDatePickerMsg dpc
|
, Cmd.map ItemDatePickerMsg dpc
|
||||||
, Cmd.map DueDatePickerMsg dpc
|
, Cmd.map DueDatePickerMsg dpc
|
||||||
|
, Cmd.map ItemMailMsg ic
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -690,6 +701,29 @@ update key flags next msg model =
|
|||||||
GetProposalResp (Err _) ->
|
GetProposalResp (Err _) ->
|
||||||
( model, Cmd.none )
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
ItemMailMsg m ->
|
||||||
|
let
|
||||||
|
( im, fa ) =
|
||||||
|
Comp.ItemMail.update m model.itemMail
|
||||||
|
in
|
||||||
|
case fa of
|
||||||
|
Comp.ItemMail.FormNone ->
|
||||||
|
( { model | itemMail = im }, Cmd.none )
|
||||||
|
|
||||||
|
Comp.ItemMail.FormCancel ->
|
||||||
|
( { model
|
||||||
|
| itemMail = Comp.ItemMail.clear im
|
||||||
|
, mailOpen = False
|
||||||
|
}
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
|
Comp.ItemMail.FormSend sm ->
|
||||||
|
Debug.todo "implement send"
|
||||||
|
|
||||||
|
ToggleMail ->
|
||||||
|
( { model | mailOpen = not model.mailOpen }, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- view
|
-- view
|
||||||
@ -711,6 +745,7 @@ view inav model =
|
|||||||
, div
|
, div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "ui ablue-comp menu", True )
|
[ ( "ui ablue-comp menu", True )
|
||||||
|
, ( "top attached", model.mailOpen )
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
[ a [ class "item", Page.href HomePage ]
|
[ a [ class "item", Page.href HomePage ]
|
||||||
@ -743,13 +778,25 @@ view inav model =
|
|||||||
[ ( "toggle item", True )
|
[ ( "toggle item", True )
|
||||||
, ( "active", model.menuOpen )
|
, ( "active", model.menuOpen )
|
||||||
]
|
]
|
||||||
, title "Expand Menu"
|
, title "Edit item"
|
||||||
, onClick ToggleMenu
|
, onClick ToggleMenu
|
||||||
, href ""
|
, href ""
|
||||||
]
|
]
|
||||||
[ i [ class "edit icon" ] []
|
[ i [ class "edit icon" ] []
|
||||||
]
|
]
|
||||||
|
, a
|
||||||
|
[ classList
|
||||||
|
[ ( "toggle item", True )
|
||||||
|
, ( "active", model.mailOpen )
|
||||||
|
]
|
||||||
|
, title "Send Mail"
|
||||||
|
, onClick ToggleMail
|
||||||
|
, href "#"
|
||||||
|
]
|
||||||
|
[ i [ class "mail icon" ] []
|
||||||
|
]
|
||||||
]
|
]
|
||||||
|
, renderMailForm model
|
||||||
, div [ class "ui grid" ]
|
, div [ class "ui grid" ]
|
||||||
[ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm)
|
[ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm)
|
||||||
, div
|
, div
|
||||||
@ -1197,3 +1244,18 @@ renderDueDateSuggestions model =
|
|||||||
Util.Time.formatDate
|
Util.Time.formatDate
|
||||||
(List.take 5 model.itemProposals.dueDate)
|
(List.take 5 model.itemProposals.dueDate)
|
||||||
SetDueDateSuggestion
|
SetDueDateSuggestion
|
||||||
|
|
||||||
|
|
||||||
|
renderMailForm : Model -> Html Msg
|
||||||
|
renderMailForm model =
|
||||||
|
div
|
||||||
|
[ classList
|
||||||
|
[ ( "ui bottom attached segment", True )
|
||||||
|
, ( "invisible hidden", not model.mailOpen )
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[ h4 [ class "ui header" ]
|
||||||
|
[ text "Send this item via E-Mail"
|
||||||
|
]
|
||||||
|
, Html.map ItemMailMsg (Comp.ItemMail.view model.itemMail)
|
||||||
|
]
|
||||||
|
225
modules/webapp/src/main/elm/Comp/ItemMail.elm
Normal file
225
modules/webapp/src/main/elm/Comp/ItemMail.elm
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
module Comp.ItemMail exposing
|
||||||
|
( FormAction(..)
|
||||||
|
, Model
|
||||||
|
, Msg
|
||||||
|
, clear
|
||||||
|
, emptyModel
|
||||||
|
, init
|
||||||
|
, update
|
||||||
|
, view
|
||||||
|
)
|
||||||
|
|
||||||
|
import Api
|
||||||
|
import Api.Model.EmailSettingsList exposing (EmailSettingsList)
|
||||||
|
import Api.Model.SimpleMail exposing (SimpleMail)
|
||||||
|
import Comp.Dropdown
|
||||||
|
import Data.Flags exposing (Flags)
|
||||||
|
import Html exposing (..)
|
||||||
|
import Html.Attributes exposing (..)
|
||||||
|
import Html.Events exposing (onCheck, onClick, onInput)
|
||||||
|
import Http
|
||||||
|
import Util.Http
|
||||||
|
|
||||||
|
|
||||||
|
type alias Model =
|
||||||
|
{ connectionModel : Comp.Dropdown.Model String
|
||||||
|
, subject : String
|
||||||
|
, receiver : String
|
||||||
|
, body : String
|
||||||
|
, attachAll : Bool
|
||||||
|
, formError : Maybe String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Msg
|
||||||
|
= SetSubject String
|
||||||
|
| SetReceiver String
|
||||||
|
| SetBody String
|
||||||
|
| ConnMsg (Comp.Dropdown.Msg String)
|
||||||
|
| ConnResp (Result Http.Error EmailSettingsList)
|
||||||
|
| ToggleAttachAll
|
||||||
|
| Cancel
|
||||||
|
| Send
|
||||||
|
|
||||||
|
|
||||||
|
type FormAction
|
||||||
|
= FormSend SimpleMail
|
||||||
|
| FormCancel
|
||||||
|
| FormNone
|
||||||
|
|
||||||
|
|
||||||
|
emptyModel : Model
|
||||||
|
emptyModel =
|
||||||
|
{ connectionModel =
|
||||||
|
Comp.Dropdown.makeSingle
|
||||||
|
{ makeOption = \a -> { value = a, text = a }
|
||||||
|
, placeholder = "Select connection..."
|
||||||
|
}
|
||||||
|
, subject = ""
|
||||||
|
, receiver = ""
|
||||||
|
, body = ""
|
||||||
|
, attachAll = True
|
||||||
|
, formError = Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
init : Flags -> ( Model, Cmd Msg )
|
||||||
|
init flags =
|
||||||
|
( emptyModel, Api.getMailSettings flags "" ConnResp )
|
||||||
|
|
||||||
|
|
||||||
|
clear : Model -> Model
|
||||||
|
clear model =
|
||||||
|
{ model
|
||||||
|
| subject = ""
|
||||||
|
, receiver = ""
|
||||||
|
, body = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
update : Msg -> Model -> ( Model, FormAction )
|
||||||
|
update msg model =
|
||||||
|
case msg of
|
||||||
|
SetSubject str ->
|
||||||
|
( { model | subject = str }, FormNone )
|
||||||
|
|
||||||
|
SetReceiver str ->
|
||||||
|
( { model | receiver = str }, FormNone )
|
||||||
|
|
||||||
|
SetBody str ->
|
||||||
|
( { model | body = str }, FormNone )
|
||||||
|
|
||||||
|
ConnMsg m ->
|
||||||
|
let
|
||||||
|
( cm, _ ) =
|
||||||
|
--TODO dropdown doesn't use cmd!!
|
||||||
|
Comp.Dropdown.update m model.connectionModel
|
||||||
|
in
|
||||||
|
( { model | connectionModel = cm }, FormNone )
|
||||||
|
|
||||||
|
ToggleAttachAll ->
|
||||||
|
( { model | attachAll = not model.attachAll }, FormNone )
|
||||||
|
|
||||||
|
ConnResp (Ok list) ->
|
||||||
|
let
|
||||||
|
names =
|
||||||
|
List.map .name list.items
|
||||||
|
|
||||||
|
cm =
|
||||||
|
Comp.Dropdown.makeSingleList
|
||||||
|
{ makeOption = \a -> { value = a, text = a }
|
||||||
|
, placeholder = "Select Connection..."
|
||||||
|
, options = names
|
||||||
|
, selected = List.head names
|
||||||
|
}
|
||||||
|
in
|
||||||
|
( { model
|
||||||
|
| connectionModel = cm
|
||||||
|
, formError =
|
||||||
|
if names == [] then
|
||||||
|
Just "No E-Mail connections configured. Goto user settings to add one."
|
||||||
|
|
||||||
|
else
|
||||||
|
Nothing
|
||||||
|
}
|
||||||
|
, FormNone
|
||||||
|
)
|
||||||
|
|
||||||
|
ConnResp (Err err) ->
|
||||||
|
( { model | formError = Just (Util.Http.errorToString err) }, FormNone )
|
||||||
|
|
||||||
|
Cancel ->
|
||||||
|
( model, FormCancel )
|
||||||
|
|
||||||
|
Send ->
|
||||||
|
let
|
||||||
|
rec =
|
||||||
|
String.split "," model.receiver
|
||||||
|
|
||||||
|
sm =
|
||||||
|
SimpleMail rec model.subject model.body model.attachAll []
|
||||||
|
in
|
||||||
|
( model, FormSend sm )
|
||||||
|
|
||||||
|
|
||||||
|
isValid : Model -> Bool
|
||||||
|
isValid model =
|
||||||
|
model.receiver
|
||||||
|
/= ""
|
||||||
|
&& model.subject
|
||||||
|
/= ""
|
||||||
|
&& model.body
|
||||||
|
/= ""
|
||||||
|
&& model.formError
|
||||||
|
== Nothing
|
||||||
|
|
||||||
|
|
||||||
|
view : Model -> Html Msg
|
||||||
|
view model =
|
||||||
|
div
|
||||||
|
[ classList
|
||||||
|
[ ( "ui form", True )
|
||||||
|
, ( "error", model.formError /= Nothing )
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[ div [ class "field" ]
|
||||||
|
[ label [] [ text "Send via" ]
|
||||||
|
, Html.map ConnMsg (Comp.Dropdown.view model.connectionModel)
|
||||||
|
]
|
||||||
|
, div [ class "ui error message" ]
|
||||||
|
[ Maybe.withDefault "" model.formError |> text
|
||||||
|
]
|
||||||
|
, div [ class "field" ]
|
||||||
|
[ label []
|
||||||
|
[ text "Receiver(s)"
|
||||||
|
, span [ class "muted" ]
|
||||||
|
[ text "Separate multiple recipients by comma" ]
|
||||||
|
]
|
||||||
|
, input
|
||||||
|
[ type_ "text"
|
||||||
|
, onInput SetReceiver
|
||||||
|
, value model.receiver
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
, div [ class "field" ]
|
||||||
|
[ label [] [ text "Subject" ]
|
||||||
|
, input
|
||||||
|
[ type_ "text"
|
||||||
|
, onInput SetSubject
|
||||||
|
, value model.subject
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
, div [ class "field" ]
|
||||||
|
[ label [] [ text "Body" ]
|
||||||
|
, textarea [ onInput SetBody ]
|
||||||
|
[ text model.body ]
|
||||||
|
]
|
||||||
|
, div [ class "inline field" ]
|
||||||
|
[ div [ class "ui checkbox" ]
|
||||||
|
[ input
|
||||||
|
[ type_ "checkbox"
|
||||||
|
, checked model.attachAll
|
||||||
|
, onCheck (\_ -> ToggleAttachAll)
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
, label [] [ text "Include all item attachments" ]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, button
|
||||||
|
[ classList
|
||||||
|
[ ( "ui primary button", True )
|
||||||
|
, ( "disabled", not (isValid model) )
|
||||||
|
]
|
||||||
|
, onClick Send
|
||||||
|
]
|
||||||
|
[ text "Send"
|
||||||
|
]
|
||||||
|
, button
|
||||||
|
[ class "ui secondary button"
|
||||||
|
, onClick Cancel
|
||||||
|
]
|
||||||
|
[ text "Cancel"
|
||||||
|
]
|
||||||
|
]
|
@ -65,6 +65,12 @@
|
|||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label span.muted {
|
||||||
|
font-size: smaller;
|
||||||
|
color: rgba(0,0,0,0.6);
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
.ui.search.dropdown.open {
|
.ui.search.dropdown.open {
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user