mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-04-05 02:49:32 +00:00
Change "empty trash" settings for a collective and submit the job
This commit is contained in:
parent
828e5cf703
commit
4901276c66
@ -62,6 +62,8 @@ trait OCollective[F[_]] {
|
||||
|
||||
def startLearnClassifier(collective: Ident): F[Unit]
|
||||
|
||||
def startEmptyTrash(collective: Ident): F[Unit]
|
||||
|
||||
/** Submits a task that (re)generates the preview images for all
|
||||
* attachments of the given collective.
|
||||
*/
|
||||
@ -147,9 +149,14 @@ object OCollective {
|
||||
.transact(RCollective.updateSettings(collective, sett))
|
||||
.attempt
|
||||
.map(AddResult.fromUpdate)
|
||||
.flatMap(res => updateLearnClassifierTask(collective, sett) *> res.pure[F])
|
||||
.flatMap(res =>
|
||||
updateLearnClassifierTask(collective, sett) *> updateEmptyTrashTask(
|
||||
collective,
|
||||
sett
|
||||
) *> res.pure[F]
|
||||
)
|
||||
|
||||
def updateLearnClassifierTask(coll: Ident, sett: Settings) =
|
||||
private def updateLearnClassifierTask(coll: Ident, sett: Settings): F[Unit] =
|
||||
for {
|
||||
id <- Ident.randomId[F]
|
||||
on = sett.classifier.map(_.enabled).getOrElse(false)
|
||||
@ -166,6 +173,22 @@ object OCollective {
|
||||
_ <- joex.notifyAllNodes
|
||||
} yield ()
|
||||
|
||||
private def updateEmptyTrashTask(coll: Ident, sett: Settings): F[Unit] =
|
||||
for {
|
||||
id <- Ident.randomId[F]
|
||||
timer = sett.emptyTrash.getOrElse(CalEvent.unsafe(""))
|
||||
ut = UserTask(
|
||||
id,
|
||||
EmptyTrashArgs.taskName,
|
||||
true,
|
||||
timer,
|
||||
None,
|
||||
EmptyTrashArgs(coll)
|
||||
)
|
||||
_ <- uts.updateOneTask(AccountId(coll, EmptyTrashArgs.taskName), ut)
|
||||
_ <- joex.notifyAllNodes
|
||||
} yield ()
|
||||
|
||||
def startLearnClassifier(collective: Ident): F[Unit] =
|
||||
for {
|
||||
id <- Ident.randomId[F]
|
||||
@ -182,6 +205,22 @@ object OCollective {
|
||||
_ <- joex.notifyAllNodes
|
||||
} yield ()
|
||||
|
||||
def startEmptyTrash(collective: Ident): F[Unit] =
|
||||
for {
|
||||
id <- Ident.randomId[F]
|
||||
ut <- UserTask(
|
||||
id,
|
||||
EmptyTrashArgs.taskName,
|
||||
true,
|
||||
CalEvent(WeekdayComponent.All, DateEvent.All, TimeEvent.All),
|
||||
None,
|
||||
EmptyTrashArgs(collective)
|
||||
).encode.toPeriodicTask(AccountId(collective, EmptyTrashArgs.taskName))
|
||||
job <- ut.toJob
|
||||
_ <- queue.insert(job)
|
||||
_ <- joex.notifyAllNodes
|
||||
} yield ()
|
||||
|
||||
def findSettings(collective: Ident): F[Option[OCollective.Settings]] =
|
||||
store.transact(RCollective.getSettings(collective))
|
||||
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2020 Docspell Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package docspell.common
|
||||
|
||||
import docspell.common.syntax.all._
|
||||
|
||||
import io.circe._
|
||||
import io.circe.generic.semiauto._
|
||||
|
||||
/** Arguments to the empty-trash task.
|
||||
*
|
||||
* This task is run periodically to really delete all soft-deleted
|
||||
* items. These are items with state `ItemState.Deleted`.
|
||||
*/
|
||||
case class EmptyTrashArgs(
|
||||
collective: Ident
|
||||
) {
|
||||
|
||||
def makeSubject: String =
|
||||
"Empty trash "
|
||||
|
||||
}
|
||||
|
||||
object EmptyTrashArgs {
|
||||
|
||||
val taskName = Ident.unsafe("empty-trash")
|
||||
|
||||
implicit val jsonEncoder: Encoder[EmptyTrashArgs] =
|
||||
deriveEncoder[EmptyTrashArgs]
|
||||
implicit val jsonDecoder: Decoder[EmptyTrashArgs] =
|
||||
deriveDecoder[EmptyTrashArgs]
|
||||
|
||||
def parse(str: String): Either[Throwable, EmptyTrashArgs] =
|
||||
str.parseJsonAs[EmptyTrashArgs]
|
||||
|
||||
}
|
@ -1136,6 +1136,27 @@ paths:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BasicResult"
|
||||
|
||||
/sec/collective/emptytrash/startonce:
|
||||
post:
|
||||
operationId: "sec-collective-emptytrash-start-now"
|
||||
tags: [ Collective ]
|
||||
summary: Starts the empty trash task
|
||||
description: |
|
||||
Submits a task to remove all items from the database that have
|
||||
been "soft-deleted". This task is also run periodically and
|
||||
can be triggered here to be immediatly submitted.
|
||||
|
||||
The request is empty, settings are used from the collective.
|
||||
security:
|
||||
- authTokenHeader: []
|
||||
responses:
|
||||
200:
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BasicResult"
|
||||
|
||||
/sec/user:
|
||||
get:
|
||||
operationId: "sec-user-get-all"
|
||||
@ -5246,6 +5267,7 @@ components:
|
||||
- language
|
||||
- integrationEnabled
|
||||
- classifier
|
||||
- emptyTrashSchedule
|
||||
properties:
|
||||
language:
|
||||
type: string
|
||||
@ -5255,6 +5277,9 @@ components:
|
||||
description: |
|
||||
Whether the collective has the integration endpoint
|
||||
enabled.
|
||||
emptyTrashSchedule:
|
||||
type: string
|
||||
format: calevent
|
||||
classifier:
|
||||
$ref: "#/components/schemas/ClassifierSetting"
|
||||
|
||||
|
@ -55,7 +55,8 @@ object CollectiveRoutes {
|
||||
settings.classifier.categoryList,
|
||||
settings.classifier.listType
|
||||
)
|
||||
)
|
||||
),
|
||||
Some(settings.emptyTrashSchedule)
|
||||
)
|
||||
res <-
|
||||
backend.collective
|
||||
@ -70,6 +71,7 @@ object CollectiveRoutes {
|
||||
CollectiveSettings(
|
||||
c.language,
|
||||
c.integrationEnabled,
|
||||
c.emptyTrash.getOrElse(CalEvent.unsafe("*-*-1/7 03:00:00")),
|
||||
ClassifierSetting(
|
||||
c.classifier.map(_.itemCount).getOrElse(0),
|
||||
c.classifier
|
||||
@ -101,6 +103,12 @@ object CollectiveRoutes {
|
||||
resp <- Ok(BasicResult(true, "Task submitted"))
|
||||
} yield resp
|
||||
|
||||
case POST -> Root / "emptytrash" / "startonce" =>
|
||||
for {
|
||||
_ <- backend.collective.startEmptyTrash(user.account.collective)
|
||||
resp <- Ok(BasicResult(true, "Task submitted"))
|
||||
} yield resp
|
||||
|
||||
case GET -> Root =>
|
||||
for {
|
||||
collDb <- backend.collective.find(user.account.collective)
|
||||
|
@ -0,0 +1,6 @@
|
||||
CREATE TABLE "empty_trash_setting" (
|
||||
"cid" varchar(254) not null primary key,
|
||||
"schedule" varchar(254) not null,
|
||||
"created" timestamp not null,
|
||||
foreign key ("cid") references "collective"("cid")
|
||||
);
|
@ -0,0 +1,6 @@
|
||||
CREATE TABLE `empty_trash_setting` (
|
||||
`cid` varchar(254) not null primary key,
|
||||
`schedule` varchar(254) not null,
|
||||
`created` timestamp not null,
|
||||
foreign key (`cid`) references `collective`(`cid`)
|
||||
);
|
@ -0,0 +1,6 @@
|
||||
CREATE TABLE "empty_trash_setting" (
|
||||
"cid" varchar(254) not null primary key,
|
||||
"schedule" varchar(254) not null,
|
||||
"created" timestamp not null,
|
||||
foreign key ("cid") references "collective"("cid")
|
||||
);
|
@ -13,6 +13,7 @@ import docspell.common._
|
||||
import docspell.store.qb.DSL._
|
||||
import docspell.store.qb._
|
||||
|
||||
import com.github.eikek.calev._
|
||||
import doobie._
|
||||
import doobie.implicits._
|
||||
|
||||
@ -73,17 +74,21 @@ object RCollective {
|
||||
T.integration.setTo(settings.integrationEnabled)
|
||||
)
|
||||
)
|
||||
cls <-
|
||||
Timestamp
|
||||
.current[ConnectionIO]
|
||||
.map(now => settings.classifier.map(_.toRecord(cid, now)))
|
||||
now <- Timestamp.current[ConnectionIO]
|
||||
cls = settings.classifier.map(_.toRecord(cid, now))
|
||||
n2 <- cls match {
|
||||
case Some(cr) =>
|
||||
RClassifierSetting.update(cr)
|
||||
case None =>
|
||||
RClassifierSetting.delete(cid)
|
||||
}
|
||||
} yield n1 + n2
|
||||
n3 <- settings.emptyTrash match {
|
||||
case Some(trashSchedule) =>
|
||||
REmptyTrashSetting.update(REmptyTrashSetting(cid, trashSchedule, now))
|
||||
case None =>
|
||||
REmptyTrashSetting.delete(cid)
|
||||
}
|
||||
} yield n1 + n2 + n3
|
||||
|
||||
// this hides categories that have been deleted in the meantime
|
||||
// they are finally removed from the json array once the learn classifier task is run
|
||||
@ -99,6 +104,7 @@ object RCollective {
|
||||
import RClassifierSetting.stringListMeta
|
||||
val c = RCollective.as("c")
|
||||
val cs = RClassifierSetting.as("cs")
|
||||
val es = REmptyTrashSetting.as("es")
|
||||
|
||||
Select(
|
||||
select(
|
||||
@ -107,9 +113,10 @@ object RCollective {
|
||||
cs.schedule.s,
|
||||
cs.itemCount.s,
|
||||
cs.categories.s,
|
||||
cs.listType.s
|
||||
cs.listType.s,
|
||||
es.schedule.s
|
||||
),
|
||||
from(c).leftJoin(cs, cs.cid === c.id),
|
||||
from(c).leftJoin(cs, cs.cid === c.id).leftJoin(es, es.cid === c.id),
|
||||
c.id === coll
|
||||
).build.query[Settings].option
|
||||
}
|
||||
@ -160,7 +167,8 @@ object RCollective {
|
||||
case class Settings(
|
||||
language: Language,
|
||||
integrationEnabled: Boolean,
|
||||
classifier: Option[RClassifierSetting.Classifier]
|
||||
classifier: Option[RClassifierSetting.Classifier],
|
||||
emptyTrash: Option[CalEvent]
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2020 Docspell Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package docspell.store.records
|
||||
|
||||
import cats.data.NonEmptyList
|
||||
import cats.implicits._
|
||||
|
||||
import docspell.common._
|
||||
import docspell.store.qb.DSL._
|
||||
import docspell.store.qb._
|
||||
|
||||
import com.github.eikek.calev._
|
||||
import doobie._
|
||||
import doobie.implicits._
|
||||
|
||||
final case class REmptyTrashSetting(
|
||||
cid: Ident,
|
||||
schedule: CalEvent,
|
||||
created: Timestamp
|
||||
)
|
||||
|
||||
object REmptyTrashSetting {
|
||||
|
||||
final case class Table(alias: Option[String]) extends TableDef {
|
||||
val tableName = "empty_trash_setting"
|
||||
|
||||
val cid = Column[Ident]("cid", this)
|
||||
val schedule = Column[CalEvent]("schedule", this)
|
||||
val created = Column[Timestamp]("created", this)
|
||||
val all = NonEmptyList.of[Column[_]](cid, schedule, created)
|
||||
}
|
||||
|
||||
val T = Table(None)
|
||||
def as(alias: String): Table =
|
||||
Table(Some(alias))
|
||||
|
||||
def insert(v: REmptyTrashSetting): ConnectionIO[Int] =
|
||||
DML.insert(
|
||||
T,
|
||||
T.all,
|
||||
fr"${v.cid},${v.schedule},${v.created}"
|
||||
)
|
||||
|
||||
def update(v: REmptyTrashSetting): ConnectionIO[Int] =
|
||||
for {
|
||||
n1 <- DML.update(
|
||||
T,
|
||||
T.cid === v.cid,
|
||||
DML.set(
|
||||
T.schedule.setTo(v.schedule)
|
||||
)
|
||||
)
|
||||
n2 <- if (n1 <= 0) insert(v) else 0.pure[ConnectionIO]
|
||||
} yield n1 + n2
|
||||
|
||||
def findById(id: Ident): ConnectionIO[Option[REmptyTrashSetting]] = {
|
||||
val sql = run(select(T.all), from(T), T.cid === id)
|
||||
sql.query[REmptyTrashSetting].option
|
||||
}
|
||||
|
||||
def delete(coll: Ident): ConnectionIO[Int] =
|
||||
DML.delete(T, T.cid === coll)
|
||||
|
||||
}
|
@ -130,6 +130,7 @@ module Api exposing
|
||||
, setTagsMultiple
|
||||
, setUnconfirmed
|
||||
, startClassifier
|
||||
, startEmptyTrash
|
||||
, startOnceNotifyDueItems
|
||||
, startOnceScanMailbox
|
||||
, startReIndex
|
||||
@ -996,6 +997,19 @@ startClassifier flags receive =
|
||||
}
|
||||
|
||||
|
||||
startEmptyTrash :
|
||||
Flags
|
||||
-> (Result Http.Error BasicResult -> msg)
|
||||
-> Cmd msg
|
||||
startEmptyTrash flags receive =
|
||||
Http2.authPost
|
||||
{ url = flags.config.baseUrl ++ "/api/v1/sec/collective/emptytrash/startonce"
|
||||
, account = getAccount flags
|
||||
, body = Http.emptyBody
|
||||
, expect = Http.expectJson receive Api.Model.BasicResult.decoder
|
||||
}
|
||||
|
||||
|
||||
getTagCloud : Flags -> (Result Http.Error TagCloud -> msg) -> Cmd msg
|
||||
getTagCloud flags receive =
|
||||
Http2.authGet
|
||||
|
@ -20,7 +20,9 @@ import Api.Model.CollectiveSettings exposing (CollectiveSettings)
|
||||
import Comp.Basic as B
|
||||
import Comp.ClassifierSettingsForm
|
||||
import Comp.Dropdown
|
||||
import Comp.EmptyTrashForm
|
||||
import Comp.MenuBar as MB
|
||||
import Data.CalEvent
|
||||
import Data.DropdownStyle as DS
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Language exposing (Language)
|
||||
@ -41,6 +43,8 @@ type alias Model =
|
||||
, fullTextReIndexResult : FulltextReindexResult
|
||||
, classifierModel : Comp.ClassifierSettingsForm.Model
|
||||
, startClassifierResult : ClassifierResult
|
||||
, emptyTrashModel : Comp.EmptyTrashForm.Model
|
||||
, startEmptyTrashResult : EmptyTrashResult
|
||||
}
|
||||
|
||||
|
||||
@ -50,6 +54,11 @@ type ClassifierResult
|
||||
| ClassifierResultSubmitError String
|
||||
| ClassifierResultOk
|
||||
|
||||
type EmptyTrashResult
|
||||
= EmptyTrashResultInitial
|
||||
| EmptyTrashResultHttpError Http.Error
|
||||
| EmptyTrashResultSubmitError String
|
||||
| EmptyTrashResultOk
|
||||
|
||||
type FulltextReindexResult
|
||||
= FulltextReindexInitial
|
||||
@ -68,6 +77,9 @@ init flags settings =
|
||||
|
||||
( cm, cc ) =
|
||||
Comp.ClassifierSettingsForm.init flags settings.classifier
|
||||
|
||||
( em, ec ) =
|
||||
Comp.EmptyTrashForm.init flags settings.emptyTrashSchedule
|
||||
in
|
||||
( { langModel =
|
||||
Comp.Dropdown.makeSingleList
|
||||
@ -80,8 +92,10 @@ init flags settings =
|
||||
, fullTextReIndexResult = FulltextReindexInitial
|
||||
, classifierModel = cm
|
||||
, startClassifierResult = ClassifierResultInitial
|
||||
, emptyTrashModel = em
|
||||
, startEmptyTrashResult = EmptyTrashResultInitial
|
||||
}
|
||||
, Cmd.map ClassifierSettingMsg cc
|
||||
, Cmd.batch [ Cmd.map ClassifierSettingMsg cc, Cmd.map EmptyTrashMsg ec ]
|
||||
)
|
||||
|
||||
|
||||
@ -96,6 +110,10 @@ getSettings model =
|
||||
|> Maybe.withDefault model.initSettings.language
|
||||
, integrationEnabled = model.intEnabled
|
||||
, classifier = cls
|
||||
, emptyTrashSchedule =
|
||||
Comp.EmptyTrashForm.getSettings model.emptyTrashModel
|
||||
|> Maybe.withDefault Data.CalEvent.everyMonth
|
||||
|> Data.CalEvent.makeEvent
|
||||
}
|
||||
)
|
||||
(Comp.ClassifierSettingsForm.getSettings
|
||||
@ -110,9 +128,12 @@ type Msg
|
||||
| TriggerReIndex
|
||||
| TriggerReIndexResult (Result Http.Error BasicResult)
|
||||
| ClassifierSettingMsg Comp.ClassifierSettingsForm.Msg
|
||||
| EmptyTrashMsg Comp.EmptyTrashForm.Msg
|
||||
| SaveSettings
|
||||
| StartClassifierTask
|
||||
| StartEmptyTrashTask
|
||||
| StartClassifierResp (Result Http.Error BasicResult)
|
||||
| StartEmptyTrashResp (Result Http.Error BasicResult)
|
||||
|
||||
|
||||
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Maybe CollectiveSettings )
|
||||
@ -188,6 +209,18 @@ update flags msg model =
|
||||
, Nothing
|
||||
)
|
||||
|
||||
EmptyTrashMsg lmsg ->
|
||||
let
|
||||
( cm, cc ) =
|
||||
Comp.EmptyTrashForm.update flags lmsg model.emptyTrashModel
|
||||
in
|
||||
( { model
|
||||
| emptyTrashModel = cm
|
||||
}
|
||||
, Cmd.map EmptyTrashMsg cc
|
||||
, Nothing
|
||||
)
|
||||
|
||||
SaveSettings ->
|
||||
case getSettings model of
|
||||
Just s ->
|
||||
@ -199,6 +232,10 @@ update flags msg model =
|
||||
StartClassifierTask ->
|
||||
( model, Api.startClassifier flags StartClassifierResp, Nothing )
|
||||
|
||||
StartEmptyTrashTask ->
|
||||
( model, Api.startEmptyTrash flags StartEmptyTrashResp, Nothing )
|
||||
|
||||
|
||||
StartClassifierResp (Ok br) ->
|
||||
( { model
|
||||
| startClassifierResult =
|
||||
@ -218,6 +255,24 @@ update flags msg model =
|
||||
, Nothing
|
||||
)
|
||||
|
||||
StartEmptyTrashResp (Ok br) ->
|
||||
( { model
|
||||
| startEmptyTrashResult =
|
||||
if br.success then
|
||||
EmptyTrashResultOk
|
||||
|
||||
else
|
||||
EmptyTrashResultSubmitError br.message
|
||||
}
|
||||
, Cmd.none
|
||||
, Nothing
|
||||
)
|
||||
|
||||
StartEmptyTrashResp (Err err) ->
|
||||
( { model | startEmptyTrashResult = EmptyTrashResultHttpError err }
|
||||
, Cmd.none
|
||||
, Nothing
|
||||
)
|
||||
|
||||
|
||||
--- View2
|
||||
@ -257,7 +312,7 @@ view2 flags texts settings model =
|
||||
, end = []
|
||||
, rootClasses = "mb-4"
|
||||
}
|
||||
, h3 [ class S.header3 ]
|
||||
, h2 [ class S.header2 ]
|
||||
[ text texts.documentLanguage
|
||||
]
|
||||
, div [ class "mb-4" ]
|
||||
@ -279,8 +334,8 @@ view2 flags texts settings model =
|
||||
[ ( "hidden", not flags.config.integrationEnabled )
|
||||
]
|
||||
]
|
||||
[ h3
|
||||
[ class S.header3
|
||||
[ h2
|
||||
[ class S.header2
|
||||
]
|
||||
[ text texts.integrationEndpoint
|
||||
]
|
||||
@ -311,8 +366,8 @@ view2 flags texts settings model =
|
||||
[ ( "hidden", not flags.config.fullTextSearchEnabled )
|
||||
]
|
||||
]
|
||||
[ h3
|
||||
[ class S.header3 ]
|
||||
[ h2
|
||||
[ class S.header2 ]
|
||||
[ text texts.fulltextSearch ]
|
||||
, div
|
||||
[ class "mb-4" ]
|
||||
@ -348,8 +403,8 @@ view2 flags texts settings model =
|
||||
[ ( " hidden", not flags.config.showClassificationSettings )
|
||||
]
|
||||
]
|
||||
[ h3
|
||||
[ class S.header3 ]
|
||||
[ h2
|
||||
[ class S.header2 ]
|
||||
[ text texts.autoTagging
|
||||
]
|
||||
, div
|
||||
@ -371,6 +426,28 @@ view2 flags texts settings model =
|
||||
]
|
||||
]
|
||||
]
|
||||
, div []
|
||||
[ h2 [ class S.header2 ]
|
||||
[ text texts.emptyTrash
|
||||
]
|
||||
, div [ class "mb-4" ]
|
||||
[ Html.map EmptyTrashMsg
|
||||
(Comp.EmptyTrashForm.view texts.emptyTrashForm
|
||||
settings
|
||||
model.emptyTrashModel
|
||||
)
|
||||
, div [ class "flex flex-row justify-end" ]
|
||||
[ B.secondaryBasicButton
|
||||
{ handler = onClick StartEmptyTrashTask
|
||||
, icon = "fa fa-play"
|
||||
, label = texts.startNow
|
||||
, disabled = model.emptyTrashModel.schedule == Nothing
|
||||
, attrs = [ href "#" ]
|
||||
}
|
||||
, renderEmptyTrashResultMessage texts model.startEmptyTrashResult
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
@ -427,3 +504,38 @@ renderFulltextReindexResultMessage texts result =
|
||||
|
||||
FulltextReindexSubmitError m ->
|
||||
text m
|
||||
|
||||
renderEmptyTrashResultMessage : Texts -> EmptyTrashResult -> Html msg
|
||||
renderEmptyTrashResultMessage texts result =
|
||||
let
|
||||
isSuccess =
|
||||
case result of
|
||||
EmptyTrashResultOk ->
|
||||
True
|
||||
|
||||
_ ->
|
||||
False
|
||||
|
||||
isError =
|
||||
not isSuccess
|
||||
in
|
||||
div
|
||||
[ classList
|
||||
[ ( S.errorMessage, isError )
|
||||
, ( S.successMessage, isSuccess )
|
||||
, ( "hidden", result == EmptyTrashResultInitial )
|
||||
]
|
||||
]
|
||||
[ case result of
|
||||
EmptyTrashResultInitial ->
|
||||
text ""
|
||||
|
||||
EmptyTrashResultOk ->
|
||||
text texts.emptyTrashTaskStarted
|
||||
|
||||
EmptyTrashResultHttpError err ->
|
||||
text (texts.httpError err)
|
||||
|
||||
EmptyTrashResultSubmitError m ->
|
||||
text m
|
||||
]
|
||||
|
106
modules/webapp/src/main/elm/Comp/EmptyTrashForm.elm
Normal file
106
modules/webapp/src/main/elm/Comp/EmptyTrashForm.elm
Normal file
@ -0,0 +1,106 @@
|
||||
{-
|
||||
Copyright 2020 Docspell Contributors
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Comp.EmptyTrashForm exposing
|
||||
( Model
|
||||
, Msg
|
||||
, getSettings
|
||||
, init
|
||||
, update
|
||||
, view
|
||||
)
|
||||
|
||||
import Api
|
||||
import Comp.CalEventInput
|
||||
import Comp.Dropdown
|
||||
import Comp.FixedDropdown
|
||||
import Comp.IntField
|
||||
import Data.CalEvent exposing (CalEvent)
|
||||
import Data.DropdownStyle as DS
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.ListType exposing (ListType)
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Http
|
||||
import Markdown
|
||||
import Messages.Comp.EmptyTrashForm exposing (Texts)
|
||||
import Styles as S
|
||||
import Util.Tag
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ scheduleModel : Comp.CalEventInput.Model
|
||||
, schedule : Maybe CalEvent
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= ScheduleMsg Comp.CalEventInput.Msg
|
||||
|
||||
|
||||
init : Flags -> String -> ( Model, Cmd Msg )
|
||||
init flags schedule =
|
||||
let
|
||||
newSchedule =
|
||||
Data.CalEvent.fromEvent schedule
|
||||
|> Maybe.withDefault Data.CalEvent.everyMonth
|
||||
|
||||
( cem, cec ) =
|
||||
Comp.CalEventInput.init flags newSchedule
|
||||
in
|
||||
( { scheduleModel = cem
|
||||
, schedule = Just newSchedule
|
||||
}
|
||||
, Cmd.map ScheduleMsg cec
|
||||
)
|
||||
|
||||
|
||||
getSettings : Model -> Maybe CalEvent
|
||||
getSettings model =
|
||||
model.schedule
|
||||
|
||||
|
||||
update : Flags -> Msg -> Model -> ( Model, Cmd Msg )
|
||||
update flags msg model =
|
||||
case msg of
|
||||
ScheduleMsg lmsg ->
|
||||
let
|
||||
( cm, cc, ce ) =
|
||||
Comp.CalEventInput.update
|
||||
flags
|
||||
model.schedule
|
||||
lmsg
|
||||
model.scheduleModel
|
||||
in
|
||||
( { model
|
||||
| scheduleModel = cm
|
||||
, schedule = ce
|
||||
}
|
||||
, Cmd.map ScheduleMsg cc
|
||||
)
|
||||
|
||||
|
||||
|
||||
--- View2
|
||||
|
||||
|
||||
view : Texts -> UiSettings -> Model -> Html Msg
|
||||
view texts _ model =
|
||||
div []
|
||||
[ div [ class "mb-4" ]
|
||||
[ label [ class S.inputLabel ]
|
||||
[ text texts.schedule ]
|
||||
, Html.map ScheduleMsg
|
||||
(Comp.CalEventInput.view2
|
||||
texts.calEventInput
|
||||
""
|
||||
model.schedule
|
||||
model.scheduleModel
|
||||
)
|
||||
]
|
||||
]
|
@ -15,6 +15,7 @@ import Data.Language exposing (Language)
|
||||
import Http
|
||||
import Messages.Basics
|
||||
import Messages.Comp.ClassifierSettingsForm
|
||||
import Messages.Comp.EmptyTrashForm
|
||||
import Messages.Comp.HttpError
|
||||
import Messages.Data.Language
|
||||
|
||||
@ -22,6 +23,7 @@ import Messages.Data.Language
|
||||
type alias Texts =
|
||||
{ basics : Messages.Basics.Texts
|
||||
, classifierSettingsForm : Messages.Comp.ClassifierSettingsForm.Texts
|
||||
, emptyTrashForm : Messages.Comp.EmptyTrashForm.Texts
|
||||
, httpError : Http.Error -> String
|
||||
, save : String
|
||||
, saveSettings : String
|
||||
@ -37,8 +39,10 @@ type alias Texts =
|
||||
, startNow : String
|
||||
, languageLabel : Language -> String
|
||||
, classifierTaskStarted : String
|
||||
, emptyTrashTaskStarted : String
|
||||
, fulltextReindexSubmitted : String
|
||||
, fulltextReindexOkMissing : String
|
||||
, emptyTrash : String
|
||||
}
|
||||
|
||||
|
||||
@ -46,6 +50,7 @@ gb : Texts
|
||||
gb =
|
||||
{ basics = Messages.Basics.gb
|
||||
, classifierSettingsForm = Messages.Comp.ClassifierSettingsForm.gb
|
||||
, emptyTrashForm = Messages.Comp.EmptyTrashForm.gb
|
||||
, httpError = Messages.Comp.HttpError.gb
|
||||
, save = "Save"
|
||||
, saveSettings = "Save Settings"
|
||||
@ -65,9 +70,11 @@ gb =
|
||||
, startNow = "Start now"
|
||||
, languageLabel = Messages.Data.Language.gb
|
||||
, classifierTaskStarted = "Classifier task started."
|
||||
, emptyTrashTaskStarted = "Empty trash task started."
|
||||
, fulltextReindexSubmitted = "Fulltext Re-Index started."
|
||||
, fulltextReindexOkMissing =
|
||||
"Please type OK in the field if you really want to start re-indexing your data."
|
||||
, emptyTrash = "Empty Trash"
|
||||
}
|
||||
|
||||
|
||||
@ -75,6 +82,7 @@ de : Texts
|
||||
de =
|
||||
{ basics = Messages.Basics.de
|
||||
, classifierSettingsForm = Messages.Comp.ClassifierSettingsForm.de
|
||||
, emptyTrashForm = Messages.Comp.EmptyTrashForm.de
|
||||
, httpError = Messages.Comp.HttpError.de
|
||||
, save = "Speichern"
|
||||
, saveSettings = "Einstellungen speichern"
|
||||
@ -94,7 +102,9 @@ de =
|
||||
, startNow = "Jetzt starten"
|
||||
, languageLabel = Messages.Data.Language.de
|
||||
, classifierTaskStarted = "Kategorisierung gestartet."
|
||||
, emptyTrashTaskStarted = "Papierkorb löschen gestartet."
|
||||
, fulltextReindexSubmitted = "Volltext Neu-Indexierung gestartet."
|
||||
, fulltextReindexOkMissing =
|
||||
"Bitte tippe OK in das Feld ein, wenn Du wirklich den Index neu erzeugen möchtest."
|
||||
, emptyTrash = "Papierkorb löschen"
|
||||
}
|
||||
|
38
modules/webapp/src/main/elm/Messages/Comp/EmptyTrashForm.elm
Normal file
38
modules/webapp/src/main/elm/Messages/Comp/EmptyTrashForm.elm
Normal file
@ -0,0 +1,38 @@
|
||||
{-
|
||||
Copyright 2020 Docspell Contributors
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Messages.Comp.EmptyTrashForm exposing
|
||||
( Texts
|
||||
, de
|
||||
, gb
|
||||
)
|
||||
|
||||
import Messages.Basics
|
||||
import Messages.Comp.CalEventInput
|
||||
|
||||
|
||||
type alias Texts =
|
||||
{ basics : Messages.Basics.Texts
|
||||
, calEventInput : Messages.Comp.CalEventInput.Texts
|
||||
, schedule : String
|
||||
}
|
||||
|
||||
|
||||
gb : Texts
|
||||
gb =
|
||||
{ basics = Messages.Basics.gb
|
||||
, calEventInput = Messages.Comp.CalEventInput.gb
|
||||
, schedule = "Schedule"
|
||||
}
|
||||
|
||||
|
||||
de : Texts
|
||||
de =
|
||||
{ basics = Messages.Basics.de
|
||||
, calEventInput = Messages.Comp.CalEventInput.de
|
||||
, schedule = "Zeitplan"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user