diff --git a/ui/src/Api.elm b/ui/src/Api.elm new file mode 100644 index 0000000..cc4f674 --- /dev/null +++ b/ui/src/Api.elm @@ -0,0 +1,101 @@ +module Api exposing + ( deleteMessage + , getGreeting + , getHeaderList + , getMessage + , getServerConfig + , getServerMetrics + , markMessageSeen + , purgeMailbox + ) + +import Data.Message as Message exposing (Message) +import Data.MessageHeader as MessageHeader exposing (MessageHeader) +import Data.Metrics as Metrics exposing (Metrics) +import Data.ServerConfig as ServerConfig exposing (ServerConfig) +import Http +import HttpUtil +import Json.Decode as Decode +import Json.Encode as Encode +import Url.Builder + + +type alias DataResult msg data = + Result Http.Error data -> msg + + +type alias HttpResult msg = + Result Http.Error () -> msg + + +{-| Builds a public REST API URL (see wiki). +-} +apiV1Url : List String -> String +apiV1Url elements = + Url.Builder.absolute ([ "api", "v1" ] ++ elements) [] + + +{-| Builds an internal `serve` REST API URL; only used by this UI. +-} +serveUrl : List String -> String +serveUrl elements = + Url.Builder.absolute ([ "serve" ] ++ elements) [] + + +deleteMessage : HttpResult msg -> String -> String -> Cmd msg +deleteMessage msg mailboxName id = + HttpUtil.delete msg (apiV1Url [ "mailbox", mailboxName, id ]) + + +getHeaderList : DataResult msg (List MessageHeader) -> String -> Cmd msg +getHeaderList msg mailboxName = + Http.get + { url = apiV1Url [ "mailbox", mailboxName ] + , expect = Http.expectJson msg (Decode.list MessageHeader.decoder) + } + + +getGreeting : DataResult msg String -> Cmd msg +getGreeting msg = + Http.get + { url = serveUrl [ "greeting" ] + , expect = Http.expectString msg + } + + +getMessage : DataResult msg Message -> String -> String -> Cmd msg +getMessage msg mailboxName id = + Http.get + { url = serveUrl [ "m", mailboxName, id ] + , expect = Http.expectJson msg Message.decoder + } + + +getServerConfig : DataResult msg ServerConfig -> Cmd msg +getServerConfig msg = + Http.get + { url = serveUrl [ "status" ] + , expect = Http.expectJson msg ServerConfig.decoder + } + + +getServerMetrics : DataResult msg Metrics -> Cmd msg +getServerMetrics msg = + Http.get + { url = Url.Builder.absolute [ "debug", "vars" ] [] + , expect = Http.expectJson msg Metrics.decoder + } + + +markMessageSeen : HttpResult msg -> String -> String -> Cmd msg +markMessageSeen msg mailboxName id = + -- The URL tells the API which message ID to update, so we only need to indicate the + -- desired change in the body. + Encode.object [ ( "seen", Encode.bool True ) ] + |> Http.jsonBody + |> HttpUtil.patch msg (apiV1Url [ "mailbox", mailboxName, id ]) + + +purgeMailbox : HttpResult msg -> String -> Cmd msg +purgeMailbox msg mailboxName = + HttpUtil.delete msg (apiV1Url [ "mailbox", mailboxName ]) diff --git a/ui/src/Page/Home.elm b/ui/src/Page/Home.elm index f997769..d9ea239 100644 --- a/ui/src/Page/Home.elm +++ b/ui/src/Page/Home.elm @@ -1,5 +1,6 @@ module Page.Home exposing (Model, Msg, init, update, view) +import Api import Data.Session as Session exposing (Session) import Html exposing (..) import Html.Attributes exposing (..) @@ -19,14 +20,7 @@ type alias Model = init : ( Model, Cmd Msg, Session.Msg ) init = - let - cmdGreeting = - Http.get - { url = "/serve/greeting" - , expect = Http.expectString GreetingLoaded - } - in - ( Model "", cmdGreeting, Session.none ) + ( Model "", Api.getGreeting GreetingLoaded, Session.none ) diff --git a/ui/src/Page/Mailbox.elm b/ui/src/Page/Mailbox.elm index 5a2a7ce..9a7ad47 100644 --- a/ui/src/Page/Mailbox.elm +++ b/ui/src/Page/Mailbox.elm @@ -1,5 +1,6 @@ module Page.Mailbox exposing (Model, Msg, init, load, subscriptions, update, view) +import Api import Data.Message as Message exposing (Message) import Data.MessageHeader as MessageHeader exposing (MessageHeader) import Data.Session as Session exposing (Session) @@ -90,7 +91,7 @@ load : String -> Cmd Msg load mailboxName = Cmd.batch [ Task.perform Tick Time.now - , getList mailboxName + , Api.getHeaderList ListLoaded mailboxName ] @@ -150,7 +151,7 @@ update session msg model = , Cmd.batch [ -- Update browser location. Route.replaceUrl session.key (Route.Message model.mailboxName id) - , getMessage model.mailboxName id + , Api.getMessage MessageLoaded model.mailboxName id ] , Session.DisableRouting ) @@ -306,9 +307,7 @@ updatePurge session model = cmd = Cmd.batch [ Route.replaceUrl session.key (Route.Mailbox model.mailboxName) - , "/api/v1/mailbox/" - ++ model.mailboxName - |> HttpUtil.delete PurgedMailbox + , Api.purgeMailbox PurgedMailbox model.mailboxName ] in case model.state of @@ -380,12 +379,6 @@ updateSelected model id = updateDeleteMessage : Session -> Model -> Message -> ( Model, Cmd Msg, Session.Msg ) updateDeleteMessage session model message = let - url = - "/api/v1/mailbox/" ++ message.mailbox ++ "/" ++ message.id - - cmd = - HttpUtil.delete DeletedMessage url - filter f messageList = { messageList | headers = List.filter f messageList.headers } in @@ -396,14 +389,14 @@ updateDeleteMessage session model message = ShowingList (filter (\x -> x.id /= message.id) list) NoMessage } , Cmd.batch - [ cmd + [ Api.deleteMessage DeletedMessage message.mailbox message.id , Route.replaceUrl session.key (Route.Mailbox model.mailboxName) ] , Session.DisableRouting ) _ -> - ( model, cmd, Session.none ) + ( model, Cmd.none, Session.none ) updateMarkMessageSeen : Model -> Message -> ( Model, Cmd Msg, Session.Msg ) @@ -418,16 +411,6 @@ updateMarkMessageSeen model message = else header - url = - "/api/v1/mailbox/" ++ message.mailbox ++ "/" ++ message.id - - command = - -- The URL tells the API what message to update, so we only need to indicate the - -- desired change in the body. - Encode.object [ ( "seen", Encode.bool True ) ] - |> Http.jsonBody - |> HttpUtil.patch MarkedSeen url - map f messageList = { messageList | headers = List.map f messageList.headers } in @@ -441,7 +424,7 @@ updateMarkMessageSeen model message = } ) } - , command + , Api.markMessageSeen MarkedSeen message.mailbox message.id , Session.None ) @@ -452,35 +435,11 @@ updateMarkMessageSeen model message = updateOpenMessage : Session -> Model -> String -> ( Model, Cmd Msg, Session.Msg ) updateOpenMessage session model id = ( updateSelected model id - , getMessage model.mailboxName id + , Api.getMessage MessageLoaded model.mailboxName id , Session.AddRecent model.mailboxName ) -getList : String -> Cmd Msg -getList mailboxName = - let - url = - "/api/v1/mailbox/" ++ mailboxName - in - Http.get - { url = url - , expect = Http.expectJson ListLoaded (Decode.list MessageHeader.decoder) - } - - -getMessage : String -> MessageID -> Cmd Msg -getMessage mailboxName id = - let - url = - "/serve/m/" ++ mailboxName ++ "/" ++ id - in - Http.get - { url = url - , expect = Http.expectJson MessageLoaded Message.decoder - } - - -- VIEW diff --git a/ui/src/Page/Status.elm b/ui/src/Page/Status.elm index e583c62..834459b 100644 --- a/ui/src/Page/Status.elm +++ b/ui/src/Page/Status.elm @@ -1,5 +1,6 @@ module Page.Status exposing (Model, Msg, init, subscriptions, update, view) +import Api import Data.Metrics as Metrics exposing (Metrics) import Data.ServerConfig as ServerConfig exposing (ServerConfig) import Data.Session as Session exposing (Session) @@ -74,7 +75,7 @@ init = } , Cmd.batch [ Task.perform Tick Time.now - , loadServerConfig + , Api.getServerConfig ServerConfigLoaded ] , Session.none ) @@ -121,7 +122,7 @@ update session msg model = ( model, Cmd.none, Session.SetFlash (HttpUtil.errorString err) ) Tick time -> - ( { model | now = time }, loadMetrics, Session.none ) + ( { model | now = time }, Api.getServerMetrics MetricsReceived, Session.none ) {-| Update all metrics in Model; increment xCounter. @@ -220,22 +221,6 @@ updateRemoteTotal metric value history = } -loadMetrics : Cmd Msg -loadMetrics = - Http.get - { url = "/debug/vars" - , expect = Http.expectJson MetricsReceived Metrics.decoder - } - - -loadServerConfig : Cmd Msg -loadServerConfig = - Http.get - { url = "/serve/status" - , expect = Http.expectJson ServerConfigLoaded ServerConfig.decoder - } - - -- VIEW --