Skip to content

Commit

Permalink
Add UI websocket open/close and send/receive (#728)
Browse files Browse the repository at this point in the history
* Add websocket open/close and send/receive

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

* Add websocket feedback/log to Elm

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

* Align WS open/close buttons

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

* Add websocket query for channel list

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

* Add websocket related encoders/decoders for port interops

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

* Fix .js indentation and simplify ws (dis)connect method

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

* Use single quotes consistently

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

* Add HTTP Send and WS Listen

Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>
  • Loading branch information
darkodraskovic authored and manuio committed Apr 26, 2019
1 parent f8ca4ba commit c37cbf9
Show file tree
Hide file tree
Showing 7 changed files with 388 additions and 53 deletions.
10 changes: 2 additions & 8 deletions ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,8 @@
var app = Elm.Main.init({
node: document.getElementById('elm')
});
var ws = new WebSocket("wss://echo.websocket.org");
// var ws = new WebSocket('wss://localhost/ws/channels/1dec73d1-2d74-456b-b1f3-0d4908e600cf/messages?authorization=9a6c7929-0213-40a9-9154-b8e43e01e103');
ws.onmessage = function(message)
{
console.log(message);
app.ports.websocketIn.send(JSON.stringify({data:message.data,timestamp:message.timeStamp}));
};
app.ports.websocketOut.subscribe(function(msg) { ws.send(msg); });
var MF = {}
</script>
<script src="src/Websocket.js"></script>
</body>
</html>
40 changes: 30 additions & 10 deletions ui/src/Connection.elm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
-- SPDX-License-Identifier: Apache-2.0


module Connection exposing (Model, Msg(..), initial, update, view)
port module Connection exposing (Model, Msg(..), initial, update, view)

import Bootstrap.Button as Button
import Bootstrap.Card as Card
Expand All @@ -13,6 +13,7 @@ import Bootstrap.Form as Form
import Bootstrap.Form.Checkbox as Checkbox
import Bootstrap.Form.Input as Input
import Bootstrap.Grid as Grid
import Bootstrap.Grid.Col as Col
import Bootstrap.Table as Table
import Bootstrap.Text as Text
import Bootstrap.Utilities.Spacing as Spacing
Expand All @@ -25,7 +26,10 @@ import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Http
import HttpMF exposing (paths)
import Json.Decode as D
import Json.Encode as E
import List.Extra
import Ports exposing (..)
import Thing
import Url.Builder as B

Expand All @@ -36,6 +40,7 @@ type alias Model =
, channels : Channel.Model
, checkedThingsIds : List String
, checkedChannelsIds : List String
, websocketIn : List String
}


Expand All @@ -46,6 +51,7 @@ initial =
, channels = Channel.initial
, checkedThingsIds = []
, checkedChannelsIds = []
, websocketIn = []
}


Expand All @@ -55,28 +61,38 @@ type Msg
| ThingMsg Thing.Msg
| ChannelMsg Channel.Msg
| GotResponse (Result Http.Error String)
| CheckThing String
| CheckThing ( String, String )
| CheckChannel String


resetChecked : Model -> Model
resetChecked model =
{ model | checkedThingsIds = [], checkedChannelsIds = [] }


isEmptyChecked : Model -> Bool
isEmptyChecked model =
List.isEmpty model.checkedThingsIds || List.isEmpty model.checkedChannelsIds


update : Msg -> Model -> String -> ( Model, Cmd Msg )
update msg model token =
case msg of
Connect ->
if List.isEmpty model.checkedThingsIds || List.isEmpty model.checkedChannelsIds then
if isEmptyChecked model then
( model, Cmd.none )

