mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-03-31 05:15:08 +00:00
Improve form
This commit is contained in:
parent
5a2e28415a
commit
3a90d874a5
@ -15,6 +15,10 @@ trait OTag[F[_]] {
|
||||
def update(s: RTag): F[AddResult]
|
||||
|
||||
def delete(id: Ident, collective: Ident): F[AddResult]
|
||||
|
||||
/** Load all tags given their ids. Ids that are not available are ignored.
|
||||
*/
|
||||
def loadAll(ids: List[Ident]): F[Vector[RTag]]
|
||||
}
|
||||
|
||||
object OTag {
|
||||
@ -48,5 +52,9 @@ object OTag {
|
||||
} yield n0.getOrElse(0) + n1.getOrElse(0)
|
||||
store.transact(io).attempt.map(AddResult.fromUpdate)
|
||||
}
|
||||
|
||||
def loadAll(ids: List[Ident]): F[Vector[RTag]] =
|
||||
if (ids.isEmpty) Vector.empty.pure[F]
|
||||
else store.transact(RTag.findAllById(ids))
|
||||
})
|
||||
}
|
||||
|
@ -1597,7 +1597,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/NotificationData"
|
||||
$ref: "#/components/schemas/NotificationSettings"
|
||||
post:
|
||||
tags: [ Notification ]
|
||||
summary: Change current settings for "Notify Due Items" task
|
||||
@ -1683,27 +1683,11 @@ components:
|
||||
tagsInclude:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: ident
|
||||
$ref: "#/components/schemas/Tag"
|
||||
tagsExclude:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: ident
|
||||
NotificationData:
|
||||
description: |
|
||||
Data for the notification settings.
|
||||
required:
|
||||
- settings
|
||||
properties:
|
||||
settings:
|
||||
$ref: "#/components/schemas/NotificationSettings"
|
||||
nextRun:
|
||||
type: integer
|
||||
format: date-time
|
||||
lastRun:
|
||||
type: integer
|
||||
format: date-time
|
||||
$ref: "#/components/schemas/Tag"
|
||||
SentMails:
|
||||
description: |
|
||||
A list of sent mails.
|
||||
|
@ -25,7 +25,8 @@ object NotifyDueItemsRoutes {
|
||||
case GET -> Root =>
|
||||
for {
|
||||
task <- ut.getNotifyDueItems(user.account)
|
||||
resp <- Ok(convert(task))
|
||||
res <- taskToSettings(user.account, backend, task)
|
||||
resp <- Ok(res)
|
||||
} yield resp
|
||||
|
||||
case req @ POST -> Root =>
|
||||
@ -41,9 +42,6 @@ object NotifyDueItemsRoutes {
|
||||
}
|
||||
}
|
||||
|
||||
def convert(task: UserTask[NotifyDueItemsArgs]): NotificationData =
|
||||
NotificationData(taskToSettings(task), None, None)
|
||||
|
||||
def makeTask(
|
||||
user: AccountId,
|
||||
settings: NotificationSettings
|
||||
@ -58,20 +56,34 @@ object NotifyDueItemsRoutes {
|
||||
settings.smtpConnection,
|
||||
settings.recipients,
|
||||
settings.remindDays,
|
||||
settings.tagsInclude.map(Ident.unsafe),
|
||||
settings.tagsExclude.map(Ident.unsafe)
|
||||
settings.tagsInclude.map(_.id),
|
||||
settings.tagsExclude.map(_.id)
|
||||
)
|
||||
)
|
||||
|
||||
def taskToSettings(task: UserTask[NotifyDueItemsArgs]): NotificationSettings =
|
||||
NotificationSettings(
|
||||
// TODO this should be inside the backend code and not here
|
||||
def taskToSettings[F[_]: Sync](
|
||||
account: AccountId,
|
||||
backend: BackendApp[F],
|
||||
task: UserTask[NotifyDueItemsArgs]
|
||||
): F[NotificationSettings] =
|
||||
for {
|
||||
tinc <- backend.tag.loadAll(task.args.tagsInclude)
|
||||
texc <- backend.tag.loadAll(task.args.tagsExclude)
|
||||
conn <- backend.mail
|
||||
.getSettings(account, None)
|
||||
.map(
|
||||
_.find(_.name == task.args.smtpConnection)
|
||||
.map(_.name)
|
||||
)
|
||||
} yield NotificationSettings(
|
||||
task.id,
|
||||
task.enabled,
|
||||
task.args.smtpConnection,
|
||||
conn.getOrElse(Ident.unsafe("none")),
|
||||
task.args.recipients,
|
||||
task.timer,
|
||||
task.args.remindDays,
|
||||
task.args.tagsInclude.map(_.id),
|
||||
task.args.tagsExclude.map(_.id)
|
||||
tinc.map(Conversions.mkTag).toList,
|
||||
texc.map(Conversions.mkTag).toList
|
||||
)
|
||||
}
|
||||
|
@ -82,6 +82,11 @@ object RTag {
|
||||
sql.query[RTag].to[Vector]
|
||||
}
|
||||
|
||||
def findAllById(ids: List[Ident]): ConnectionIO[Vector[RTag]] =
|
||||
selectSimple(all, table, tid.isIn(ids.map(id => sql"$id").toSeq))
|
||||
.query[RTag]
|
||||
.to[Vector]
|
||||
|
||||
def findByItem(itemId: Ident): ConnectionIO[Vector[RTag]] = {
|
||||
val rcol = all.map(_.prefix("t"))
|
||||
(selectSimple(
|
||||
|
@ -21,6 +21,7 @@ module Api exposing
|
||||
, getJobQueueState
|
||||
, getJobQueueStateIn
|
||||
, getMailSettings
|
||||
, getNotifyDueItems
|
||||
, getOrgLight
|
||||
, getOrganizations
|
||||
, getPersons
|
||||
@ -85,6 +86,7 @@ import Api.Model.ItemProposals exposing (ItemProposals)
|
||||
import Api.Model.ItemSearch exposing (ItemSearch)
|
||||
import Api.Model.ItemUploadMeta exposing (ItemUploadMeta)
|
||||
import Api.Model.JobQueueState exposing (JobQueueState)
|
||||
import Api.Model.NotificationSettings exposing (NotificationSettings)
|
||||
import Api.Model.OptionalDate exposing (OptionalDate)
|
||||
import Api.Model.OptionalId exposing (OptionalId)
|
||||
import Api.Model.OptionalText exposing (OptionalText)
|
||||
@ -117,6 +119,22 @@ import Util.Http as Http2
|
||||
|
||||
|
||||
|
||||
--- NotifyDueItems
|
||||
|
||||
|
||||
getNotifyDueItems :
|
||||
Flags
|
||||
-> (Result Http.Error NotificationSettings -> msg)
|
||||
-> Cmd msg
|
||||
getNotifyDueItems flags receive =
|
||||
Http2.authGet
|
||||
{ url = flags.config.baseUrl ++ "/api/v1/sec/usertask/notifydueitems"
|
||||
, account = getAccount flags
|
||||
, expect = Http.expectJson receive Api.Model.NotificationSettings.decoder
|
||||
}
|
||||
|
||||
|
||||
|
||||
--- CalEvent
|
||||
|
||||
|
||||
|
@ -2,7 +2,6 @@ module Comp.CalEventInput exposing
|
||||
( Model
|
||||
, Msg
|
||||
, init
|
||||
, initialSchedule
|
||||
, update
|
||||
, view
|
||||
)
|
||||
@ -10,7 +9,9 @@ module Comp.CalEventInput exposing
|
||||
import Api
|
||||
import Api.Model.CalEventCheck exposing (CalEventCheck)
|
||||
import Api.Model.CalEventCheckResult exposing (CalEventCheckResult)
|
||||
import Data.CalEvent exposing (CalEvent)
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Validated exposing (Validated(..))
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onInput)
|
||||
@ -21,14 +22,7 @@ import Util.Time
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ year : String
|
||||
, month : String
|
||||
, day : String
|
||||
, hour : String
|
||||
, minute : String
|
||||
, weekday : Maybe String
|
||||
, event : Maybe String
|
||||
, checkResult : Maybe CalEventCheckResult
|
||||
{ checkResult : Maybe CalEventCheckResult
|
||||
}
|
||||
|
||||
|
||||
@ -39,68 +33,29 @@ type Msg
|
||||
| SetHour String
|
||||
| SetMinute String
|
||||
| SetWeekday String
|
||||
| CheckInputMsg (Result Http.Error CalEventCheckResult)
|
||||
| CheckInputMsg CalEvent (Result Http.Error CalEventCheckResult)
|
||||
|
||||
|
||||
initialSchedule : String
|
||||
initialSchedule =
|
||||
"*-*-01 00:00"
|
||||
init : Flags -> CalEvent -> ( Model, Cmd Msg )
|
||||
init flags ev =
|
||||
( Model Nothing, checkInput flags ev )
|
||||
|
||||
|
||||
init : Flags -> ( Model, Cmd Msg )
|
||||
init flags =
|
||||
checkInput : Flags -> CalEvent -> Cmd Msg
|
||||
checkInput flags ev =
|
||||
let
|
||||
model =
|
||||
{ year = "*"
|
||||
, month = "*"
|
||||
, day = "1"
|
||||
, hour = "0"
|
||||
, minute = "0"
|
||||
, weekday = Nothing
|
||||
, event = Nothing
|
||||
, checkResult = Nothing
|
||||
}
|
||||
in
|
||||
( model, checkInput flags model )
|
||||
|
||||
|
||||
toEvent : Model -> String
|
||||
toEvent model =
|
||||
let
|
||||
datetime =
|
||||
model.year
|
||||
++ "-"
|
||||
++ model.month
|
||||
++ "-"
|
||||
++ model.day
|
||||
++ " "
|
||||
++ model.hour
|
||||
++ ":"
|
||||
++ model.minute
|
||||
in
|
||||
case model.weekday of
|
||||
Just wd ->
|
||||
wd ++ " " ++ datetime
|
||||
|
||||
Nothing ->
|
||||
datetime
|
||||
|
||||
|
||||
checkInput : Flags -> Model -> Cmd Msg
|
||||
checkInput flags model =
|
||||
let
|
||||
event =
|
||||
toEvent model
|
||||
eventStr =
|
||||
Data.CalEvent.makeEvent ev
|
||||
|
||||
input =
|
||||
CalEventCheck event
|
||||
CalEventCheck eventStr
|
||||
in
|
||||
Api.checkCalEvent flags input CheckInputMsg
|
||||
Api.checkCalEvent flags input (CheckInputMsg ev)
|
||||
|
||||
|
||||
withCheckInput : Flags -> Model -> ( Model, Cmd Msg, Maybe String )
|
||||
withCheckInput flags model =
|
||||
( model, checkInput flags model, Nothing )
|
||||
withCheckInput : Flags -> CalEvent -> Model -> ( Model, Cmd Msg, Validated CalEvent )
|
||||
withCheckInput flags ev model =
|
||||
( model, checkInput flags ev, Unknown ev )
|
||||
|
||||
|
||||
isCheckError : Model -> Bool
|
||||
@ -110,46 +65,49 @@ isCheckError model =
|
||||
|> not
|
||||
|
||||
|
||||
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Maybe String )
|
||||
update flags msg model =
|
||||
update : Flags -> CalEvent -> Msg -> Model -> ( Model, Cmd Msg, Validated CalEvent )
|
||||
update flags ev msg model =
|
||||
case msg of
|
||||
SetYear str ->
|
||||
withCheckInput flags { model | year = str }
|
||||
withCheckInput flags { ev | year = str } model
|
||||
|
||||
SetMonth str ->
|
||||
withCheckInput flags { model | month = str }
|
||||
withCheckInput flags { ev | month = str } model
|
||||
|
||||
SetDay str ->
|
||||
withCheckInput flags { model | day = str }
|
||||
withCheckInput flags { ev | day = str } model
|
||||
|
||||
SetHour str ->
|
||||
withCheckInput flags { model | hour = str }
|
||||
withCheckInput flags { ev | hour = str } model
|
||||
|
||||
SetMinute str ->
|
||||
withCheckInput flags { model | minute = str }
|
||||
withCheckInput flags { ev | minute = str } model
|
||||
|
||||
SetWeekday str ->
|
||||
withCheckInput flags { model | weekday = Util.Maybe.fromString str }
|
||||
withCheckInput flags { ev | weekday = Util.Maybe.fromString str } model
|
||||
|
||||
CheckInputMsg (Ok res) ->
|
||||
CheckInputMsg event (Ok res) ->
|
||||
let
|
||||
m =
|
||||
{ model
|
||||
| event = res.event
|
||||
, checkResult = Just res
|
||||
}
|
||||
{ model | checkResult = Just res }
|
||||
in
|
||||
( m, Cmd.none, res.event )
|
||||
( m
|
||||
, Cmd.none
|
||||
, if res.success then
|
||||
Valid event
|
||||
|
||||
CheckInputMsg (Err err) ->
|
||||
else
|
||||
Invalid event
|
||||
)
|
||||
|
||||
CheckInputMsg event (Err err) ->
|
||||
let
|
||||
emptyResult =
|
||||
Api.Model.CalEventCheckResult.empty
|
||||
|
||||
m =
|
||||
{ model
|
||||
| event = Nothing
|
||||
, checkResult =
|
||||
| checkResult =
|
||||
Just
|
||||
{ emptyResult
|
||||
| success = False
|
||||
@ -157,14 +115,14 @@ update flags msg model =
|
||||
}
|
||||
}
|
||||
in
|
||||
( m, Cmd.none, Nothing )
|
||||
( m, Cmd.none, Unknown event )
|
||||
|
||||
|
||||
view : String -> Model -> Html Msg
|
||||
view extraClasses model =
|
||||
view : String -> CalEvent -> Model -> Html Msg
|
||||
view extraClasses ev model =
|
||||
let
|
||||
yearLen =
|
||||
Basics.max 4 (String.length model.year)
|
||||
Basics.max 4 (String.length ev.year)
|
||||
|
||||
otherLen str =
|
||||
Basics.max 2 (String.length str)
|
||||
@ -181,10 +139,10 @@ view extraClasses model =
|
||||
[ type_ "text"
|
||||
, class "time-input"
|
||||
, size
|
||||
(Maybe.map otherLen model.weekday
|
||||
(Maybe.map otherLen ev.weekday
|
||||
|> Maybe.withDefault 4
|
||||
)
|
||||
, Maybe.withDefault "" model.weekday
|
||||
, Maybe.withDefault "" ev.weekday
|
||||
|> value
|
||||
, onInput SetWeekday
|
||||
]
|
||||
@ -196,7 +154,7 @@ view extraClasses model =
|
||||
[ type_ "text"
|
||||
, class "time-input"
|
||||
, size yearLen
|
||||
, value model.year
|
||||
, value ev.year
|
||||
, onInput SetYear
|
||||
]
|
||||
[]
|
||||
@ -209,8 +167,8 @@ view extraClasses model =
|
||||
, input
|
||||
[ type_ "text"
|
||||
, class "time-input"
|
||||
, size (otherLen model.month)
|
||||
, value model.month
|
||||
, size (otherLen ev.month)
|
||||
, value ev.month
|
||||
, onInput SetMonth
|
||||
]
|
||||
[]
|
||||
@ -223,8 +181,8 @@ view extraClasses model =
|
||||
, input
|
||||
[ type_ "text"
|
||||
, class "time-input"
|
||||
, size (otherLen model.day)
|
||||
, value model.day
|
||||
, size (otherLen ev.day)
|
||||
, value ev.day
|
||||
, onInput SetDay
|
||||
]
|
||||
[]
|
||||
@ -237,8 +195,8 @@ view extraClasses model =
|
||||
, input
|
||||
[ type_ "text"
|
||||
, class "time-input"
|
||||
, size (otherLen model.hour)
|
||||
, value model.hour
|
||||
, size (otherLen ev.hour)
|
||||
, value ev.hour
|
||||
, onInput SetHour
|
||||
]
|
||||
[]
|
||||
@ -251,8 +209,8 @@ view extraClasses model =
|
||||
, input
|
||||
[ type_ "text"
|
||||
, class "time-input"
|
||||
, size (otherLen model.minute)
|
||||
, value model.minute
|
||||
, size (otherLen ev.minute)
|
||||
, value ev.minute
|
||||
, onInput SetMinute
|
||||
]
|
||||
[]
|
||||
|
@ -15,7 +15,9 @@ import Comp.CalEventInput
|
||||
import Comp.Dropdown
|
||||
import Comp.EmailInput
|
||||
import Comp.IntField
|
||||
import Data.CalEvent exposing (CalEvent)
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Validated exposing (Validated)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onCheck, onClick)
|
||||
@ -35,7 +37,7 @@ type alias Model =
|
||||
, remindDays : Maybe Int
|
||||
, remindDaysModel : Comp.IntField.Model
|
||||
, enabled : Bool
|
||||
, schedule : String
|
||||
, schedule : Validated CalEvent
|
||||
, scheduleModel : Comp.CalEventInput.Model
|
||||
, formError : Maybe String
|
||||
}
|
||||
@ -52,6 +54,7 @@ type Msg
|
||||
| RemindDaysMsg Comp.IntField.Msg
|
||||
| ToggleEnabled
|
||||
| CalEventMsg Comp.CalEventInput.Msg
|
||||
| SetNotificationSettings (Result Http.Error NotificationSettings)
|
||||
|
||||
|
||||
initCmd : Flags -> Cmd Msg
|
||||
@ -59,14 +62,18 @@ initCmd flags =
|
||||
Cmd.batch
|
||||
[ Api.getMailSettings flags "" ConnResp
|
||||
, Api.getTags flags "" GetTagsResp
|
||||
, Api.getNotifyDueItems flags SetNotificationSettings
|
||||
]
|
||||
|
||||
|
||||
init : Flags -> ( Model, Cmd Msg )
|
||||
init flags =
|
||||
let
|
||||
initialSchedule =
|
||||
Data.Validated.Unknown Data.CalEvent.everyMonth
|
||||
|
||||
( sm, sc ) =
|
||||
Comp.CalEventInput.init flags
|
||||
Comp.CalEventInput.init flags Data.CalEvent.everyMonth
|
||||
in
|
||||
( { settings = Api.Model.NotificationSettings.empty
|
||||
, connectionModel =
|
||||
@ -81,7 +88,7 @@ init flags =
|
||||
, remindDays = Just 1
|
||||
, remindDaysModel = Comp.IntField.init (Just 1) Nothing True "Remind Days"
|
||||
, enabled = False
|
||||
, schedule = Comp.CalEventInput.initialSchedule
|
||||
, schedule = initialSchedule
|
||||
, scheduleModel = sm
|
||||
, formError = Nothing
|
||||
}
|
||||
@ -98,10 +105,13 @@ update flags msg model =
|
||||
CalEventMsg lmsg ->
|
||||
let
|
||||
( cm, cc, cs ) =
|
||||
Comp.CalEventInput.update flags lmsg model.scheduleModel
|
||||
Comp.CalEventInput.update flags
|
||||
(Data.Validated.value model.schedule)
|
||||
lmsg
|
||||
model.scheduleModel
|
||||
in
|
||||
( { model
|
||||
| schedule = Maybe.withDefault model.schedule cs
|
||||
| schedule = cs
|
||||
, scheduleModel = cm
|
||||
}
|
||||
, Cmd.map CalEventMsg cc
|
||||
@ -141,7 +151,7 @@ update flags msg model =
|
||||
| connectionModel = cm
|
||||
, formError =
|
||||
if names == [] then
|
||||
Just "No E-Mail connections configured. Goto user settings to add one."
|
||||
Just "No E-Mail connections configured. Goto E-Mail Settings to add one."
|
||||
|
||||
else
|
||||
Nothing
|
||||
@ -199,7 +209,40 @@ update flags msg model =
|
||||
ToggleEnabled ->
|
||||
( { model | enabled = not model.enabled }, Cmd.none )
|
||||
|
||||
_ ->
|
||||
SetNotificationSettings (Ok s) ->
|
||||
let
|
||||
( nm, nc ) =
|
||||
Util.Update.andThen1
|
||||
[ update flags (ConnMsg (Comp.Dropdown.SetSelection [ s.smtpConnection ]))
|
||||
, update flags (TagIncMsg (Comp.Dropdown.SetSelection s.tagsInclude))
|
||||
, update flags (TagExcMsg (Comp.Dropdown.SetSelection s.tagsExclude))
|
||||
]
|
||||
model
|
||||
|
||||
newSchedule =
|
||||
Data.CalEvent.fromEvent s.schedule
|
||||
|> Maybe.withDefault Data.CalEvent.everyMonth
|
||||
|
||||
( sm, sc ) =
|
||||
Comp.CalEventInput.init flags newSchedule
|
||||
in
|
||||
( { nm
|
||||
| settings = s
|
||||
, recipients = s.recipients
|
||||
, remindDays = Just s.remindDays
|
||||
, enabled = s.enabled
|
||||
, schedule = Data.Validated.Unknown newSchedule
|
||||
}
|
||||
, Cmd.batch
|
||||
[ nc
|
||||
, Cmd.map CalEventMsg sc
|
||||
]
|
||||
)
|
||||
|
||||
SetNotificationSettings (Err err) ->
|
||||
( { model | formError = Just (Util.Http.errorToString err) }, Cmd.none )
|
||||
|
||||
Submit ->
|
||||
( model, Cmd.none )
|
||||
|
||||
|
||||
@ -275,14 +318,22 @@ view extraClasses model =
|
||||
]
|
||||
]
|
||||
, Html.map CalEventMsg
|
||||
(Comp.CalEventInput.view "" model.scheduleModel)
|
||||
(Comp.CalEventInput.view ""
|
||||
(Data.Validated.value model.schedule)
|
||||
model.scheduleModel
|
||||
)
|
||||
, span [ class "small-info" ]
|
||||
[ text "Specify how often and when this task should run. "
|
||||
, text "Use English 3-letter weekdays. Either a single value, "
|
||||
, text "a list or a '*' (meaning all) is allowed for each part."
|
||||
, text "a list (ex. 1,2,3), a range (ex. 1..3) or a '*' (meaning all) "
|
||||
, text "is allowed for each part."
|
||||
]
|
||||
]
|
||||
, div [ class "ui divider" ] []
|
||||
, div [ class "ui error message" ]
|
||||
[ Maybe.withDefault "" model.formError
|
||||
|> text
|
||||
]
|
||||
, button
|
||||
[ class "ui primary button"
|
||||
, onClick Submit
|
||||
|
107
modules/webapp/src/main/elm/Data/CalEvent.elm
Normal file
107
modules/webapp/src/main/elm/Data/CalEvent.elm
Normal file
@ -0,0 +1,107 @@
|
||||
module Data.CalEvent exposing
|
||||
( CalEvent
|
||||
, everyMonth
|
||||
, fromEvent
|
||||
, makeEvent
|
||||
)
|
||||
|
||||
import Util.Maybe
|
||||
|
||||
|
||||
type alias CalEvent =
|
||||
{ weekday : Maybe String
|
||||
, year : String
|
||||
, month : String
|
||||
, day : String
|
||||
, hour : String
|
||||
, minute : String
|
||||
}
|
||||
|
||||
|
||||
everyMonth : CalEvent
|
||||
everyMonth =
|
||||
CalEvent Nothing "*" "*" "01" "00" "00"
|
||||
|
||||
|
||||
makeEvent : CalEvent -> String
|
||||
makeEvent ev =
|
||||
let
|
||||
datetime =
|
||||
ev.year
|
||||
++ "-"
|
||||
++ ev.month
|
||||
++ "-"
|
||||
++ ev.day
|
||||
++ " "
|
||||
++ ev.hour
|
||||
++ ":"
|
||||
++ ev.minute
|
||||
in
|
||||
case ev.weekday of
|
||||
Just wd ->
|
||||
wd ++ " " ++ datetime
|
||||
|
||||
Nothing ->
|
||||
datetime
|
||||
|
||||
|
||||
fromEvent : String -> Maybe CalEvent
|
||||
fromEvent str =
|
||||
let
|
||||
init =
|
||||
everyMonth
|
||||
|
||||
parts =
|
||||
String.split " " str
|
||||
in
|
||||
case parts of
|
||||
wd :: date :: time :: [] ->
|
||||
Maybe.andThen
|
||||
(fromDate date)
|
||||
(fromTime time init)
|
||||
|> Maybe.map (withWeekday wd)
|
||||
|
||||
date :: time :: [] ->
|
||||
Maybe.andThen
|
||||
(fromDate date)
|
||||
(fromTime time init)
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
|
||||
|
||||
fromDate : String -> CalEvent -> Maybe CalEvent
|
||||
fromDate date ev =
|
||||
let
|
||||
parts =
|
||||
String.split "-" date
|
||||
in
|
||||
case parts of
|
||||
y :: m :: d :: [] ->
|
||||
Just
|
||||
{ ev
|
||||
| year = y
|
||||
, month = m
|
||||
, day = d
|
||||
}
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
|
||||
|
||||
fromTime : String -> CalEvent -> Maybe CalEvent
|
||||
fromTime time ev =
|
||||
case String.split ":" time of
|
||||
h :: m :: _ :: [] ->
|
||||
Just { ev | hour = h, minute = m }
|
||||
|
||||
h :: m :: [] ->
|
||||
Just { ev | hour = h, minute = m }
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
|
||||
|
||||
withWeekday : String -> CalEvent -> CalEvent
|
||||
withWeekday wd ev =
|
||||
{ ev | weekday = Util.Maybe.fromString wd }
|
20
modules/webapp/src/main/elm/Data/Validated.elm
Normal file
20
modules/webapp/src/main/elm/Data/Validated.elm
Normal file
@ -0,0 +1,20 @@
|
||||
module Data.Validated exposing (Validated(..), value)
|
||||
|
||||
|
||||
type Validated a
|
||||
= Valid a
|
||||
| Invalid a
|
||||
| Unknown a
|
||||
|
||||
|
||||
value : Validated a -> a
|
||||
value va =
|
||||
case va of
|
||||
Valid a ->
|
||||
a
|
||||
|
||||
Invalid a ->
|
||||
a
|
||||
|
||||
Unknown a ->
|
||||
a
|
@ -11,6 +11,7 @@
|
||||
}
|
||||
.calevent-input input.time-input {
|
||||
border: 0 !important;
|
||||
font-family: monospace !important;
|
||||
text-align: center;
|
||||
}
|
||||
.calevent-input .separator {
|
||||
@ -27,6 +28,7 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.default-layout .right-float {
|
||||
float: right;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user