diff --git a/src/app/components/dashboard/dashboard.component.html b/src/app/components/dashboard/dashboard.component.html index 84b81852..db3d39ef 100644 --- a/src/app/components/dashboard/dashboard.component.html +++ b/src/app/components/dashboard/dashboard.component.html @@ -222,219 +222,50 @@ -
-
-
- - {{ data.combinedPerformance.performance1d | mcurrency : 'GWEI' : unit.pref.Cons }} - -
-
- - Today - -
-
- -
-
- - {{ data.combinedPerformance.performance7d | mcurrency : 'GWEI' : unit.pref.Cons }} - -
-
- Last 7d -
-
- -
-
- - {{ data.combinedPerformance.performance31d | mcurrency : 'GWEI' : unit.pref.Cons }} - -
-
- Last 31d -
-
- -
-
- - {{ data.combinedPerformance.total | mcurrency : 'GWEI' : unit.pref.Cons }} - -
-
- Total -
-
- -
-
- {{ data.combinedPerformance.apr }} % -
-
- - APR - -
-
-
-
-
-
- - {{ data.consensusPerformance.performance1d | mcurrency : 'GWEI' : unit.pref.Cons }} - -
-
- - Today - -
-
- -
-
- - {{ data.consensusPerformance.performance7d | mcurrency : 'GWEI' : unit.pref.Cons }} - -
-
- Last 7d -
-
- -
-
- - {{ data.consensusPerformance.performance31d | mcurrency : 'GWEI' : unit.pref.Cons }} - -
-
- Last 31d -
-
- -
-
- - {{ data.consensusPerformance.total | mcurrency : 'GWEI' : unit.pref.Cons }} - -
-
- - Total - -
-
- -
-
- {{ data.consensusPerformance.apr }} % -
-
- - APR - -
-
-
-
-
-
- - {{ data.executionPerformance.performance1d | mcurrency : 'GWEI' : unit.pref.Exec }} - -
-
- - Today - -
-
- -
-
- - {{ data.executionPerformance.performance7d | mcurrency : 'GWEI' : unit.pref.Exec }} - -
-
- Last 7d -
-
- -
-
- - {{ data.executionPerformance.performance31d | mcurrency : 'GWEI' : unit.pref.Exec }} - -
-
- Last 31d -
-
- -
-
- - {{ data.executionPerformance.total | mcurrency : 'GWEI' : unit.pref.Exec }} - -
-
- Total -
-
- -
-
- {{ data.executionPerformance.apr }} % -
-
- - APR - -
-
+
+ + + + +
diff --git a/src/app/components/dashboard/dashboard.module.ts b/src/app/components/dashboard/dashboard.module.ts index f78bf8be..f46589db 100644 --- a/src/app/components/dashboard/dashboard.module.ts +++ b/src/app/components/dashboard/dashboard.module.ts @@ -30,6 +30,7 @@ import { ClientupdateComponentModule } from '../../components/clientupdate/clien import { MessageComponentModule } from '../../components/message/message.module' import { TooltipModule } from 'ng2-tooltip-directive-major-angular-updates' import { AdComponentModule } from '../ad/ad.module' +import { PerformanceItemComponentModule } from '../dashboard/performance-item.module' @NgModule({ imports: [ @@ -41,6 +42,7 @@ import { AdComponentModule } from '../ad/ad.module' MessageComponentModule, TooltipModule, AdComponentModule, + PerformanceItemComponentModule, ], declarations: [DashboardComponent], exports: [DashboardComponent], diff --git a/src/app/components/dashboard/performance-item.component.html b/src/app/components/dashboard/performance-item.component.html new file mode 100644 index 00000000..0c3a4c22 --- /dev/null +++ b/src/app/components/dashboard/performance-item.component.html @@ -0,0 +1,88 @@ + + +
+
+
+ + {{ performanceData.performance1d | mcurrency : currency : targetCurrency }} + +
+
+ + Today + Today + +
+
+ +
+
+ + {{ performanceData.performance7d | mcurrency : currency : targetCurrency }} + +
+
+ + Last 7d + Last 7d + +
+
+ +
+
+ + {{ performanceData.performance31d | mcurrency : currency : targetCurrency }} + +
+
+ + Last 31d + Last 31d + +
+
+ +
+
+ + {{ performanceData.total | mcurrency : currency : targetCurrency }} + +
+
+ + Total + Total + +
+
+ +
+
+ {{ performanceData.apr31d }} % +
+
+ + APR 31d + APR 31d + +
+
+
diff --git a/src/app/components/dashboard/performance-item.component.scss b/src/app/components/dashboard/performance-item.component.scss new file mode 100644 index 00000000..4efdfc96 --- /dev/null +++ b/src/app/components/dashboard/performance-item.component.scss @@ -0,0 +1,35 @@ +/* + * // Copyright (C) 2020 - 2023 Bitfly GmbH + * // + * // This file is part of Beaconchain Dashboard. + * // + * // Beaconchain Dashboard is free software: you can redistribute it and/or modify + * // it under the terms of the GNU General Public License as published by + * // the Free Software Foundation, either version 3 of the License, or + * // (at your option) any later version. + * // + * // Beaconchain Dashboard is distributed in the hope that it will be useful, + * // but WITHOUT ANY WARRANTY; without even the implied warranty of + * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * // GNU General Public License for more details. + * // + * // You should have received a copy of the GNU General Public License + * // along with Beaconchain Dashboard. If not, see . + */ + +@import '../../../theme/variables.scss'; + +.grid-cell { + width: 50%; + float: left; + margin-bottom: 7px; + margin-top: 7px; +} + +.left { + text-align: start !important; +} + +.right { + text-align: end !important; +} diff --git a/src/app/components/dashboard/performance-item.component.ts b/src/app/components/dashboard/performance-item.component.ts new file mode 100644 index 00000000..e5c23282 --- /dev/null +++ b/src/app/components/dashboard/performance-item.component.ts @@ -0,0 +1,39 @@ +/* + * // Copyright (C) 2020 - 2023 Bitfly GmbH + * // + * // This file is part of Beaconchain Dashboard. + * // + * // Beaconchain Dashboard is free software: you can redistribute it and/or modify + * // it under the terms of the GNU General Public License as published by + * // the Free Software Foundation, either version 3 of the License, or + * // (at your option) any later version. + * // + * // Beaconchain Dashboard is distributed in the hope that it will be useful, + * // but WITHOUT ANY WARRANTY; without even the implied warranty of + * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * // GNU General Public License for more details. + * // + * // You should have received a copy of the GNU General Public License + * // along with Beaconchain Dashboard. If not, see . + */ + +import { Component, Input } from '@angular/core' +import { Performance } from 'src/app/controllers/OverviewController' +import { Currency, UnitconvService } from 'src/app/services/unitconv.service' + +@Component({ + selector: 'app-performance-item', + templateUrl: './performance-item.component.html', + styleUrls: ['./performance-item.component.scss'], +}) +export class PerformanceItemComponent { + @Input() performanceData: Performance + @Input() unit: UnitconvService + @Input() targetCurrency: Currency + @Input() currency: string + @Input() todayTooltip: string + @Input() last7DaysTooltip: string + @Input() last31DaysTooltip: string + @Input() totalTooltip: string + @Input() aprTooltip: string +} diff --git a/src/app/components/dashboard/performance-item.module.ts b/src/app/components/dashboard/performance-item.module.ts new file mode 100644 index 00000000..5f746400 --- /dev/null +++ b/src/app/components/dashboard/performance-item.module.ts @@ -0,0 +1,35 @@ +/* + * // Copyright (C) 2020 - 2023 Bitfly GmbH + * // + * // This file is part of Beaconchain Dashboard. + * // + * // Beaconchain Dashboard is free software: you can redistribute it and/or modify + * // it under the terms of the GNU General Public License as published by + * // the Free Software Foundation, either version 3 of the License, or + * // (at your option) any later version. + * // + * // Beaconchain Dashboard is distributed in the hope that it will be useful, + * // but WITHOUT ANY WARRANTY; without even the implied warranty of + * // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * // GNU General Public License for more details. + * // + * // You should have received a copy of the GNU General Public License + * // along with Beaconchain Dashboard. If not, see . + */ + +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { FormsModule } from '@angular/forms' + +import { IonicModule } from '@ionic/angular' + +import { PerformanceItemComponent } from './performance-item.component' +import { PipesModule } from '../../pipes/pipes.module' +import { TooltipModule } from 'ng2-tooltip-directive-major-angular-updates' + +@NgModule({ + imports: [CommonModule, FormsModule, IonicModule, PipesModule, TooltipModule], + declarations: [PerformanceItemComponent], + exports: [PerformanceItemComponent], +}) +export class PerformanceItemComponentModule {} diff --git a/src/app/controllers/OverviewController.ts b/src/app/controllers/OverviewController.ts index 5ab41a48..f128edca 100644 --- a/src/app/controllers/OverviewController.ts +++ b/src/app/controllers/OverviewController.ts @@ -52,7 +52,6 @@ export type OverviewData = { foreignValidator: boolean foreignValidatorItem?: Validator foreignValidatorWithdrawalCredsAre0x01: boolean - apr: number effectiveBalance: BigNumber currentEpoch: EpochResponse rocketpool: Rocketpool @@ -69,7 +68,9 @@ export type Performance = { performance7d: BigNumber performance365d: BigNumber total: BigNumber - apr: number + apr7d: number + apr31d: number + apr365d: number } export type Rocketpool = { @@ -168,10 +169,6 @@ export default class OverviewController { } }) - const aprPerformance31dExecution = sumBigInt(validators, (cur) => - this.sumExcludeSmoothingPool(cur, (fieldCur) => fieldCur.execution.performance31d.toString()) - ) - const overallBalance = this.sumBigIntBalanceRP(validators, (cur) => new BigNumber(cur.data.balance)) const validatorCount = validators.length const activeValidators = this.getActiveValidators(validators) @@ -179,7 +176,7 @@ export default class OverviewController { const consensusPerf = this.getConsensusPerformance(validators, validatorDepositActive) - const executionPerf = this.getExecutionPerformance(validators, validatorDepositActive, aprPerformance31dExecution) + const executionPerf = this.getExecutionPerformance(validators, validatorDepositActive) const smoothingPoolClaimed = this.sumRocketpoolSmoothingBigIntPerNodeAddress( true, @@ -200,9 +197,15 @@ export default class OverviewController { performance31d: consensusPerf.performance31d.plus(this.unit.convertELtoCL(executionPerf.performance31d)), performance7d: consensusPerf.performance7d.plus(this.unit.convertELtoCL(executionPerf.performance7d)), performance365d: consensusPerf.performance365d.plus(this.unit.convertELtoCL(executionPerf.performance365d)), - apr: this.getAPRFromMonth(validatorDepositActive, this.unit.convertELtoCL(aprPerformance31dExecution).plus(consensusPerf.performance31d)), + apr31d: this.getAPRFrom(31, validatorDepositActive, this.unit.convertELtoCL(executionPerf.performance31d).plus(consensusPerf.performance31d)), + apr7d: this.getAPRFrom(7, validatorDepositActive, this.unit.convertELtoCL(executionPerf.performance7d).plus(consensusPerf.performance7d)), + apr365d: this.getAPRFrom( + 365, + validatorDepositActive, + this.unit.convertELtoCL(executionPerf.performance365d).plus(consensusPerf.performance365d) + ), total: consensusPerf.total.plus(this.unit.convertELtoCL(executionPerf.total)).plus(smoothingPoolClaimed).plus(smoothingPoolUnclaimed), - } + } as Performance let attrEffectiveness = 0 let displayAttrEffectiveness = false @@ -272,7 +275,6 @@ export default class OverviewController { foreignValidatorWithdrawalCredsAre0x01: foreignWCAre0x01, effectiveBalance: effectiveBalance, currentEpoch: currentEpoch, - apr: combinedPerf.apr, currentSyncCommittee: currentSync ? currentSync.currentSyncCommittee : null, nextSyncCommittee: nextSync ? nextSync.nextSyncCommittee : null, syncCommitteesStats: this.calculateSyncCommitteeStats(syncCommitteesStatsResponse, network), @@ -330,7 +332,7 @@ export default class OverviewController { } as OverviewData } - private getExecutionPerformance(validators: Validator[], validatorDepositActive: BigNumber, aprPerformance31dExecution: BigNumber) { + private getExecutionPerformance(validators: Validator[], validatorDepositActive: BigNumber) { const performance1d = this.sumBigIntPerformanceRP(validators, (cur) => this.sumExcludeSmoothingPool(cur, (fieldCur) => fieldCur.execution.performance1d.toString()).multipliedBy( new BigNumber(cur.execshare == null ? 1 : cur.execshare) @@ -357,13 +359,14 @@ export default class OverviewController { ) ) - const aprExecution = this.getAPRFromMonth(validatorDepositActive, aprPerformance31dExecution) // todo return { performance1d: performance1d, performance31d: performance31d, performance7d: performance7d, performance365d: performance365d, - apr: aprExecution, + apr31d: this.getAPRFrom(31, validatorDepositActive, performance31d), + apr7d: this.getAPRFrom(7, validatorDepositActive, performance7d), + apr365d: this.getAPRFrom(365, validatorDepositActive, performance365d), total: total, } } @@ -376,7 +379,7 @@ export default class OverviewController { return new BigNumber(0) } - private getConsensusPerformance(validators: Validator[], validatorDepositActive: BigNumber) { + private getConsensusPerformance(validators: Validator[], validatorDepositActive: BigNumber): Performance { const performance1d = this.sumBigIntPerformanceRP(validators, (cur) => new BigNumber(cur.data.performance1d).multipliedBy(new BigNumber(cur.share == null ? 1 : cur.share)) ) @@ -397,14 +400,14 @@ export default class OverviewController { } }) - const aprConsensus = this.getAPRFromMonth(validatorDepositActive, performance31d) - return { performance1d: performance1d, performance31d: performance31d, performance7d: performance7d, performance365d: performance365d, - apr: aprConsensus, + apr31d: this.getAPRFrom(31, validatorDepositActive, performance31d), + apr7d: this.getAPRFrom(7, validatorDepositActive, performance7d), + apr365d: this.getAPRFrom(365, validatorDepositActive, performance365d), total: total, } } @@ -566,8 +569,12 @@ export default class OverviewController { }) } - private getAPRFromMonth(validatorDepositActive: BigNumber, performance: BigNumber): number { - return new BigNumber(performance.toString()).multipliedBy('1177').dividedBy(validatorDepositActive).decimalPlaces(1).toNumber() + private getAPRFrom(days: number, validatorDepositActive: BigNumber, performance: BigNumber): number { + return new BigNumber(performance.toString()) + .multipliedBy(36500 / days) + .dividedBy(validatorDepositActive) + .decimalPlaces(1) + .toNumber() } private getDashboardState(validators: Validator[], currentEpoch: EpochResponse, foreignValidator, network: ApiNetwork): DashboardStatus { diff --git a/src/app/tab-validators/tab-validators.page.html b/src/app/tab-validators/tab-validators.page.html index cfd171ec..b48c0635 100644 --- a/src/app/tab-validators/tab-validators.page.html +++ b/src/app/tab-validators/tab-validators.page.html @@ -54,7 +54,7 @@ - + Search Results My Validators Add Validators
-
+
diff --git a/src/app/tab-validators/tab-validators.page.ts b/src/app/tab-validators/tab-validators.page.ts index b14223b2..f2bdb523 100644 --- a/src/app/tab-validators/tab-validators.page.ts +++ b/src/app/tab-validators/tab-validators.page.ts @@ -176,12 +176,9 @@ export class Tab2Page { private setLoading(loading: boolean) { if (loading) { - // Reasoning: Don't show loading indicator if it takes less than 400ms (already cached locally but storage is slow-ish so we adjust for that) - setTimeout(() => { - if (!this.dataSource || !this.dataSource.hasItems()) { - this.loading = true - } - }, 200) + if (!this.dataSource || !this.dataSource.hasItems()) { + this.loading = true + } } else { if (this.loading) { setTimeout(() => {