web: Simplify hledgerLayout into defaultLayout
This commit is contained in:
parent
9beec88727
commit
0e7b713a80
@ -9,8 +9,10 @@ import Data.IORef (IORef, readIORef, writeIORef)
|
|||||||
import Data.List (isPrefixOf)
|
import Data.List (isPrefixOf)
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Text as T
|
||||||
import Data.Time.Calendar (Day)
|
import Data.Time.Calendar (Day)
|
||||||
import Network.HTTP.Conduit (Manager)
|
import Network.HTTP.Conduit (Manager)
|
||||||
|
import System.FilePath (takeFileName)
|
||||||
import Text.Blaze (Markup)
|
import Text.Blaze (Markup)
|
||||||
import Text.Blaze.Html.Renderer.String (renderHtml)
|
import Text.Blaze.Html.Renderer.String (renderHtml)
|
||||||
import Text.Hamlet (hamletFile)
|
import Text.Hamlet (hamletFile)
|
||||||
@ -19,6 +21,7 @@ import Yesod.Static
|
|||||||
import Yesod.Default.Config
|
import Yesod.Default.Config
|
||||||
|
|
||||||
import Handler.AddForm
|
import Handler.AddForm
|
||||||
|
import Handler.Common (balanceReportAsHtml)
|
||||||
import Settings.StaticFiles
|
import Settings.StaticFiles
|
||||||
import Settings (widgetFile, Extra (..))
|
import Settings (widgetFile, Extra (..))
|
||||||
#ifndef DEVELOPMENT
|
#ifndef DEVELOPMENT
|
||||||
@ -28,7 +31,7 @@ import Yesod.Default.Util (addStaticContentExternal)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
import Hledger
|
import Hledger
|
||||||
import Hledger.Cli
|
import Hledger.Cli (CliOpts(..), journalReloadIfChanged)
|
||||||
import Hledger.Web.WebOptions
|
import Hledger.Web.WebOptions
|
||||||
|
|
||||||
-- | The site argument for your application. This can be a good place to
|
-- | The site argument for your application. This can be a good place to
|
||||||
@ -86,7 +89,20 @@ instance Yesod App where
|
|||||||
defaultLayout widget = do
|
defaultLayout widget = do
|
||||||
master <- getYesod
|
master <- getYesod
|
||||||
lastmsg <- getMessage
|
lastmsg <- getMessage
|
||||||
VD{j, opts} <- getViewData
|
VD{am, here, j, opts, q, qopts, showsidebar} <- getViewData
|
||||||
|
|
||||||
|
let journalcurrent = if here == JournalR then "inacct" else "" :: Text
|
||||||
|
ropts = reportopts_ (cliopts_ opts)
|
||||||
|
-- flip the default for items with zero amounts, show them by default
|
||||||
|
ropts' = ropts { empty_ = not (empty_ ropts) }
|
||||||
|
accounts = balanceReportAsHtml RegisterR j qopts $ balanceReport ropts' am j
|
||||||
|
|
||||||
|
topShowmd = if showsidebar then "col-md-4" else "col-any-0" :: Text
|
||||||
|
topShowsm = if showsidebar then "col-sm-4" else "" :: Text
|
||||||
|
sideShowmd = if showsidebar then "col-md-4" else "col-any-0" :: Text
|
||||||
|
sideShowsm = if showsidebar then "col-sm-4" else "" :: Text
|
||||||
|
mainShowmd = if showsidebar then "col-md-8" else "col-md-12" :: Text
|
||||||
|
mainShowsm = if showsidebar then "col-sm-8" else "col-sm-12" :: Text
|
||||||
|
|
||||||
-- We break up the default layout into two components:
|
-- We break up the default layout into two components:
|
||||||
-- default-layout is the contents of the body tag, and
|
-- default-layout is the contents of the body tag, and
|
||||||
|
|||||||
@ -62,7 +62,7 @@ postAddR = do
|
|||||||
Right t -> do
|
Right t -> do
|
||||||
-- 3. all fields look good and form a balanced transaction; append it to the file
|
-- 3. all fields look good and form a balanced transaction; append it to the file
|
||||||
liftIO (appendTransaction journalfile t)
|
liftIO (appendTransaction journalfile t)
|
||||||
setMessage [shamlet|<span>Transaction added.|]
|
setMessage "Transaction added."
|
||||||
redirect JournalR
|
redirect JournalR
|
||||||
where
|
where
|
||||||
bail :: [Text] -> Handler ()
|
bail :: [Text] -> Handler ()
|
||||||
|
|||||||
@ -4,80 +4,17 @@
|
|||||||
|
|
||||||
module Handler.Common where
|
module Handler.Common where
|
||||||
|
|
||||||
import Import
|
import Data.Semigroup ((<>))
|
||||||
|
import Data.Text (Text)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Data.Time.Calendar (Day, toGregorian)
|
import Data.Time.Calendar (Day, toGregorian)
|
||||||
import System.FilePath (takeFileName)
|
|
||||||
import Text.Blaze (ToMarkup)
|
import Text.Blaze (ToMarkup)
|
||||||
import Text.Blaze.Internal (preEscapedString)
|
import Text.Blaze.Internal (preEscapedString)
|
||||||
import Text.Printf (printf)
|
import Yesod
|
||||||
|
|
||||||
import Hledger.Cli.CliOptions
|
import Settings (manualurl)
|
||||||
import Hledger.Data
|
|
||||||
import Hledger.Query
|
|
||||||
import Hledger.Reports
|
|
||||||
import Hledger.Utils
|
|
||||||
import Hledger.Web.WebOptions
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
import Hledger
|
||||||
-- Common page layout
|
|
||||||
|
|
||||||
-- | Standard hledger-web page layout.
|
|
||||||
#if MIN_VERSION_yesod(1,6,0)
|
|
||||||
hledgerLayout :: ViewData -> Text -> HtmlUrl AppRoute -> HandlerFor App Html
|
|
||||||
#else
|
|
||||||
hledgerLayout :: ViewData -> Text -> HtmlUrl AppRoute -> HandlerT App IO Html
|
|
||||||
#endif
|
|
||||||
hledgerLayout vd title content = do
|
|
||||||
defaultLayout $ do
|
|
||||||
setTitle $ toHtml $ title <> " - hledger-web"
|
|
||||||
toWidget [hamlet|
|
|
||||||
^{topbar vd}
|
|
||||||
^{sidebar vd}
|
|
||||||
<div #main-content .col-xs-12 .#{showmd} .#{showsm}>
|
|
||||||
^{searchform vd}
|
|
||||||
^{content}
|
|
||||||
|]
|
|
||||||
where
|
|
||||||
showmd = if showsidebar vd then "col-md-8" else "col-md-12" :: Text
|
|
||||||
showsm = if showsidebar vd then "col-sm-8" else "col-sm-12" :: Text
|
|
||||||
|
|
||||||
-- | Global toolbar/heading area.
|
|
||||||
topbar :: ViewData -> HtmlUrl AppRoute
|
|
||||||
topbar VD{j, showsidebar} = [hamlet|
|
|
||||||
<div#spacer .#{showsm} .#{showmd} .col-xs-2>
|
|
||||||
<h1>
|
|
||||||
<button .visible-xs .btn .btn-default type="button" data-toggle="offcanvas">
|
|
||||||
<span .glyphicon .glyphicon-align-left .tgl-icon>
|
|
||||||
<div#topbar .col-md-8 .col-sm-8 .col-xs-10>
|
|
||||||
<h1>#{title}
|
|
||||||
|]
|
|
||||||
where
|
|
||||||
title = takeFileName $ journalFilePath j
|
|
||||||
showmd = if showsidebar then "col-md-4" else "col-any-0" :: Text
|
|
||||||
showsm = if showsidebar then "col-sm-4" else "" :: Text
|
|
||||||
|
|
||||||
-- | The sidebar used on most views.
|
|
||||||
sidebar :: ViewData -> HtmlUrl AppRoute
|
|
||||||
sidebar vd@VD{am, here, j, opts, showsidebar} =
|
|
||||||
[hamlet|
|
|
||||||
<div #sidebar-menu .#{showmd} .#{showsm} .sidebar-offcanvas>
|
|
||||||
<table .main-menu .table>
|
|
||||||
<tr .#{journalcurrent}>
|
|
||||||
<td .top .acct>
|
|
||||||
<a href=@{JournalR} .#{journalcurrent} title="Show general journal entries, most recent first">Journal
|
|
||||||
<td .top>
|
|
||||||
^{accounts}
|
|
||||||
|]
|
|
||||||
where
|
|
||||||
journalcurrent = if here == JournalR then "inacct" else "" :: Text
|
|
||||||
ropts = reportopts_ $ cliopts_ opts
|
|
||||||
-- flip the default for items with zero amounts, show them by default
|
|
||||||
ropts' = ropts{empty_=not $ empty_ ropts}
|
|
||||||
accounts = balanceReportAsHtml vd $ balanceReport ropts' am j
|
|
||||||
showmd = if showsidebar then "col-md-4" else "col-any-0" :: Text
|
|
||||||
showsm = if showsidebar then "col-sm-4" else "" :: Text
|
|
||||||
|
|
||||||
-- -- | Navigation link, preserving parameters and possibly highlighted.
|
-- -- | Navigation link, preserving parameters and possibly highlighted.
|
||||||
-- navlink :: ViewData -> String -> AppRoute -> String -> HtmlUrl AppRoute
|
-- navlink :: ViewData -> String -> AppRoute -> String -> HtmlUrl AppRoute
|
||||||
@ -97,67 +34,43 @@ sidebar vd@VD{am, here, j, opts, showsidebar} =
|
|||||||
-- <a#importformlink href="#" onclick="return importformToggle(event)" style="display:none;">import transactions
|
-- <a#importformlink href="#" onclick="return importformToggle(event)" style="display:none;">import transactions
|
||||||
-- |]
|
-- |]
|
||||||
|
|
||||||
-- | Search form for entering custom queries to filter journal data.
|
|
||||||
searchform :: ViewData -> HtmlUrl AppRoute
|
|
||||||
searchform VD{q, here} = [hamlet|
|
|
||||||
<div#searchformdiv .row>
|
|
||||||
<form#searchform .form-inline method=GET>
|
|
||||||
<div .form-group .col-md-12 .col-sm-12 .col-xs-12>
|
|
||||||
<div #searchbar .input-group>
|
|
||||||
<input .form-control name=q value=#{q} title="Enter hledger search patterns to filter the data below" placeholder="Search">
|
|
||||||
<div .input-group-btn>
|
|
||||||
$if not (T.null q)
|
|
||||||
<a href=@{here} .btn .btn-default title="Clear search terms">
|
|
||||||
<span .glyphicon .glyphicon-remove-circle>
|
|
||||||
<button .btn .btn-default type=submit title="Apply search terms">
|
|
||||||
<span .glyphicon .glyphicon-search>
|
|
||||||
<button .btn .btn-default type=button data-toggle="modal" data-target="#helpmodal" title="Show search and general help">?
|
|
||||||
|]
|
|
||||||
|
|
||||||
-- | Link to a topic in the manual.
|
-- | Link to a topic in the manual.
|
||||||
helplink :: Text -> Text -> HtmlUrl AppRoute
|
helplink :: Text -> Text -> HtmlUrl r
|
||||||
helplink topic label = [hamlet|
|
helplink topic label = [hamlet|<a href=#{u} target=hledgerhelp>#{label}|]
|
||||||
<a href=#{u} target=hledgerhelp>#{label}
|
|
||||||
|]
|
|
||||||
where u = manualurl <> if T.null topic then "" else T.cons '#' topic
|
where u = manualurl <> if T.null topic then "" else T.cons '#' topic
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
-- hledger report renderers
|
-- hledger report renderers
|
||||||
|
|
||||||
-- | Render a "BalanceReport" as html.
|
-- | Render a "BalanceReport" as html.
|
||||||
balanceReportAsHtml :: ViewData -> BalanceReport -> HtmlUrl AppRoute
|
balanceReportAsHtml :: r -> Journal -> [QueryOpt] -> BalanceReport -> HtmlUrl r
|
||||||
balanceReportAsHtml VD{j, qopts} (items, total) =
|
balanceReportAsHtml registerR j qopts (items, total) = [hamlet|
|
||||||
[hamlet|
|
$forall (acct, adisplay, aindent, abal) <- items
|
||||||
$forall i <- items
|
<tr .#{inacctClass acct}>
|
||||||
^{itemAsHtml i}
|
|
||||||
<tr .total>
|
|
||||||
<td>
|
|
||||||
<td>
|
|
||||||
#{mixedAmountAsHtml total}
|
|
||||||
|]
|
|
||||||
where
|
|
||||||
l = ledgerFromJournal Any j
|
|
||||||
inacctmatcher = inAccountQuery qopts
|
|
||||||
itemAsHtml :: BalanceReportItem -> HtmlUrl AppRoute
|
|
||||||
itemAsHtml (acct, adisplay, aindent, abal) = [hamlet|
|
|
||||||
<tr .#{inacctclass}>
|
|
||||||
<td .acct>
|
<td .acct>
|
||||||
<div .ff-wrapper>
|
<div .ff-wrapper>
|
||||||
\#{indent}
|
\#{indent aindent}
|
||||||
<a href="@?{acctquery}" .#{inacctclass} title="Show transactions affecting this account and subaccounts">#{adisplay}
|
<a href="@?{acctLink acct}" .#{inacctClass acct}
|
||||||
$if hassubs
|
title="Show transactions affecting this account and subaccounts">
|
||||||
<a href="@?{acctonlyquery}" .only .hidden-sm .hidden-xs title="Show transactions affecting this account but not subaccounts">only
|
#{adisplay}
|
||||||
|
$if hasSubs acct
|
||||||
|
<a href="@?{acctOnlyLink acct}" .only .hidden-sm .hidden-xs
|
||||||
|
title="Show transactions affecting this account but not subaccounts">only
|
||||||
<td>
|
<td>
|
||||||
#{mixedAmountAsHtml abal}
|
^{mixedAmountAsHtml abal}
|
||||||
|]
|
<tr .total>
|
||||||
where
|
<td>
|
||||||
hassubs = not $ maybe False (null.asubs) $ ledgerAccount l acct
|
<td>
|
||||||
inacctclass = case inacctmatcher of
|
^{mixedAmountAsHtml total}
|
||||||
|
|] where
|
||||||
|
l = ledgerFromJournal Any j
|
||||||
|
inacctClass acct = case inAccountQuery qopts of
|
||||||
Just m' -> if m' `matchesAccount` acct then "inacct" else ""
|
Just m' -> if m' `matchesAccount` acct then "inacct" else ""
|
||||||
Nothing -> "" :: Text
|
Nothing -> "" :: Text
|
||||||
indent = preEscapedString $ concat $ replicate (2 * (1+aindent)) " "
|
hasSubs acct = maybe True (not . null . asubs) (ledgerAccount l acct)
|
||||||
acctquery = (RegisterR, [("q", accountQuery acct)])
|
indent a = preEscapedString $ concat $ replicate (2 + 2 * a) " "
|
||||||
acctonlyquery = (RegisterR, [("q", accountOnlyQuery acct)])
|
acctLink acct = (registerR, [("q", accountQuery acct)])
|
||||||
|
acctOnlyLink acct = (registerR, [("q", accountOnlyQuery acct)])
|
||||||
|
|
||||||
accountQuery :: AccountName -> Text
|
accountQuery :: AccountName -> Text
|
||||||
accountQuery = ("inacct:" <>) . quoteIfSpaced
|
accountQuery = ("inacct:" <>) . quoteIfSpaced
|
||||||
@ -165,28 +78,31 @@ accountQuery = ("inacct:" <>) . quoteIfSpaced
|
|||||||
accountOnlyQuery :: AccountName -> Text
|
accountOnlyQuery :: AccountName -> Text
|
||||||
accountOnlyQuery = ("inacctonly:" <>) . quoteIfSpaced
|
accountOnlyQuery = ("inacctonly:" <>) . quoteIfSpaced
|
||||||
|
|
||||||
numberTransactionsReportItems :: [TransactionsReportItem] -> [(Int,Bool,Bool,Bool,TransactionsReportItem)]
|
numberTransactionsReportItems :: [TransactionsReportItem] -> [(Int, Bool, Bool, TransactionsReportItem)]
|
||||||
numberTransactionsReportItems [] = []
|
numberTransactionsReportItems [] = []
|
||||||
numberTransactionsReportItems items = number 0 nulldate items
|
numberTransactionsReportItems items = number 0 nulldate items
|
||||||
where
|
where
|
||||||
number :: Int -> Day -> [TransactionsReportItem] -> [(Int,Bool,Bool,Bool,TransactionsReportItem)]
|
number :: Int -> Day -> [TransactionsReportItem] -> [(Int, Bool, Bool, TransactionsReportItem)]
|
||||||
number _ _ [] = []
|
number _ _ [] = []
|
||||||
number n prevd (i@(Transaction{tdate=d},_,_,_,_,_):rest) = (n+1,newday,newmonth,newyear,i): number (n+1) d rest
|
number n prevd (i@(Transaction{tdate=d},_,_,_,_,_):rest) = (n+1, newday, newmonth, i): number (n+1) d rest
|
||||||
where
|
where
|
||||||
newday = d/=prevd
|
newday = d /= prevd
|
||||||
newmonth = dm/=prevdm || dy/=prevdy
|
newmonth = dm /= prevdm || dy /= prevdy
|
||||||
newyear = dy/=prevdy
|
(dy, dm, _) = toGregorian d
|
||||||
(dy,dm,_) = toGregorian d
|
(prevdy, prevdm, _) = toGregorian prevd
|
||||||
(prevdy,prevdm,_) = toGregorian prevd
|
|
||||||
|
|
||||||
mixedAmountAsHtml :: MixedAmount -> Html
|
mixedAmountAsHtml :: MixedAmount -> HtmlUrl a
|
||||||
mixedAmountAsHtml b = preEscapedString $ unlines $ map addclass $ lines $ showMixedAmountWithoutPrice b
|
mixedAmountAsHtml b = [hamlet|
|
||||||
where addclass = printf "<span class=\"%s\">%s</span><br/>" (c :: Text)
|
$forall t <- ts
|
||||||
|
<span .#{c}>#{t}
|
||||||
|
<br>
|
||||||
|
|] where
|
||||||
|
ts = T.lines . T.pack $ showMixedAmountWithoutPrice b
|
||||||
c = case isNegativeMixedAmount b of
|
c = case isNegativeMixedAmount b of
|
||||||
Just True -> "negative amount"
|
Just True -> "negative amount" :: Text
|
||||||
_ -> "positive amount"
|
_ -> "positive amount"
|
||||||
|
|
||||||
showErrors :: ToMarkup a => [a] -> Handler ()
|
showErrors :: ToMarkup a => [a] -> HandlerFor a ()
|
||||||
showErrors errs = setMessage [shamlet|
|
showErrors errs = setMessage [shamlet|
|
||||||
Errors:<br>
|
Errors:<br>
|
||||||
$forall e<-errs
|
$forall e<-errs
|
||||||
|
|||||||
@ -5,9 +5,7 @@ module Handler.JournalR where
|
|||||||
|
|
||||||
import Import
|
import Import
|
||||||
|
|
||||||
import Handler.Common
|
import Handler.Common (accountQuery, mixedAmountAsHtml)
|
||||||
(accountQuery, hledgerLayout, mixedAmountAsHtml,
|
|
||||||
numberTransactionsReportItems)
|
|
||||||
|
|
||||||
import Hledger.Cli.CliOptions
|
import Hledger.Cli.CliOptions
|
||||||
import Hledger.Data
|
import Hledger.Data
|
||||||
@ -19,19 +17,21 @@ import Hledger.Web.WebOptions
|
|||||||
-- | The formatted journal view, with sidebar.
|
-- | The formatted journal view, with sidebar.
|
||||||
getJournalR :: Handler Html
|
getJournalR :: Handler Html
|
||||||
getJournalR = do
|
getJournalR = do
|
||||||
vd@VD{j, m, opts, qopts} <- getViewData
|
VD{j, m, opts, qopts} <- getViewData
|
||||||
-- XXX like registerReportAsHtml
|
-- XXX like registerReportAsHtml
|
||||||
let title = case inAccount qopts of
|
let title = case inAccount qopts of
|
||||||
Nothing -> "General Journal"
|
Nothing -> "General Journal"
|
||||||
Just (a, inclsubs) -> "Transactions in " <> a <> if inclsubs then "" else " (excluding subaccounts)"
|
Just (a, inclsubs) -> "Transactions in " <> a <> if inclsubs then "" else " (excluding subaccounts)"
|
||||||
title' = title <> if m /= Any then ", filtered" else ""
|
title' = title <> if m /= Any then ", filtered" else ""
|
||||||
maincontent = transactionsReportAsHtml $ journalTransactionsReport (reportopts_ $ cliopts_ opts) j m
|
maincontent = transactionsReportAsHtml $ journalTransactionsReport (reportopts_ $ cliopts_ opts) j m
|
||||||
hledgerLayout vd "journal" [hamlet|
|
defaultLayout $ do
|
||||||
<div .row>
|
setTitle "journal - hledger-web"
|
||||||
|
toWidget [hamlet|
|
||||||
|
<div .row>
|
||||||
<h2 #contenttitle>#{title'}
|
<h2 #contenttitle>#{title'}
|
||||||
<!-- p>Journal entries record movements of commodities between accounts. -->
|
<!-- p>Journal entries record movements of commodities between accounts. -->
|
||||||
<a #addformlink role="button" style="cursor:pointer; margin-top:1em;" data-toggle="modal" data-target="#addmodal" title="Add a new transaction to the journal" href="#">Add a transaction
|
<a #addformlink role="button" style="cursor:pointer; margin-top:1em;" data-toggle="modal" data-target="#addmodal" title="Add a new transaction to the journal" href="#">Add a transaction
|
||||||
<div .table-responsive>
|
<div .table-responsive>
|
||||||
^{maincontent}
|
^{maincontent}
|
||||||
|]
|
|]
|
||||||
|
|
||||||
@ -45,18 +45,18 @@ transactionsReportAsHtml (_,items) = [hamlet|
|
|||||||
<th .description style="text-align:left;">Description
|
<th .description style="text-align:left;">Description
|
||||||
<th .account style="text-align:left;">Account
|
<th .account style="text-align:left;">Account
|
||||||
<th .amount style="text-align:right;">Amount
|
<th .amount style="text-align:right;">Amount
|
||||||
$forall i <- numberTransactionsReportItems items
|
$forall i <- items
|
||||||
^{transactionReportItem i}
|
^{transactionReportItem i}
|
||||||
|]
|
|]
|
||||||
|
|
||||||
transactionReportItem :: (Int, Bool, Bool, Bool, TransactionsReportItem) -> HtmlUrl AppRoute
|
transactionReportItem :: TransactionsReportItem -> HtmlUrl AppRoute
|
||||||
transactionReportItem (_, _, _, _, (torig, _, split, _, amt, _)) = [hamlet|
|
transactionReportItem (torig, _, split, _, amt, _) = [hamlet|
|
||||||
<tr .title #transaction-#{tindex torig}>
|
<tr .title #transaction-#{tindex torig}>
|
||||||
<td .date nowrap>#{date}
|
<td .date nowrap>#{date}
|
||||||
<td .description colspan=2>#{textElideRight 60 desc}
|
<td .description colspan=2>#{textElideRight 60 desc}
|
||||||
<td .amount style="text-align:right;">
|
<td .amount style="text-align:right;">
|
||||||
$if showamt
|
$if showamt
|
||||||
\#{mixedAmountAsHtml amt}
|
\^{mixedAmountAsHtml amt}
|
||||||
$forall p' <- tpostings torig
|
$forall p' <- tpostings torig
|
||||||
<tr .item .posting title="#{show torig}">
|
<tr .item .posting title="#{show torig}">
|
||||||
<td .nonhead>
|
<td .nonhead>
|
||||||
@ -64,7 +64,7 @@ $forall p' <- tpostings torig
|
|||||||
<td .nonhead>
|
<td .nonhead>
|
||||||
|
|
||||||
<a href="@?{acctlink (paccount p')}##{tindex torig}" title="#{paccount p'}">#{elideAccountName 40 $ paccount p'}
|
<a href="@?{acctlink (paccount p')}##{tindex torig}" title="#{paccount p'}">#{elideAccountName 40 $ paccount p'}
|
||||||
<td .amount .nonhead style="text-align:right;">#{mixedAmountAsHtml $ pamount p'}
|
<td .amount .nonhead style="text-align:right;">^{mixedAmountAsHtml $ pamount p'}
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
acctlink a = (RegisterR, [("q", accountQuery a)])
|
acctlink a = (RegisterR, [("q", accountQuery a)])
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import Data.List (intersperse)
|
|||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Safe (headMay)
|
import Safe (headMay)
|
||||||
|
|
||||||
import Handler.Common (hledgerLayout, numberTransactionsReportItems, mixedAmountAsHtml)
|
import Handler.Common (mixedAmountAsHtml, numberTransactionsReportItems)
|
||||||
|
|
||||||
import Hledger
|
import Hledger
|
||||||
import Hledger.Cli.CliOptions
|
import Hledger.Cli.CliOptions
|
||||||
@ -19,15 +19,16 @@ import Hledger.Web.WebOptions
|
|||||||
-- | The main journal/account register view, with accounts sidebar.
|
-- | The main journal/account register view, with accounts sidebar.
|
||||||
getRegisterR :: Handler Html
|
getRegisterR :: Handler Html
|
||||||
getRegisterR = do
|
getRegisterR = do
|
||||||
vd@VD{j, m, opts, qopts} <- getViewData
|
VD{j, m, opts, qopts} <- getViewData
|
||||||
let title = a <> s1 <> s2
|
let title = a <> s1 <> s2
|
||||||
where
|
where
|
||||||
(a,inclsubs) = fromMaybe ("all accounts",True) $ inAccount qopts
|
(a,inclsubs) = fromMaybe ("all accounts",True) $ inAccount qopts
|
||||||
s1 = if inclsubs then "" else " (excluding subaccounts)"
|
s1 = if inclsubs then "" else " (excluding subaccounts)"
|
||||||
s2 = if m /= Any then ", filtered" else ""
|
s2 = if m /= Any then ", filtered" else ""
|
||||||
hledgerLayout vd "register" $ do
|
defaultLayout $ do
|
||||||
_ <- [hamlet|<h2 #contenttitle>#{title}|]
|
setTitle "register - hledger-web"
|
||||||
registerReportHtml qopts $ accountTransactionsReport (reportopts_ $ cliopts_ opts) j m $ fromMaybe Any $ inAccountQuery qopts
|
_ <- toWidget [hamlet|<h2 #contenttitle>#{title}|]
|
||||||
|
toWidget $ registerReportHtml qopts $ accountTransactionsReport (reportopts_ $ cliopts_ opts) j m $ fromMaybe Any $ inAccountQuery qopts
|
||||||
|
|
||||||
-- | Generate html for an account register, including a balance chart and transaction list.
|
-- | Generate html for an account register, including a balance chart and transaction list.
|
||||||
registerReportHtml :: [QueryOpt] -> TransactionsReport -> HtmlUrl AppRoute
|
registerReportHtml :: [QueryOpt] -> TransactionsReport -> HtmlUrl AppRoute
|
||||||
@ -58,8 +59,8 @@ registerItemsHtml qopts (balancelabel,items) = [hamlet|
|
|||||||
insomeacct = isJust $ inAccount qopts
|
insomeacct = isJust $ inAccount qopts
|
||||||
balancelabel' = if insomeacct then balancelabel else "Total"
|
balancelabel' = if insomeacct then balancelabel else "Total"
|
||||||
|
|
||||||
itemAsHtml :: (Int, Bool, Bool, Bool, TransactionsReportItem) -> HtmlUrl AppRoute
|
itemAsHtml :: (Int, Bool, Bool, TransactionsReportItem) -> HtmlUrl AppRoute
|
||||||
itemAsHtml (n, newd, newm, _, (torig, tacct, split, acct, amt, bal)) = [hamlet|
|
itemAsHtml (n, newd, newm, (torig, tacct, split, acct, amt, bal)) = [hamlet|
|
||||||
<tr ##{tindex torig} .item.#{evenodd}.#{firstposting}.#{datetransition} title="#{show torig}" style="vertical-align:top;">
|
<tr ##{tindex torig} .item.#{evenodd}.#{firstposting}.#{datetransition} title="#{show torig}" style="vertical-align:top;">
|
||||||
<td .date>
|
<td .date>
|
||||||
<a href="@{JournalR}#transaction-#{tindex torig}">#{date}
|
<a href="@{JournalR}#transaction-#{tindex torig}">#{date}
|
||||||
@ -67,8 +68,8 @@ registerItemsHtml qopts (balancelabel,items) = [hamlet|
|
|||||||
<td .account>#{elideRight 40 acct}
|
<td .account>#{elideRight 40 acct}
|
||||||
<td .amount style="text-align:right; white-space:nowrap;">
|
<td .amount style="text-align:right; white-space:nowrap;">
|
||||||
$if showamt
|
$if showamt
|
||||||
\#{mixedAmountAsHtml amt}
|
\^{mixedAmountAsHtml amt}
|
||||||
<td .balance style="text-align:right;">#{mixedAmountAsHtml bal}
|
<td .balance style="text-align:right;">^{mixedAmountAsHtml bal}
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
evenodd = if even n then "even" else "odd" :: Text
|
evenodd = if even n then "even" else "odd" :: Text
|
||||||
|
|||||||
@ -1,4 +1,38 @@
|
|||||||
$maybe m <- lastmsg
|
$maybe m <- lastmsg
|
||||||
$if not $ isPrefixOf "Errors" (renderHtml m)
|
$if not $ isPrefixOf "Errors" (renderHtml m)
|
||||||
<div #message>#{m}
|
<div #message>#{m}
|
||||||
^{widget}
|
|
||||||
|
<div#spacer .col-xs-2.#{topShowsm}.#{topShowmd}>
|
||||||
|
<h1>
|
||||||
|
<button .visible-xs.btn.btn-default type="button" data-toggle="offcanvas">
|
||||||
|
<span .glyphicon.glyphicon-align-left.tgl-icon>
|
||||||
|
|
||||||
|
<div#topbar .col-md-8 .col-sm-8 .col-xs-10>
|
||||||
|
<h1>#{takeFileName (journalFilePath j)}
|
||||||
|
|
||||||
|
<div #sidebar-menu .sidebar-offcanvas.#{sideShowmd}.#{sideShowsm}>
|
||||||
|
<table .main-menu .table>
|
||||||
|
<tr .#{journalcurrent}>
|
||||||
|
<td .top .acct>
|
||||||
|
<a href=@{JournalR} .#{journalcurrent}
|
||||||
|
title="Show general journal entries, most recent first">
|
||||||
|
Journal
|
||||||
|
<td .top>
|
||||||
|
^{accounts}
|
||||||
|
|
||||||
|
<div #main-content .col-xs-12.#{mainShowmd}.#{mainShowsm}>
|
||||||
|
<div#searchformdiv .row>
|
||||||
|
<form#searchform .form-inline method=GET>
|
||||||
|
<div .form-group .col-md-12 .col-sm-12 .col-xs-12>
|
||||||
|
<div #searchbar .input-group>
|
||||||
|
<input .form-control name=q value=#{q} placeholder="Search"
|
||||||
|
title="Enter hledger search patterns to filter the data below">
|
||||||
|
<div .input-group-btn>
|
||||||
|
$if not (T.null q)
|
||||||
|
<a href=@{here} .btn .btn-default title="Clear search terms">
|
||||||
|
<span .glyphicon .glyphicon-remove-circle>
|
||||||
|
<button .btn .btn-default type=submit title="Apply search terms">
|
||||||
|
<span .glyphicon .glyphicon-search>
|
||||||
|
<button .btn .btn-default type=button data-toggle="modal" data-target="#helpmodal"
|
||||||
|
title="Show search and general help">?
|
||||||
|
^{widget}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user