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

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

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