1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-04-28 13:48:49 +08:00

MF-571 - Add Env.elm to set custom base URL (#654)

* Add Env module

Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>

* Modify README.md

Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>

* Remove literal vals from Env.elm

Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>

* Replace protocol, host and port env setting by url

Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>

* Remove default env.url value and update README.md

Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>

* Add http://localhost:80/ as a default baseURL val

Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>

* Replace Gateflux by Mainflux

Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>
This commit is contained in:
Darko Draskovic 2019-03-20 14:30:38 +01:00 committed by Manuel Imperiale
parent e95e010a3a
commit d504c4f67d
10 changed files with 120 additions and 126 deletions

View File

@ -3,42 +3,7 @@ Dashboard made with [elm-bootstrap](http://elm-bootstrap.info/).
## Install
### Install GUI as a part of Mainflux build
Install Elm (https://guide.elm-lang.org/install.html) and then
```
git clone https://github.com/mainflux/mainflux
cd mainflux/ui
make
```
This will produce `index.html` in the _ui_ directory. In order to use it, `cd`
to _ui_ and do
`make run`
### Build a standalone native GUI
Install Elm (https://guide.elm-lang.org/install.html), `cd` to _ui_ and then
`elm make --optimize src/Main.elm`
This will produce `index.html` in the _ui_ directory. In order to use it do
`make run`
### About Elm `make`
`make` does `elm make src/Main.elm`.
`make run` just executes `elm reactor`. You can execute `elm reactor` in other
terminal window and keep it running, and then see changes as you change-compile
in the first window. You can even use something as
[entr](http://eradman.com/entrproject/) to have your source compiled
automatically when you change and save some files.
### Build as a part of Docker composition
### Docker container GUI build
Install Docker (https://docs.docker.com/install/) and Docker compose
(https://docs.docker.com/compose/install/), `cd` to Mainflux root directory and
@ -46,15 +11,44 @@ then
`docker-compose -f docker/docker-compose.yml up`
if you want to launch a whole Mainflux docker composition or just
if you want to launch a whole Mainflux docker composition, or just
`docker-compose -f docker/docker-compose.yml up ui`
if you want to launch just GUI.
### Contribute to the GUI development
### Native GUI build
Install GUI as a part of Mainflux build or as a standalone native GUI and run
it. Launch Mainflux without ui service, either natively or as a Docker
composition. Follow the guidelines for Mainflux contributors found here
Install Elm (https://guide.elm-lang.org/install.html) and then run the following
commands:
```
git clone https://github.com/mainflux/mainflux
cd mainflux/ui
make
```
This will produce `index.html` in the _ui_ directory. Still in the _mainflux/ui_
folder, enter
`make run`
and follow the instructions on screen.
**NB:** `make` does `elm make src/Main.elm` and `make run` executes `elm
reactor`. Cf. _Makefile_ for more options.
## Configuration
Open the _src/Env.elm_ file and edit the values of the `env` record.
## Contribute to the GUI development
Follow the instructions above to install and run GUI as a native build. Instead
of `make run` you can install `elm-live` (https://github.com/wking-io/elm-live)
and execute `elm-live src/Main.elm` to get a live reload when your `.Elm` pages
change.
Launch Mainflux without ui service, either natively or as a Docker composition.
Please follow the guidelines for Mainflux contributors found here
https://mainflux.readthedocs.io/en/latest/CONTRIBUTING/.

View File

@ -24,7 +24,7 @@ import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Http
import HttpMF exposing (path)
import HttpMF exposing (paths)
import Json.Decode as D
import Json.Encode as E
import ModalMF
@ -123,7 +123,7 @@ update msg model token =
ProvisionChannel ->
( resetEdit model
, HttpMF.provision
(B.relative [ path.channels ] [])
(B.relative [ paths.channels ] [])
token
{ emptyChannel
| name = Just model.name
@ -160,7 +160,7 @@ update msg model token =
UpdateChannel ->
( resetEdit { model | editMode = False }
, HttpMF.update
(B.relative [ path.channels, model.channel.id ] [])
(B.relative [ paths.channels, model.channel.id ] [])
token
{ emptyChannel
| name = Just model.name
@ -181,7 +181,7 @@ update msg model token =
RetrieveChannel channelid ->
( model
, HttpMF.retrieve
(B.relative [ path.channels, channelid ] [])
(B.relative [ paths.channels, channelid ] [])
token
RetrievedChannel
channelDecoder
@ -198,7 +198,7 @@ update msg model token =
RetrieveChannels ->
( model
, HttpMF.retrieve
(B.relative [ path.channels ] (Helpers.buildQueryParamList model.offset model.limit))
(B.relative [ paths.channels ] (Helpers.buildQueryParamList model.offset model.limit))
token
RetrievedChannels
channelsDecoder
@ -207,7 +207,7 @@ update msg model token =
RetrieveChannelsForThing thingid ->
( model
, HttpMF.retrieve
(B.relative [ path.things, thingid, path.channels ] (Helpers.buildQueryParamList model.offset model.limit))
(B.relative [ paths.things, thingid, paths.channels ] (Helpers.buildQueryParamList model.offset model.limit))
token
RetrievedChannels
channelsDecoder
@ -224,7 +224,7 @@ update msg model token =
RemoveChannel id ->
( resetEdit model
, HttpMF.remove
(B.relative [ path.channels, id ] [])
(B.relative [ paths.channels, id ] [])
token
RemovedChannel
)
@ -433,12 +433,12 @@ updateChannelList model token =
( model
, Cmd.batch
[ HttpMF.retrieve
(B.relative [ path.channels ] (Helpers.buildQueryParamList model.offset model.limit))
(B.relative [ paths.channels ] (Helpers.buildQueryParamList model.offset model.limit))
token
RetrievedChannels
channelsDecoder
, HttpMF.retrieve
(B.relative [ path.channels, model.channel.id ] [])
(B.relative [ paths.channels, model.channel.id ] [])
token
RetrievedChannel
channelDecoder
@ -450,7 +450,7 @@ updateChannelListForThing : Model -> String -> String -> ( Model, Cmd Msg )
updateChannelListForThing model token thingid =
( model
, HttpMF.retrieve
(B.relative [ path.things, thingid, path.channels ] (Helpers.buildQueryParamList model.offset model.limit))
(B.relative [ paths.things, thingid, paths.channels ] (Helpers.buildQueryParamList model.offset model.limit))
token
RetrievedChannels
channelsDecoder

View File

@ -24,7 +24,7 @@ import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Http
import HttpMF exposing (path)
import HttpMF exposing (paths)
import List.Extra
import Thing
import Url.Builder as B
@ -207,7 +207,7 @@ connect checkedThingsIds checkedChannelsIds method token =
List.map
(\channelid ->
HttpMF.request
(B.relative [ path.channels, channelid, path.things, thingid ] [])
(B.relative [ paths.channels, channelid, paths.things, thingid ] [])
method
token
Http.emptyBody

12
ui/src/Env.elm Normal file
View File

@ -0,0 +1,12 @@
-- Copyright (c) 2019
-- Mainflux
--
-- SPDX-License-Identifier: Apache-2.0
module Env exposing (env)
env =
{ url = "http://localhost:80/"
}

View File

@ -4,9 +4,10 @@
-- SPDX-License-Identifier: Apache-2.0
module HttpMF exposing (expectID, expectRetrieve, expectStatus, path, provision, remove, request, retrieve, update, url)
module HttpMF exposing (baseURL, expectID, expectRetrieve, expectStatus, paths, provision, remove, request, retrieve, update, user, version)
import Dict
import Env exposing (env)
import Helpers
import Http
import Json.Decode as D
@ -14,12 +15,11 @@ import Json.Encode as E
import Url.Builder as B
url =
{ base = "http://localhost"
}
baseURL =
env.url
path =
paths =
{ users = "users"
, tokens = "tokens"
, things = "things"
@ -107,12 +107,30 @@ expectRetrieve toMsg decoder =
-- REQUEST
version : String -> (Result Http.Error String -> msg) -> D.Decoder String -> Cmd msg
version path msg decoder =
Http.get
{ url = baseURL ++ path
, expect = Http.expectJson msg decoder
}
user : String -> String -> String -> E.Value -> Http.Expect msg -> Cmd msg
user email password u value expect =
Http.post
{ url = baseURL ++ u
, body =
value |> Http.jsonBody
, expect = expect
}
request : String -> String -> String -> Http.Body -> (Result Http.Error String -> msg) -> Cmd msg
request u method token b msg =
request path method token b msg =
Http.request
{ method = method
, headers = [ Http.header "Authorization" token ]
, url = u
, url = baseURL ++ path
, body = b
, expect = expectStatus msg
, timeout = Nothing
@ -121,11 +139,11 @@ request u method token b msg =
retrieve : String -> String -> (Result Http.Error a -> msg) -> D.Decoder a -> Cmd msg
retrieve u token msg decoder =
retrieve path token msg decoder =
Http.request
{ method = "GET"
, headers = [ Http.header "Authorization" token ]
, url = u
, url = baseURL ++ path
, body = Http.emptyBody
, expect = expectRetrieve msg decoder
, timeout = Nothing
@ -134,11 +152,11 @@ retrieve u token msg decoder =
provision : String -> String -> entity -> (entity -> E.Value) -> (Result Http.Error String -> msg) -> String -> Cmd msg
provision u token e encoder msg prefix =
provision path token e encoder msg prefix =
Http.request
{ method = "POST"
, headers = [ Http.header "Authorization" token ]
, url = u
, url = baseURL ++ path
, body =
encoder e
|> Http.jsonBody
@ -149,11 +167,11 @@ provision u token e encoder msg prefix =
update : String -> String -> entity -> (entity -> E.Value) -> (Result Http.Error String -> msg) -> Cmd msg
update u token e encoder msg =
update path token e encoder msg =
Http.request
{ method = "PUT"
, headers = [ Http.header "Authorization" token ]
, url = u
, url = baseURL ++ path
, body =
encoder e
|> Http.jsonBody
@ -164,11 +182,11 @@ update u token e encoder msg =
remove : String -> String -> (Result Http.Error String -> msg) -> Cmd msg
remove u token msg =
remove path token msg =
Http.request
{ method = "DELETE"
, headers = [ Http.header "Authorization" token ]
, url = u
, url = baseURL ++ path
, body = Http.emptyBody
, expect = expectStatus msg
, timeout = Nothing

View File

@ -299,7 +299,7 @@ mfStylesheet =
view : Model -> Browser.Document Msg
view model =
{ title = "Gateflux"
{ title = "Mainflux"
, body =
let
buttonAttrs =

View File

@ -23,7 +23,7 @@ import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Http
import HttpMF exposing (path)
import HttpMF exposing (paths)
import List.Extra
import Thing
import Url.Builder as B
@ -217,7 +217,7 @@ genChannelRows checkedChannelsIds channels =
send : String -> String -> String -> Cmd Msg
send channelid thingkey message =
HttpMF.request
(B.relative [ "http", path.channels, channelid, path.messages ] [])
(B.relative [ "http", paths.channels, channelid, paths.messages ] [])
"POST"
thingkey
(Http.stringBody "application/json" message)

View File

@ -27,7 +27,7 @@ import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Http
import HttpMF exposing (path)
import HttpMF exposing (paths)
import Json.Decode as D
import Json.Encode as E
import ModalMF
@ -143,7 +143,7 @@ update msg model token =
ProvisionThing ->
( resetEdit model
, HttpMF.provision
(B.relative [ path.things ] [])
(B.relative [ paths.things ] [])
token
{ emptyThing
| name = Just model.name
@ -181,7 +181,7 @@ update msg model token =
UpdateThing ->
( resetEdit { model | editMode = False }
, HttpMF.update
(B.relative [ path.things, model.thing.id ] [])
(B.relative [ paths.things, model.thing.id ] [])
token
{ emptyThing
| name = Just model.name
@ -203,7 +203,7 @@ update msg model token =
RetrieveThing thingid ->
( model
, HttpMF.retrieve
(B.relative [ path.things, thingid ] [])
(B.relative [ paths.things, thingid ] [])
token
RetrievedThing
thingDecoder
@ -220,7 +220,7 @@ update msg model token =
RetrieveThings ->
( model
, HttpMF.retrieve
(B.relative [ path.things ] (Helpers.buildQueryParamList model.offset model.limit))
(B.relative [ paths.things ] (Helpers.buildQueryParamList model.offset model.limit))
token
RetrievedThings
thingsDecoder
@ -237,7 +237,7 @@ update msg model token =
RemoveThing id ->
( model
, HttpMF.remove
(B.relative [ path.things, id ] [])
(B.relative [ paths.things, id ] [])
token
RemovedThing
)
@ -491,12 +491,12 @@ updateThingList model token =
( model
, Cmd.batch
[ HttpMF.retrieve
(B.relative [ path.things ] (Helpers.buildQueryParamList model.offset model.limit))
(B.relative [ paths.things ] (Helpers.buildQueryParamList model.offset model.limit))
token
RetrievedThings
thingsDecoder
, HttpMF.retrieve
(B.relative [ path.things, model.thing.id ] [])
(B.relative [ paths.things, model.thing.id ] [])
token
RetrievedThing
thingDecoder

View File

@ -19,7 +19,7 @@ import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Http
import HttpMF exposing (path)
import HttpMF exposing (baseURL, paths)
import Json.Decode as D
import Json.Encode as E
import Url.Builder as B
@ -66,10 +66,12 @@ update msg model =
Create ->
( model
, create
, HttpMF.user
model.email
model.password
(B.relative [ path.users ] [])
(B.relative [ paths.users ] [])
(encode (User model.email model.password))
(HttpMF.expectStatus Created)
)
Created result ->
@ -82,10 +84,15 @@ update msg model =
GetToken ->
( model
, getToken
, HttpMF.user
model.email
model.password
(B.relative [ path.tokens ] [])
(B.relative [ paths.tokens ] [])
(encode (User model.email model.password))
(HttpMF.expectRetrieve
GotToken
(D.field "token" D.string)
)
)
GotToken result ->
@ -182,43 +189,6 @@ decoder =
-- HTTP
create : String -> String -> String -> Cmd Msg
create email password u =
Http.request
{ method = "POST"
, headers = []
, url = u
, body =
encode (User email password)
|> Http.jsonBody
, expect = HttpMF.expectStatus Created
, timeout = Nothing
, tracker = Nothing
}
getToken : String -> String -> String -> Cmd Msg
getToken email password u =
Http.request
{ method = "POST"
, headers = []
, url = u
, body =
encode (User email password)
|> Http.jsonBody
, expect =
HttpMF.expectRetrieve
GotToken
(D.field "token" D.string)
, timeout = Nothing
, tracker = Nothing
}
-- Helpers
loggedIn : Model -> Bool
loggedIn model =
if String.length model.token > 0 then

View File

@ -10,7 +10,7 @@ import Error
import Html exposing (..)
import Html.Attributes exposing (..)
import Http
import HttpMF exposing (path)
import HttpMF exposing (paths)
import Json.Decode as D
import Json.Encode as E
import Url.Builder as B
@ -35,10 +35,10 @@ update msg model =
case msg of
GetVersion ->
( model
, Http.get
{ url = B.relative [ path.version ] []
, expect = Http.expectJson GotVersion (D.field "version" D.string)
}
, HttpMF.version
(B.relative [ paths.version ] [])
GotVersion
(D.field "version" D.string)
)
GotVersion result ->