frontend: attempt 1

This commit is contained in:
Cadey Ratio 2020-01-13 01:23:46 +00:00
parent 1c6c0a44a2
commit 9b9b1f5fd5
5 changed files with 200 additions and 89 deletions

View File

@ -7,7 +7,8 @@ import Html.Attributes exposing (..)
import Html.Events exposing (onInput) import Html.Events exposing (onInput)
import Http import Http
import Json.Decode as D import Json.Decode as D
import Skeleton exposing (..) import Mi exposing (..)
import Page exposing (..)
import SwitchData import SwitchData
import Url import Url
import Url.Builder import Url.Builder
@ -54,35 +55,6 @@ type Msg
| TokenInput String | TokenInput String
| TokenValidate (Result Http.Error TokenData) | TokenValidate (Result Http.Error TokenData)
| Logout | 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 ) update : Msg -> Model -> ( Model, Cmd Msg )
@ -91,7 +63,11 @@ update msg model =
LinkClicked urlRequest -> LinkClicked urlRequest ->
case urlRequest of case urlRequest of
Browser.Internal url -> Browser.Internal url ->
( model, Nav.pushUrl model.key (Url.toString url) ) ( model
, Nav.pushUrl
model.key
(Url.toString url)
)
Browser.External href -> Browser.External href ->
( model, Nav.load href ) ( model, Nav.load href )
@ -108,7 +84,12 @@ update msg model =
TokenInput token -> TokenInput token ->
( { model | token = Just 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 -> TokenValidate result ->
@ -128,23 +109,6 @@ update msg model =
, Nav.load "/" , 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 : Model -> Sub Msg
subscriptions _ = 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 -> other ->
template "Not found" template "Not found"
[ h1 [] [ text "Not found" ] [ h1 [] [ text "Not found" ]
@ -207,29 +158,3 @@ view model =
, text " was not found." , 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))

57
frontend/src/Mi.elm Normal file
View File

@ -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))

View File

@ -1,4 +1,4 @@
module Skeleton exposing (footer, navBar, template, viewInput, viewLink) module Page exposing (..)
import Browser exposing (Document) import Browser exposing (Document)
import Html exposing (Html, a, div, input, node, p, text) 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) 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 : String -> List (Html msg) -> Browser.Document msg
template title body = template title body =
{ title = title { title = title

104
frontend/src/Page/Token.elm Normal file
View File

@ -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
]
]

6
frontend/src/Session.elm Normal file
View File

@ -0,0 +1,6 @@
module Session exposing (Session)
type Session
= Guest
| LoggedIn String