diff --git a/frontend/src/Main.elm b/frontend/src/Main.elm index df1888f..dfb721d 100644 --- a/frontend/src/Main.elm +++ b/frontend/src/Main.elm @@ -7,7 +7,8 @@ import Html.Attributes exposing (..) import Html.Events exposing (onInput) import Http import Json.Decode as D -import Skeleton exposing (..) +import Mi exposing (..) +import Page exposing (..) import SwitchData import Url import Url.Builder @@ -54,35 +55,6 @@ type Msg | TokenInput String | TokenValidate (Result Http.Error TokenData) | Logout - | GetSwitchData ( Int, Int ) - | GotSwitchData (Result Http.Error (List SwitchData.Switch)) - - -type alias TokenData = - { sub : String - , jti : String - } - - -tokenDecoder : D.Decoder TokenData -tokenDecoder = - D.map2 TokenData - (D.field "sub" D.string) - (D.field "jti" D.string) - - -request method token path body expect = - Http.request - { method = method - , body = body - , headers = - [ Http.header "Authorization" token - ] - , url = path - , expect = expect - , timeout = Nothing - , tracker = Nothing - } update : Msg -> Model -> ( Model, Cmd Msg ) @@ -91,7 +63,11 @@ update msg model = LinkClicked urlRequest -> case urlRequest of Browser.Internal url -> - ( model, Nav.pushUrl model.key (Url.toString url) ) + ( model + , Nav.pushUrl + model.key + (Url.toString url) + ) Browser.External href -> ( model, Nav.load href ) @@ -108,7 +84,12 @@ update msg model = TokenInput token -> ( { model | token = Just token } - , request "GET" token "/.within/tokeninfo" Http.emptyBody (expectJson TokenValidate tokenDecoder) + , request + "GET" + token + "/.within/tokeninfo" + Http.emptyBody + (expectJson TokenValidate tokenDecoder) ) TokenValidate result -> @@ -128,23 +109,6 @@ update msg model = , Nav.load "/" ) - GetSwitchData ( limit, page ) -> - case model.token of - Just token -> - ( model - , request "GET" - token - (SwitchData.dataURL limit page) - Http.emptyBody - (expectJson GotSwitchData (D.list SwitchData.decoder)) - ) - - Nothing -> - ( model, Cmd.none ) - - _ -> - ( model, Cmd.none ) - subscriptions : Model -> Sub Msg subscriptions _ = @@ -185,19 +149,6 @@ view model = ] ] - "/switch" -> - case model.switch_data of - Nothing -> - template "Switch counter" - [ h1 [] [ text "Switch counter" ] - , p [] [ text "loading..." ] - ] - - Just switches -> - template "Switch counter" - [ h1 [] [ text "TODO: table" ] - ] - other -> template "Not found" [ h1 [] [ text "Not found" ] @@ -207,29 +158,3 @@ view model = , text " was not found." ] ] - - -expectJson : (Result Http.Error a -> msg) -> D.Decoder a -> Http.Expect msg -expectJson toMsg decoder = - Http.expectStringResponse toMsg <| - \response -> - case response of - Http.BadUrl_ url -> - Err (Http.BadUrl url) - - Http.Timeout_ -> - Err Http.Timeout - - Http.NetworkError_ -> - Err Http.NetworkError - - Http.BadStatus_ metadata body -> - Err (Http.BadStatus metadata.statusCode) - - Http.GoodStatus_ metadata body -> - case D.decodeString decoder body of - Ok value -> - Ok value - - Err err -> - Err (Http.BadBody (D.errorToString err)) diff --git a/frontend/src/Mi.elm b/frontend/src/Mi.elm new file mode 100644 index 0000000..70908df --- /dev/null +++ b/frontend/src/Mi.elm @@ -0,0 +1,57 @@ +module Mi exposing (TokenData, expectJson, request, tokenDecoder) + +import Http +import Json.Decode as D + + +type alias TokenData = + { sub : String + , jti : String + } + + +tokenDecoder : D.Decoder TokenData +tokenDecoder = + D.map2 TokenData + (D.field "sub" D.string) + (D.field "jti" D.string) + + +request method token path body expect = + Http.request + { method = method + , body = body + , headers = + [ Http.header "Authorization" token + ] + , url = path + , expect = expect + , timeout = Nothing + , tracker = Nothing + } + + +expectJson : (Result Http.Error a -> msg) -> D.Decoder a -> Http.Expect msg +expectJson toMsg decoder = + Http.expectStringResponse toMsg <| + \response -> + case response of + Http.BadUrl_ url -> + Err (Http.BadUrl url) + + Http.Timeout_ -> + Err Http.Timeout + + Http.NetworkError_ -> + Err Http.NetworkError + + Http.BadStatus_ metadata body -> + Err (Http.BadStatus metadata.statusCode) + + Http.GoodStatus_ metadata body -> + case D.decodeString decoder body of + Ok value -> + Ok value + + Err err -> + Err (Http.BadBody (D.errorToString err)) diff --git a/frontend/src/Skeleton.elm b/frontend/src/Page.elm similarity index 82% rename from frontend/src/Skeleton.elm rename to frontend/src/Page.elm index 8c5fc73..508bec2 100644 --- a/frontend/src/Skeleton.elm +++ b/frontend/src/Page.elm @@ -1,4 +1,4 @@ -module Skeleton exposing (footer, navBar, template, viewInput, viewLink) +module Page exposing (..) import Browser exposing (Document) import Html exposing (Html, a, div, input, node, p, text) @@ -6,6 +6,25 @@ import Html.Attributes exposing (href, placeholder, type_, value) import Html.Events exposing (onInput) +type Page + = Login + | TokenData + | NotFound String + + +fromPath : String -> Page +fromPath path = + case path of + "/" -> + TokenData + + "/login" -> + Login + + other -> + NotFound other + + template : String -> List (Html msg) -> Browser.Document msg template title body = { title = title diff --git a/frontend/src/Page/Token.elm b/frontend/src/Page/Token.elm new file mode 100644 index 0000000..29611f5 --- /dev/null +++ b/frontend/src/Page/Token.elm @@ -0,0 +1,104 @@ +module Page.Token exposing + ( Model + , Msg + , init + , update + , view + ) + +import Browser +import Html exposing (Html, h1, h2, li, p, text, ul) +import Http exposing (..) +import Mi exposing (TokenData, expectJson, request, tokenDecoder) +import Page + + +type alias Model = + { token : Maybe String + , token_data : Maybe TokenData + , error : Maybe String + } + + +init : Model +init = + Model Nothing Nothing Nothing + + +type Msg + = GotToken String + | GotTokenData (Result Http.Error TokenData) + + +update : Msg -> Model -> ( Model, Cmd Msg ) +update msg model = + case msg of + GotToken token -> + ( { model | token = Just token } + , Mi.request + "GET" + token + "/.within/tokeninfo" + Http.emptyBody + (Mi.expectJson GotTokenData tokenDecoder) + ) + + GotTokenData result -> + case result of + Ok data -> + ( { model | token_data = Just data } + , Cmd.none + ) + + Err (BadUrl val) -> + ( { model | error = Just ("bad URL " ++ val) } + , Cmd.none + ) + + Err Timeout -> + ( { model | error = Just "Timeout" } + , Cmd.none + ) + + Err NetworkError -> + ( { model | error = Just "network error" } + , Cmd.none + ) + + Err (BadStatus code) -> + ( { model | error = Just ("bad status code " ++ String.fromInt code) } + , Cmd.none + ) + + Err (BadBody err_msg) -> + ( { model | error = Just err_msg } + , Cmd.none + ) + + +view : Model -> Browser.Document msg +view model = + case model.token_data of + Nothing -> + Page.template "No token data?" + [ h1 [] [ text "No token data?" ] + , p [] [ text "this should be impossible" ] + ] + + Just token_data -> + Page.template "Mi" + [ h1 [] [ text "Mi" ] + , h2 [] [ text "TODO" ] + , ul [] + [ li [] [ text "Switch CRUD" ] + , li [] [ text "POSSE manual announcement" ] + ] + , h2 [] [ text "Token data" ] + , p [] + [ text "Token sub: " + , text token_data.sub + , Html.br [] [] + , text "ID: " + , text token_data.jti + ] + ] diff --git a/frontend/src/Session.elm b/frontend/src/Session.elm new file mode 100644 index 0000000..d178cfa --- /dev/null +++ b/frontend/src/Session.elm @@ -0,0 +1,6 @@ +module Session exposing (Session) + + +type Session + = Guest + | LoggedIn String