Manage notification channels separately and migrate

It's more convenient to manage notification channels separately, as it
is done with email settings. Notification hook and other forms are
adopted to only select channels. Hooks can now use more than one
channel.
This commit is contained in:
eikek
2022-01-19 21:51:18 +01:00
parent d41490dd88
commit 23cb34a6ff
78 changed files with 2583 additions and 1422 deletions

View File

@ -48,17 +48,11 @@ type alias HttpModel =
}
type alias RefModel =
{ channelType : ChannelType
}
type Model
= Matrix MatrixModel
| Gotify GotifyModel
| Mail MailModel
| Http HttpModel
| Ref RefModel
type Msg
@ -147,11 +141,6 @@ initWith flags channel =
, Cmd.none
)
Data.NotificationChannel.Ref m ->
( Ref { channelType = m.channelType }
, Cmd.none
)
channelType : Model -> ChannelType
channelType model =
@ -168,9 +157,6 @@ channelType model =
Http _ ->
Data.ChannelType.Http
Ref ref ->
ref.channelType
getChannel : Model -> Maybe NotificationChannel
getChannel model =
@ -187,9 +173,6 @@ getChannel model =
Http mm ->
Maybe.map Data.NotificationChannel.Http mm.value
Ref _ ->
Nothing
--- Update
@ -269,12 +252,3 @@ view texts settings model =
Http m ->
Html.map HttpMsg
(Comp.NotificationHttpForm.view texts.httpForm m.form)
-- Note: currently when retrieving hooks, this is not
-- send from the server. The server always sends
-- concrete channel details. However, it is possible
-- to create hooks with a reference to an existing
-- channel, but this is not supported in this client.
-- So this channel is ignored here.
Ref _ ->
span [ class "hidden" ] []

View File

@ -0,0 +1,154 @@
{-
Copyright 2020 Eike K. & Contributors
SPDX-License-Identifier: AGPL-3.0-or-later
-}
module Comp.ChannelRefInput exposing (Model, Msg, getSelected, init, initSelected, initWith, setOptions, setSelected, update, view)
import Api
import Api.Model.NotificationChannelRef exposing (NotificationChannelRef)
import Comp.Dropdown exposing (Option)
import Data.ChannelType
import Data.DropdownStyle
import Data.Flags exposing (Flags)
import Data.NotificationChannel
import Data.UiSettings exposing (UiSettings)
import Html exposing (Html)
import Messages.Comp.ChannelRefInput exposing (Texts)
import Util.String
type alias Model =
{ ddm : Comp.Dropdown.Model NotificationChannelRef
, all : List NotificationChannelRef
}
type Msg
= DropdownMsg (Comp.Dropdown.Msg NotificationChannelRef)
| LoadChannelsResp (List NotificationChannelRef)
emptyModel : Model
emptyModel =
{ ddm = makeDropdownModel
, all = []
}
init : Flags -> ( Model, Cmd Msg )
init flags =
( emptyModel, getOptions flags )
getOptions : Flags -> Cmd Msg
getOptions flags =
Api.getChannelsIgnoreError flags (List.map Data.NotificationChannel.getRef >> LoadChannelsResp)
setOptions : List NotificationChannelRef -> Msg
setOptions refs =
LoadChannelsResp refs
initSelected : Flags -> List NotificationChannelRef -> ( Model, Cmd Msg )
initSelected flags selected =
( update (setSelected selected) emptyModel
|> Tuple.first
, getOptions flags
)
initWith : List NotificationChannelRef -> List NotificationChannelRef -> Model
initWith options selected =
update (setSelected selected) emptyModel
|> Tuple.first
|> update (setOptions options)
|> Tuple.first
getSelected : Model -> List NotificationChannelRef
getSelected model =
Comp.Dropdown.getSelected model.ddm
setSelected : List NotificationChannelRef -> Msg
setSelected refs =
DropdownMsg (Comp.Dropdown.SetSelection refs)
--- Update
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
DropdownMsg lm ->
let
( dm, dc ) =
Comp.Dropdown.update lm model.ddm
in
( { model | ddm = dm }
, Cmd.map DropdownMsg dc
)
LoadChannelsResp refs ->
let
( dm, dc ) =
Comp.Dropdown.update (Comp.Dropdown.SetOptions refs) model.ddm
in
( { model
| all = refs
, ddm = dm
}
, Cmd.map DropdownMsg dc
)
--- View
view : Texts -> UiSettings -> Model -> Html Msg
view texts settings model =
let
idShort id =
String.slice 0 6 id
joinName name ct =
Option (ct ++ " (" ++ name ++ ")") ""
mkName ref =
Data.ChannelType.fromString ref.channelType
|> Maybe.map texts.channelType
|> Maybe.withDefault ref.channelType
|> joinName (Maybe.withDefault (idShort ref.id) ref.name)
viewCfg =
{ makeOption = mkName
, placeholder = texts.placeholder
, labelColor = \_ -> \_ -> ""
, style = Data.DropdownStyle.mainStyle
}
in
Html.map DropdownMsg
(Comp.Dropdown.view2 viewCfg settings model.ddm)
--- Helpers
makeDropdownModel : Comp.Dropdown.Model NotificationChannelRef
makeDropdownModel =
let
m =
Comp.Dropdown.makeModel
{ multiple = True
, searchable = \n -> n > 0
}
in
{ m | searchWithAdditional = True }

View File

