Use project listing functionality to check for whether we have a cookie.

[?]
Aug 18, 2020, 4:49 AM
WRPIYG3EUHZR6N6T74ZXZDXATRMIRLXAQ24UNUNSVTVYGMT2VDSQC

Dependencies

  • [2] BFZN4SUA Make timeline component work.
  • [3] NJNMO72S Add zcash.com submodule and update client to modern halogen.
  • [4] JXG3FCXY Upgrade ps + halogen versions.
  • [5] HO2PFRAB Client login now handles response correctly.
  • [6] TKGBRIQT Login component now raises LoginComplete message.
  • [7] TUA4HMUD Use real API capability for login.
  • [8] 3LMXT7Z6 preventDefault on login form submission.
  • [9] ARX7SHY5 Begin work on login UI.
  • [10] EA5BFM5G Split Login component into its own module.
  • [*] RB2ETNIF Add skeletal PureScript client project.

Change contents

  • edit in client/package-lock.json at line 5855
    [3.231989][3.231989:232245]()
    },
    "purty": {
    "version": "6.2.0",
    "resolved": "https://registry.npmjs.org/purty/-/purty-6.2.0.tgz",
    "integrity": "sha512-JfT8kJHSyxuOFQtRiH2x55SiPxXZsSdedQlZap8JehQ7KzB49B5C9cWwVybtSB36BdADQcxPvtw8D52z4EPnBw==",
    "dev": true
  • edit in client/package-lock.json at line 7242
    [3.283335]
    [3.283335]
    "uuid-validate": {
    "version": "0.0.3",
    "resolved": "https://registry.npmjs.org/uuid-validate/-/uuid-validate-0.0.3.tgz",
    "integrity": "sha512-Fykw5U4eZESbq739BeLvEBFRuJODfrlmjx5eJux7W817LjRaq4b7/i4t2zxQmhcX+fAj4nMfRdTzO4tmwLKn0w=="
    },
  • replacement in client/package.json at line 6
    [3.291020][3.291020:291043]()
    "spago": "^0.15.3"
    [3.291020]
    [3.291043]
    "spago": "^0.15.3",
    "uuid-validate": "^0.0.3"
  • edit in client/package.json at line 15
    [3.291376]
    [3.467]
    },
    "dependencies": {
    "uuid-validate": "0.0.3"
  • edit in client/spago.dhall at line 10
    [3.295116]
    [3.295116]
    , "uuid"
    , "js-date"
  • replacement in client/src/Aftok/Login.purs at line 50
    [3.596][3.295914:295949]()
    data LoginComplete = LoginComplete
    [3.596]
    [3.725]
    newtype LoginComplete = LoginComplete { username :: String }
  • edit in client/src/Aftok/Login.purs at line 72
    [3.296445][3.296445:296446]()
  • replacement in client/src/Aftok/Login.purs at line 169
    [3.300507][3.300507:300546]()
    OK -> H.raise LoginComplete
    [3.300507]
    [3.300546]
    OK -> H.raise (LoginComplete { username: user })
  • file addition: Project.purs (----------)
    [3.1]
    module Aftok.Project where
    import Prelude
    import Control.Monad.Trans.Class (lift)
    import Control.Monad.Except.Trans (ExceptT, runExceptT, except)
    import Control.Monad.Error.Class (throwError)
    import Data.Argonaut.Core (Json)
    import Data.Argonaut.Decode (class DecodeJson, decodeJson, (.:))
    import Data.Bifunctor (lmap)
    import Data.DateTime (DateTime)
    import Data.JSDate as JSDate
    import Data.Either (Either(..), note)
    -- import Data.HTTP.Method (Method(POST))
    import Data.Maybe (Maybe(..))
    import Data.Traversable (traverse)
    import Data.UUID (UUID, parseUUID)
    import Effect (Effect)
    import Effect.Aff (Aff)
    import Effect.Class (liftEffect)
    import Affjax (get, printError)
    import Affjax.StatusCode (StatusCode(..))
    import Affjax.ResponseFormat as RF
    -- import Halogen as H
    -- import Halogen.HTML.Core (ClassName(..))
    -- import Halogen.HTML as HH
    -- import Halogen.HTML.CSS as CSS
    -- import Halogen.HTML.Events as E
    -- import Web.Event.Event as WE
    -- import Halogen.HTML.Properties as P
    newtype Project' date = Project'
    { projectName :: String
    , inceptionDate :: date
    , initiator :: UUID
    }
    type Project = Project' DateTime
    type Capability m =
    { listProjects :: m (Either APIError (Array Project))
    }
    data APIError
    = Forbidden
    | ParseFailure Json String
    | Error { status :: Maybe StatusCode, message :: String }
    instance decodeJsonProject :: DecodeJson (Project' String) where
    decodeJson json = do
    x <- decodeJson json
    projectName <- x .: "projectName"
    inceptionDate <- x .: "inceptionDate"
    initiatorStr <- x .: "initiator"
    initiator <- note "Failed to decode initiator UUID" $ parseUUID initiatorStr
    pure $ Project' { projectName, inceptionDate, initiator }
    listProjects :: Aff (Either APIError (Array Project))
    listProjects = do
    result <- get RF.json "/api/projects"
    liftEffect <<< runExceptT $ case result of
    Left err -> throwError $ Error { status: Nothing, message: printError err }
    Right r -> case r.status of
    StatusCode 403 ->
    throwError Forbidden
    StatusCode 200 -> do
    records <- except $ lmap (ParseFailure r.body) (decodeJson r.body)
    traverse parseProject records
    other ->
    throwError $ Error { status: Just other, message: r.statusText }
    parseProject :: Json -> ExceptT APIError Effect Project
    parseProject json = do
    Project' p <- except <<< lmap (ParseFailure json) $ decodeJson json
    jsDate <- lift $ JSDate.parse p.inceptionDate
    pdate <- except $ note (ParseFailure json "Could not parse inception date")
    (JSDate.toDateTime jsDate)
    pure $ Project' (p { inceptionDate = pdate })
    apiCapability :: Capability Aff
    apiCapability = { listProjects }
    mockCapability :: forall m. Applicative m => Capability m
    mockCapability = { listProjects: pure (Right []) }
  • edit in client/src/Aftok/Timeline.purs at line 12
    [3.2784][3.2784:2811]()
    import Data.Int (toNumber)
  • replacement in client/src/Aftok/Timeline.purs at line 122
    [3.303838][3.303838:303899]()
    endOfDay = adjust (Days (toNumber 1)) startOfDay
    [3.303838]
    [3.303899]
    endOfDay = adjust (Days 1.0) startOfDay
  • replacement in client/src/Aftok/Timeline.purs at line 155
    [3.304615][3.304615:304643]()
    let px5 = px (toNumber 5)
    [3.304615]
    [3.304643]
    let px5 = px 5.0
  • replacement in client/src/Aftok/Timeline.purs at line 158
    [3.304675][3.304675:304769]()
    border solid (px $ toNumber 3) (rgb 0x00 0xFF 0x00)
    height (px $ toNumber 50)
    [3.304675]
    [3.304769]
    border solid (px 3.0) (rgb 0x00 0xFF 0x00)
    height (px 50.0)
  • replacement in client/src/Aftok/Timeline.purs at line 175
    [2.1204][3.305192:305220](),[3.305192][3.305192:305220](),[3.305220][2.1205:1255]()
    px5 = px (toNumber 5)
    toPct n = pct (toNumber 100 * n / maxWidth)
    [2.1204]
    [3.305220]
    px5 = px (5.0)
    toPct n = pct (100.0 * n / maxWidth)
  • replacement in client/src/Aftok/Timeline.purs at line 181
    [3.305325][2.1256:1290]()
    height (px $ toNumber 44)
    [3.305325]
    [2.1290]
    height (px $ 44.0)
  • replacement in client/src/Aftok/Timeline.purs at line 191
    [3.305594][3.305594:305634]()
    Aff.delay $ Aff.Milliseconds 1000.0
    [3.305594]
    [3.305634]
    Aff.delay $ Aff.Milliseconds 10000.0
  • edit in client/src/Main.purs at line 4
    [3.307475]
    [3.492]
    import Control.Monad.Trans.Class (lift)
  • replacement in client/src/Main.purs at line 7
    [3.493][3.307476:307503]()
    import Data.Int (toNumber)
    [3.493]
    [3.307503]
    import Data.Either (Either(..))
  • edit in client/src/Main.purs at line 21
    [3.307748]
    [3.307786]
    import Aftok.Project as Project
  • replacement in client/src/Main.purs at line 30
    [2.1658][2.1658:1693](),[3.578][3.307936:307956](),[2.1693][3.307936:307956](),[3.307936][3.307936:307956]()
    let c = component login timeline
    runUI c unit body
    [2.1658]
    [3.1116]
    project = Project.apiCapability
    mainc = component login timeline project
    runUI mainc unit body
  • replacement in client/src/Main.purs at line 39
    [3.308080][3.308080:308118]()
    = LoginComplete Login.LoginComplete
    [3.308080]
    [3.1118]
    = Initialize
    | LoginComplete Login.LoginComplete
  • edit in client/src/Main.purs at line 54
    [2.1788]
    [3.308345]
    -> Project.Capability Aff
  • replacement in client/src/Main.purs at line 56
    [3.308393][2.1789:1831]()
    component loginCap tlCap = H.mkComponent
    [3.308393]
    [3.308429]
    component loginCap tlCap pCap = H.mkComponent
  • replacement in client/src/Main.purs at line 59
    [3.308458][3.308458:308517]()
    , eval: H.mkEval $ H.defaultEval { handleAction = eval }
    [3.308458]
    [3.308517]
    , eval: H.mkEval $ H.defaultEval
    { handleAction = eval
    , initialize = Just Initialize
    }
  • edit in client/src/Main.purs at line 64
    [3.308527][3.308527:308528]()
  • replacement in client/src/Main.purs at line 72
    [3.308824][2.1930:2036]()
    HH.div_ [ HH.slot _timeline unit (Timeline.component tlCap { width: toNumber 600 }) unit absurd ]
    [3.308824]
    [3.308924]
    HH.div_ [ HH.slot _timeline unit (Timeline.component tlCap { width: 600.0 }) unit absurd ]
  • replacement in client/src/Main.purs at line 76
    [3.309026][3.309026:309066]()
    LoginComplete _ -> H.put LoggedIn
    [3.309026]
    Initialize -> do
    projects <- lift pCap.listProjects
    case projects of
    Left err -> H.put LoggedOut
    Right _ -> H.put LoggedIn
    LoginComplete (Login.LoginComplete xs) ->
    H.put LoggedIn