Begin work on timeline component.
JXG3FCXYBDKMUD77DOM7RCIJYKB7BILC43OHHDZBE7YQRGAMUCCAC QQXR7DTOQ3BDRAIYASTMTFQXAVIG4MFIRNUH4C5M72WZMHPFL2YAC PGZJ736CG2E4HXIRYTZTGOMJRX2CHPIFG6H45PPO57EONOWJJ74QC ADMKQQGCGVSHHIMVQ4XFRDCG544SBJCYALSKZV45CQQBZ4ACUH2AC ARX7SHY5UXL5ZZDY4BJ6LVQSC2XCI5M6FFXQ35MBWDRUHNJNICHQC RB2ETNIFLQUA6OA66DAEOXZ25ENMQGNKX5CZRSKEYHTD6BQ6NTFQC EA5BFM5GMM7KNMDLTVOSUKVKMSIDD72TAFVHDVGEOUY5VELECU3QC .psc-package
"purescript-console": "^0.1.0","purescript-halogen": "~0.5.14","purescript-affjax": "~0.10.1"
"purescript-halogen": "^1.2.1","purescript-css": "^2.1.0","purescript-halogen-css": "^5.0.0","purescript-dom": "^3.7.0","purescript-affjax": "^3.0.2","purescript-now": "^2.0.0"
.tl-wrapper {height: 45px;width: 962px;margin-left: auto;margin-right: auto;}
{"devDependencies": {"pulp": "^10.0.0","purescript": "^0.10.7","purescript-psa": "^0.4.0","rimraf": "^2.5.4"}}
import Halogenimport Halogen.HTML.Core (className)import qualified Halogen.HTML.Indexed as Himport qualified Halogen.HTML.Events.Indexed as Eimport qualified Halogen.HTML.Properties.Indexed as P
import Halogen as Himport Halogen.Aff (HalogenEffects)import Halogen.HTML.Core (ClassName(..))import Halogen.HTML as HHimport Halogen.HTML.Events as Eimport Halogen.HTML.Properties as P
ui :: forall eff. Component LoginState LoginAction (Aff (LoginEffects eff))ui = component render evalwhere
ui :: forall eff. H.Component HH.HTML LoginAction LoginState Void (Aff (LoginEffects eff))ui = H.component{ initialState: const initialState, render, eval, receiver: const Nothing} where
H.div[ P.classes (className <$> ["container"]) ][ H.form[ P.classes [ className "form-signin" ] ][ H.h2 [ P.classes [ className "form-signin-heading" ]] [ H.text "Aftok Login" ], H.label [ P.for "inputUsername", P.classes [ className "sr-only" ]] [ H.text "username" ], H.input[ P.inputType P.InputText
HH.div[ P.classes (ClassName <$> ["container"]) ][ HH.form[ P.classes [ ClassName "form-signin" ] ][ HH.h2 [ P.classes [ ClassName "form-signin-heading" ]] [ HH.text "Aftok Login" ], HH.label [ P.for "inputUsername", P.classes [ ClassName "sr-only" ]] [ HH.text "username" ], HH.input[ P.type_ P.InputText
, H.label [ P.for "inputPassword", P.classes [ className "sr-only" ]] [ H.text "username" ], H.input[ P.inputType P.InputPassword
, HH.label [ P.for "inputPassword", P.classes [ ClassName "sr-only" ]] [ HH.text "username" ], HH.input[ P.type_ P.InputPassword
eval :: Natural LoginAction (ComponentDSL LoginState LoginAction (Aff (LoginEffects eff)))eval (SetUsername user next) = modify (_ { username = user }) $> nexteval (SetPassword pass next) = modify (_ { password = pass }) $> next
eval :: LoginAction ~> H.ComponentDSL LoginState LoginAction Void (Aff (LoginEffects eff))eval (SetUsername user next) = H.modify (_ { username = user }) $> nexteval (SetPassword pass next) = H.modify (_ { password = pass }) $> next
module Aftok.Timeline whereimport Preludeimport Control.Monad.Eff (Eff())import Control.Monad.Eff.Class (liftEff)import Control.Monad.Eff.Now (NOW, nowDateTime, now)import Control.Monad.Aff (Aff())import Control.Alt ((<|>))import Data.Array (cons)--import Data.Bounded (bottom)--import Data.Date (Date(..), day, month, year)import Data.DateTime (DateTime(..), date, adjust)import Data.DateTime.Instant (Instant, unInstant, fromDateTime)import Data.DateTime.Locale (LocalValue(..))import Data.Int (toNumber)import Data.Time.Duration (Milliseconds(..), Days(..))import Data.Maybe (Maybe(..), maybe)import Math (abs)import CSS.Display (position, absolute)import CSS.Geometry (left) --, width, top, height)import CSS.Size (px)import Halogen as Himport Halogen.Aff (HalogenEffects)import Halogen.HTML.CSS as CSSimport Halogen.HTML as HH-- import Halogen.HTML.Events as Eimport Halogen.HTML.Properties as Ptype Interval ={ start :: Instant, end :: Instant}type TimelineLimits ={ start :: Instant, current :: Instant, end :: Instant}type TimelineConfig ={ width :: Number}type TimelineState ={ limits :: TimelineLimits, history :: Array Interval, active :: Maybe Interval}data TimelineAction a= Start a| Stop a| Refresh a-- | Open a-- | Close atype TimelineEffects eff = HalogenEffects (now :: NOW | eff)initialState :: forall eff. Eff (now :: NOW | eff) TimelineStateinitialState = doLocalValue l t <- nowDateTimelet startOfDay = DateTime (date t) bottomendOfDay = adjust (Days (toNumber 1)) startOfDaystartInstant = fromDateTime startOfDaylimits ={ start: startInstant, current: fromDateTime t, end: maybe startInstant fromDateTime endOfDay}pure $ { limits : limits, history : [], active : Nothing}ui :: forall eff. TimelineConfig -> TimelineState -> H.Component HH.HTML TimelineAction TimelineState Void (Aff (TimelineEffects eff))ui conf s = H.component{ initialState: const s, render, eval, receiver: const Nothing} whereintervalHtml :: forall f. TimelineLimits -> Interval -> H.ComponentHTML fintervalHtml limits i =let offset = ((ilen limits.start i.start) / (ilen limits.start limits.end)) * conf.widthin HH.div[ CSS.style doposition absoluteleft (px offset)][ HH.div[ P.classes (H.ClassName <$> ["center"]) ][]]-- <div style="position: absolute; left: 582.268px; width: 92.4619px; top: 6px; height: 33px;" class="TimelineElement Element ui-resizable ui-draggable" data-original-title=""><div class="center" style="background-color: rgb(255, 0, 0);"></div><div class="ui-resizable-w ui-resizable-handle"></div><div class="ui-draggable-pad"></div><div class="ui-resizable-e ui-resizable-handle"></div></div>render :: TimelineState -> H.ComponentHTML TimelineActionrender st =HH.div[ P.classes (H.ClassName <$> ["container"]) ][ HH.div[ P.classes (H.ClassName <$> ["tl-wrapper"]) ](intervalHtml st.limits <$> st.history)]eval :: TimelineAction ~> H.ComponentDSL TimelineState TimelineAction Void (Aff (TimelineEffects eff))-- The user has requested to start the clock.eval (Start next) = dot <- liftEff nowH.modify (start t)pure next-- The user has requested to stop the clockeval (Stop next) = dot <- liftEff nowH.modify (stop t)pure next-- The runtime system renders a clock tickeval (Refresh next) = dot <- liftEff nowH.modify (refresh t)pure next-- The user has requested to open a new interval beginning at a-- specific point on the timeline (mouse down)-- The user has requested to close the currently open interval-- at a specific point on the timeline (mouse up)--start :: Instant -> TimelineState -> TimelineStatestart t s ={ limits: s.limits, history: s.history, active: s.active <|> Just { start: t, end: t }}stop :: Instant -> TimelineState -> TimelineStatestop t s ={ limits: s.limits, history: maybe s.history (\st -> cons { start: st.start, end: t } s.history) s.active, active: Nothing}refresh :: Instant -> TimelineState -> TimelineStaterefresh t s ={ limits: s.limits, history: s.history, active: map (\a -> { start: a.start, end: t }) s.active}ilen :: Instant -> Instant -> Numberilen d d' =let n (Milliseconds x) = xin abs $ n (unInstant d) - n (unInstant d')
import Halogenimport Halogen.Util (appendToBody, onLoad)import Halogen.Util (appendToBody, onLoad)import qualified Aftok.Login as L
import Halogen.Aff (HalogenEffects)import Halogen.VDom.Driver (runUI)import Halogen.Aff as HAimport Aftok.Login as L
main = runAff throwException (const (pure unit)) $ doapp <- runUI L.ui L.initialStateonLoad $ appendToBody app.node
main = HA.runHalogenAff $ dobody <- HA.awaitBodyrunUI L.ui L.initialState body