Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
RaphaelGauthier committed Feb 3, 2022
1 parent 33f1067 commit c9253b7
Show file tree
Hide file tree
Showing 15 changed files with 876 additions and 94 deletions.
@@ -0,0 +1,6 @@
#!/bin/bash

# we want that all elm-stuff stay in src/main/elm
# whatever the path from which this script is called
ELM_DIR="$( cd "$( dirname "$0" )" && pwd )"
${ELM_DIR}/../build-app.sh
47 changes: 47 additions & 0 deletions webapp/sources/rudder/rudder-web/src/main/elm/accounts/elm.json
@@ -0,0 +1,47 @@
{
"type": "application",
"source-directories": [
"sources"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
"TSFoster/elm-tuple-extra": "2.0.0",
"TSFoster/elm-uuid": "4.1.0",
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"elm/http": "2.0.0",
"elm/json": "1.1.3",
"elm/random": "1.0.0",
"elm/url": "1.0.0",
"elm-community/dict-extra": "2.4.0",
"elm-community/list-extra": "8.5.1",
"elm-community/maybe-extra": "5.2.1",
"isaacseymour/deprecated-time": "1.0.0",
"mcordova47/elm-natural-ordering": "1.0.5",
"toastal/either": "3.6.3",
"webbhuset/elm-json-decode": "1.1.0",
"myrho/elm-round": "1.0.4"
},
"indirect": {
"TSFoster/elm-bytes-extra": "1.3.0",
"TSFoster/elm-md5": "2.0.1",
"TSFoster/elm-sha1": "2.1.1",
"danfishgold/base64-bytes": "1.1.0",
"elm/bytes": "1.0.8",
"elm/file": "1.0.5",
"elm/parser": "1.1.0",
"elm/regex": "1.0.0",
"elm/time": "1.0.0",
"elm/virtual-dom": "1.0.2",
"kuon/elm-string-normalize": "1.0.2",
"rtfeldman/elm-hex": "1.0.0"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}
@@ -0,0 +1,129 @@
port module Accounts exposing (..)

import Browser
import Dict
import Dict.Extra
import DataTypes exposing (..)
import Http exposing (..)
import Init exposing (init, subscriptions)
import View exposing (view)
import Result
import ApiCalls exposing (..)
import ViewUtils exposing (..)
import List.Extra
import Random
import UUID

-- PORTS / SUBSCRIPTIONS

port successNotification : String -> Cmd msg
port errorNotification : String -> Cmd msg
port initTooltips : String -> Cmd msg
port copy : String -> Cmd msg
port initAcl : String -> Cmd msg

main = Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}

generator : Random.Generator String
generator = Random.map (UUID.toString) UUID.generator

--
-- update loop --
--
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Copy s -> (model, copy s)

-- Generate random id
GenerateId nextMsg ->
(model, Random.generate nextMsg generator)

-- Do an API call
CallApi call ->
(model, call model)

-- neutral element
Ignore ->
( model , Cmd.none)

{--
OpenDeletionPopup rule ->
case model.mode of
RuleForm _ ->
let ui = model.ui
in
( { model | ui = {ui | modal = DeletionValidation rule} } , Cmd.none )
_ -> (model, Cmd.none)
OpenDeletionPopupCat category ->
case model.mode of
CategoryForm _ ->
let ui = model.ui
in
( { model | ui = {ui | modal = DeletionValidationCat category} } , Cmd.none )
_ -> (model, Cmd.none)
OpenDeactivationPopup rule ->
case model.mode of
RuleForm _ ->
let ui = model.ui
in
( { model | ui = {ui | modal = DeactivationValidation rule}} , Cmd.none )
_ -> (model, Cmd.none)
--}
ClosePopup callback ->
let
ui = model.ui
(nm,cmd) = update callback { model | ui = { ui | modal = NoModal } }
in
(nm , cmd)

UpdateTableFilters tableFilters ->
let
ui = model.ui
in
({model | ui = { ui | tableFilters = tableFilters}}, Cmd.none)

GetAccountsResult res ->
case res of
Ok apiResult ->
let
modelUi = model.ui
accounts = apiResult.accounts
aclPluginEnabled = apiResult.aclPluginEnabled
in
( { model | accounts = accounts, aclPluginEnabled = aclPluginEnabled, ui = { modelUi | loadingAccounts = False } }
, Cmd.batch [initTooltips "", successNotification ""]
)
Err err ->
processApiError "Getting API accounts list" err model

processApiError : String -> Error -> Model -> ( Model, Cmd Msg )
processApiError apiName err model =
let
modelUi = model.ui
message =
case err of
Http.BadUrl url ->
"The URL " ++ url ++ " was invalid"
Http.Timeout ->
"Unable to reach the server, try again"
Http.NetworkError ->
"Unable to reach the server, check your network connection"
Http.BadStatus 500 ->
"The server had a problem, try again later"
Http.BadStatus 400 ->
"Verify your information and try again"
Http.BadStatus _ ->
"Unknown error"
Http.BadBody errorMessage ->
errorMessage

in
({ model | ui = { modelUi | loadingAccounts = False}}, errorNotification ("Error when "++apiName ++", details: \n" ++ message ) )
@@ -0,0 +1,33 @@
module ApiCalls exposing (..)

import DataTypes exposing (..)
import Http exposing (..)
import JsonDecoder exposing (..)
import JsonEncoder exposing (..)
import Url.Builder exposing (QueryParameter)


--
-- This files contains all API calls for the Rules UI
-- Summary:
-- GET /apiaccounts: get the api accounts list

getUrl: DataTypes.Model -> List String -> List QueryParameter -> String
getUrl m url p=
Url.Builder.relative (m.contextPath :: "secure" :: url) p

getAccounts : Model -> Cmd Msg
getAccounts model =
let
req =
request
{ method = "GET"
, headers = []
, url = getUrl model [ "apiaccounts" ] []
, body = emptyBody
, expect = expectJson GetAccountsResult decodeGetAccounts
, timeout = Nothing
, tracker = Nothing
}
in
req
@@ -0,0 +1,69 @@
module DataTypes exposing (..)

import Dict exposing (Dict)
import Http exposing (Error)

--
-- All our data types
--

type ModalState = NoModal | NewAccount | EditAccount Account

type SortOrder = Asc | Desc

type SortBy
= Name
| Token
| ExpDate

type alias TableFilters =
{ sortBy : SortBy
, sortOrder : SortOrder
, filter : String
, authType : String
}

type alias UI =
{ tableFilters : TableFilters
, modal : ModalState
, hasWriteRights : Bool
, loadingAccounts : Bool
}

type alias Account =
{ id : String
, name : String
, description : String
, authorisationType : String
, kind : String
, enabled : Bool
, creationDate : String
, token : String
, tokenGenerationDate : String
, expirationDateDefined : Bool
, expirationDate : String
}

type alias ApiResult =
{ aclPluginEnabled : Bool
, accounts : List Account
}

type alias Model =
{ contextPath : String
, ui : UI
, accounts : List Account
, aclPluginEnabled : Bool
}

type Msg
= Copy String
| GenerateId (String -> Msg)
| CallApi (Model -> Cmd Msg)
--| OpenDeletionPopup Rule
--| OpenDeletionPopupCat (Category Rule)
--| OpenDeactivationPopup Rule
| GetAccountsResult (Result Error ApiResult)
| ClosePopup Msg
| Ignore
| UpdateTableFilters TableFilters
@@ -0,0 +1,19 @@
module Init exposing (..)

import ApiCalls exposing (..)
import DataTypes exposing (..)
import Dict

-- PORTS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none

init : { contextPath : String, hasWriteRights : Bool } -> ( Model, Cmd Msg )
init flags =
let
initFilters = TableFilters Name Asc "" ""
initUi = UI initFilters NoModal False True
initModel = Model flags.contextPath initUi [] False
in
( initModel , getAccounts initModel )
@@ -0,0 +1,38 @@
module JsonDecoder exposing (..)

import DataTypes exposing (..)
import Dict exposing (Dict)
import Json.Decode exposing (..)
import Json.Decode.Pipeline exposing (..)
import Json.Decode.Field exposing (..)
import Time.Iso8601
import Time.Iso8601ErrorMsg
import Time.TimeZones exposing (utc)
import Time.ZonedDateTime exposing (ZonedDateTime)
import Tuple


-- GENERAL
decodeAccount : Decoder Account
decodeAccount =
succeed Account
|> required "id" string
|> required "name" string
|> required "description" string
|> required "authorizationType" string
|> required "kind" string
|> required "enabled" bool
|> required "creationDate" string
|> required "token" string
|> required "tokenGenerationDate" string
|> required "expirationDateDefined" bool
|> required "expirationDate" string

decodeResult : Decoder (ApiResult)
decodeResult =
succeed ApiResult
|> required "aclPluginEnabled" bool
|> required "accounts" (list decodeAccount)

decodeGetAccounts =
at [ "data" ] decodeResult
@@ -0,0 +1,20 @@
module JsonEncoder exposing (..)

import DataTypes exposing (..)
import Json.Encode exposing (..)

encodeAccount : Account -> Value
encodeAccount account =
object
[ ( "id" , string account.id )
, ( "name" , string account.name )
, ( "description" , string account.description )
, ( "authorisationType" , string account.authorisationType )
, ( "kind" , string account.kind )
, ( "enabled" , bool account.enabled )
, ( "creationDate" , string account.creationDate )
, ( "token" , string account.token )
, ( "tokenGenerationDate" , string account.tokenGenerationDate )
, ( "expirationDateDefined" , bool account.expirationDateDefined )
, ( "expirationDate" , string account.expirationDate )
]

0 comments on commit c9253b7

Please sign in to comment.