else
( { model | checkedThingsIds = [], checkedChannelsIds = [] }
( resetChecked model
, Cmd.batch (connect model.checkedThingsIds model.checkedChannelsIds "PUT" token)
)

Disconnect ->
if List.isEmpty model.checkedThingsIds || List.isEmpty model.checkedChannelsIds then
if isEmptyChecked model then
( model, Cmd.none )

else
( { model | checkedThingsIds = [], checkedChannelsIds = [] }
( resetChecked model
, Cmd.batch (connect model.checkedThingsIds model.checkedChannelsIds "DELETE" token)
)

Expand All @@ -102,8 +118,12 @@ update msg model token =
in
( { model | channels = updatedChannel }, Cmd.map ChannelMsg channelCmd )

CheckThing id ->
( { model | checkedThingsIds = Helpers.checkEntity id model.checkedThingsIds }, Cmd.none )
CheckThing thing ->
( { model
| checkedThingsIds = Helpers.checkEntity (Tuple.first thing) model.checkedThingsIds
}
, Cmd.none
)

CheckChannel id ->
( { model | checkedChannelsIds = Helpers.checkEntity id model.checkedChannelsIds }, Cmd.none )
Expand All @@ -129,7 +149,7 @@ view model =
)
]
, Grid.row []
[ Grid.col []
[ Grid.col [ Col.attrs [ align "left" ] ]
[ Form.form []
[ Button.button [ Button.success, Button.attrs [ Spacing.ml1 ], Button.onClick Connect ] [ text "Connect" ]
, Button.button [ Button.danger, Button.attrs [ Spacing.ml1 ], Button.onClick Disconnect ] [ text "Disconnect" ]
Expand All @@ -147,7 +167,7 @@ genThingRows checkedThingsIds things =
Table.tr []
[ Table.td [] [ text (" " ++ Helpers.parseString thing.name) ]
, Table.td [] [ text thing.id ]
, Table.td [] [ input [ type_ "checkbox", onClick (CheckThing thing.id), checked (Helpers.isChecked thing.id checkedThingsIds) ] [] ]
, Table.td [] [ input [ type_ "checkbox", onClick (CheckThing ( thing.id, thing.key )), checked (Helpers.isChecked thing.id checkedThingsIds) ] [] ]
]
)
things
Expand Down
32 changes: 26 additions & 6 deletions ui/src/Helpers.elm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
-- SPDX-License-Identifier: Apache-2.0


module Helpers exposing (appendIf, buildQueryParamList, checkEntity, disableNext, faIcons, fontAwesome, genCardConfig, genPagination, isChecked, offsetToPage, pageToOffset, parseString, response, validateInt, validateOffset)
module Helpers exposing (appendIf, buildQueryParamList, checkEntity, disableNext, faIcons, fontAwesome, genCardConfig, genOrderedList, genPagination, isChecked, offsetToPage, pageToOffset, parseString, resetList, response, validateInt, validateOffset)

import Bootstrap.Button as Button
import Bootstrap.Card as Card
Expand Down Expand Up @@ -94,6 +94,11 @@ validateOffset offset total limit =
offset


disableNext : Int -> Int -> Bool
disableNext currPage total =
currPage == Basics.ceiling (Basics.toFloat total / 10)


genPagination : Int -> Int -> (Int -> msg) -> Html msg
genPagination total currPage msg =
let
Expand Down Expand Up @@ -159,6 +164,8 @@ faIcons =
, messages = "far fa-paper-plane"
, version = "fa fa-code-branch"
, websocket = "fas fa-arrows-alt-v"
, send = "fas fa-arrow-up"
, receive = "fas fa-arrow-down"
}


Expand Down Expand Up @@ -193,11 +200,6 @@ appendIf flag list value =
list


disableNext : Int -> Int -> Bool
disableNext currPage total =
currPage == Basics.ceiling (Basics.toFloat total / 10)


genCardConfig : String -> String -> List (Table.Row msg) -> Html msg
genCardConfig faClass title rows =
Card.config
Expand All @@ -217,3 +219,21 @@ genCardConfig faClass title rows =
)
]
|> Card.view


genOrderedList : List String -> Html msg
genOrderedList strings =
Html.ol []
(strings
|> List.map
(\string -> Html.li [] [ Html.text string ])
)


resetList : List String -> Int -> List String
resetList strings limit =
if List.length strings >= limit then
[]

else
strings
1 change: 1 addition & 0 deletions ui/src/Main.elm
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch
[ Sub.map UserMsg (User.subscriptions model.user)
, Sub.map MessageMsg (Message.subscriptions model.message)
]


Expand Down
Loading

0 comments on commit c37cbf9

Please sign in to comment.