mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-23 10:58:26 +00:00
Add mail form when creating shares
This commit is contained in:
@ -12,7 +12,9 @@ module Comp.ItemMail exposing
|
||||
, clear
|
||||
, emptyModel
|
||||
, init
|
||||
, setMailInfo
|
||||
, update
|
||||
, view
|
||||
, view2
|
||||
)
|
||||
|
||||
@ -28,7 +30,7 @@ import Data.Flags exposing (Flags)
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick, onInput)
|
||||
import Html.Events exposing (onClick, onFocus, onInput)
|
||||
import Http
|
||||
import Messages.Comp.ItemMail exposing (Texts)
|
||||
import Styles as S
|
||||
@ -61,6 +63,7 @@ type Msg
|
||||
| CCRecipientMsg Comp.EmailInput.Msg
|
||||
| BCCRecipientMsg Comp.EmailInput.Msg
|
||||
| SetBody String
|
||||
| SetSubjectBody String String
|
||||
| ConnMsg (Comp.Dropdown.Msg String)
|
||||
| ConnResp (Result Http.Error EmailSettingsList)
|
||||
| ToggleAttachAll
|
||||
@ -112,12 +115,20 @@ clear model =
|
||||
}
|
||||
|
||||
|
||||
setMailInfo : String -> String -> Msg
|
||||
setMailInfo subject body =
|
||||
SetSubjectBody subject body
|
||||
|
||||
|
||||
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, FormAction )
|
||||
update flags msg model =
|
||||
case msg of
|
||||
SetSubject str ->
|
||||
( { model | subject = str }, Cmd.none, FormNone )
|
||||
|
||||
SetSubjectBody subj body ->
|
||||
( { model | subject = subj, body = body }, Cmd.none, FormNone )
|
||||
|
||||
RecipientMsg m ->
|
||||
let
|
||||
( em, ec, rec ) =
|
||||
@ -239,8 +250,31 @@ isValid model =
|
||||
--- View2
|
||||
|
||||
|
||||
type alias ViewConfig =
|
||||
{ withAttachments : Bool
|
||||
, subjectTemplate : Maybe String
|
||||
, bodyTemplate : Maybe String
|
||||
, textAreaClass : String
|
||||
, showCancel : Bool
|
||||
}
|
||||
|
||||
|
||||
view2 : Texts -> UiSettings -> Model -> Html Msg
|
||||
view2 texts settings model =
|
||||
let
|
||||
cfg =
|
||||
{ withAttachments = True
|
||||
, subjectTemplate = Nothing
|
||||
, bodyTemplate = Nothing
|
||||
, textAreaClass = ""
|
||||
, showCancel = True
|
||||
}
|
||||
in
|
||||
view texts settings cfg model
|
||||
|
||||
|
||||
view : Texts -> UiSettings -> ViewConfig -> Model -> Html Msg
|
||||
view texts settings cfg model =
|
||||
let
|
||||
dds =
|
||||
Data.DropdownStyle.mainStyle
|
||||
@ -323,6 +357,11 @@ view2 texts settings model =
|
||||
[ type_ "text"
|
||||
, class S.textInput
|
||||
, onInput SetSubject
|
||||
, if model.subject == "" then
|
||||
onFocus (SetSubject <| Maybe.withDefault "" cfg.subjectTemplate)
|
||||
|
||||
else
|
||||
class ""
|
||||
, value model.subject
|
||||
]
|
||||
[]
|
||||
@ -334,18 +373,27 @@ view2 texts settings model =
|
||||
]
|
||||
, textarea
|
||||
[ onInput SetBody
|
||||
, value model.body
|
||||
, if model.body == "" then
|
||||
value <| Maybe.withDefault "" cfg.bodyTemplate
|
||||
|
||||
else
|
||||
value model.body
|
||||
, class S.textAreaInput
|
||||
, class cfg.textAreaClass
|
||||
]
|
||||
[]
|
||||
]
|
||||
, MB.viewItem <|
|
||||
MB.Checkbox
|
||||
{ tagger = \_ -> ToggleAttachAll
|
||||
, label = texts.includeAllAttachments
|
||||
, value = model.attachAll
|
||||
, id = "item-send-mail-attach-all"
|
||||
}
|
||||
, if cfg.withAttachments then
|
||||
MB.viewItem <|
|
||||
MB.Checkbox
|
||||
{ tagger = \_ -> ToggleAttachAll
|
||||
, label = texts.includeAllAttachments
|
||||
, value = model.attachAll
|
||||
, id = "item-send-mail-attach-all"
|
||||
}
|
||||
|
||||
else
|
||||
span [ class "hidden" ] []
|
||||
, div [ class "flex flex-row space-x-2" ]
|
||||
[ B.primaryButton
|
||||
{ label = texts.sendLabel
|
||||
@ -358,7 +406,10 @@ view2 texts settings model =
|
||||
{ label = texts.basics.cancel
|
||||
, icon = "fa fa-times"
|
||||
, handler = onClick Cancel
|
||||
, attrs = [ href "#" ]
|
||||
, attrs =
|
||||
[ href "#"
|
||||
, classList [ ( "hidden", not cfg.showCancel ) ]
|
||||
]
|
||||
, disabled = False
|
||||
}
|
||||
]
|
||||
|
@ -21,11 +21,13 @@ import Api.Model.ShareDetail exposing (ShareDetail)
|
||||
import Comp.Basic as B
|
||||
import Comp.MenuBar as MB
|
||||
import Comp.ShareForm
|
||||
import Comp.ShareMail
|
||||
import Comp.ShareView
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Icons as Icons
|
||||
import Data.ItemQuery exposing (ItemQuery)
|
||||
import Data.SearchMode exposing (SearchMode)
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Http
|
||||
@ -52,39 +54,54 @@ type FormError
|
||||
|
||||
type alias Model =
|
||||
{ formModel : Comp.ShareForm.Model
|
||||
, mailModel : Comp.ShareMail.Model
|
||||
, viewMode : ViewMode
|
||||
, formError : FormError
|
||||
, loading : Bool
|
||||
}
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
init : Flags -> ( Model, Cmd Msg )
|
||||
init flags =
|
||||
let
|
||||
( fm, fc ) =
|
||||
Comp.ShareForm.init
|
||||
|
||||
( mm, mc ) =
|
||||
Comp.ShareMail.init flags
|
||||
in
|
||||
( { formModel = fm
|
||||
, mailModel = mm
|
||||
, viewMode = ViewModeEdit
|
||||
, formError = FormErrorNone
|
||||
, loading = False
|
||||
}
|
||||
, Cmd.map FormMsg fc
|
||||
, Cmd.batch
|
||||
[ Cmd.map FormMsg fc
|
||||
, Cmd.map MailMsg mc
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
initQuery : ItemQuery -> ( Model, Cmd Msg )
|
||||
initQuery query =
|
||||
initQuery : Flags -> ItemQuery -> ( Model, Cmd Msg )
|
||||
initQuery flags query =
|
||||
let
|
||||
( fm, fc ) =
|
||||
Comp.ShareForm.initQuery (Data.ItemQuery.render query)
|
||||
|
||||
( mm, mc ) =
|
||||
Comp.ShareMail.init flags
|
||||
in
|
||||
( { formModel = fm
|
||||
, mailModel = mm
|
||||
, viewMode = ViewModeEdit
|
||||
, formError = FormErrorNone
|
||||
, loading = False
|
||||
}
|
||||
, Cmd.map FormMsg fc
|
||||
, Cmd.batch
|
||||
[ Cmd.map FormMsg fc
|
||||
, Cmd.map MailMsg mc
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@ -94,6 +111,7 @@ initQuery query =
|
||||
|
||||
type Msg
|
||||
= FormMsg Comp.ShareForm.Msg
|
||||
| MailMsg Comp.ShareMail.Msg
|
||||
| CancelPublish
|
||||
| SubmitPublish
|
||||
| PublishResp (Result Http.Error IdResult)
|
||||
@ -134,6 +152,17 @@ update flags msg model =
|
||||
, outcome = OutcomeInProgress
|
||||
}
|
||||
|
||||
MailMsg lm ->
|
||||
let
|
||||
( mm, mc ) =
|
||||
Comp.ShareMail.update flags lm model.mailModel
|
||||
in
|
||||
{ model = { model | mailModel = mm }
|
||||
, cmd = Cmd.map MailMsg mc
|
||||
, sub = Sub.none
|
||||
, outcome = OutcomeInProgress
|
||||
}
|
||||
|
||||
SubmitPublish ->
|
||||
case Comp.ShareForm.getShare model.formModel of
|
||||
Just ( _, data ) ->
|
||||
@ -173,13 +202,22 @@ update flags msg model =
|
||||
}
|
||||
|
||||
GetShareResp (Ok share) ->
|
||||
let
|
||||
( mm, mc ) =
|
||||
Comp.ShareMail.update flags (Comp.ShareMail.setMailInfo share) model.mailModel
|
||||
in
|
||||
{ model =
|
||||
{ model
|
||||
| formError = FormErrorNone
|
||||
, loading = False
|
||||
, viewMode = ViewModeInfo share
|
||||
, mailModel = mm
|
||||
}
|
||||
, cmd = Ports.initClipboard (Comp.ShareView.clipboardData share)
|
||||
, cmd =
|
||||
Cmd.batch
|
||||
[ Ports.initClipboard (Comp.ShareView.clipboardData share)
|
||||
, Cmd.map MailMsg mc
|
||||
]
|
||||
, sub = Sub.none
|
||||
, outcome = OutcomeInProgress
|
||||
}
|
||||
@ -196,8 +234,8 @@ update flags msg model =
|
||||
--- View
|
||||
|
||||
|
||||
view : Texts -> Flags -> Model -> Html Msg
|
||||
view texts flags model =
|
||||
view : Texts -> UiSettings -> Flags -> Model -> Html Msg
|
||||
view texts settings flags model =
|
||||
div []
|
||||
[ B.loadingDimmer
|
||||
{ active = model.loading
|
||||
@ -208,12 +246,12 @@ view texts flags model =
|
||||
viewForm texts model
|
||||
|
||||
ViewModeInfo share ->
|
||||
viewInfo texts flags model share
|
||||
viewInfo texts settings flags model share
|
||||
]
|
||||
|
||||
|
||||
viewInfo : Texts -> Flags -> Model -> ShareDetail -> Html Msg
|
||||
viewInfo texts flags model share =
|
||||
viewInfo : Texts -> UiSettings -> Flags -> Model -> ShareDetail -> Html Msg
|
||||
viewInfo texts settings flags model share =
|
||||
let
|
||||
cfg =
|
||||
{ mainClasses = ""
|
||||
@ -244,6 +282,15 @@ viewInfo texts flags model share =
|
||||
, div []
|
||||
[ Comp.ShareView.view cfg texts.shareView flags share
|
||||
]
|
||||
, div [ class "flex flex-col mt-6" ]
|
||||
[ div
|
||||
[ class S.header2
|
||||
]
|
||||
[ text texts.sendViaMail
|
||||
]
|
||||
, Html.map MailMsg
|
||||
(Comp.ShareMail.view texts.shareMail flags settings model.mailModel)
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
183
modules/webapp/src/main/elm/Comp/ShareMail.elm
Normal file
183
modules/webapp/src/main/elm/Comp/ShareMail.elm
Normal file
@ -0,0 +1,183 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Comp.ShareMail exposing (Model, Msg, init, setMailInfo, update, view)
|
||||
|
||||
import Api
|
||||
import Api.Model.BasicResult exposing (BasicResult)
|
||||
import Api.Model.ShareDetail exposing (ShareDetail)
|
||||
import Comp.Basic as B
|
||||
import Comp.ItemMail
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Http
|
||||
import Messages.Comp.ShareMail exposing (Texts)
|
||||
import Page exposing (Page(..))
|
||||
import Styles as S
|
||||
|
||||
|
||||
type FormState
|
||||
= FormStateNone
|
||||
| FormStateSubmit String
|
||||
| FormStateHttp Http.Error
|
||||
| FormStateSent
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ mailModel : Comp.ItemMail.Model
|
||||
, share : ShareDetail
|
||||
, sending : Bool
|
||||
, formState : FormState
|
||||
}
|
||||
|
||||
|
||||
init : Flags -> ( Model, Cmd Msg )
|
||||
init flags =
|
||||
let
|
||||
( mm, mc ) =
|
||||
Comp.ItemMail.init flags
|
||||
in
|
||||
( { mailModel = mm
|
||||
, share = Api.Model.ShareDetail.empty
|
||||
, sending = False
|
||||
, formState = FormStateNone
|
||||
}
|
||||
, Cmd.map MailMsg mc
|
||||
)
|
||||
|
||||
|
||||
type Msg
|
||||
= MailMsg Comp.ItemMail.Msg
|
||||
| SetMailInfo ShareDetail
|
||||
| SendMailResp (Result Http.Error BasicResult)
|
||||
|
||||
|
||||
|
||||
--- Update
|
||||
|
||||
|
||||
setMailInfo : ShareDetail -> Msg
|
||||
setMailInfo share =
|
||||
SetMailInfo share
|
||||
|
||||
|
||||
update : Flags -> Msg -> Model -> ( Model, Cmd Msg )
|
||||
update flags msg model =
|
||||
case msg of
|
||||
MailMsg lm ->
|
||||
let
|
||||
( mm, mc, fa ) =
|
||||
Comp.ItemMail.update flags lm model.mailModel
|
||||
|
||||
defaultResult =
|
||||
( { model | mailModel = mm }, Cmd.map MailMsg mc )
|
||||
in
|
||||
case fa of
|
||||
Comp.ItemMail.FormSend sm ->
|
||||
let
|
||||
mail =
|
||||
{ mail =
|
||||
{ shareId = model.share.id
|
||||
, recipients = sm.mail.recipients
|
||||
, cc = sm.mail.cc
|
||||
, bcc = sm.mail.bcc
|
||||
, subject = sm.mail.subject
|
||||
, body = sm.mail.body
|
||||
}
|
||||
, conn = sm.conn
|
||||
}
|
||||
in
|
||||
( { model | sending = True, mailModel = mm }
|
||||
, Cmd.batch
|
||||
[ Cmd.map MailMsg mc
|
||||
, Api.shareSendMail flags mail SendMailResp
|
||||
]
|
||||
)
|
||||
|
||||
Comp.ItemMail.FormNone ->
|
||||
defaultResult
|
||||
|
||||
Comp.ItemMail.FormCancel ->
|
||||
defaultResult
|
||||
|
||||
SetMailInfo share ->
|
||||
( { model | share = share }, Cmd.none )
|
||||
|
||||
SendMailResp (Ok res) ->
|
||||
if res.success then
|
||||
( { model
|
||||
| formState = FormStateSent
|
||||
, mailModel = Comp.ItemMail.clear model.mailModel
|
||||
, sending = False
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
else
|
||||
( { model
|
||||
| formState = FormStateSubmit res.message
|
||||
, sending = False
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
SendMailResp (Err err) ->
|
||||
( { model | formState = FormStateHttp err }, Cmd.none )
|
||||
|
||||
|
||||
|
||||
--- View
|
||||
|
||||
|
||||
view : Texts -> Flags -> UiSettings -> Model -> Html Msg
|
||||
view texts flags settings model =
|
||||
let
|
||||
url =
|
||||
flags.config.baseUrl ++ (Page.pageToString <| SharePage model.share.id)
|
||||
|
||||
subject =
|
||||
texts.subjectTemplate model.share.name
|
||||
|
||||
body =
|
||||
texts.bodyTemplate url
|
||||
|
||||
cfg =
|
||||
{ withAttachments = False
|
||||
, subjectTemplate = Just subject
|
||||
, bodyTemplate = Just body
|
||||
, textAreaClass = "h-52"
|
||||
, showCancel = False
|
||||
}
|
||||
in
|
||||
div [ class "relative" ]
|
||||
[ case model.formState of
|
||||
FormStateNone ->
|
||||
span [ class "hidden" ] []
|
||||
|
||||
FormStateSubmit msg ->
|
||||
div [ class S.errorMessage ]
|
||||
[ text msg
|
||||
]
|
||||
|
||||
FormStateHttp err ->
|
||||
div [ class S.errorMessage ]
|
||||
[ text (texts.httpError err)
|
||||
]
|
||||
|
||||
FormStateSent ->
|
||||
div [ class S.successMessage ]
|
||||
[ text "Mail sent."
|
||||
]
|
||||
, Html.map MailMsg
|
||||
(Comp.ItemMail.view texts.itemMail settings cfg model.mailModel)
|
||||
, B.loadingDimmer
|
||||
{ active = model.sending
|
||||
, label = ""
|
||||
}
|
||||
]
|
@ -16,14 +16,17 @@ import Comp.Basic as B
|
||||
import Comp.ItemDetail.Model exposing (Msg(..))
|
||||
import Comp.MenuBar as MB
|
||||
import Comp.ShareForm
|
||||
import Comp.ShareMail
|
||||
import Comp.ShareTable
|
||||
import Comp.ShareView
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick)
|
||||
import Http
|
||||
import Messages.Comp.ShareManage exposing (Texts)
|
||||
import Page exposing (Page(..))
|
||||
import Ports
|
||||
import Styles as S
|
||||
|
||||
@ -49,26 +52,34 @@ type alias Model =
|
||||
{ viewMode : ViewMode
|
||||
, shares : List ShareDetail
|
||||
, formModel : Comp.ShareForm.Model
|
||||
, mailModel : Comp.ShareMail.Model
|
||||
, loading : Bool
|
||||
, formError : FormError
|
||||
, deleteConfirm : DeleteConfirm
|
||||
}
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
init : Flags -> ( Model, Cmd Msg )
|
||||
init flags =
|
||||
let
|
||||
( fm, fc ) =
|
||||
Comp.ShareForm.init
|
||||
|
||||
( mm, mc ) =
|
||||
Comp.ShareMail.init flags
|
||||
in
|
||||
( { viewMode = Table
|
||||
, shares = []
|
||||
, formModel = fm
|
||||
, mailModel = mm
|
||||
, loading = False
|
||||
, formError = FormErrorNone
|
||||
, deleteConfirm = DeleteConfirmOff
|
||||
}
|
||||
, Cmd.map FormMsg fc
|
||||
, Cmd.batch
|
||||
[ Cmd.map FormMsg fc
|
||||
, Cmd.map MailMsg mc
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@ -76,6 +87,7 @@ type Msg
|
||||
= LoadShares
|
||||
| TableMsg Comp.ShareTable.Msg
|
||||
| FormMsg Comp.ShareForm.Msg
|
||||
| MailMsg Comp.ShareMail.Msg
|
||||
| InitNewShare
|
||||
| SetViewMode ViewMode
|
||||
| Submit
|
||||
@ -212,10 +224,20 @@ update flags msg model =
|
||||
DeleteShareResp (Err err) ->
|
||||
( { model | formError = FormErrorHttp err, loading = False }, Cmd.none, Sub.none )
|
||||
|
||||
MailMsg lm ->
|
||||
let
|
||||
( mm, mc ) =
|
||||
Comp.ShareMail.update flags lm model.mailModel
|
||||
in
|
||||
( { model | mailModel = mm }, Cmd.map MailMsg mc, Sub.none )
|
||||
|
||||
|
||||
setShare : ShareDetail -> Flags -> Model -> ( Model, Cmd Msg, Sub Msg )
|
||||
setShare share flags model =
|
||||
let
|
||||
shareUrl =
|
||||
flags.config.baseUrl ++ Page.pageToString (SharePage share.id)
|
||||
|
||||
nextModel =
|
||||
{ model | formError = FormErrorNone, viewMode = Form, loading = False }
|
||||
|
||||
@ -224,21 +246,24 @@ setShare share flags model =
|
||||
|
||||
( nm, nc, ns ) =
|
||||
update flags (FormMsg <| Comp.ShareForm.setShare share) nextModel
|
||||
|
||||
( nm2, nc2, ns2 ) =
|
||||
update flags (MailMsg <| Comp.ShareMail.setMailInfo share) nm
|
||||
in
|
||||
( nm, Cmd.batch [ initClipboard, nc ], ns )
|
||||
( nm2, Cmd.batch [ initClipboard, nc, nc2 ], Sub.batch [ ns, ns2 ] )
|
||||
|
||||
|
||||
|
||||
--- view
|
||||
|
||||
|
||||
view : Texts -> Flags -> Model -> Html Msg
|
||||
view texts flags model =
|
||||
view : Texts -> UiSettings -> Flags -> Model -> Html Msg
|
||||
view texts settings flags model =
|
||||
if model.viewMode == Table then
|
||||
viewTable texts model
|
||||
|
||||
else
|
||||
viewForm texts flags model
|
||||
viewForm texts settings flags model
|
||||
|
||||
|
||||
viewTable : Texts -> Model -> Html Msg
|
||||
@ -265,13 +290,13 @@ viewTable texts model =
|
||||
]
|
||||
|
||||
|
||||
viewForm : Texts -> Flags -> Model -> Html Msg
|
||||
viewForm texts flags model =
|
||||
viewForm : Texts -> UiSettings -> Flags -> Model -> Html Msg
|
||||
viewForm texts settings flags model =
|
||||
let
|
||||
newShare =
|
||||
model.formModel.share.id == ""
|
||||
in
|
||||
div [ class "relative" ]
|
||||
div []
|
||||
[ Html.form []
|
||||
[ if newShare then
|
||||
h1 [ class S.header2 ]
|
||||
@ -367,6 +392,7 @@ viewForm texts flags model =
|
||||
)
|
||||
]
|
||||
, shareInfo texts flags model.formModel.share
|
||||
, shareSendMail texts flags settings model
|
||||
]
|
||||
|
||||
|
||||
@ -376,8 +402,34 @@ shareInfo texts flags share =
|
||||
[ class "mt-6"
|
||||
, classList [ ( "hidden", share.id == "" ) ]
|
||||
]
|
||||
[ h2 [ class S.header2 ]
|
||||
[ h2
|
||||
[ class S.header2
|
||||
, class "border-b-2 dark:border-bluegray-600"
|
||||
]
|
||||
[ text texts.shareInformation
|
||||
]
|
||||
, Comp.ShareView.viewDefault texts.shareView flags share
|
||||
]
|
||||
|
||||
|
||||
shareSendMail : Texts -> Flags -> UiSettings -> Model -> Html Msg
|
||||
shareSendMail texts flags settings model =
|
||||
let
|
||||
share =
|
||||
model.formModel.share
|
||||
in
|
||||
div
|
||||
[ class "mt-8 mb-2"
|
||||
, classList [ ( "hidden", share.id == "" || not share.enabled || share.expired ) ]
|
||||
]
|
||||
[ h2
|
||||
[ class S.header2
|
||||
, class "border-b-2 dark:border-bluegray-600"
|
||||
]
|
||||
[ text "Send via E-Mail"
|
||||
]
|
||||
, div [ class "px-2 py-2 dark:border-bluegray-600" ]
|
||||
[ Html.map MailMsg
|
||||
(Comp.ShareMail.view texts.shareMail flags settings model.mailModel)
|
||||
]
|
||||
]
|
||||
|
@ -1,3 +1,10 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Comp.SharePasswordForm exposing (Model, Msg, init, update, view)
|
||||
|
||||
import Api
|
||||
|
@ -1,3 +1,10 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Comp.UrlCopy exposing (..)
|
||||
|
||||
import Comp.Basic as B
|
||||
|
Reference in New Issue
Block a user