Skip to content
Permalink
Browse files

feat(sessions list): move to elm and use checkboxes

  • Loading branch information...
3v0k4 committed Mar 26, 2019
1 parent f7b594f commit 4cff375d6b9d83ab58ff16bd69b8069c27eb51d1
@@ -1,5 +1,6 @@
import _ from 'underscore';
import { formatSessionForList } from '../values/session'
import { Elm } from '../../../elm/src/SessionsList.elm';

export const SessionsListCtrl = (
$scope,
@@ -18,6 +19,7 @@ export const SessionsListCtrl = (
) => {
let sessions;
let singleSession;
let elmApp;
const CANNOT_SELECT_MULTIPLE_SESSIONS = "You can't select multiple sessions";

$scope.setDefaults = function() {
@@ -93,6 +95,7 @@ export const SessionsListCtrl = (
$scope.$watch("newSessionsForList()", function(newSessions, oldSessions) {
console.log("newSessionsForList()", newSessions, oldSessions);
$scope.sessionsForList = newSessions;
if (elmApp) elmApp.ports.updateSessions.send(newSessions.map(formatSessionForElm));
}, true);

$scope.$on('markerSelected', function(event, data){
@@ -172,4 +175,26 @@ export const SessionsListCtrl = (
};

$scope.setDefaults();
};

if (process.env.NODE_ENV !== 'test') {
angular.element(document).ready(() => {
const node = document.getElementById('sessions-bottom-elm');
const flags = $scope.sessions.get().map(formatSessionForList).map(formatSessionForElm);
elmApp = Elm.SessionsList.init({ node, flags });

elmApp.ports.checkedSession.subscribe(({ selected, deselected }) => {
if (deselected) $scope.toggleSession(deselected, true);
if (selected) $scope.toggleSession(selected, true);
$scope.$apply();
});

elmApp.ports.loadMoreSessions.subscribe(() => {
$scope.updateSessionsPage();
$scope.$apply();
});
});
};
}

const formatSessionForElm = s =>
({ ...s , shortTypes: s.shortTypes.map(({ name, type }) => ({ name, type_: type })) });
@@ -0,0 +1,188 @@
port module SessionsList exposing (Model, Msg(..), Session, ShortType, checkedSession, init, loadMoreSessions, main, subscriptions, update, updateSessions, view, viewSession, viewShortType)

import Browser
import Html exposing (Html, button, dd, div, dl, dt, input, label, li, span, text, ul)
import Html.Attributes as Attr
import Html.Events as Events
import String exposing (fromInt)


---- MODEL ----


type alias ShortType =
{ name : String
, type_ : String
}


type alias Session =
{ title : String
, id : Int
, timeframe : String
, username : String
, shortTypes : List ShortType
, selected : Bool -- THIS IS USED IN JS, IN ELM WE TRACK SELECTION IN selectedSessionId. REMOVE WHEN MOVING FETCHING FROM JS TO ELM
}


type alias Model =
{ sessions : List Session
, selectedSessionId : Maybe Int
}


init : List Session -> ( Model, Cmd Msg )
init flags =
( { sessions = flags, selectedSessionId = Nothing }, Cmd.none )


subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch [ updateSessions UpdateSessions ]



---- UPDATE ----


port updateSessions : (List Session -> msg) -> Sub msg


port checkedSession : { deselected : Maybe Int, selected : Maybe Int } -> Cmd msg


port loadMoreSessions : () -> Cmd msg


type Msg
= ToggleSessionSelection Int
| UpdateSessions (List Session)
| LoadMoreSessions


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
ToggleSessionSelection id ->
if model.selectedSessionId == Just id then
( { model | selectedSessionId = Nothing }
, checkedSession { deselected = model.selectedSessionId, selected = Nothing }
)
else
( { model | selectedSessionId = Just id }
, checkedSession { deselected = model.selectedSessionId, selected = Just id }
)

UpdateSessions sessions ->
let
selectedSessionId =
List.head << List.map .id << List.filter .selected
in
( { model | sessions = sessions, selectedSessionId = selectedSessionId sessions }, Cmd.none )

LoadMoreSessions ->
( model, loadMoreSessions () )



---- VIEW ----


viewSession : Maybe Int -> Session -> Html Msg
viewSession selectedSessionId session =
li
[ Attr.style "padding" "5px 10px"
, Attr.style "clear" "both"
, Attr.style "overflow" "hidden"
]
[ input
[ Attr.type_ "radio"
, Attr.id <| "radio-" ++ fromInt session.id
, Attr.checked <| selectedSessionId == Just session.id
, Events.onClick <| ToggleSessionSelection session.id
, Attr.style "float" "left"
, Attr.style "margin" "3px 0 0"
]
[]
, dl
[ Attr.style "float" "left"
, Attr.style "margin" "0 0 0 10px"
]
[ dt
[ Attr.style "font-size" "14px"
, Attr.style "color" "#000"
, Attr.style "font-weight" "normal"
]
[ label
[ Attr.class "narrow"
, Attr.style "display" "block"
, Attr.style "cursor" "pointer"
, Attr.style "width" "170px"
, Attr.for <| "radio-" ++ fromInt session.id
]
[ text session.title ]
]
, dd
[ Attr.style "font-size" "11px"
, Attr.style "margin" "0"
, Attr.style "color" "#000"
, Attr.style "font-weight" "normal"
]
[ label
[ Attr.class "narrow"
, Attr.style "display" "block"
, Attr.style "cursor" "pointer"
, Attr.style "width" "170px"
]
([ div [] [ text <| session.username ++ ", " ++ session.timeframe ]
]
++ List.indexedMap (viewShortType <| List.length session.shortTypes) session.shortTypes
)
]
]
]


viewShortType : Int -> Int -> ShortType -> Html msg
viewShortType length index shortType =
span [ Attr.class shortType.type_ ]
[ text shortType.name
, span []
[ if index == length - 1 then
text ""
else
text "/"
]
]


view : Model -> Html Msg
view model =
ul
[]
(List.map (viewSession model.selectedSessionId) model.sessions
++ [ viewLoadMore <| List.length model.sessions ]
)


viewLoadMore : Int -> Html Msg
viewLoadMore sessionCount =
if sessionCount /= 0 && modBy 50 sessionCount == 0 then
li [] [ button [ Events.onClick LoadMoreSessions ] [ text "Load More..." ] ]
else
text ""



---- PROGRAM ----


main : Program (List Session) Model Msg
main =
Browser.element
{ view = view
, init = init
, update = update
, subscriptions = subscriptions
}

0 comments on commit 4cff375

Please sign in to comment.
You can’t perform that action at this time.