From 92a336cb5a299ec691e68e0e8242ff1387f0112a Mon Sep 17 00:00:00 2001
From: NickolaiYurchenko
Date: Wed, 22 Jul 2020 18:15:24 +0300
Subject: [PATCH] web/storagenode: held returned block added
WHAT: held information block on payout page
WHY: to show held and held disposed amounts
Change-Id: I34b8f17993f93d7fdbc65021d0a088c8a5490f8d
---
.../app/components/payments/TotalHeldArea.vue | 120 ++++++++++++++++++
web/storagenode/src/app/types/payout.ts | 3 +-
web/storagenode/src/app/views/PayoutArea.vue | 39 +++---
.../src/storagenode/payouts/payouts.ts | 2 +
.../components/payments/TotalHeldArea.spec.ts | 77 +++++++++++
.../__snapshots__/TotalHeldArea.spec.ts.snap | 49 +++++++
.../tests/unit/store/payout.spec.ts | 7 +-
7 files changed, 279 insertions(+), 18 deletions(-)
create mode 100644 web/storagenode/src/app/components/payments/TotalHeldArea.vue
create mode 100644 web/storagenode/tests/unit/components/payments/TotalHeldArea.spec.ts
create mode 100644 web/storagenode/tests/unit/components/payments/__snapshots__/TotalHeldArea.spec.ts.snap
diff --git a/web/storagenode/src/app/components/payments/TotalHeldArea.vue b/web/storagenode/src/app/components/payments/TotalHeldArea.vue
new file mode 100644
index 000000000..3809a2abf
--- /dev/null
+++ b/web/storagenode/src/app/components/payments/TotalHeldArea.vue
@@ -0,0 +1,120 @@
+// Copyright (C) 2020 Storj Labs, Inc.
+// See LICENSE for copying information.
+
+
+
+
+
+
Held Amount Rate
+
{{ heldPercentage }}%
+
+
+
Total Held Amount
+
{{ totalHeldAndPaid.held | centsToDollars }}
+
+
+
Total Held Returned
+
{{ totalHeldAndPaid.disposed | centsToDollars }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/storagenode/src/app/types/payout.ts b/web/storagenode/src/app/types/payout.ts
index e35d5b7c6..8975b365d 100644
--- a/web/storagenode/src/app/types/payout.ts
+++ b/web/storagenode/src/app/types/payout.ts
@@ -4,7 +4,8 @@
import {
EstimatedPayout,
PayoutPeriod,
- SatelliteHeldHistory, SatellitePayoutForPeriod,
+ SatelliteHeldHistory,
+ SatellitePayoutForPeriod,
TotalHeldAndPaid,
TotalPaystubForPeriod,
} from '@/storagenode/payouts/payouts';
diff --git a/web/storagenode/src/app/views/PayoutArea.vue b/web/storagenode/src/app/views/PayoutArea.vue
index f806e37a4..0cf5842ca 100644
--- a/web/storagenode/src/app/views/PayoutArea.vue
+++ b/web/storagenode/src/app/views/PayoutArea.vue
@@ -27,10 +27,13 @@
-
+
@@ -45,6 +48,7 @@ import HeldHistoryTable from '@/app/components/payments/HeldHistoryMonthlyBreakd
import HeldProgress from '@/app/components/payments/HeldProgress.vue';
import PayoutHistoryTable from '@/app/components/payments/PayoutHistoryTable.vue';
import SingleInfo from '@/app/components/payments/SingleInfo.vue';
+import TotalHeldArea from '@/app/components/payments/TotalHeldArea.vue';
import SatelliteSelection from '@/app/components/SatelliteSelection.vue';
import BackArrowIcon from '@/../static/images/notifications/backArrow.svg';
@@ -54,11 +58,11 @@ import { NODE_ACTIONS } from '@/app/store/modules/node';
import { NOTIFICATIONS_ACTIONS } from '@/app/store/modules/notifications';
import { PAYOUT_ACTIONS } from '@/app/store/modules/payout';
import { NotificationsCursor } from '@/app/types/notifications';
-import { SatelliteInfo } from '@/storagenode/dashboard';
-import { PayoutPeriod } from '@/storagenode/payouts/payouts';
+import { PayoutPeriod, TotalHeldAndPaid } from '@/storagenode/payouts/payouts';
@Component ({
components: {
+ TotalHeldArea,
PayoutHistoryTable,
HeldHistoryArea,
HeldProgress,
@@ -110,20 +114,15 @@ export default class PayoutArea extends Vue {
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, false);
}
- public get totalHeld(): number {
- return this.$store.state.payoutModule.totalHeldAndPaid.held;
- }
-
- public get heldPercentage(): number {
- return this.$store.state.payoutModule.heldPercentage;
+ public get totalHeldAndPaid(): TotalHeldAndPaid {
+ return this.$store.state.payoutModule.totalHeldAndPaid;
}
/**
- * selectedSatellite - current selected satellite from store.
- * @return SatelliteInfo - current selected satellite
+ * Indicates if satellite is selected.
*/
- public get selectedSatellite(): SatelliteInfo {
- return this.$store.state.node.selectedSatellite.id;
+ public get isSatelliteSelected(): boolean {
+ return !!this.$store.state.node.selectedSatellite.id;
}
public get payoutPeriods(): PayoutPeriod[] {
@@ -222,6 +221,12 @@ export default class PayoutArea extends Vue {
}
}
+ .row {
+ display: flex;
+ justify-content: space-between;
+ width: 100%;
+ }
+
@media screen and (max-width: 890px) {
.payout-area-container {
@@ -259,5 +264,9 @@ export default class PayoutArea extends Vue {
}
}
}
+
+ .row {
+ flex-direction: column;
+ }
}
diff --git a/web/storagenode/src/storagenode/payouts/payouts.ts b/web/storagenode/src/storagenode/payouts/payouts.ts
index 798a6e3e5..17310f5cd 100644
--- a/web/storagenode/src/storagenode/payouts/payouts.ts
+++ b/web/storagenode/src/storagenode/payouts/payouts.ts
@@ -172,6 +172,7 @@ export class TotalPaystubForPeriod {
export class TotalHeldAndPaid {
public held: number = 0;
public paid: number = 0;
+ public disposed: number = 0;
// TODO: remove
public currentMonthEarnings: number = 0;
@@ -181,6 +182,7 @@ export class TotalHeldAndPaid {
paystubs.forEach(paystub => {
this.held += this.convertToCents(paystub.held - paystub.disposed);
this.paid += this.convertToCents(paystub.paid);
+ this.disposed += this.convertToCents(paystub.disposed);
});
}
diff --git a/web/storagenode/tests/unit/components/payments/TotalHeldArea.spec.ts b/web/storagenode/tests/unit/components/payments/TotalHeldArea.spec.ts
new file mode 100644
index 000000000..538cead46
--- /dev/null
+++ b/web/storagenode/tests/unit/components/payments/TotalHeldArea.spec.ts
@@ -0,0 +1,77 @@
+// Copyright (C) 2020 Storj Labs, Inc.
+// See LICENSE for copying information.
+
+import Vuex from 'vuex';
+
+import TotalHeldArea from '@/app/components/payments/TotalHeldArea.vue';
+
+import { makeNodeModule, NODE_MUTATIONS } from '@/app/store/modules/node';
+import { makePayoutModule, PAYOUT_MUTATIONS } from '@/app/store/modules/payout';
+import { PayoutHttpApi } from '@/storagenode/api/payout';
+import { SNOApi } from '@/storagenode/api/storagenode';
+import { Paystub, TotalHeldAndPaid } from '@/storagenode/payouts/payouts';
+import { PayoutService } from '@/storagenode/payouts/service';
+import { Metric, Satellite, Stamp } from '@/storagenode/satellite';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+localVue.filter('centsToDollars', (cents: number): string => {
+ return `$${(cents / 100).toFixed(2)}`;
+});
+
+const payoutApi = new PayoutHttpApi();
+const payoutService = new PayoutService(payoutApi);
+const payoutModule = makePayoutModule(payoutApi, payoutService);
+const nodeApi = new SNOApi();
+const nodeModule = makeNodeModule(nodeApi);
+
+const store = new Vuex.Store({ modules: { payoutModule, node: nodeModule }});
+
+describe('TotalHeldArea', (): void => {
+ it('renders correctly', (): void => {
+ const wrapper = shallowMount(TotalHeldArea, {
+ store,
+ localVue,
+ });
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('renders correctly with actual values', async (): Promise => {
+ const wrapper = shallowMount(TotalHeldArea, {
+ store,
+ localVue,
+ });
+
+ const testJoinAt = new Date(Date.UTC(2018, 0, 30));
+
+ const satelliteInfo = new Satellite(
+ '3',
+ [new Stamp()],
+ [],
+ [],
+ [],
+ 111,
+ 222,
+ 50,
+ 70,
+ new Metric(1, 1, 1, 0, 1),
+ new Metric(2, 1, 1, 0, 1),
+ testJoinAt,
+ );
+ const paystub = new Paystub();
+ paystub.held = 600000;
+ paystub.disposed = 100000;
+ paystub.paid = 1000000;
+
+ const totalHeldAndPaid = new TotalHeldAndPaid([paystub]);
+
+ await store.commit(NODE_MUTATIONS.SELECT_SATELLITE, satelliteInfo);
+
+ await store.commit(PAYOUT_MUTATIONS.SET_TOTAL, totalHeldAndPaid);
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/web/storagenode/tests/unit/components/payments/__snapshots__/TotalHeldArea.spec.ts.snap b/web/storagenode/tests/unit/components/payments/__snapshots__/TotalHeldArea.spec.ts.snap
new file mode 100644
index 000000000..959e4c72a
--- /dev/null
+++ b/web/storagenode/tests/unit/components/payments/__snapshots__/TotalHeldArea.spec.ts.snap
@@ -0,0 +1,49 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`TotalHeldArea renders correctly 1`] = `
+
+
+
+
Held Amount Rate
+
0%
+
+
+
Total Held Amount
+
$0.00
+
+
+
Total Held Returned
+
$0.00
+
+
+
+
+
+
+
+
+`;
+
+exports[`TotalHeldArea renders correctly with actual values 1`] = `
+
+
+
+
Held Amount Rate
+
0%
+
+
+
Total Held Amount
+
$0.50
+
+
+
Total Held Returned
+
$0.10
+
+
+
+
+
+
+
+
+`;
diff --git a/web/storagenode/tests/unit/store/payout.spec.ts b/web/storagenode/tests/unit/store/payout.spec.ts
index a537aef0e..5c542d09a 100644
--- a/web/storagenode/tests/unit/store/payout.spec.ts
+++ b/web/storagenode/tests/unit/store/payout.spec.ts
@@ -64,6 +64,7 @@ describe('mutations', (): void => {
expect(state.payoutModule.totalHeldAndPaid.held).toBe(50);
expect(state.payoutModule.totalHeldAndPaid.paid).toBe(100);
+ expect(state.payoutModule.totalHeldAndPaid.disposed).toBe(10);
expect(state.payoutModule.currentMonthEarnings).toBe(22);
});
@@ -246,6 +247,7 @@ describe('actions', () => {
it('success get total', async (): Promise => {
const paystub = new Paystub();
paystub.held = 100000;
+ paystub.disposed = 50000;
paystub.paid = 200000;
jest.spyOn(payoutApi, 'getPaystubsForPeriod').mockReturnValue(
@@ -254,8 +256,9 @@ describe('actions', () => {
await store.dispatch(PAYOUT_ACTIONS.GET_TOTAL);
- expect(state.payoutModule.totalHeldAndPaid.held).toBe(10);
+ expect(state.payoutModule.totalHeldAndPaid.held).toBe(5);
expect(state.payoutModule.totalHeldAndPaid.paid).toBe(20);
+ expect(state.payoutModule.totalHeldAndPaid.disposed).toBe(5);
expect(state.payoutModule.currentMonthEarnings).toBe(0);
});
@@ -266,7 +269,7 @@ describe('actions', () => {
await store.dispatch(PAYOUT_ACTIONS.GET_TOTAL);
expect(true).toBe(false);
} catch (error) {
- expect(state.payoutModule.totalHeldAndPaid.held).toBe(10);
+ expect(state.payoutModule.totalHeldAndPaid.held).toBe(5);
expect(state.payoutModule.totalHeldAndPaid.paid).toBe(20);
expect(state.payoutModule.currentMonthEarnings).toBe(0);
}