From ebbbe908809d570d1a16bd65e5e6089971a976a5 Mon Sep 17 00:00:00 2001 From: Vidir Valberg Gudmundsson Date: Mon, 17 Jul 2017 12:53:38 +0200 Subject: [PATCH] Split elm views up for better maintainability. --- schedule/src/Views.elm | 218 +----------------------- schedule/src/Views/DayPicker.elm | 44 +++++ schedule/src/Views/DayView.elm | 21 +++ schedule/src/Views/EventDetail.elm | 53 ++++++ schedule/src/Views/FilterView.elm | 74 ++++++++ schedule/src/Views/ScheduleOverview.elm | 82 +++++++++ 6 files changed, 280 insertions(+), 212 deletions(-) create mode 100644 schedule/src/Views/DayPicker.elm create mode 100644 schedule/src/Views/DayView.elm create mode 100644 schedule/src/Views/EventDetail.elm create mode 100644 schedule/src/Views/FilterView.elm create mode 100644 schedule/src/Views/ScheduleOverview.elm diff --git a/schedule/src/Views.elm b/schedule/src/Views.elm index c199c5c4..20a37439 100644 --- a/schedule/src/Views.elm +++ b/schedule/src/Views.elm @@ -4,50 +4,21 @@ module Views exposing (..) import Models exposing (..) import Messages exposing (Msg(..)) - - --- Core modules - -import Html exposing (Html, Attribute, div, input, text, li, ul, a, h4, label, i, span, hr, small, p) -import Html.Attributes exposing (class, classList, id, type_, for, style, href) -import Html.Events exposing (onClick) +import Views.DayPicker exposing (dayPicker) +import Views.DayView exposing (dayView) +import Views.EventDetail exposing (eventInstanceDetailView) +import Views.ScheduleOverview exposing (scheduleOverviewView) -- External modules -import Markdown - - -dayButton : Day -> Day -> Html Msg -dayButton day activeDay = - a - [ classList - [ ( "btn", True ) - , ( "btn-default", day /= activeDay ) - , ( "btn-primary", day == activeDay ) - ] - , onClick (MakeActiveday day) - , href - ("#" - ++ case day.iso of - "" -> - "" - - iso -> - "day/" ++ iso - ) - ] - [ text day.day_name - ] +import Html exposing (Html, Attribute, div, input, text, li, ul, a, h4, label, i, span, hr, small, p) view : Model -> Html Msg view model = div [] - [ div [ class "row" ] - [ div [ id "schedule-days", class "btn-group" ] - (List.map (\day -> dayButton day model.activeDay) (allDaysDay :: model.days)) - ] + [ dayPicker model , hr [] [] , case model.route of OverviewRoute -> @@ -62,180 +33,3 @@ view model = NotFoundRoute -> div [] [ text "Not found!" ] ] - - -dayView : DayIso -> Model -> Html Msg -dayView dayIso model = - div [] - [ filterSideBar model - ] - - -eventInstanceDetailView : EventInstanceSlug -> Model -> Html Msg -eventInstanceDetailView eventInstanceSlug model = - let - eventInstance = - case List.head (List.filter (\e -> e.slug == eventInstanceSlug) model.eventInstances) of - Just eventInstance -> - eventInstance - - Nothing -> - emptyEventInstance - - event = - case List.head (List.filter (\e -> e.slug == eventInstance.eventSlug) model.events) of - Just event -> - event - - Nothing -> - { title = "", slug = "", abstract = "", speakers = [] } - in - div [ class "row" ] - [ div [ class "col-sm-9" ] - [ a [ href "#" ] - [ text "Back" - ] - , h4 [] [ text eventInstance.title ] - , p [] [ Markdown.toHtml [] event.abstract ] - , hr [] [] - , h4 [] [ text "TODO: Show all instances here!" ] - ] - , div - [ classList - [ ( "col-sm-3", True ) - , ( "schedule-sidebar", True ) - ] - ] - [ h4 [] [ text "Speakers" ] - ] - ] - - -filterSideBar : Model -> Html Msg -filterSideBar model = - div - [ classList - [ ( "col-sm-3", True ) - , ( "col-sm-push-9", True ) - , ( "schedule-sidebar", True ) - , ( "schedule-filter", True ) - ] - ] - [ h4 [] [ text "Filter" ] - , div [ class "form-group" ] - [ filterView "Type" model.eventTypes model.filter.eventTypes ToggleEventTypeFilter - , filterView "Location" model.eventLocations model.filter.eventLocations ToggleEventLocationFilter - ] - ] - - -scheduleOverviewView : Model -> Html Msg -scheduleOverviewView model = - div [ class "row" ] - [ filterSideBar model - , div - [ classList - [ ( "col-sm-9", True ) - , ( "col-sm-pull-3", True ) - ] - ] - (List.map (\day -> dayRowView day model) model.days) - ] - - -dayRowView : Day -> Model -> Html Msg -dayRowView day model = - let - types = - List.map (\eventType -> eventType.slug) - (if List.isEmpty model.filter.eventTypes then - model.eventTypes - else - model.filter.eventTypes - ) - - locations = - List.map (\eventLocation -> eventLocation.slug) - (if List.isEmpty model.filter.eventLocations then - model.eventLocations - else - model.filter.eventLocations - ) - - filteredEventInstances = - List.filter - (\eventInstance -> - ((String.slice 0 10 eventInstance.from) == day.iso) - && List.member eventInstance.location locations - && List.member eventInstance.eventType types - ) - model.eventInstances - in - div [] - [ h4 [] - [ text day.repr ] - , div [ class "schedule-day-row" ] - (List.map dayEventInstanceView filteredEventInstances) - ] - - -dayEventInstanceView : EventInstance -> Html Msg -dayEventInstanceView eventInstance = - a - [ class "event" - , href ("#event/" ++ eventInstance.slug) - , style - [ ( "background-color", eventInstance.backgroundColor ) - , ( "color", eventInstance.forgroundColor ) - ] - ] - [ small [] - [ text ((String.slice 11 16 eventInstance.from) ++ " - " ++ (String.slice 11 16 eventInstance.to)) ] - , i [ classList [ ( "fa", True ), ( "fa-" ++ eventInstance.locationIcon, True ), ( "pull-right", True ) ] ] [] - , p - [] - [ text eventInstance.title ] - ] - - -filterView : - String - -> List { a | name : String } - -> List { a | name : String } - -> ({ a | name : String } -> Msg) - -> Html Msg -filterView name possibleFilters currentFilters action = - div [] - [ text (name ++ ":") - , ul [] (List.map (\filter -> filterChoiceView filter currentFilters action) possibleFilters) - ] - - -filterChoiceView : - { a | name : String } - -> List { a | name : String } - -> ({ a | name : String } -> Msg) - -> Html Msg -filterChoiceView filter currentFilters action = - let - active = - List.member filter currentFilters - - notActive = - not active - in - li [] - [ div - [ classList - [ ( "btn", True ) - , ( "btn-default", True ) - , ( "filter-choice-active", active ) - ] - , onClick (action filter) - ] - [ span [] - [ i [ classList [ ( "fa", True ), ( "fa-minus", active ), ( "fa-plus", notActive ) ] ] [] - , text (" " ++ filter.name) - ] - ] - ] diff --git a/schedule/src/Views/DayPicker.elm b/schedule/src/Views/DayPicker.elm new file mode 100644 index 00000000..8c446a7c --- /dev/null +++ b/schedule/src/Views/DayPicker.elm @@ -0,0 +1,44 @@ +module Views.DayPicker exposing (..) + +-- Local modules + +import Models exposing (..) +import Messages exposing (Msg(..)) + + +-- External modules + +import Html exposing (Html, text, a, div) +import Html.Attributes exposing (class, classList, href, id) +import Html.Events exposing (onClick) + + +dayPicker : Model -> Html Msg +dayPicker model = + div [ class "row" ] + [ div [ id "schedule-days", class "btn-group" ] + (List.map (\day -> dayButton day model.activeDay) (allDaysDay :: model.days)) + ] + + +dayButton : Day -> Day -> Html Msg +dayButton day activeDay = + a + [ classList + [ ( "btn", True ) + , ( "btn-default", day /= activeDay ) + , ( "btn-primary", day == activeDay ) + ] + , onClick (MakeActiveday day) + , href + ("#" + ++ case day.iso of + "" -> + "" + + iso -> + "day/" ++ iso + ) + ] + [ text day.day_name + ] diff --git a/schedule/src/Views/DayView.elm b/schedule/src/Views/DayView.elm new file mode 100644 index 00000000..db14feb1 --- /dev/null +++ b/schedule/src/Views/DayView.elm @@ -0,0 +1,21 @@ +module Views.DayView exposing (dayView) + +-- Local modules + +import Messages exposing (Msg(..)) +import Models exposing (Model, DayIso) +import Views.FilterView exposing (filterSidebar) + + +-- External modules + +import Html exposing (Html, text, div, ul, li, span, i, h4) +import Html.Attributes exposing (class, classList, href) +import Html.Events exposing (onClick) + + +dayView : DayIso -> Model -> Html Msg +dayView dayIso model = + div [] + [ filterSidebar model + ] diff --git a/schedule/src/Views/EventDetail.elm b/schedule/src/Views/EventDetail.elm new file mode 100644 index 00000000..88ab809c --- /dev/null +++ b/schedule/src/Views/EventDetail.elm @@ -0,0 +1,53 @@ +module Views.EventDetail exposing (eventInstanceDetailView) + +-- Local modules + +import Messages exposing (Msg(..)) +import Models exposing (..) + + +-- External modules + +import Html exposing (Html, text, div, ul, li, span, i, h4, a, p, hr) +import Html.Attributes exposing (class, classList, href) +import Markdown + + +eventInstanceDetailView : EventInstanceSlug -> Model -> Html Msg +eventInstanceDetailView eventInstanceSlug model = + let + eventInstance = + case List.head (List.filter (\e -> e.slug == eventInstanceSlug) model.eventInstances) of + Just eventInstance -> + eventInstance + + Nothing -> + emptyEventInstance + + event = + case List.head (List.filter (\e -> e.slug == eventInstance.eventSlug) model.events) of + Just event -> + event + + Nothing -> + { title = "", slug = "", abstract = "", speakers = [] } + in + div [ class "row" ] + [ div [ class "col-sm-9" ] + [ a [ href "#" ] + [ text "Back" + ] + , h4 [] [ text eventInstance.title ] + , p [] [ Markdown.toHtml [] event.abstract ] + , hr [] [] + , h4 [] [ text "TODO: Show all instances here!" ] + ] + , div + [ classList + [ ( "col-sm-3", True ) + , ( "schedule-sidebar", True ) + ] + ] + [ h4 [] [ text "Speakers" ] + ] + ] diff --git a/schedule/src/Views/FilterView.elm b/schedule/src/Views/FilterView.elm new file mode 100644 index 00000000..b8119068 --- /dev/null +++ b/schedule/src/Views/FilterView.elm @@ -0,0 +1,74 @@ +module Views.FilterView exposing (filterSidebar) + +-- Local modules + +import Messages exposing (Msg(..)) +import Models exposing (Model) + + +-- External modules + +import Html exposing (Html, text, div, ul, li, span, i, h4) +import Html.Attributes exposing (class, classList, href) +import Html.Events exposing (onClick) + + +filterSidebar : Model -> Html Msg +filterSidebar model = + div + [ classList + [ ( "col-sm-3", True ) + , ( "col-sm-push-9", True ) + , ( "schedule-sidebar", True ) + , ( "schedule-filter", True ) + ] + ] + [ h4 [] [ text "Filter" ] + , div [ class "form-group" ] + [ filterView "Type" model.eventTypes model.filter.eventTypes ToggleEventTypeFilter + , filterView "Location" model.eventLocations model.filter.eventLocations ToggleEventLocationFilter + ] + ] + + +filterView : + String + -> List { a | name : String } + -> List { a | name : String } + -> ({ a | name : String } -> Msg) + -> Html Msg +filterView name possibleFilters currentFilters action = + div [] + [ text (name ++ ":") + , ul [] (List.map (\filter -> filterChoiceView filter currentFilters action) possibleFilters) + ] + + +filterChoiceView : + { a | name : String } + -> List { a | name : String } + -> ({ a | name : String } -> Msg) + -> Html Msg +filterChoiceView filter currentFilters action = + let + active = + List.member filter currentFilters + + notActive = + not active + in + li [] + [ div + [ classList + [ ( "btn", True ) + , ( "btn-default", True ) + , ( "filter-choice-active", active ) + ] + , onClick (action filter) + ] + [ span [] + [ i [ classList [ ( "fa", True ), ( "fa-minus", active ), ( "fa-plus", notActive ) ] ] [] + , text (" " ++ filter.name) + ] + ] + ] diff --git a/schedule/src/Views/ScheduleOverview.elm b/schedule/src/Views/ScheduleOverview.elm new file mode 100644 index 00000000..e47c817a --- /dev/null +++ b/schedule/src/Views/ScheduleOverview.elm @@ -0,0 +1,82 @@ +module Views.ScheduleOverview exposing (scheduleOverviewView) + +-- Local modules + +import Messages exposing (Msg(..)) +import Models exposing (Model, Day, EventInstance) +import Views.FilterView exposing (filterSidebar) + + +-- External modules + +import Html exposing (Html, text, div, ul, li, span, i, h4, p, small, a) +import Html.Attributes exposing (class, classList, href, style) + + +scheduleOverviewView : Model -> Html Msg +scheduleOverviewView model = + div [ class "row" ] + [ filterSidebar model + , div + [ classList + [ ( "col-sm-9", True ) + , ( "col-sm-pull-3", True ) + ] + ] + (List.map (\day -> dayRowView day model) model.days) + ] + + +dayRowView : Day -> Model -> Html Msg +dayRowView day model = + let + types = + List.map (\eventType -> eventType.slug) + (if List.isEmpty model.filter.eventTypes then + model.eventTypes + else + model.filter.eventTypes + ) + + locations = + List.map (\eventLocation -> eventLocation.slug) + (if List.isEmpty model.filter.eventLocations then + model.eventLocations + else + model.filter.eventLocations + ) + + filteredEventInstances = + List.filter + (\eventInstance -> + ((String.slice 0 10 eventInstance.from) == day.iso) + && List.member eventInstance.location locations + && List.member eventInstance.eventType types + ) + model.eventInstances + in + div [] + [ h4 [] + [ text day.repr ] + , div [ class "schedule-day-row" ] + (List.map dayEventInstanceView filteredEventInstances) + ] + + +dayEventInstanceView : EventInstance -> Html Msg +dayEventInstanceView eventInstance = + a + [ class "event" + , href ("#event/" ++ eventInstance.slug) + , style + [ ( "background-color", eventInstance.backgroundColor ) + , ( "color", eventInstance.forgroundColor ) + ] + ] + [ small [] + [ text ((String.slice 11 16 eventInstance.from) ++ " - " ++ (String.slice 11 16 eventInstance.to)) ] + , i [ classList [ ( "fa", True ), ( "fa-" ++ eventInstance.locationIcon, True ), ( "pull-right", True ) ] ] [] + , p + [] + [ text eventInstance.title ] + ]