Skip to content

Instantly share code, notes, and snippets.

@jippi
Created November 24, 2016 13:04
Show Gist options
  • Save jippi/ed36a56eab260345146f0318f02a909f to your computer and use it in GitHub Desktop.
Save jippi/ed36a56eab260345146f0318f02a909f to your computer and use it in GitHub Desktop.
module Main exposing (..)
import Allocation.List
import Allocation.View
import Array exposing (Array)
import Date exposing (Date)
import Html exposing (..)
import Html.Attributes exposing (..)
import Job.List
import Material
import Material.Layout as Layout
import Material.Options as Option
import Material.Color as Color
import Navigation exposing (Location)
import Task
import Time exposing (Time)
import Types exposing (..)
import UrlParser as Url exposing ((</>))
main : Program Never Model Msg
main =
Navigation.program UrlChange
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- MODEL
type Route
= ListAllocationsRoute
| ViewAllocationRoute1 String
| ViewAllocationRoute2 String String
| JobsPage
| EvaluationListRoute
route : Url.Parser (Route -> a) a
route =
Url.oneOf
[ Url.map ListAllocationsRoute Url.top
, Url.map ListAllocationsRoute (Url.s "allocations")
, Url.map ViewAllocationRoute1 (Url.s "allocations" </> Url.string)
, Url.map ViewAllocationRoute2 (Url.s "allocations" </> Url.string </> Url.string)
, Url.map EvaluationListRoute (Url.s "evaluations")
, Url.map JobsPage (Url.s "jobs")
]
type alias Model =
{ currentRoute : Route
, allocation : Maybe Allocation
, mdl : Material.Model
, currentDate : Date
, listAllocationsModel : Allocation.List.Model
, viewAllocationModel : Allocation.View.Model
, jobsListModel : Job.List.Model
}
init : Location -> ( Model, Cmd Msg )
init loc =
( { currentRoute = Url.parseHash route loc |> Maybe.withDefault ListAllocationsRoute
, allocation = Nothing
, mdl = Material.model
, currentDate = Date.fromTime 0
, listAllocationsModel = Allocation.List.init
, viewAllocationModel = Allocation.View.init
, jobsListModel = Job.List.init
}
, Cmd.batch [ Date.now |> Task.perform UpdateCurrentDate ]
)
-- UPDATE
type Msg
= ViewAllocation Allocation.View.Msg
| ListAllocations Allocation.List.Msg
| UrlChange Location
| NavigateTo String
| UpdateLayout Layout.Msg
| UpdateCurrentDate Date
| JobList Job.List.Msg
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
UpdateCurrentDate date ->
{ model | currentDate = date } ! []
UrlChange location ->
let
newRoute =
Url.parseHash route location
|> Maybe.withDefault model.currentRoute
in
( { model | currentRoute = newRoute }, Cmd.none )
NavigateTo newUrl ->
model ! [ Navigation.newUrl <| "#/" ++ newUrl ]
UpdateLayout lMsg ->
let
mdl =
model.mdl
( newLayout, cmd ) =
Layout.update lMsg mdl.layout
newMdl =
{ mdl | layout = newLayout }
in
( { model | mdl = newMdl }, Cmd.map UpdateLayout cmd )
ViewAllocation msg ->
let
ViewAllocationRoute2 firstVar secondVar = model.currentRoute
_ = Debug.log "firstVar" (toString firstVar)
( viewModel, cmd ) =
Allocation.View.update msg model.viewAllocationModel
in
( { model | viewAllocationModel = viewModel }, Cmd.none )
ListAllocations msg ->
( { model | listAllocationsModel = Allocation.List.update msg model.listAllocationsModel }, Cmd.none )
JobList msg ->
( { model | jobsListModel = Job.List.update msg model.jobsListModel }, Cmd.none )
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch
[ Time.every (Time.minute) (Date.fromTime >> UpdateCurrentDate)
, Sub.map UpdateLayout <|
Layout.subscriptions model.mdl.layout
, case model.currentRoute of
ViewAllocationRoute1 allocationId ->
Sub.map ViewAllocation <|
Allocation.View.subscriptions allocationId
ViewAllocationRoute2 allocationId _ ->
Sub.map ViewAllocation <|
Allocation.View.subscriptions allocationId
ListAllocationsRoute ->
Sub.map ListAllocations <|
Allocation.List.subscriptions model.listAllocationsModel
JobsPage ->
Sub.map JobList <|
Job.List.subscriptions model.jobsListModel
_ ->
Sub.none
]
-- VIEW
view : Model -> Html Msg
view model =
div []
[ globalStyles
, layout viewPage model
]
viewPage : Model -> Html Msg
viewPage model =
case model.currentRoute of
ListAllocationsRoute ->
Html.map ListAllocations <|
Allocation.List.view model.currentDate model.listAllocationsModel
ViewAllocationRoute1 _ ->
Html.map ViewAllocation <|
Allocation.View.view model.currentDate model.viewAllocationModel
ViewAllocationRoute2 _ _ ->
Html.map ViewAllocation <|
Allocation.View.view model.currentDate model.viewAllocationModel
JobsPage ->
Html.map JobList <|
Job.List.view model.jobsListModel
EvaluationListRoute ->
text "This is the evaluations page"
-- Layout
layout : (Model -> Html Msg) -> Model -> Html Msg
layout renderMain model =
Layout.view UpdateLayout
model.mdl.layout
[ Layout.fixedHeader, Layout.onSelectTab navigateTo ]
{ header = header, drawer = [], tabs = (tabs model.currentRoute), main = [ renderMain model ] }
header : List (Html Msg)
header =
[ Layout.row []
[ Layout.title [] [ text "Hashi-UI" ] ]
]
tabs : Route -> ( List (Html Msg), List (Option.Property c m) )
tabs currentRoute =
( tabList
|> Array.toList
|> List.map (highlightTab currentRoute)
, [ Color.background (Color.color Color.Teal Color.S400)
]
)
highlightTab : Route -> ( String, String ) -> Html Msg
highlightTab route tab =
let
isActive =
case ( route, Tuple.second tab ) of
( ListAllocationsRoute, "allocations" ) ->
True
( ViewAllocationRoute1 _, "allocations" ) ->
True
( ViewAllocationRoute2 _ _, "allocations" ) ->
True
( EvaluationListRoute, "evaluations" ) ->
True
( JobsPage, "jobs" ) ->
True
_ ->
False
classes =
[ ( "mdl-layout__tab", True ), ( "is-active", isActive ) ]
in
span
[ classList classes ]
[ text <| Tuple.first tab ]
tabList : Array ( String, String )
tabList =
Array.fromList
[ ( "Jobs", "jobs" )
, ( "Allocations", "allocations" )
, ( "Evaluations", "evaluations" )
]
navigateTo : Int -> Msg
navigateTo tabIndex =
Array.get tabIndex tabList
|> Maybe.map (Tuple.second >> NavigateTo)
|> Maybe.withDefault (NavigateTo "allocations")
-- Global styles
globalStyles : Html Msg
globalStyles =
div []
[ node "link"
[ href "https://fonts.googleapis.com/css?family=Roboto:400,300,500|Roboto+Mono|Roboto+Condensed:400,700&subset=latin,latin-ext"
, rel "stylesheet"
, type_ "text/css"
]
[]
, node "link" [ href "https://fonts.googleapis.com/icon?family=Material+Icons", rel "stylesheet" ] []
, node "link" [ href "https://code.getmdl.io/1.2.0/material.teal-red.min.css", rel "stylesheet" ] []
, node "style" [] [ text ".elm-overlay { z-index: 2; }" ]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment