Add billable list (in-progress)
[?]
Feb 6, 2021, 6:42 PM
KET5QGQPM5STWGRDL72HTZ5T57QRKQQ3L564PST2PNG4YJHKATSACDependencies
- [2]
3PFXXJTLWIP - [3]
ANDJ6GEYAdd billing component skeleton. - [4]
YBLHJFCNImplement billing modal. - [5]
NAFJ6RB3Minor module reorg. - [6]
4GOBY5NQWIP on modals. - [7]
3HTCTHHUAdd halogen-portal dependency and update argonaut. - [8]
VTZT2ILUWire up billing navigation. - [9]
T2DN23M7Factor out billing create component. - [10]
N6FG4EW6Working bootstrap modal! Only a little FFI. - [11]
27H4DECZAdd billing create API call. - [*]
RFYEVKZQAdd nix-shell based build environment. - [*]
DJATFGICSupport client builds in nix-shell --pure.
Change contents
- replacement in client/src/Aftok/Api/Billing.purs at line 4
import Control.Monad.Error.Class (throwError)import Control.Monad.Except.Trans (runExceptT, except, withExceptT)import Control.Alternative ((<|>))-- import Control.Monad.Error.Class (throwError)-- import Control.Monad.Except.Trans (runExceptT, except, withExceptT) - replacement in client/src/Aftok/Api/Billing.purs at line 10
import Data.Argonaut.Decode (class DecodeJson, decodeJson, JsonDecodeError(..), (.:))import Data.Argonaut.Decode (class DecodeJson, decodeJson, JsonDecodeError(..), (.:), (.:?)) - replacement in client/src/Aftok/Api/Billing.purs at line 12
import Data.BigInt (toNumber)import Data.BigInt (toNumber, fromNumber) as BigInt - edit in client/src/Aftok/Api/Billing.purs at line 16
import Foreign.Object (Object) - replacement in client/src/Aftok/Api/Billing.purs at line 24[2.53]→[3.315:341](∅→∅),[3.142]→[3.315:341](∅→∅),[3.336]→[3.315:341](∅→∅),[3.755]→[3.315:341](∅→∅),[3.341]→[3.785:842](∅→∅),[3.785]→[3.785:842](∅→∅)
import Data.Tuple (Tuple)-- import Data.Traversable (class Traversable, traverse)import Data.Tuple (Tuple(..))import Data.Traversable (traverse) - replacement in client/src/Aftok/Api/Billing.purs at line 31
import Affjax (post, printError)import Affjax (post, get) - replacement in client/src/Aftok/Api/Billing.purs at line 34
import Affjax.StatusCode (StatusCode(..))-- import Affjax.StatusCode (StatusCode(..)) - replacement in client/src/Aftok/Api/Billing.purs at line 38
( Zatoshi )( Zatoshi(..) ) - replacement in client/src/Aftok/Api/Billing.purs at line 41
-- import Aftok.Api.Json-- ( Decode-- , decompose-- , parseDatedResponse-- , parseDatedResponseMay-- )import Aftok.Api.Json( parseResponse) - replacement in client/src/Aftok/Api/Billing.purs at line 94
, amount: toNumber (unwrap b.amount), amount: BigInt.toNumber (unwrap b.amount) - replacement in client/src/Aftok/Api/Billing.purs at line 101
-- parseBillableJSON :: Object Json -> Either JsonDecodeError (Tuple BillableId Billable)-- parseBillableJSON obj = do-- billableId <- parseBillableIdJSON =<< obj .: "billableId"-- bobj <- obj .: "billable"-- amount <--- Zatoshi <$> (note (TypeMismatch "Failed to decode as Zatoshi") <<< BigInt.fromNumber)-- =<< (_ .: "zatoshi")-- =<< (bobj .: "amount")-- gracePeriod <- Hours <$> bobj .: "gracePeriod"-- recurrence <- parseRecurrence =<< bobj .: "recurrence"parseRecurrence :: Json -> Either JsonDecodeError RecurrenceparseRecurrence json = doobj <- decodeJson jsonlet annually = traverse (map \(_ :: Unit) -> Annually) (obj .:? "annually")monthly = traverse (map Monthly) (obj .:? "monthly")weekly = traverse (map Weekly) (obj .:? "weekly")onetime = traverse (map \(_ :: Unit) -> OneTime) (obj .:? "onetime")join $ note (UnexpectedValue json) (annually <|> monthly <|> weekly <|> onetime) - edit in client/src/Aftok/Api/Billing.purs at line 112
parseBillableJSON :: Object Json -> Either JsonDecodeError (Tuple BillableId Billable)parseBillableJSON obj = dobillableId <- parseBillableIdJSON =<< obj .: "billableId"bobj <- obj .: "billable"name :: String <- bobj .: "name"description :: String <- bobj .: "description"let message = ""recurrence :: Recurrence <- parseRecurrence =<< bobj .: "recurrence"amount <-map Zatoshi$ (note (TypeMismatch "Failed to decode as Zatoshi") <<< BigInt.fromNumber)=<< (_ .: "zatoshi")=<< (bobj .: "amount")gracePeriod <- Days <$> bobj .: "gracePeriod"expiryPeriod <- Hours <$> bobj .: "gracePeriod"pure $ Tuple billableId {name, description, message, recurrence, amount, gracePeriod, expiryPeriod } - edit in client/src/Aftok/Api/Billing.purs at line 129
- replacement in client/src/Aftok/Api/Billing.purs at line 154[3.1195]→[3.1195:1387](∅→∅),[3.1387]→[3.882:962](∅→∅),[3.962]→[3.1476:1556](∅→∅),[3.1476]→[3.1476:1556](∅→∅)
runExceptT $ case response ofLeft err -> throwError $ Error { status: Nothing, message: printError err }Right r -> case r.status ofStatusCode 403 -> throwError $ ForbiddenStatusCode 200 -> withExceptT ParseFailure <<< except $ decodeJson r.bodyother -> throwError $ Error { status: Just other, message: r.statusText }parseResponse decodeJson response - replacement in client/src/Aftok/Api/Billing.purs at line 157
listProjectBillables pid = pure $ Left ForbiddenlistProjectBillables pid = doresponse <- get RF.json ("/api/projects/" <> pidStr pid <> "/billables")parseResponse (traverse parseBillableJSON <=< decodeJson) response - replacement in client/src/Aftok/Api/Json.purs at line 5
import Control.Monad.Except.Trans (ExceptT, except, withExceptT)import Control.Monad.Except.Trans (ExceptT, except, withExceptT, runExceptT) - edit in client/src/Aftok/Api/Json.purs at line 19
import Effect.Aff (Aff) - edit in client/src/Aftok/Api/Json.purs at line 62
parseResponse ::forall a.Decode a ->Either AJAX.Error (Response Json) ->Aff (Either APIError a)parseResponse decode response =runExceptT $ case response ofLeft err -> throwError $ Error { status: Nothing, message: printError err }Right r -> case r.status ofStatusCode 403 -> throwError $ ForbiddenStatusCode 200 -> withExceptT ParseFailure <<< except $ decode r.bodyother -> throwError $ Error { status: Just other, message: r.statusText } - replacement in client/src/Aftok/Billing.purs at line 9
-- import Data.Unfoldable as Uimport Data.Unfoldable as U - replacement in client/src/Aftok/Billing.purs at line 14
import Data.Tuple (Tuple)import Data.Tuple (Tuple(..)) - edit in client/src/Aftok/Billing.purs at line 37
import Aftok.Zcash (toZEC, zecString) - replacement in client/src/Aftok/Billing.purs at line 122
[ Modals.modalButton "createBillable" "Create billable"[ renderBillableList st.billables, Modals.modalButton "createBillable" "Create billable" - edit in client/src/Aftok/Billing.purs at line 137
renderBillableList :: Array (Tuple BillableId Billable) -> H.ComponentHTML BillingAction Slots mrenderBillableList billables =HH.div[ P.classes (ClassName <$> [ "container-fluid" ]) ][ HH.section[ P.id_ "projectOverview", P.classes (ClassName <$> [ "pt-3" ]) ]([ HH.div-- header[ P.classes (ClassName <$> [ "row", "pt-3", "font-weight-bold" ]) ][ colmd2 (Just "Billable Name"), colmd2 (Just "Description"), colmd2 (Just "Amount"), colmd2 (Just "Recurrence"), colmd2 Nothing]] <> (billableRow <$> billables))]wherebillableRow (Tuple bid b) =HH.div[ P.classes (ClassName <$> [ "row", "pt-3" ]) ][ colmd2 (Just b.name), colmd2 (Just b.description), colmd2 (Just (zecString <<< toZEC $ b.amount))]colmd2 :: forall i w. Maybe String -> HH.HTML i wcolmd2 xs = HH.div [ P.classes (ClassName <$> [ "col-md-2" ]) ] (U.fromMaybe $ HH.text <$> xs) - replacement in client/src/Aftok/Billing.purs at line 173
billables <- lift $ traverse (caps.listProjectBillables <<< (_.projectId) <<< unwrap) currentProjectcase billables ofNothing -> pure unitJust (Left err) -> lift $ system.error (show err)Just (Right b) -> H.modify_ (_ { billables = b })refreshBillables currentProject - edit in client/src/Aftok/Billing.purs at line 177
refreshBillables currentProject - replacement in client/src/Aftok/Billing.purs at line 182
BillableCreated _ ->pure unitBillableCreated _ -> docurrentProject <- H.gets (_.selectedProject)refreshBillables currentProjectwhererefreshBillables currentProject = dobillables <- lift $ traverse (caps.listProjectBillables <<< (_.projectId) <<< unwrap) currentProjectcase billables ofNothing -> pure unitJust (Left err) -> lift $ system.error (show err)Just (Right b) -> H.modify_ (_ { billables = b }) - replacement in client/src/Aftok/Zcash.purs at line 7
import Data.Fixed (Fixed, P1000000, TenTimes, fromInt, numerator)import Data.Fixed (Fixed, P1000000, TenTimes, fromInt, numerator, fromBigInt) - edit in client/src/Aftok/Zcash.purs at line 20
toZEC :: Zatoshi -> ZECtoZEC (Zatoshi z) =ZEC $ fromBigInt z / fromInt 100000000 - edit in shell.nix at line 23[14.38][13.99129]
haskellPackages.HDBC-postgresqlhaskellPackages.dbmigrations-postgresql