frontend: attempt 1
This commit is contained in:
parent
1c6c0a44a2
commit
9b9b1f5fd5
|
@ -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))
|
|
||||||
|
|
|
@ -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))
|
|
@ -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
|
|
@ -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
|
||||||
|
]
|
||||||
|
]
|
|
@ -0,0 +1,6 @@
|
||||||
|
module Session exposing (Session)
|
||||||
|
|
||||||
|
|
||||||
|
type Session
|
||||||
|
= Guest
|
||||||
|
| LoggedIn String
|
Loading…
Reference in New Issue