@ -16,22 +16,18 @@ module Comp.DueItemsTaskForm exposing
)
import Api
import Api.Model.EmailSettingsList exposing (EmailSettingsList)
import Api.Model.Tag exposing (Tag)
import Api.Model.PeriodicDueItemsSettings exposing (PeriodicDueItemsSettings)
import Api.Model.TagList exposing (TagList)
import Comp.Basic as B
import Comp.CalEventInput
import Comp.ChannelForm
import Comp.ChannelRefInput
import Comp.IntField
import Comp.MenuBar as MB
import Comp.TagDropdown
import Comp.YesNoDimmer
import Data.CalEvent exposing (CalEvent)
import Data.ChannelType exposing (ChannelType)
import Data.DropdownStyle as DS
import Data.Flags exposing (Flags)
import Data.NotificationChannel
import Data.PeriodicDueItemsSettings exposing (PeriodicDueItemsSettings)
import Data.TagOrder
import Data.UiSettings exposing (UiSettings)
import Data.Validated exposing (Validated(..))
@ -43,13 +39,11 @@ import Markdown
import Messages.Comp.DueItemsTaskForm exposing (Texts)
import Styles as S
import Util.Maybe
import Util.Tag
import Util.Update
type alias Model =
{ settings : PeriodicDueItemsSettings
, channelModel : Comp.ChannelForm.Model
, channelModel : Comp.ChannelRefInput.Model
, tagInclModel : Comp.TagDropdown.Model
, tagExclModel : Comp.TagDropdown.Model
, remindDays : Maybe Int
@ -99,18 +93,14 @@ type Msg
| RequestDelete
| YesNoDeleteMsg Comp.YesNoDimmer.Msg
| SetSummary String
| ChannelMsg Comp.ChannelForm.Msg
| ChannelMsg Comp.ChannelRefInput.Msg
initWith : Flags -> PeriodicDueItemsSettings -> ( Model, Cmd Msg )
initWith flags s =
let
ct =
Data.NotificationChannel.channelType s.channel
|> Maybe.withDefault Data.ChannelType.Matrix
( im, ic ) =
init flags ct
init flags
newSchedule =
Data.CalEvent.fromEvent s.schedule
@ -120,7 +110,7 @@ initWith flags s =
Comp.CalEventInput.init flags newSchedule
( cfm, cfc ) =
Comp.ChannelForm.initWith flags s.channel
Comp.ChannelRefInput.initSelected flags s.channels
in
( { im
| settings = s
@ -145,8 +135,8 @@ initWith flags s =
)
init : Flags -> ChannelType -> ( Model, Cmd Msg )
init flags ct =
init : Flags -> ( Model, Cmd Msg )
init flags =
let
initialSchedule =
Data.CalEvent.everyMonth
@ -155,9 +145,9 @@ init flags ct =
Comp.CalEventInput.init flags initialSchedule
( cfm, cfc ) =
Comp.ChannelForm.init flags ct
Comp.ChannelRefInput.init flags
in
( { settings = Data.PeriodicDueItemsSettings.empty ct
( { settings = Api.Model.PeriodicDueItemsSettings.empty
, channelModel = cfm
, tagInclModel = Comp.TagDropdown.initWith [] []
, tagExclModel = Comp.TagDropdown.initWith [] []
@ -203,11 +193,17 @@ makeSettings model =
Err ValidateCalEventInvalid
channelM =
Result.fromMaybe
ValidateChannelRequired
(Comp.ChannelForm.getChannel model.channelModel)
let
list =
Comp.ChannelRefInput.getSelected model.channelModel
in
if list == [] then
Err ValidateChannelRequired
make days timer channel =
else
Ok list
make days timer channels =
{ prev
| tagsInclude = Comp.TagDropdown.getSelected model.tagInclModel
, tagsExclude = Comp.TagDropdown.getSelected model.tagExclModel
@ -216,7 +212,7 @@ makeSettings model =
, enabled = model.enabled
, schedule = Data.CalEvent.makeEvent timer
, summary = model.summary
, channel = channel
, channels = channels
}
in
Result.map3 make
@ -247,7 +243,7 @@ update flags msg model =
ChannelMsg lm ->
let
( cfm, cfc ) =
Comp.ChannelForm.update flags lm model.channelModel
Comp.ChannelRefInput.update lm model.channelModel
in
( { model | channelModel = cfm }
, NoAction
@ -538,9 +534,9 @@ view2 texts extraClasses settings model =
]
]
, div [ class "mb-4" ]
[ formHeader (texts.channelHeader (Comp.ChannelForm.channelType model.channelModel))
[ formHeader texts.channelHeader
, Html.map ChannelMsg
(Comp.ChannelForm.view texts.channelForm settings model.channelModel)
(Comp.ChannelRefInput.view texts.channelRef settings model.channelModel)
]
, formHeader texts.queryLabel
, div [ class "mb-4" ]

View File

@ -14,15 +14,16 @@ module Comp.DueItemsTaskList exposing
, view2
)
import Api.Model.PeriodicDueItemsSettings exposing (PeriodicDueItemsSettings)
import Comp.Basic as B
import Data.ChannelRef
import Data.ChannelType
import Data.NotificationChannel
import Data.PeriodicDueItemsSettings exposing (PeriodicDueItemsSettings)
import Html exposing (..)
import Html.Attributes exposing (..)
import Messages.Comp.DueItemsTaskList exposing (Texts)
import Styles as S
import Util.Html
import Util.List
type alias Model =
@ -94,9 +95,7 @@ viewItem2 texts item =
]
]
, td [ class "text-left mr-2" ]
[ Data.NotificationChannel.channelType item.channel
|> Maybe.map Data.ChannelType.asString
|> Maybe.withDefault "-"
|> text
[ div [ class " space-x-1" ]
(Data.ChannelRef.asDivs texts.channelType [ class "inline" ] item.channels)
]
]

View File

@ -15,13 +15,11 @@ module Comp.DueItemsTaskManage exposing
import Api
import Api.Model.BasicResult exposing (BasicResult)
import Comp.ChannelMenu
import Api.Model.PeriodicDueItemsSettings exposing (PeriodicDueItemsSettings)
import Comp.DueItemsTaskForm
import Comp.DueItemsTaskList
import Comp.MenuBar as MB
import Data.ChannelType exposing (ChannelType)
import Data.Flags exposing (Flags)
import Data.PeriodicDueItemsSettings exposing (PeriodicDueItemsSettings)
import Data.UiSettings exposing (UiSettings)
import Html exposing (..)
import Html.Attributes exposing (..)
@ -35,7 +33,6 @@ type alias Model =
, detailModel : Maybe Comp.DueItemsTaskForm.Model
, items : List PeriodicDueItemsSettings
, formState : FormState
, channelMenuOpen : Bool
}
@ -57,9 +54,8 @@ type Msg
= ListMsg Comp.DueItemsTaskList.Msg
| DetailMsg Comp.DueItemsTaskForm.Msg
| GetDataResp (Result Http.Error (List PeriodicDueItemsSettings))
| NewTaskInit ChannelType
| NewTaskInit
| SubmitResp SubmitType (Result Http.Error BasicResult)
| ToggleChannelMenu
initModel : Model
@ -68,7 +64,6 @@ initModel =
, detailModel = Nothing
, items = []
, formState = FormStateInitial
, channelMenuOpen = False
}
@ -89,11 +84,6 @@ init flags =
update : Flags -> Msg -> Model -> ( Model, Cmd Msg )
update flags msg model =
case msg of
ToggleChannelMenu ->
( { model | channelMenuOpen = not model.channelMenuOpen }
, Cmd.none
)
GetDataResp (Ok items) ->
( { model
| items = items
@ -194,12 +184,12 @@ update flags msg model =
Nothing ->
( model, Cmd.none )
NewTaskInit ct ->
NewTaskInit ->
let
( mm, mc ) =
Comp.DueItemsTaskForm.init flags ct
Comp.DueItemsTaskForm.init flags
in
( { model | detailModel = Just mm, channelMenuOpen = False }, Cmd.map DetailMsg mc )
( { model | detailModel = Just mm }, Cmd.map DetailMsg mc )
SubmitResp submitType (Ok res) ->
( { model
@ -295,18 +285,15 @@ viewForm2 texts settings model =
viewList2 : Texts -> Model -> List (Html Msg)
viewList2 texts model =
let
menuModel =
{ menuOpen = model.channelMenuOpen
, toggleMenu = ToggleChannelMenu
, menuLabel = texts.newTask
, onItem = NewTaskInit
}
in
[ MB.view
{ start = []
, end =
[ Comp.ChannelMenu.channelMenu texts.channelType menuModel
[ MB.PrimaryButton
{ tagger = NewTaskInit
, title = texts.newTask
, icon = Just "fa fa-plus"
, label = texts.newTask
}
]
, rootClasses = "mb-4"
}

View File

@ -115,8 +115,8 @@ dropdownCfg texts =
}
viewJson : Texts -> Model -> Html Msg
viewJson texts model =
viewJson : Texts -> Bool -> Model -> Html Msg
viewJson texts enableEventChooser model =
let
json =
Result.withDefault ""
@ -125,7 +125,10 @@ viewJson texts model =
div
[ class "flex flex-col w-full relative"
]
[ div [ class "flex inline-flex items-center absolute top-2 right-4" ]
[ div
[ class "flex inline-flex items-center absolute top-2 right-4"
, classList [ ( "hidden", not enableEventChooser ) ]
]
[ Html.map EventTypeMsg
(Comp.FixedDropdown.viewStyled2 (dropdownCfg texts)
False
@ -144,8 +147,8 @@ viewJson texts model =
]
viewMessage : Texts -> Model -> Html Msg
viewMessage texts model =
viewMessage : Texts -> Bool -> Model -> Html Msg
viewMessage texts enableEventChooser model =
let
titleDecoder =
D.at [ "message", "title" ] D.string
@ -162,7 +165,10 @@ viewMessage texts model =
div
[ class "flex flex-col w-full relative"
]
[ div [ class "flex inline-flex items-center absolute top-2 right-4" ]
[ div
[ class "flex inline-flex items-center absolute top-2 right-4"
, classList [ ( "hidden", not enableEventChooser ) ]
]
[ Html.map EventTypeMsg
(Comp.FixedDropdown.viewStyled2 (dropdownCfg texts)
False

View File

@ -0,0 +1,454 @@
{-
Copyright 2020 Eike K. & Contributors
SPDX-License-Identifier: AGPL-3.0-or-later
-}
module Comp.NotificationChannelManage exposing
( Model
, Msg
, init
, update
, view
)
import Api
import Api.Model.BasicResult exposing (BasicResult)
import Comp.Basic as B
import Comp.ChannelForm
import Comp.ChannelMenu
import Comp.MenuBar as MB
import Comp.NotificationChannelTable
import Data.ChannelType exposing (ChannelType)
import Data.Flags exposing (Flags)
import Data.NotificationChannel exposing (NotificationChannel)
import Data.UiSettings exposing (UiSettings)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Http
import Messages.Comp.NotificationChannelManage exposing (Texts)
import Styles as S
type alias Model =
{ listModel : Comp.NotificationChannelTable.Model
, detailModel : Maybe Comp.ChannelForm.Model
, items : List NotificationChannel
, deleteConfirm : DeleteConfirm
, loading : Bool
, formState : FormState
, newChannelMenuOpen : Bool
, jsonFilterError : Maybe String
}
type DeleteConfirm
= DeleteConfirmOff
| DeleteConfirmOn
type SubmitType
= SubmitDelete
| SubmitUpdate
| SubmitCreate
type FormState
= FormStateInitial
| FormErrorHttp Http.Error
| FormSubmitSuccessful SubmitType
| FormErrorSubmit String
| FormErrorInvalid
type Msg
= TableMsg Comp.NotificationChannelTable.Msg
| DetailMsg Comp.ChannelForm.Msg
| GetDataResp (Result Http.Error (List NotificationChannel))
| ToggleNewChannelMenu
| SubmitResp SubmitType (Result Http.Error BasicResult)
| NewChannelInit ChannelType
| BackToTable
| Submit
| RequestDelete
| CancelDelete
| DeleteChannelNow String
initModel : Model
initModel =
{ listModel = Comp.NotificationChannelTable.init
, detailModel = Nothing
, items = []
, loading = False
, formState = FormStateInitial
, newChannelMenuOpen = False
, deleteConfirm = DeleteConfirmOff
, jsonFilterError = Nothing
}
initCmd : Flags -> Cmd Msg
initCmd flags =
Api.getChannels flags GetDataResp
init : Flags -> ( Model, Cmd Msg )
init flags =
( initModel, initCmd flags )
--- Update
update : Flags -> Msg -> Model -> ( Model, Cmd Msg )
update flags msg model =
case msg of
GetDataResp (Ok res) ->
( { model
| items = res
, formState = FormStateInitial
}
, Cmd.none
)
GetDataResp (Err err) ->
( { model | formState = FormErrorHttp err }
, Cmd.none
)
TableMsg lm ->
let
( mm, action ) =
Comp.NotificationChannelTable.update flags lm model.listModel
( detail, cmd ) =
case action of
Comp.NotificationChannelTable.NoAction ->
( Nothing, Cmd.none )
Comp.NotificationChannelTable.EditAction channel ->
let
( dm, dc ) =
Comp.ChannelForm.initWith flags channel
in
( Just dm, Cmd.map DetailMsg dc )
in
( { model
| listModel = mm
, detailModel = detail
}
, cmd
)
DetailMsg lm ->
case model.detailModel of
Just dm ->
let
( mm, mc ) =
Comp.ChannelForm.update flags lm dm
in
( { model | detailModel = Just mm }
, Cmd.map DetailMsg mc
)
Nothing ->
( model, Cmd.none )
ToggleNewChannelMenu ->
( { model | newChannelMenuOpen = not model.newChannelMenuOpen }, Cmd.none )
SubmitResp submitType (Ok res) ->
( { model
| formState =
if res.success then
FormSubmitSuccessful submitType
else
FormErrorSubmit res.message
, detailModel =
if submitType == SubmitDelete then
Nothing
else
model.detailModel
, loading = False
}
, if submitType == SubmitDelete then
initCmd flags
else
Cmd.none
)
SubmitResp _ (Err err) ->
( { model | formState = FormErrorHttp err, loading = False }
, Cmd.none
)
NewChannelInit ct ->
let
( mm, mc ) =
Comp.ChannelForm.init flags ct
in
( { model | detailModel = Just mm, newChannelMenuOpen = False }, Cmd.map DetailMsg mc )
BackToTable ->
( { model | detailModel = Nothing }, initCmd flags )
Submit ->
case model.detailModel of
Just dm ->
case Comp.ChannelForm.getChannel dm of
Just data ->
postChannel flags data model
Nothing ->
( { model | formState = FormErrorInvalid }, Cmd.none )
Nothing ->
( model, Cmd.none )
RequestDelete ->
( { model | deleteConfirm = DeleteConfirmOn }, Cmd.none )
CancelDelete ->
( { model | deleteConfirm = DeleteConfirmOff }, Cmd.none )
DeleteChannelNow id ->
( { model | deleteConfirm = DeleteConfirmOff, loading = True }
, Api.deleteChannel flags id (SubmitResp SubmitDelete)
)
postChannel : Flags -> NotificationChannel -> Model -> ( Model, Cmd Msg )
postChannel flags channel model =
if (Data.NotificationChannel.getRef channel |> .id) == "" then
( { model | loading = True }, Api.createChannel flags channel (SubmitResp SubmitCreate) )
else
( { model | loading = True }, Api.updateChannel flags channel (SubmitResp SubmitUpdate) )
--- View2
view : Texts -> UiSettings -> Model -> Html Msg
view texts settings model =
div [ class "flex flex-col" ]
(case model.detailModel of
Just msett ->
viewForm texts settings model msett
Nothing ->
viewList texts model
)
viewState : Texts -> Model -> Html Msg
viewState texts model =
div
[ classList
[ ( S.errorMessage, not (isSuccess model.formState) )
, ( S.successMessage, isSuccess model.formState )
, ( "hidden", model.formState == FormStateInitial )
]
, class "mb-2"
]
[ case model.formState of
FormStateInitial ->
text ""
FormSubmitSuccessful SubmitCreate ->
text texts.channelCreated
FormSubmitSuccessful SubmitUpdate ->
text texts.channelUpdated
FormSubmitSuccessful SubmitDelete ->
text texts.channelDeleted
FormErrorSubmit m ->
text m
FormErrorHttp err ->
text (texts.httpError err)
FormErrorInvalid ->
text texts.formInvalid
]
isSuccess : FormState -> Bool
isSuccess state =
case state of
FormSubmitSuccessful _ ->
True
_ ->
False
viewForm : Texts -> UiSettings -> Model -> Comp.ChannelForm.Model -> List (Html Msg)
viewForm texts settings outerModel model =
let
channelId =
Comp.ChannelForm.getChannel model
|> Maybe.map Data.NotificationChannel.getRef
|> Maybe.map .id
newChannel =
channelId |> (==) (Just "")
headline =
case Comp.ChannelForm.channelType model of
Data.ChannelType.Matrix ->
span []
[ text texts.integrate
, a
[ href "https://matrix.org"
, target "_blank"
, class S.link
, class "mx-3"
]
[ i [ class "fa fa-external-link-alt mr-1" ] []
, text "Matrix"
]
, text texts.intoDocspell
]
Data.ChannelType.Mail ->
span []
[ text texts.notifyEmailInfo
]
Data.ChannelType.Gotify ->
span []
[ text texts.integrate
, a
[ href "https://gotify.net"
, target "_blank"
, class S.link
, class "mx-3"
]
[ i [ class "fa fa-external-link-alt mr-1" ] []
, text "Gotify"
]
, text texts.intoDocspell
]
Data.ChannelType.Http ->
span []
[ text texts.postRequestInfo
]
in
[ h1 [ class S.header2 ]
[ Data.ChannelType.icon (Comp.ChannelForm.channelType model) "w-8 h-8 inline-block mr-2"
, if newChannel then
text texts.addChannel
else
text texts.updateChannel
, div [ class "text-xs opacity-50 font-mono" ]
[ Maybe.withDefault "" channelId |> text
]
]
, div [ class "pt-2 pb-4 font-medium" ]
[ headline
]
, MB.view
{ start =
[ MB.CustomElement <|
B.primaryButton
{ handler = onClick Submit
, title = texts.basics.submitThisForm
, icon = "fa fa-save"
, label = texts.basics.submit
, disabled = False
, attrs = [ href "#" ]
}
, MB.SecondaryButton
{ tagger = BackToTable
, title = texts.basics.backToList
, icon = Just "fa fa-arrow-left"
, label = texts.basics.backToList
}
]
, end =
if not newChannel then
[ MB.DeleteButton
{ tagger = RequestDelete
, title = texts.deleteThisChannel
, icon = Just "fa fa-trash"
, label = texts.basics.delete
}
]
else
[]
, rootClasses = "mb-4"
}
, div [ class "mt-2" ]
[ viewState texts outerModel
]
, Html.map DetailMsg
(Comp.ChannelForm.view texts.notificationForm settings model)
, B.loadingDimmer
{ active = outerModel.loading
, label = texts.basics.loading
}
, B.contentDimmer
(outerModel.deleteConfirm == DeleteConfirmOn)
(div [ class "flex flex-col" ]
[ div [ class "text-lg" ]
[ i [ class "fa fa-info-circle mr-2" ] []
, text texts.reallyDeleteChannel
]
, div [ class "mt-4 flex flex-row items-center" ]
[ B.deleteButton
{ label = texts.basics.yes
, icon = "fa fa-check"
, disabled = False
, handler = onClick (DeleteChannelNow (Maybe.withDefault "" channelId))
, attrs = [ href "#" ]
}
, B.secondaryButton
{ label = texts.basics.no
, icon = "fa fa-times"
, disabled = False
, handler = onClick CancelDelete
, attrs = [ href "#", class "ml-2" ]
}
]
]
)
]
viewList : Texts -> Model -> List (Html Msg)
viewList texts model =
let
menuModel =
{ menuOpen = model.newChannelMenuOpen
, toggleMenu = ToggleNewChannelMenu
, menuLabel = texts.newChannel
, onItem = NewChannelInit
}
in
[ MB.view
{ start = []
, end =
[ Comp.ChannelMenu.channelMenu texts.channelType menuModel
]
, rootClasses = "mb-4"
}
, Html.map TableMsg
(Comp.NotificationChannelTable.view texts.notificationTable
model.listModel
model.items
)
]

View File

@ -0,0 +1,87 @@
{-
Copyright 2020 Eike K. & Contributors
SPDX-License-Identifier: AGPL-3.0-or-later
-}
module Comp.NotificationChannelTable exposing (..)
import Comp.Basic as B
import Data.ChannelType
import Data.Flags exposing (Flags)
import Data.NotificationChannel exposing (NotificationChannel)
import Html exposing (..)
import Html.Attributes exposing (..)
import Messages.Comp.NotificationChannelTable exposing (Texts)
import Styles as S
type alias Model =
{}
type Action
= NoAction
| EditAction NotificationChannel
init : Model
init =
{}
type Msg
= Select NotificationChannel
update : Flags -> Msg -> Model -> ( Model, Action )
update _ msg model =
case msg of
Select channel ->
( model, EditAction channel )
--- View
view : Texts -> Model -> List NotificationChannel -> Html Msg
view texts model channels =
table [ class S.tableMain ]
[ thead []
[ tr []
[ th [ class "" ] []
, th [ class "text-left" ]
[ text texts.basics.name
]
, th [ class "text-left" ]
[ text texts.channelType
]
]
]
, tbody []
(List.map (renderNotificationChannelLine texts model) channels)
]
renderNotificationChannelLine : Texts -> Model -> NotificationChannel -> Html Msg
renderNotificationChannelLine texts _ channel =
let
ref =
Data.NotificationChannel.getRef channel
in
tr
[ class S.tableRow
]
[ B.editLinkTableCell texts.basics.edit (Select channel)
, td
[ class "text-left "
, classList [ ( "font-mono", ref.name == Nothing ) ]
]
[ Maybe.withDefault (String.slice 0 10 ref.id) ref.name |> text
]
, td [ class "text-left py-4 md:py-2" ]
[ text ref.channelType
]
]

View File

@ -17,24 +17,25 @@ import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
import Messages.Comp.NotificationGotifyForm exposing (Texts)
import Styles as S
import Util.Maybe
type alias Model =
{ hook : NotificationGotify
{ channel : NotificationGotify
, prioModel : Comp.FixedDropdown.Model Int
}
init : Model
init =
{ hook = Data.NotificationChannel.setTypeGotify Api.Model.NotificationGotify.empty
{ channel = Data.NotificationChannel.setTypeGotify Api.Model.NotificationGotify.empty
, prioModel = Comp.FixedDropdown.init (List.range 0 10)
}
initWith : NotificationGotify -> Model
initWith hook =
{ hook = Data.NotificationChannel.setTypeGotify hook
initWith channel =
{ channel = Data.NotificationChannel.setTypeGotify channel
, prioModel = Comp.FixedDropdown.init (List.range 0 10)
}
@ -42,6 +43,7 @@ initWith hook =
type Msg
= SetUrl String
| SetAppKey String
| SetName String
| PrioMsg (Comp.FixedDropdown.Msg Int)
@ -52,30 +54,33 @@ type Msg
update : Msg -> Model -> ( Model, Maybe NotificationGotify )
update msg model =
let
hook =
model.hook
channel =
model.channel
newModel =
case msg of
SetUrl s ->
{ model | hook = { hook | url = s } }
{ model | channel = { channel | url = s } }
SetAppKey s ->
{ model | hook = { hook | appKey = s } }
{ model | channel = { channel | appKey = s } }
SetName s ->
{ model | channel = { channel | name = Util.Maybe.fromString s } }
PrioMsg lm ->
let
( m, sel ) =
Comp.FixedDropdown.update lm model.prioModel
in
{ model | hook = { hook | priority = sel }, prioModel = m }
{ model | channel = { channel | priority = sel }, prioModel = m }
in
( newModel, check newModel.hook )
( newModel, check newModel.channel )
check : NotificationGotify -> Maybe NotificationGotify
check hook =
Just hook
check channel =
Just channel
@ -94,6 +99,25 @@ view texts model =
in
div []
[ div
[ class "mb-2"
]
[ label
[ for "name"
, class S.inputLabel
]
[ text texts.basics.name
]
, input
[ type_ "text"
, onInput SetName
, placeholder texts.basics.name
, value (Maybe.withDefault "" model.channel.name)
, name "name"
, class S.textInput
]
[]
]
, div
[ class "mb-2"
]
[ label
@ -107,7 +131,7 @@ view texts model =
[ type_ "text"
, onInput SetUrl
, placeholder texts.gotifyUrl
, value model.hook.url
, value model.channel.url
, name "gotifyurl"
, class S.textInput
]
@ -127,7 +151,7 @@ view texts model =
[ type_ "text"
, onInput SetAppKey
, placeholder texts.appKey
, value model.hook.appKey
, value model.channel.appKey
, name "appkey"
, class S.textInput
]
@ -142,7 +166,7 @@ view texts model =
]
[ text texts.priority
]
, Html.map PrioMsg (Comp.FixedDropdown.viewStyled2 cfg False model.hook.priority model.prioModel)
, Html.map PrioMsg (Comp.FixedDropdown.viewStyled2 cfg False model.channel.priority model.prioModel)
, span [ class "text-sm opacity-75" ]
[ text texts.priorityInfo
]

View File

@ -8,7 +8,6 @@
module Comp.NotificationHookForm exposing
( Model
, Msg(..)
, channelType
, getHook
, init
, initWith
@ -16,17 +15,16 @@ module Comp.NotificationHookForm exposing
, view
)
import Api.Model.NotificationHook exposing (NotificationHook)
import Comp.Basic as B
import Comp.ChannelForm
import Comp.ChannelRefInput
import Comp.Dropdown
import Comp.EventSample
import Comp.MenuBar as MB
import Comp.NotificationTest
import Data.ChannelType exposing (ChannelType)
import Data.DropdownStyle as DS
import Data.EventType exposing (EventType)
import Data.Flags exposing (Flags)
import Data.NotificationHook exposing (NotificationHook)
import Data.UiSettings exposing (UiSettings)
import Html exposing (..)
import Html.Attributes exposing (..)
@ -39,7 +37,7 @@ import Util.Maybe
type alias Model =
{ hook : NotificationHook
, enabled : Bool
, channelModel : Comp.ChannelForm.Model
, channelModel : Comp.ChannelRefInput.Model
, eventsDropdown : Comp.Dropdown.Model EventType
, eventSampleModel : Comp.EventSample.Model
, testDeliveryModel : Comp.NotificationTest.Model
@ -48,16 +46,16 @@ type alias Model =
}
init : Flags -> ChannelType -> ( Model, Cmd Msg )
init flags ct =
init : Flags -> ( Model, Cmd Msg )
init flags =
let
( cm, cc ) =
Comp.ChannelForm.init flags ct
Comp.ChannelRefInput.init flags
( esm, esc ) =
Comp.EventSample.initWith flags Data.EventType.TagsChanged
in
( { hook = Data.NotificationHook.empty ct
( { hook = Api.Model.NotificationHook.empty
, enabled = True
, channelModel = cm
, eventsDropdown =
@ -81,7 +79,7 @@ initWith : Flags -> NotificationHook -> ( Model, Cmd Msg )
initWith flags h =
let
( cm, cc ) =
Comp.ChannelForm.initWith flags h.channel
Comp.ChannelRefInput.initSelected flags h.channels
( esm, esc ) =
Comp.EventSample.initWith flags Data.EventType.TagsChanged
@ -92,7 +90,7 @@ initWith flags h =
, eventsDropdown =
Comp.Dropdown.makeMultipleList
{ options = Data.EventType.all
, selected = h.events
, selected = List.filterMap Data.EventType.fromString h.events
}
, eventSampleModel = esm
, testDeliveryModel = Comp.NotificationTest.init
@ -106,11 +104,6 @@ initWith flags h =
)
channelType : Model -> ChannelType
channelType model =
Comp.ChannelForm.channelType model.channelModel
getHook : Model -> Maybe NotificationHook
getHook model =
let
@ -123,20 +116,28 @@ getHook model =
Nothing
else
Just ev
Just (List.map Data.EventType.asString ev)
channel =
Comp.ChannelForm.getChannel model.channelModel
channels =
let
list =
Comp.ChannelRefInput.getSelected model.channelModel
in
if list == [] then
Nothing
else
Just list
mkHook ev ch =
NotificationHook model.hook.id model.enabled ch model.allEvents model.eventFilter ev
in
Maybe.map2 mkHook events channel
Maybe.map2 mkHook events channels
type Msg
= ToggleEnabled
| ChannelFormMsg Comp.ChannelForm.Msg
| ChannelFormMsg Comp.ChannelRefInput.Msg
| EventMsg (Comp.Dropdown.Msg EventType)
| EventSampleMsg Comp.EventSample.Msg
| DeliveryTestMsg Comp.NotificationTest.Msg
@ -163,7 +164,7 @@ update flags msg model =
ChannelFormMsg lm ->
let
( cm, cc ) =
Comp.ChannelForm.update flags lm model.channelModel
Comp.ChannelRefInput.update lm model.channelModel
in
( { model | channelModel = cm }, Cmd.map ChannelFormMsg cc )
@ -229,9 +230,9 @@ view texts settings model =
}
]
, div [ class "mb-4" ]
[ formHeader (texts.channelHeader (Comp.ChannelForm.channelType model.channelModel))
[ formHeader texts.channelHeader
, Html.map ChannelFormMsg
(Comp.ChannelForm.view texts.channelForm settings model.channelModel)
(Comp.ChannelRefInput.view texts.channelRef settings model.channelModel)
]
, div [ class "mb-4" ]
[ formHeader texts.events
@ -290,21 +291,21 @@ view texts settings model =
]
, div
[ class "mt-4"
, classList [ ( "hidden", channelType model /= Data.ChannelType.Http ) ]
]
[ h3 [ class S.header3 ]
[ text texts.samplePayload
]
, Html.map EventSampleMsg
(Comp.EventSample.viewJson texts.eventSample model.eventSampleModel)
]
, div
[ class "mt-4"
, classList [ ( "hidden", channelType model == Data.ChannelType.Http ) ]
]
[ formHeader texts.samplePayload
, div [ class "opacity-80 mb-1" ]
[ text texts.payloadInfo
]
, Html.map EventSampleMsg
(Comp.EventSample.viewMessage texts.eventSample model.eventSampleModel)
(Comp.EventSample.viewMessage texts.eventSample True model.eventSampleModel)
, div [ class "py-2 text-center text-sm" ]
[ text texts.jsonPayload
, i [ class "fa fa-arrow-down ml-1 mr-3" ] []
, i [ class "fa fa-arrow-up mr-1" ] []
, text texts.messagePayload
]
, Html.map EventSampleMsg
(Comp.EventSample.viewJson texts.eventSample False model.eventSampleModel)
]
, div [ class "mt-4" ]
[ formHeader "Test Delviery"

View File

@ -15,14 +15,12 @@ module Comp.NotificationHookManage exposing
import Api
import Api.Model.BasicResult exposing (BasicResult)
import Api.Model.NotificationHook exposing (NotificationHook)
import Comp.Basic as B
import Comp.ChannelMenu
import Comp.MenuBar as MB
import Comp.NotificationHookForm
import Comp.NotificationHookTable
import Data.ChannelType exposing (ChannelType)
import Data.Flags exposing (Flags)
import Data.NotificationHook exposing (NotificationHook)
import Data.UiSettings exposing (UiSettings)
import Html exposing (..)
import Html.Attributes exposing (..)
@ -39,7 +37,6 @@ type alias Model =
, deleteConfirm : DeleteConfirm
, loading : Bool
, formState : FormState
, newHookMenuOpen : Bool
, jsonFilterError : Maybe String
}
@ -67,9 +64,8 @@ type Msg
= TableMsg Comp.NotificationHookTable.Msg
| DetailMsg Comp.NotificationHookForm.Msg
| GetDataResp (Result Http.Error (List NotificationHook))
| ToggleNewHookMenu
| SubmitResp SubmitType (Result Http.Error BasicResult)
| NewHookInit ChannelType
| NewHookInit
| BackToTable
| Submit
| RequestDelete
@ -85,7 +81,6 @@ initModel =
, items = []
, loading = False
, formState = FormStateInitial
, newHookMenuOpen = False
, deleteConfirm = DeleteConfirmOff
, jsonFilterError = Nothing
}
@ -177,9 +172,6 @@ update flags msg model =
Nothing ->
( model, Cmd.none )
ToggleNewHookMenu ->
( { model | newHookMenuOpen = not model.newHookMenuOpen }, Cmd.none )
SubmitResp submitType (Ok res) ->
( { model
| formState =
@ -208,12 +200,12 @@ update flags msg model =
, Cmd.none
)
NewHookInit ct ->
NewHookInit ->
let
( mm, mc ) =
Comp.NotificationHookForm.init flags ct
Comp.NotificationHookForm.init flags
in
( { model | detailModel = Just mm, newHookMenuOpen = False }, Cmd.map DetailMsg mc )
( { model | detailModel = Just mm }, Cmd.map DetailMsg mc )
BackToTable ->
( { model | detailModel = Nothing }, initCmd flags )
@ -327,60 +319,14 @@ viewForm texts settings outerModel model =
let
newHook =
model.hook.id == ""
headline =
case Comp.NotificationHookForm.channelType model of
Data.ChannelType.Matrix ->
span []
[ text texts.integrate
, a
[ href "https://matrix.org"
, target "_blank"
, class S.link
, class "mx-3"
]
[ i [ class "fa fa-external-link-alt mr-1" ] []
, text "Matrix"
]
, text texts.intoDocspell
]
Data.ChannelType.Mail ->
span []
[ text texts.notifyEmailInfo
]
Data.ChannelType.Gotify ->
span []
[ text texts.integrate
, a
[ href "https://gotify.net"
, target "_blank"
, class S.link
, class "mx-3"
]
[ i [ class "fa fa-external-link-alt mr-1" ] []
, text "Gotify"
]
, text texts.intoDocspell
]
Data.ChannelType.Http ->
span []
[ text texts.postRequestInfo
]
in
[ h1 [ class S.header2 ]
[ Data.ChannelType.icon (Comp.NotificationHookForm.channelType model) "w-8 h-8 inline-block mr-4"
, if newHook then
[ if newHook then
text texts.addWebhook
else
text texts.updateWebhook
]
, div [ class "pt-2 pb-4 font-medium" ]
[ headline
]
, MB.view
{ start =
[ MB.CustomElement <|
@ -452,18 +398,15 @@ viewForm texts settings outerModel model =
viewList : Texts -> Model -> List (Html Msg)
viewList texts model =
let
menuModel =
{ menuOpen = model.newHookMenuOpen
, toggleMenu = ToggleNewHookMenu
, menuLabel = texts.newHook
, onItem = NewHookInit
}
in
[ MB.view
{ start = []
, end =
[ Comp.ChannelMenu.channelMenu texts.channelType menuModel
[ MB.PrimaryButton
{ tagger = NewHookInit
, title = texts.newHook
, icon = Just "fa fa-plus"
, label = texts.newHook
}
]
, rootClasses = "mb-4"
}

View File

@ -14,15 +14,13 @@ module Comp.NotificationHookTable exposing
, view
)
import Api.Model.NotificationHook exposing (NotificationHook)
import Comp.Basic as B
import Data.ChannelType
import Data.ChannelRef
import Data.EventType
import Data.Flags exposing (Flags)
import Data.NotificationChannel
import Data.NotificationHook exposing (NotificationHook)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Messages.Comp.NotificationHookTable exposing (Texts)
import Styles as S
import Util.Html
@ -80,7 +78,7 @@ view texts model hooks =
renderNotificationHookLine : Texts -> Model -> NotificationHook -> Html Msg
renderNotificationHookLine texts model hook =
renderNotificationHookLine texts _ hook =
let
eventName =
texts.eventType >> .name
@ -93,14 +91,17 @@ renderNotificationHookLine texts model hook =
[ Util.Html.checkbox2 hook.enabled
]
, td [ class "text-left py-4 md:py-2" ]
[ Data.NotificationChannel.channelType hook.channel
|> Maybe.map Data.ChannelType.asString
|> Maybe.withDefault "-"
|> text
[ div [ class "space-x-1" ]
(Data.ChannelRef.asDivs texts.channelType [ class "inline" ] hook.channels)
]
, td [ class "text-left hidden sm:table-cell" ]
[ List.map eventName hook.events
|> String.join ", "
|> text
[ if hook.allEvents then
text texts.allEvents
else
List.filterMap Data.EventType.fromString hook.events
|> List.map eventName
|> String.join ", "
|> text
]
]

View File

@ -15,29 +15,31 @@ import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
import Messages.Comp.NotificationHttpForm exposing (Texts)
import Styles as S
import Util.Maybe
type alias Model =
{ hook : NotificationHttp
{ channel : NotificationHttp
}
init : Model
init =
{ hook =
{ channel =
Data.NotificationChannel.setTypeHttp
Api.Model.NotificationHttp.empty
}
initWith : NotificationHttp -> Model
initWith hook =
{ hook = Data.NotificationChannel.setTypeHttp hook
initWith channel =
{ channel = Data.NotificationChannel.setTypeHttp channel
}
type Msg
= SetUrl String
| SetName String
@ -47,26 +49,29 @@ type Msg
update : Msg -> Model -> ( Model, Maybe NotificationHttp )
update msg model =
let
newHook =
updateHook msg model.hook
newChannel =
updateChannel msg model.channel
in
( { model | hook = newHook }, check newHook )
( { model | channel = newChannel }, check newChannel )
check : NotificationHttp -> Maybe NotificationHttp
check hook =
if hook.url == "" then
check channel =
if channel.url == "" then
Nothing
else
Just hook
Just channel
updateHook : Msg -> NotificationHttp -> NotificationHttp
updateHook msg hook =
updateChannel : Msg -> NotificationHttp -> NotificationHttp
updateChannel msg channel =
case msg of
SetUrl s ->
{ hook | url = s }
{ channel | url = s }
SetName s ->
{ channel | name = Util.Maybe.fromString s }
@ -77,6 +82,25 @@ view : Texts -> Model -> Html Msg
view texts model =
div []
[ div
[ class "mb-2"
]
[ label
[ for "name"
, class S.inputLabel
]
[ text texts.basics.name
]
, input
[ type_ "text"
, onInput SetName
, placeholder texts.basics.name
, value (Maybe.withDefault "" model.channel.name)
, name "name"
, class S.textInput
]
[]
]
, div
[ class "mb-2"
]
[ label
@ -90,7 +114,7 @@ view texts model =
[ type_ "text"
, onInput SetUrl
, placeholder texts.httpUrl
, value model.hook.url
, value model.channel.url
, name "httpurl"
, class S.textInput
]

View File

@ -23,13 +23,15 @@ import Html.Events exposing (onInput)
import Http
import Messages.Comp.NotificationMailForm exposing (Texts)
import Styles as S
import Util.Maybe
type alias Model =
{ hook : NotificationMail
{ channel : NotificationMail
, connectionModel : Comp.Dropdown.Model String
, recipients : List String
, recipientsModel : Comp.EmailInput.Model
, name : Maybe String
, formState : FormState
}
@ -46,10 +48,11 @@ type ValidateError
init : Flags -> ( Model, Cmd Msg )
init flags =
( { hook = Data.NotificationChannel.setTypeMail Api.Model.NotificationMail.empty
( { channel = Data.NotificationChannel.setTypeMail Api.Model.NotificationMail.empty
, connectionModel = Comp.Dropdown.makeSingle
, recipients = []
, recipientsModel = Comp.EmailInput.init
, name = Nothing
, formState = FormStateInitial
}
, Cmd.batch
@ -59,17 +62,17 @@ init flags =
initWith : Flags -> NotificationMail -> ( Model, Cmd Msg )
initWith flags hook =
initWith flags channel =
let
( mm, mc ) =
init flags
( cm, _ ) =
Comp.Dropdown.update (Comp.Dropdown.SetSelection [ hook.connection ]) mm.connectionModel
Comp.Dropdown.update (Comp.Dropdown.SetSelection [ channel.connection ]) mm.connectionModel
in
( { mm
| hook = Data.NotificationChannel.setTypeMail hook
, recipients = hook.recipients
| channel = Data.NotificationChannel.setTypeMail channel
, recipients = channel.recipients
, connectionModel = cm
}
, mc
@ -80,6 +83,7 @@ type Msg
= ConnResp (Result Http.Error EmailSettingsList)
| ConnMsg (Comp.Dropdown.Msg String)
| RecipientMsg Comp.EmailInput.Msg
| SetName String
@ -108,12 +112,12 @@ check model =
|> List.head
h =
model.hook
model.channel
makeHook _ rec conn =
{ h | connection = conn, recipients = rec }
makeChannel _ rec conn =
{ h | connection = conn, recipients = rec, name = model.name }
in
Maybe.map3 makeHook formState recipients connection
Maybe.map3 makeChannel formState recipients connection
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Maybe NotificationMail )
@ -152,6 +156,16 @@ update flags msg model =
, Nothing
)
SetName s ->
let
model_ =
{ model | name = Util.Maybe.fromString s }
in
( model_
, Cmd.none
, check model_
)
ConnMsg lm ->
let
( cm, cc ) =
@ -201,7 +215,26 @@ view texts settings model =
}
in
div []
[ div [ class "mb-4" ]
[ div
[ class "mb-2"
]
[ label
[ for "name"
, class S.inputLabel
]
[ text texts.basics.name
]
, input
[ type_ "text"
, onInput SetName
, placeholder texts.basics.name
, value (Maybe.withDefault "" model.name)
, name "name"
, class S.textInput
]
[]
]
, div [ class "mb-4" ]
[ label [ class S.inputLabel ]
[ text texts.sendVia
, B.inputRequired

View File

@ -15,22 +15,23 @@ import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
import Messages.Comp.NotificationMatrixForm exposing (Texts)
import Styles as S
import Util.Maybe
type alias Model =
{ hook : NotificationMatrix
{ channel : NotificationMatrix
}
init : Model
init =
{ hook = Data.NotificationChannel.setTypeMatrix Api.Model.NotificationMatrix.empty
{ channel = Data.NotificationChannel.setTypeMatrix Api.Model.NotificationMatrix.empty
}
initWith : NotificationMatrix -> Model
initWith hook =
{ hook = Data.NotificationChannel.setTypeMatrix hook
initWith channel =
{ channel = Data.NotificationChannel.setTypeMatrix channel
}
@ -38,6 +39,7 @@ type Msg
= SetHomeServer String
| SetRoomId String
| SetAccessKey String
| SetName String
@ -47,28 +49,31 @@ type Msg
update : Msg -> Model -> ( Model, Maybe NotificationMatrix )
update msg model =
let
newHook =
updateHook msg model.hook
newChannel =
updateChannel msg model.channel
in
( { model | hook = newHook }, check newHook )
( { model | channel = newChannel }, check newChannel )
check : NotificationMatrix -> Maybe NotificationMatrix
check hook =
Just hook
check channel =
Just channel
updateHook : Msg -> NotificationMatrix -> NotificationMatrix
updateHook msg hook =
updateChannel : Msg -> NotificationMatrix -> NotificationMatrix
updateChannel msg channel =
case msg of
SetHomeServer s ->
{ hook | homeServer = s }
{ channel | homeServer = s }
SetRoomId s ->
{ hook | roomId = s }
{ channel | roomId = s }
SetAccessKey s ->
{ hook | accessToken = s }
{ channel | accessToken = s }
SetName s ->
{ channel | name = Util.Maybe.fromString s }
@ -79,6 +84,25 @@ view : Texts -> Model -> Html Msg
view texts model =
div []
[ div
[ class "mb-2"
]
[ label
[ for "name"
, class S.inputLabel
]
[ text texts.basics.name
]
, input
[ type_ "text"
, onInput SetName
, placeholder texts.basics.name
, value (Maybe.withDefault "" model.channel.name)
, name "name"
, class S.textInput
]
[]
]
, div
[ class "mb-2"
]
[ label
@ -92,7 +116,7 @@ view texts model =
[ type_ "text"
, onInput SetHomeServer
, placeholder texts.homeServer
, value model.hook.homeServer
, value model.channel.homeServer
, name "homeserver"
, class S.textInput
]
@ -112,7 +136,7 @@ view texts model =
[ type_ "text"
, onInput SetRoomId
, placeholder texts.roomId
, value model.hook.roomId
, value model.channel.roomId
, name "roomid"
, class S.textInput
]
@ -131,7 +155,7 @@ view texts model =
, textarea
[ onInput SetAccessKey
, placeholder texts.accessKey
, value model.hook.accessToken
, value model.channel.accessToken
, name "accesskey"
, class S.textAreaInput
]

View File

@ -9,10 +9,10 @@ module Comp.NotificationTest exposing (Model, Msg, ViewConfig, init, update, vie
import Api
import Api.Model.NotificationChannelTestResult exposing (NotificationChannelTestResult)
import Api.Model.NotificationHook exposing (NotificationHook)
import Comp.Basic as B
import Comp.MenuBar as MB
import Data.Flags exposing (Flags)
import Data.NotificationHook exposing (NotificationHook)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)

View File

@ -16,16 +16,15 @@ module Comp.PeriodicQueryTaskForm exposing
, view
)
import Api.Model.PeriodicQuerySettings exposing (PeriodicQuerySettings)
import Comp.Basic as B
import Comp.BookmarkDropdown
import Comp.CalEventInput
import Comp.ChannelForm
import Comp.ChannelRefInput
import Comp.MenuBar as MB
import Comp.PowerSearchInput
import Data.CalEvent exposing (CalEvent)
import Data.ChannelType exposing (ChannelType)
import Data.Flags exposing (Flags)
import Data.PeriodicQuerySettings exposing (PeriodicQuerySettings)
import Data.UiSettings exposing (UiSettings)
import Data.Validated exposing (Validated(..))
import Html exposing (..)
@ -44,7 +43,7 @@ type alias Model =
, schedule : Maybe CalEvent
, scheduleModel : Comp.CalEventInput.Model
, queryModel : Comp.PowerSearchInput.Model
, channelModel : Comp.ChannelForm.Model
, channelModel : Comp.ChannelRefInput.Model
, bookmarkDropdown : Comp.BookmarkDropdown.Model
, contentStart : Maybe String
, formState : FormState
@ -78,7 +77,7 @@ type Msg
| ToggleEnabled
| CalEventMsg Comp.CalEventInput.Msg
| QueryMsg Comp.PowerSearchInput.Msg
| ChannelMsg Comp.ChannelForm.Msg
| ChannelMsg Comp.ChannelRefInput.Msg
| BookmarkMsg Comp.BookmarkDropdown.Msg
| SetContentStart String
| StartOnce
@ -105,7 +104,7 @@ initWith flags s =
Comp.PowerSearchInput.init
( cfm, cfc ) =
Comp.ChannelForm.initWith flags s.channel
Comp.ChannelRefInput.initSelected flags s.channels
( bm, bc ) =
Comp.BookmarkDropdown.init flags s.bookmark
@ -132,8 +131,8 @@ initWith flags s =
)
init : Flags -> ChannelType -> ( Model, Cmd Msg )
init flags ct =
init : Flags -> ( Model, Cmd Msg )
init flags =
let
initialSchedule =
Data.CalEvent.everyMonth
@ -142,12 +141,12 @@ init flags ct =
Comp.CalEventInput.init flags initialSchedule
( cfm, cfc ) =
Comp.ChannelForm.init flags ct
Comp.ChannelRefInput.init flags
( bm, bc ) =
Comp.BookmarkDropdown.init flags Nothing
in
( { settings = Data.PeriodicQuerySettings.empty ct
( { settings = Api.Model.PeriodicQuerySettings.empty
, enabled = False
, schedule = Just initialSchedule
, scheduleModel = sm
@ -210,16 +209,22 @@ makeSettings model =
Result.Ok ( qstr, bm )
channelM =
Result.fromMaybe
ValidateChannelRequired
(Comp.ChannelForm.getChannel model.channelModel)
let
list =
Comp.ChannelRefInput.getSelected model.channelModel
in
if list == [] then
Err ValidateChannelRequired
make timer channel q =
else
Ok list
make timer channels q =
{ prev
| enabled = model.enabled
, schedule = Data.CalEvent.makeEvent timer
, summary = model.summary
, channel = channel
, channels = channels
, query = Tuple.first q
, bookmark = Tuple.second q
, contentStart = model.contentStart
@ -285,7 +290,7 @@ update flags msg model =
ChannelMsg lm ->
let
( cfm, cfc ) =
Comp.ChannelForm.update flags lm model.channelModel
Comp.ChannelRefInput.update lm model.channelModel
in
{ model = { model | channelModel = cfm }
, action = NoAction
@ -536,9 +541,9 @@ view texts extraClasses settings model =
]
]
, div [ class "mb-4" ]
[ formHeader (texts.channelHeader (Comp.ChannelForm.channelType model.channelModel)) False
[ formHeader texts.channelHeader True
, Html.map ChannelMsg
(Comp.ChannelForm.view texts.channelForm settings model.channelModel)
(Comp.ChannelRefInput.view texts.channelRef settings model.channelModel)
]
, div [ class "mb-4" ]
[ formHeader texts.queryLabel True

View File

@ -14,15 +14,17 @@ module Comp.PeriodicQueryTaskList exposing
, view2
)
import Api.Model.PeriodicQuerySettings exposing (PeriodicQuerySettings)
import Comp.Basic as B
import Data.ChannelRef
import Data.ChannelType
import Data.NotificationChannel
import Data.PeriodicQuerySettings exposing (PeriodicQuerySettings)
import Html exposing (..)
import Html.Attributes exposing (..)
import Messages.Comp.PeriodicQueryTaskList exposing (Texts)
import Styles as S
import Util.Html
import Util.List
type alias Model =
@ -94,9 +96,7 @@ viewItem2 texts item =
]
]
, td [ class "text-left py-4 md:py-2" ]
[ Data.NotificationChannel.channelType item.channel
|> Maybe.map Data.ChannelType.asString
|> Maybe.withDefault "-"
|> text
[ div [ class " space-x-1" ]
(Data.ChannelRef.asDivs texts.channelType [ class "inline" ] item.channels)
]
]

View File

@ -15,17 +15,16 @@ module Comp.PeriodicQueryTaskManage exposing
import Api
import Api.Model.BasicResult exposing (BasicResult)
import Api.Model.PeriodicQuerySettings exposing (PeriodicQuerySettings)
import Comp.ChannelMenu
import Comp.MenuBar as MB
import Comp.PeriodicQueryTaskForm
import Comp.PeriodicQueryTaskList
import Data.ChannelType exposing (ChannelType)
import Data.Flags exposing (Flags)
import Data.PeriodicQuerySettings exposing (PeriodicQuerySettings)
import Data.UiSettings exposing (UiSettings)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Http
import Messages.Comp.PeriodicQueryTaskManage exposing (Texts)
import Styles as S
@ -36,7 +35,6 @@ type alias Model =
, detailModel : Maybe Comp.PeriodicQueryTaskForm.Model
, items : List PeriodicQuerySettings
, formState : FormState
, channelMenuOpen : Bool
}
@ -58,9 +56,8 @@ type Msg
= ListMsg Comp.PeriodicQueryTaskList.Msg
| DetailMsg Comp.PeriodicQueryTaskForm.Msg
| GetDataResp (Result Http.Error (List PeriodicQuerySettings))
| NewTaskInit ChannelType
| NewTaskInit
| SubmitResp SubmitType (Result Http.Error BasicResult)
| ToggleChannelMenu
initModel : Model
@ -69,7 +66,6 @@ initModel =
, detailModel = Nothing
, items = []
, formState = FormStateInitial
, channelMenuOpen = False
}
@ -195,12 +191,12 @@ update flags msg model =
Nothing ->
( model, Cmd.none, Sub.none )
NewTaskInit ct ->
NewTaskInit ->
let
( mm, mc ) =
Comp.PeriodicQueryTaskForm.init flags ct
Comp.PeriodicQueryTaskForm.init flags
in
( { model | detailModel = Just mm, channelMenuOpen = False }, Cmd.map DetailMsg mc, Sub.none )
( { model | detailModel = Just mm }, Cmd.map DetailMsg mc, Sub.none )
SubmitResp submitType (Ok res) ->
( { model
@ -231,9 +227,6 @@ update flags msg model =
, Sub.none
)
ToggleChannelMenu ->
( { model | channelMenuOpen = not model.channelMenuOpen }, Cmd.none, Sub.none )
--- View2
@ -301,18 +294,15 @@ viewForm2 texts settings model =
viewList2 : Texts -> Model -> List (Html Msg)
viewList2 texts model =
let
menuModel =
{ menuOpen = model.channelMenuOpen
, toggleMenu = ToggleChannelMenu
, menuLabel = texts.newTask
, onItem = NewTaskInit
}
in
[ MB.view
{ start = []
, end =
[ Comp.ChannelMenu.channelMenu texts.channelType menuModel
[ MB.PrimaryButton
{ tagger = NewTaskInit
, title = texts.newTask
, icon = Just "fa fa-plus"
, label = texts.newTask
}
]
, rootClasses = "mb-4"
}