From ccc79d9e021da0b4a6f796cc76e03f1c8554fb61 Mon Sep 17 00:00:00 2001 From: jholdstock Date: Mon, 5 Oct 2020 16:34:02 +0100 Subject: [PATCH] gui: Display pending/archived payment totals --- gui/account.go | 40 ++++++++++++-------- gui/admin.go | 26 +++++++++---- gui/assets/public/css/dcrpool.css | 5 +++ gui/assets/templates/payments.html | 19 ++++++++-- gui/cache.go | 61 +++++++++++++++++++++--------- 5 files changed, 108 insertions(+), 43 deletions(-) diff --git a/gui/account.go b/gui/account.go index 7b45d805..337ca5a2 100644 --- a/gui/account.go +++ b/gui/account.go @@ -14,14 +14,16 @@ import ( // accountPageData contains all of the necessary information to render the // account template. type accountPageData struct { - HeaderData headerData - MinedWork []*minedWork - ArchivedPayments []*archivedPayment - PendingPayments []*pendingPayment - ConnectedClients []*client - AccountID string - Address string - BlockExplorerURL string + HeaderData headerData + MinedWork []*minedWork + ArchivedPaymentsTotal string + ArchivedPayments []*archivedPayment + PendingPaymentsTotal string + PendingPayments []*pendingPayment + ConnectedClients []*client + AccountID string + Address string + BlockExplorerURL string } // account is the handler for "GET /account". Renders the account template if @@ -43,6 +45,12 @@ func (ui *GUI) account(w http.ResponseWriter, r *http.Request) { return } + totalPending := ui.cache.getPendingPaymentsTotal(accountID) + totalArchived := ui.cache.getArchivedPaymentsTotal(accountID) + + // We don't need to handle errors on the following cache access because we + // are passing hard-coded, good params. + // Get the 10 most recently mined blocks by this account. _, recentWork, _ := ui.cache.getMinedWorkByAccount(0, 9, accountID) @@ -61,13 +69,15 @@ func (ui *GUI) account(w http.ResponseWriter, r *http.Request) { Designation: ui.cfg.Designation, ShowMenu: true, }, - MinedWork: recentWork, - PendingPayments: pendingPmts, - ArchivedPayments: archivedPmts, - ConnectedClients: clients, - AccountID: accountID, - Address: address, - BlockExplorerURL: ui.cfg.BlockExplorerURL, + MinedWork: recentWork, + PendingPaymentsTotal: totalPending, + PendingPayments: pendingPmts, + ArchivedPaymentsTotal: totalArchived, + ArchivedPayments: archivedPmts, + ConnectedClients: clients, + AccountID: accountID, + Address: address, + BlockExplorerURL: ui.cfg.BlockExplorerURL, } ui.renderTemplate(w, "account", data) diff --git a/gui/admin.go b/gui/admin.go index f7083042..c2488b8e 100644 --- a/gui/admin.go +++ b/gui/admin.go @@ -15,11 +15,13 @@ import ( // adminPageData contains all of the necessary information to render the admin // template. type adminPageData struct { - HeaderData headerData - PoolStatsData poolStatsData - ConnectedClients map[string][]*client - ArchivedPayments []*archivedPayment - PendingPayments []*pendingPayment + HeaderData headerData + PoolStatsData poolStatsData + ConnectedClients map[string][]*client + ArchivedPaymentsTotal string + ArchivedPayments []*archivedPayment + PendingPaymentsTotal string + PendingPayments []*pendingPayment } // adminPage is the handler for "GET /admin". If the current session is @@ -35,6 +37,12 @@ func (ui *GUI) adminPage(w http.ResponseWriter, r *http.Request) { clients := ui.cache.getClients() + totalPending := ui.cache.getPendingPaymentsTotal(pool.PoolFeesK) + totalArchived := ui.cache.getArchivedPaymentsTotal(pool.PoolFeesK) + + // We don't need to handle errors on the following cache access because we + // are passing hard-coded, good params. + // Get the 10 most recent pending payments. _, pendingPmts, _ := ui.cache.getPendingPayments(0, 9, pool.PoolFeesK) @@ -56,9 +64,11 @@ func (ui *GUI) adminPage(w http.ResponseWriter, r *http.Request) { PoolFee: ui.cfg.PoolFee, SoloPool: ui.cfg.SoloPool, }, - ConnectedClients: clients, - PendingPayments: pendingPmts, - ArchivedPayments: archivedPmts, + ConnectedClients: clients, + PendingPaymentsTotal: totalPending, + PendingPayments: pendingPmts, + ArchivedPaymentsTotal: totalArchived, + ArchivedPayments: archivedPmts, } ui.renderTemplate(w, "admin", pageData) diff --git a/gui/assets/public/css/dcrpool.css b/gui/assets/public/css/dcrpool.css index b36550dc..66bcf4e0 100644 --- a/gui/assets/public/css/dcrpool.css +++ b/gui/assets/public/css/dcrpool.css @@ -8781,6 +8781,11 @@ table td { padding-bottom: 10px; } +.block__content h2 { + color: #3D5873; + font-size: 22px; +} + .dcr-label { background: #D3F0FD 0% 0% no-repeat padding-box; border-radius: 3px; diff --git a/gui/assets/templates/payments.html b/gui/assets/templates/payments.html index b7203acb..3e989397 100644 --- a/gui/assets/templates/payments.html +++ b/gui/assets/templates/payments.html @@ -5,7 +5,13 @@
-

Pending Payments

+
+

Pending Payments

+ +

+ Total: {{ .PendingPaymentsTotal }} +

+
@@ -37,8 +43,15 @@

Pending Payments

-

Payments Received

- + +
+

Payments Received

+ +

+ Total: {{ .ArchivedPaymentsTotal }} +

+
+
diff --git a/gui/cache.go b/gui/cache.go index a0e22dd7..089a0ffb 100644 --- a/gui/cache.go +++ b/gui/cache.go @@ -10,6 +10,7 @@ import ( "sort" "sync" + "github.com/decred/dcrd/dcrutil/v3" "github.com/decred/dcrpool/pool" ) @@ -68,19 +69,21 @@ type archivedPayment struct { // access. Data returned by the getters is already formatted for display in the // GUI, so the formatting does not need to be repeated. type Cache struct { - blockExplorerURL string - minedWork []*minedWork - minedWorkMtx sync.RWMutex - rewardQuotas []*rewardQuota - rewardQuotasMtx sync.RWMutex - poolHash string - poolHashMtx sync.RWMutex - clients map[string][]*client - clientsMtx sync.RWMutex - pendingPayments map[string][]*pendingPayment - pendingPaymentsMtx sync.RWMutex - archivedPayments map[string][]*archivedPayment - archivedPaymentsMtx sync.RWMutex + blockExplorerURL string + minedWork []*minedWork + minedWorkMtx sync.RWMutex + rewardQuotas []*rewardQuota + rewardQuotasMtx sync.RWMutex + poolHash string + poolHashMtx sync.RWMutex + clients map[string][]*client + clientsMtx sync.RWMutex + pendingPayments map[string][]*pendingPayment + pendingPaymentTotals map[string]dcrutil.Amount + pendingPaymentsMtx sync.RWMutex + archivedPayments map[string][]*archivedPayment + archivedPaymentTotals map[string]dcrutil.Amount + archivedPaymentsMtx sync.RWMutex } // InitCache initialises and returns a cache for use in the GUI. @@ -281,6 +284,7 @@ func (c *Cache) updatePayments(pendingPmts []*pool.Payment, archivedPmts []*pool return pendingPmts[i].Height > pendingPmts[j].Height }) + pendingPaymentTotals := make(map[string]dcrutil.Amount) pendingPayments := make(map[string][]*pendingPayment) for _, p := range pendingPmts { accountID := p.Account @@ -292,9 +296,14 @@ func (c *Cache) updatePayments(pendingPmts []*pool.Payment, archivedPmts []*pool CreatedOn: formatUnixTime(p.CreatedOn), }, ) + if _, ok := pendingPaymentTotals[accountID]; !ok { + pendingPaymentTotals[accountID] = dcrutil.Amount(0) + } + pendingPaymentTotals[accountID] += p.Amount } c.pendingPaymentsMtx.Lock() + c.pendingPaymentTotals = pendingPaymentTotals c.pendingPayments = pendingPayments c.pendingPaymentsMtx.Unlock() @@ -303,6 +312,7 @@ func (c *Cache) updatePayments(pendingPmts []*pool.Payment, archivedPmts []*pool return archivedPmts[i].Height > archivedPmts[j].Height }) + archivedPaymentTotals := make(map[string]dcrutil.Amount) archivedPayments := make(map[string][]*archivedPayment) for _, p := range archivedPmts { accountID := p.Account @@ -317,15 +327,21 @@ func (c *Cache) updatePayments(pendingPmts []*pool.Payment, archivedPmts []*pool TxURL: txURL(c.blockExplorerURL, p.TransactionID), TxID: fmt.Sprintf("%.10s...", p.TransactionID), }) + if _, ok := archivedPaymentTotals[accountID]; !ok { + archivedPaymentTotals[accountID] = dcrutil.Amount(0) + } + archivedPaymentTotals[accountID] += p.Amount } c.archivedPaymentsMtx.Lock() + c.archivedPaymentTotals = archivedPaymentTotals c.archivedPayments = archivedPayments c.archivedPaymentsMtx.Unlock() } -// getPendingPayments retrieves the cached list of unpaid payments for a given -// account ID. +// getArchivedPayments accesses the cached list of unpaid payments for a given +// account ID. Returns the total number of payments and the set of payments +// requested with first and last params. func (c *Cache) getPendingPayments(first, last int, accountID string) (int, []*pendingPayment, error) { c.pendingPaymentsMtx.RLock() defer c.pendingPaymentsMtx.RUnlock() @@ -345,8 +361,9 @@ func (c *Cache) getPendingPayments(first, last int, accountID string) (int, []*p return count, pendingPmts[first:min(last, count)], nil } -// getArchivedPayments retrieves the cached list of paid payments for a given -// account ID. +// getArchivedPayments accesses the cached list of paid payments for a given +// account ID. Returns the total number of payments and the set of payments +// requested with first and last params. func (c *Cache) getArchivedPayments(first, last int, accountID string) (int, []*archivedPayment, error) { c.archivedPaymentsMtx.RLock() defer c.archivedPaymentsMtx.RUnlock() @@ -365,3 +382,13 @@ func (c *Cache) getArchivedPayments(first, last int, accountID string) (int, []* return count, archivedPmts[first:min(last, count)], nil } + +func (c *Cache) getArchivedPaymentsTotal(accountID string) string { + total := c.archivedPaymentTotals[accountID] + return amount(total) +} + +func (c *Cache) getPendingPaymentsTotal(accountID string) string { + total := c.pendingPaymentTotals[accountID] + return amount(total) +}