From 404fb2a37f383b094ee0e96f60eeb25ac9e4ff0c Mon Sep 17 00:00:00 2001 From: eikek Date: Tue, 11 Jan 2022 22:50:19 +0100 Subject: [PATCH] Allow a custom message part for the periodic query task --- .../joex/notify/PeriodicDueItemsTask.scala | 1 + .../joex/notify/PeriodicQueryTask.scala | 1 + .../docspell/joex/notify/TaskOperations.scala | 3 +- .../docspell/notification/api/Event.scala | 5 +- .../notification/api/PeriodicQueryArgs.scala | 3 +- .../impl/EventContextSyntax.scala | 13 +++- .../impl/context/DeleteFieldValueCtx.scala | 4 +- .../impl/context/ItemSelectionCtx.scala | 62 +++++++++++-------- .../impl/context/JobDoneCtx.scala | 4 +- .../impl/context/JobSubmittedCtx.scala | 4 +- .../impl/context/SetFieldValueCtx.scala | 4 +- .../impl/context/TagsChangedCtx.scala | 4 +- .../impl/context/TagsChangedCtxTest.scala | 8 +-- .../restapi/model/PeriodicQuerySettings.scala | 1 + .../routes/PeriodicQueryRoutes.scala | 4 +- .../db/migration/NotifyDueItemsArgs.scala | 5 +- .../main/elm/Comp/PeriodicQueryTaskForm.elm | 28 +++++++++ .../main/elm/Data/PeriodicQuerySettings.elm | 6 +- .../Messages/Comp/PeriodicQueryTaskForm.elm | 12 ++++ 19 files changed, 128 insertions(+), 44 deletions(-) diff --git a/modules/joex/src/main/scala/docspell/joex/notify/PeriodicDueItemsTask.scala b/modules/joex/src/main/scala/docspell/joex/notify/PeriodicDueItemsTask.scala index 9446478d..ebaa60b5 100644 --- a/modules/joex/src/main/scala/docspell/joex/notify/PeriodicDueItemsTask.scala +++ b/modules/joex/src/main/scala/docspell/joex/notify/PeriodicDueItemsTask.scala @@ -106,6 +106,7 @@ object PeriodicDueItemsTask { ctx.args.account, ctx.args.baseUrl, items, + None, limit, now )(cont) diff --git a/modules/joex/src/main/scala/docspell/joex/notify/PeriodicQueryTask.scala b/modules/joex/src/main/scala/docspell/joex/notify/PeriodicQueryTask.scala index c24e47e8..ad16f2b9 100644 --- a/modules/joex/src/main/scala/docspell/joex/notify/PeriodicQueryTask.scala +++ b/modules/joex/src/main/scala/docspell/joex/notify/PeriodicQueryTask.scala @@ -143,6 +143,7 @@ object PeriodicQueryTask { ctx.args.account, ctx.args.baseUrl, items, + ctx.args.contentStart, limit, now )(cont) diff --git a/modules/joex/src/main/scala/docspell/joex/notify/TaskOperations.scala b/modules/joex/src/main/scala/docspell/joex/notify/TaskOperations.scala index 788f3131..a1152c13 100644 --- a/modules/joex/src/main/scala/docspell/joex/notify/TaskOperations.scala +++ b/modules/joex/src/main/scala/docspell/joex/notify/TaskOperations.scala @@ -45,6 +45,7 @@ trait TaskOperations { account: AccountId, baseUrl: Option[LenientUri], items: Vector[ListItem], + contentStart: Option[String], limit: Int, now: Timestamp )(cont: EventContext => F[Unit]): F[Unit] = @@ -52,7 +53,7 @@ trait TaskOperations { case Some(nel) => val more = items.size >= limit val eventCtx = ItemSelectionCtx( - Event.ItemSelection(account, nel.map(_.id), more, baseUrl), + Event.ItemSelection(account, nel.map(_.id), more, baseUrl, contentStart), ItemSelectionCtx.Data .create(account, items, baseUrl, more, now) ) diff --git a/modules/notification/api/src/main/scala/docspell/notification/api/Event.scala b/modules/notification/api/src/main/scala/docspell/notification/api/Event.scala index 371d4ebe..18ff790a 100644 --- a/modules/notification/api/src/main/scala/docspell/notification/api/Event.scala +++ b/modules/notification/api/src/main/scala/docspell/notification/api/Event.scala @@ -148,7 +148,8 @@ object Event { account: AccountId, items: Nel[Ident], more: Boolean, - baseUrl: Option[LenientUri] + baseUrl: Option[LenientUri], + contentStart: Option[String] ) extends Event { val eventType = ItemSelection } @@ -161,7 +162,7 @@ object Event { for { id1 <- Ident.randomId[F] id2 <- Ident.randomId[F] - } yield ItemSelection(account, Nel.of(id1, id2), true, baseUrl) + } yield ItemSelection(account, Nel.of(id1, id2), true, baseUrl, None) } /** Event when a new job is added to the queue */ diff --git a/modules/notification/api/src/main/scala/docspell/notification/api/PeriodicQueryArgs.scala b/modules/notification/api/src/main/scala/docspell/notification/api/PeriodicQueryArgs.scala index e8ffd089..cf1c16a1 100644 --- a/modules/notification/api/src/main/scala/docspell/notification/api/PeriodicQueryArgs.scala +++ b/modules/notification/api/src/main/scala/docspell/notification/api/PeriodicQueryArgs.scala @@ -17,7 +17,8 @@ final case class PeriodicQueryArgs( channel: ChannelOrRef, query: Option[ItemQueryString], bookmark: Option[String], - baseUrl: Option[LenientUri] + baseUrl: Option[LenientUri], + contentStart: Option[String] ) object PeriodicQueryArgs { diff --git a/modules/notification/impl/src/main/scala/docspell/notification/impl/EventContextSyntax.scala b/modules/notification/impl/src/main/scala/docspell/notification/impl/EventContextSyntax.scala index 781fdbb5..79fa66a6 100644 --- a/modules/notification/impl/src/main/scala/docspell/notification/impl/EventContextSyntax.scala +++ b/modules/notification/impl/src/main/scala/docspell/notification/impl/EventContextSyntax.scala @@ -1,7 +1,14 @@ +/* + * Copyright 2020 Eike K. & Contributors + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + package docspell.notification.impl -import docspell.notification.api.EventContext import docspell.common.Logger +import docspell.notification.api.EventContext + import io.circe.Json trait EventContextSyntax { @@ -21,7 +28,9 @@ trait EventContextSyntax { case Left(err) => logError(logger)(err) } - def withDefaultBoth[F[_]](logger: Logger[F])(f: (String, String) => F[Unit]): F[Unit] = + def withDefaultBoth[F[_]]( + logger: Logger[F] + )(f: (String, String) => F[Unit]): F[Unit] = (for { md <- self.defaultBoth html <- self.defaultBothHtml diff --git a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/DeleteFieldValueCtx.scala b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/DeleteFieldValueCtx.scala index 1a96071a..b204f823 100644 --- a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/DeleteFieldValueCtx.scala +++ b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/DeleteFieldValueCtx.scala @@ -32,7 +32,9 @@ final case class DeleteFieldValueCtx( val titleTemplate = Right(mustache"{{eventType}} (by *{{account.user}}*)") val bodyTemplate = - Right(mustache"""{{#content}}{{#field.label}}*{{field.label}}* {{/field.label}}{{^field.label}}*{{field.name}}* {{/field.label}} was removed from {{#items}}{{^-first}}, {{/-first}}{{#itemUrl}}[`{{name}}`]({{{itemUrl}}}/{{{id}}}){{/itemUrl}}{{^itemUrl}}`{{name}}`{{/itemUrl}}{{/items}}.{{/content}}""") + Right( + mustache"""{{#content}}{{#field.label}}*{{field.label}}* {{/field.label}}{{^field.label}}*{{field.name}}* {{/field.label}} was removed from {{#items}}{{^-first}}, {{/-first}}{{#itemUrl}}[`{{name}}`]({{{itemUrl}}}/{{{id}}}){{/itemUrl}}{{^itemUrl}}`{{name}}`{{/itemUrl}}{{/items}}.{{/content}}""" + ) } diff --git a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/ItemSelectionCtx.scala b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/ItemSelectionCtx.scala index 2fd19eb6..994ab1b9 100644 --- a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/ItemSelectionCtx.scala +++ b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/ItemSelectionCtx.scala @@ -19,39 +19,29 @@ import doobie._ import io.circe.Encoder import io.circe.syntax._ import yamusca.implicits._ +import yamusca.imports._ final case class ItemSelectionCtx(event: Event.ItemSelection, data: ItemSelectionCtx.Data) extends AbstractEventContext { - val content = data.asJson val titleTemplate = Right(mustache"Your items") - val bodyTemplate = Right(mustache""" -Hello {{{ content.username }}}, + val bodyTemplate = event.contentStart match { + case Some(cnt) => + mustache + .parse(cnt) + .leftMap { case (in, err) => + s"Error parsing template: $err! Near ${in.pos}: ${in.raw}." + } + .map(start => start ++ ItemSelectionCtx.basicBody) -this is Docspell informing you about your next items. + case None => + Right(ItemSelectionCtx.basicBodyStart ++ ItemSelectionCtx.basicBody) + } -{{#content}} -{{#itemUrl}} -{{#items}} -- {{#overDue}}**(OVERDUE)** {{/overDue}}[{{name}}]({{itemUrl}}/{{id}}){{#dueDate}}, {{#overDue}}was {{/overDue}}due {{dueIn}} on *{{dueDate}}*{{/dueDate}}; {{#corrOrg}}from {{corrOrg}}{{/corrOrg}} received on {{date}} via {{source}} -{{/items}} -{{/itemUrl}} -{{^itemUrl}} -{{#items}} -- {{#overDue}}**(OVERDUE)** {{/overDue}}*{{name}}*{{#dueDate}}, {{#overDue}}was {{/overDue}}due {{dueIn}} on *{{dueDate}}*{{/dueDate}}; {{#corrOrg}}from {{corrOrg}}{{/corrOrg}} received on {{date}} via {{source}} -{{/items}} -{{/itemUrl}} -{{#more}} -- … more have been left out for brevity -{{/more}} -{{/content}} - - -Sincerely yours, - -Docspell -""") + implicit final class TemplateOps(self: Template) { + def ++(next: Template) = Template(self.els ++ next.els) + } } object ItemSelectionCtx { @@ -113,4 +103,26 @@ object ItemSelectionCtx { account.user.id ) } + + private val basicBodyStart = mustache""" +Hello {{{ content.username }}}, + +this is Docspell informing you about your next items.""" + + private val basicBody = mustache""" +{{#content}} +{{#itemUrl}} +{{#items}} +- {{#overDue}}**(OVERDUE)** {{/overDue}}[{{name}}]({{itemUrl}}/{{id}}){{#dueDate}}, {{#overDue}}was {{/overDue}}due {{dueIn}} on *{{dueDate}}*{{/dueDate}}; {{#corrOrg}}from {{corrOrg}}{{/corrOrg}} received on {{date}} via {{source}} +{{/items}} +{{/itemUrl}} +{{^itemUrl}} +{{#items}} +- {{#overDue}}**(OVERDUE)** {{/overDue}}*{{name}}*{{#dueDate}}, {{#overDue}}was {{/overDue}}due {{dueIn}} on *{{dueDate}}*{{/dueDate}}; {{#corrOrg}}from {{corrOrg}}{{/corrOrg}} received on {{date}} via {{source}} +{{/items}} +{{/itemUrl}} +{{#more}} +- … more have been left out for brevity +{{/more}} +{{/content}}""" } diff --git a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/JobDoneCtx.scala b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/JobDoneCtx.scala index 43e21d3b..2b5c9b24 100644 --- a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/JobDoneCtx.scala +++ b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/JobDoneCtx.scala @@ -23,7 +23,9 @@ final case class JobDoneCtx(event: Event.JobDone, data: JobDoneCtx.Data) val content = data.asJson val titleTemplate = Right(mustache"{{eventType}} (by *{{account.user}}*)") - val bodyTemplate = Right(mustache"""{{#content}}_'{{subject}}'_ finished {{/content}}""") + val bodyTemplate = Right( + mustache"""{{#content}}_'{{subject}}'_ finished {{/content}}""" + ) } object JobDoneCtx { diff --git a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/JobSubmittedCtx.scala b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/JobSubmittedCtx.scala index 045fd7b3..c996fd90 100644 --- a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/JobSubmittedCtx.scala +++ b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/JobSubmittedCtx.scala @@ -24,7 +24,9 @@ final case class JobSubmittedCtx(event: Event.JobSubmitted, data: JobSubmittedCt val titleTemplate = Right(mustache"{{eventType}} (by *{{account.user}}*)") val bodyTemplate = - Right(mustache"""{{#content}}_'{{subject}}'_ submitted by {{submitter}} {{/content}}""") + Right( + mustache"""{{#content}}_'{{subject}}'_ submitted by {{submitter}} {{/content}}""" + ) } object JobSubmittedCtx { diff --git a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/SetFieldValueCtx.scala b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/SetFieldValueCtx.scala index 60feb607..ebb8dc70 100644 --- a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/SetFieldValueCtx.scala +++ b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/SetFieldValueCtx.scala @@ -30,7 +30,9 @@ final case class SetFieldValueCtx(event: Event.SetFieldValue, data: SetFieldValu val titleTemplate = Right(mustache"{{eventType}} (by *{{account.user}}*)") val bodyTemplate = - Right(mustache"""{{#content}}{{#field.label}}*{{field.label}}* {{/field.label}}{{^field.label}}*{{field.name}}* {{/field.label}} was set to '{{value}}' on {{#items}}{{^-first}}, {{/-first}}{{#itemUrl}}[`{{name}}`]({{{itemUrl}}}/{{{id}}}){{/itemUrl}}{{^itemUrl}}`{{name}}`{{/itemUrl}}{{/items}}.{{/content}}""") + Right( + mustache"""{{#content}}{{#field.label}}*{{field.label}}* {{/field.label}}{{^field.label}}*{{field.name}}* {{/field.label}} was set to '{{value}}' on {{#items}}{{^-first}}, {{/-first}}{{#itemUrl}}[`{{name}}`]({{{itemUrl}}}/{{{id}}}){{/itemUrl}}{{^itemUrl}}`{{name}}`{{/itemUrl}}{{/items}}.{{/content}}""" + ) } diff --git a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/TagsChangedCtx.scala b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/TagsChangedCtx.scala index a6410b50..bd7aa8d4 100644 --- a/modules/notification/impl/src/main/scala/docspell/notification/impl/context/TagsChangedCtx.scala +++ b/modules/notification/impl/src/main/scala/docspell/notification/impl/context/TagsChangedCtx.scala @@ -28,7 +28,9 @@ final case class TagsChangedCtx(event: Event.TagsChanged, data: TagsChangedCtx.D val titleTemplate = Right(mustache"{{eventType}} (by *{{account.user}}*)") val bodyTemplate = - Right(mustache"""{{#content}}{{#added}}{{#-first}}Adding {{/-first}}{{^-first}}, {{/-first}}*{{name}}*{{/added}}{{#removed}}{{#added}}{{#-first}};{{/-first}}{{/added}}{{#-first}} Removing {{/-first}}{{^-first}}, {{/-first}}*{{name}}*{{/removed}} on {{#items}}{{^-first}}, {{/-first}}{{#itemUrl}}[`{{name}}`]({{{itemUrl}}}/{{{id}}}){{/itemUrl}}{{^itemUrl}}`{{name}}`{{/itemUrl}}{{/items}}.{{/content}}""") + Right( + mustache"""{{#content}}{{#added}}{{#-first}}Adding {{/-first}}{{^-first}}, {{/-first}}*{{name}}*{{/added}}{{#removed}}{{#added}}{{#-first}};{{/-first}}{{/added}}{{#-first}} Removing {{/-first}}{{^-first}}, {{/-first}}*{{name}}*{{/removed}} on {{#items}}{{^-first}}, {{/-first}}{{#itemUrl}}[`{{name}}`]({{{itemUrl}}}/{{{id}}}){{/itemUrl}}{{^itemUrl}}`{{name}}`{{/itemUrl}}{{/items}}.{{/content}}""" + ) } object TagsChangedCtx { diff --git a/modules/notification/impl/src/test/scala/docspell/notification/impl/context/TagsChangedCtxTest.scala b/modules/notification/impl/src/test/scala/docspell/notification/impl/context/TagsChangedCtxTest.scala index 4aded5c5..094ae368 100644 --- a/modules/notification/impl/src/test/scala/docspell/notification/impl/context/TagsChangedCtxTest.scala +++ b/modules/notification/impl/src/test/scala/docspell/notification/impl/context/TagsChangedCtxTest.scala @@ -46,9 +46,9 @@ class TagsChangedCtxTest extends FunSuite { TagsChangedCtx.Data(account, List(item), List(tag), Nil, url.some.map(_.asString)) ) - assertEquals(ctx.defaultTitle, "TagsChanged (by *user2*)") + assertEquals(ctx.defaultTitle.toOption.get, "TagsChanged (by *user2*)") assertEquals( - ctx.defaultBody, + ctx.defaultBody.toOption.get, "Adding *tag-red* on [`Report 2`](http://test/item-1)." ) } @@ -65,9 +65,9 @@ class TagsChangedCtxTest extends FunSuite { ) ) - assertEquals(ctx.defaultTitle, "TagsChanged (by *user2*)") + assertEquals(ctx.defaultTitle.toOption.get, "TagsChanged (by *user2*)") assertEquals( - ctx.defaultBody, + ctx.defaultBody.toOption.get, "Adding *tag-red*; Removing *tag-blue* on [`Report 2`](http://test/item-1)." ) } diff --git a/modules/restapi/src/main/scala/docspell/restapi/model/PeriodicQuerySettings.scala b/modules/restapi/src/main/scala/docspell/restapi/model/PeriodicQuerySettings.scala index 964ad125..a3cc89ab 100644 --- a/modules/restapi/src/main/scala/docspell/restapi/model/PeriodicQuerySettings.scala +++ b/modules/restapi/src/main/scala/docspell/restapi/model/PeriodicQuerySettings.scala @@ -23,6 +23,7 @@ final case class PeriodicQuerySettings( channel: NotificationChannel, query: Option[ItemQuery], bookmark: Option[String], + contentStart: Option[String], schedule: CalEvent ) {} diff --git a/modules/restserver/src/main/scala/docspell/restserver/routes/PeriodicQueryRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/routes/PeriodicQueryRoutes.scala index 93b90b6e..32e767b8 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/PeriodicQueryRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/PeriodicQueryRoutes.scala @@ -144,7 +144,8 @@ object PeriodicQueryRoutes extends MailAddressCodec { Right(channel), qstr, settings.bookmark, - Some(baseUrl / "app" / "item") + Some(baseUrl / "app" / "item"), + settings.contentStart ) ) } @@ -167,6 +168,7 @@ object PeriodicQueryRoutes extends MailAddressCodec { ch, task.args.query.map(_.query).map(ItemQueryParser.parseUnsafe), task.args.bookmark, + task.args.contentStart, task.timer ) } diff --git a/modules/store/src/main/scala/db/migration/NotifyDueItemsArgs.scala b/modules/store/src/main/scala/db/migration/NotifyDueItemsArgs.scala index d80fced5..e664b58f 100644 --- a/modules/store/src/main/scala/db/migration/NotifyDueItemsArgs.scala +++ b/modules/store/src/main/scala/db/migration/NotifyDueItemsArgs.scala @@ -18,8 +18,9 @@ import io.circe.generic.semiauto._ * If the structure changes, there must be some database migration to update or remove * the json data of the corresponding task. * - * @deprecated note: This has been removed and copied to this place to be able to - * migrate away from this structure. Replaced by PeriodicDueItemsArgs + * @deprecated + * note: This has been removed and copied to this place to be able to migrate away from + * this structure. Replaced by PeriodicDueItemsArgs */ case class NotifyDueItemsArgs( account: AccountId, diff --git a/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskForm.elm b/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskForm.elm index 38ef5da6..154c6ab5 100644 --- a/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskForm.elm +++ b/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskForm.elm @@ -46,6 +46,7 @@ type alias Model = , queryModel : Comp.PowerSearchInput.Model , channelModel : Comp.ChannelForm.Model , bookmarkDropdown : Comp.BookmarkDropdown.Model + , contentStart : Maybe String , formState : FormState , loading : Int , deleteRequested : Bool @@ -79,6 +80,7 @@ type Msg | QueryMsg Comp.PowerSearchInput.Msg | ChannelMsg Comp.ChannelForm.Msg | BookmarkMsg Comp.BookmarkDropdown.Msg + | SetContentStart String | StartOnce | Cancel | RequestDelete @@ -115,6 +117,7 @@ initWith flags s = , queryModel = res.model , channelModel = cfm , bookmarkDropdown = bm + , contentStart = Nothing , formState = FormStateInitial , loading = 0 , summary = s.summary @@ -151,6 +154,7 @@ init flags ct = , queryModel = Comp.PowerSearchInput.init , channelModel = cfm , bookmarkDropdown = bm + , contentStart = Nothing , formState = FormStateInitial , loading = 0 , summary = Nothing @@ -218,6 +222,7 @@ makeSettings model = , channel = channel , query = Tuple.first q , bookmark = Tuple.second q + , contentStart = model.contentStart } in Result.map3 make @@ -299,6 +304,13 @@ update flags msg model = , sub = Sub.none } + SetContentStart str -> + { model = { model | contentStart = Util.Maybe.fromString str } + , action = NoAction + , cmd = Cmd.none + , sub = Sub.none + } + ToggleEnabled -> { model = { model @@ -545,6 +557,22 @@ view texts extraClasses settings model = , queryInput ] ] + , div [ class "mb-4" ] + [ formHeader texts.messageContentTitle False + , label [ class S.inputLabel ] + [ text texts.messageContentLabel + ] + , textarea + [ onInput SetContentStart + , Maybe.withDefault "" model.contentStart |> value + , placeholder texts.messageContentPlaceholder + , class S.textAreaInput + ] + [] + , span [ class "text-sm opacity-75" ] + [ text texts.messageContentInfo + ] + ] , div [ class "mb-4" ] [ formHeader texts.schedule False , label [ class S.inputLabel ] diff --git a/modules/webapp/src/main/elm/Data/PeriodicQuerySettings.elm b/modules/webapp/src/main/elm/Data/PeriodicQuerySettings.elm index 6a3a5b1e..73603fc1 100644 --- a/modules/webapp/src/main/elm/Data/PeriodicQuerySettings.elm +++ b/modules/webapp/src/main/elm/Data/PeriodicQuerySettings.elm @@ -20,6 +20,7 @@ type alias PeriodicQuerySettings = , channel : NotificationChannel , query : Maybe String , bookmark : Maybe String + , contentStart : Maybe String , schedule : String } @@ -32,19 +33,21 @@ empty ct = , channel = Data.NotificationChannel.empty ct , query = Nothing , bookmark = Nothing + , contentStart = Nothing , schedule = "" } decoder : D.Decoder PeriodicQuerySettings decoder = - D.map7 PeriodicQuerySettings + D.map8 PeriodicQuerySettings (D.field "id" D.string) (D.field "enabled" D.bool) (D.maybe (D.field "summary" D.string)) (D.field "channel" Data.NotificationChannel.decoder) (D.maybe (D.field "query" D.string)) (D.maybe (D.field "bookmark" D.string)) + (D.maybe (D.field "contentStart" D.string)) (D.field "schedule" D.string) @@ -57,5 +60,6 @@ encode s = , ( "channel", Data.NotificationChannel.encode s.channel ) , ( "query", Maybe.map E.string s.query |> Maybe.withDefault E.null ) , ( "bookmark", Maybe.map E.string s.bookmark |> Maybe.withDefault E.null ) + , ( "contentStart", Maybe.map E.string s.contentStart |> Maybe.withDefault E.null ) , ( "schedule", E.string s.schedule ) ] diff --git a/modules/webapp/src/main/elm/Messages/Comp/PeriodicQueryTaskForm.elm b/modules/webapp/src/main/elm/Messages/Comp/PeriodicQueryTaskForm.elm index e988ce72..49e717a7 100644 --- a/modules/webapp/src/main/elm/Messages/Comp/PeriodicQueryTaskForm.elm +++ b/modules/webapp/src/main/elm/Messages/Comp/PeriodicQueryTaskForm.elm @@ -42,6 +42,10 @@ type alias Texts = , channelRequired : String , queryStringRequired : String , channelHeader : ChannelType -> String + , messageContentTitle : String + , messageContentLabel : String + , messageContentInfo : String + , messageContentPlaceholder : String } @@ -71,6 +75,10 @@ gb = , channelRequired = "A valid channel must be given." , queryStringRequired = "A query string and/or bookmark must be supplied" , channelHeader = \ct -> "Connection details for " ++ Messages.Data.ChannelType.gb ct + , messageContentTitle = "Customize message" + , messageContentLabel = "Beginning of message" + , messageContentInfo = "Insert text that is prependend to the generated message." + , messageContentPlaceholder = "Hello, this is Docspell informing you about new items …" } @@ -100,4 +108,8 @@ de = , channelRequired = "Ein Versandkanal muss angegeben werden." , queryStringRequired = "Eine Suchabfrage und/oder ein Bookmark muss angegeben werden." , channelHeader = \ct -> "Details für " ++ Messages.Data.ChannelType.de ct + , messageContentTitle = "Nachricht anpassen" + , messageContentLabel = "Anfang der Nachricht" + , messageContentInfo = "Dieser Text wird an den Anfang der generierten Nachricht angefügt." + , messageContentPlaceholder = "Hallo, hier ist Docspell mit den nächsten Themen …" }