web/storagenode: disk stat chrt added
Change-Id: I6f0c78992598ebbb3f1b3ee73c74e1559fc886b1
This commit is contained in:
parent
b6771d0c52
commit
427bfc13fb
7759
web/storagenode/package-lock.json
generated
7759
web/storagenode/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -32,14 +32,14 @@
|
||||
"compression-webpack-plugin": "3.0.1",
|
||||
"core-js": "3.6.5",
|
||||
"jest-fetch-mock": "3.0.0",
|
||||
"node-sass": "4.13.1",
|
||||
"node-sass": "4.14.1",
|
||||
"sass-loader": "8.0.0",
|
||||
"sinon": "7.5.0",
|
||||
"stylelint": "12.0.1",
|
||||
"stylelint": "13.3.3",
|
||||
"stylelint-config-standard": "19.0.0",
|
||||
"stylelint-scss": "3.13.0",
|
||||
"stylelint-webpack-plugin": "1.2.1",
|
||||
"ts-jest": "24.2.0",
|
||||
"ts-jest": "25.5.0",
|
||||
"tslint": "5.20.1",
|
||||
"tslint-consistent-codestyle": "1.16.0",
|
||||
"tslint-loader": "3.5.4",
|
||||
|
@ -150,6 +150,7 @@ export default class BandwidthChart extends BaseChart {
|
||||
border-radius: 14px;
|
||||
color: var(--regular-text-color);
|
||||
pointer-events: none;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
#bandwidth-tooltip-arrow {
|
||||
|
@ -123,6 +123,7 @@ export default class DiskSpaceChart extends BaseChart {
|
||||
border-radius: 14px;
|
||||
color: var(--regular-text-color);
|
||||
pointer-events: none;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
#disk-space-tooltip-arrow {
|
||||
|
273
web/storagenode/src/app/components/DiskStatChart.vue
Normal file
273
web/storagenode/src/app/components/DiskStatChart.vue
Normal file
@ -0,0 +1,273 @@
|
||||
// Copyright (C) 2020 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<template>
|
||||
<div class="disk-stat-area">
|
||||
<p class="disk-stat-area__title">Total Disk Space</p>
|
||||
<p class="disk-stat-area__amount">{{ total }}</p>
|
||||
<DoughnutChart class="disk-stat-area__chart" :chart-data="chartData" />
|
||||
<div class="disk-stat-area__info-area">
|
||||
<div class="disk-stat-area__info-area__item">
|
||||
<div class="disk-stat-area__info-area__item__labels-area">
|
||||
<div class="disk-stat-area__info-area__item__labels-area__circle used"></div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__label">Used</p>
|
||||
</div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__amount">{{ used }}</p>
|
||||
</div>
|
||||
<div class="disk-stat-area__info-area__item">
|
||||
<div class="disk-stat-area__info-area__item__labels-area">
|
||||
<div class="disk-stat-area__info-area__item__labels-area__circle free"></div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__label">Free</p>
|
||||
</div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__amount">{{ free }}</p>
|
||||
</div>
|
||||
<div class="disk-stat-area__info-area__item">
|
||||
<div class="disk-stat-area__info-area__item__labels-area">
|
||||
<div class="disk-stat-area__info-area__item__labels-area__circle trash"></div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__label">Trash</p>
|
||||
</div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__amount">{{ trash }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
|
||||
import DoughnutChart from '@/app/components/DoughnutChart.vue';
|
||||
|
||||
import {
|
||||
DiskStatChartData,
|
||||
DiskStatDataSet,
|
||||
} from '@/app/types/chartData';
|
||||
import { formatBytes } from '@/app/utils/converter';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
DoughnutChart,
|
||||
},
|
||||
})
|
||||
export default class DiskStatChart extends Vue {
|
||||
/**
|
||||
* Holds datasets for chart.
|
||||
*/
|
||||
public get chartData(): DiskStatChartData {
|
||||
const diskSpace = this.$store.state.node.utilization.diskSpace;
|
||||
|
||||
return new DiskStatChartData([
|
||||
new DiskStatDataSet(
|
||||
'',
|
||||
['#D6D6D6', '#0059D0', '#8FA7C6'],
|
||||
[
|
||||
diskSpace.available,
|
||||
diskSpace.used,
|
||||
diskSpace.trash,
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted used disk space amount.
|
||||
*/
|
||||
public get total(): string {
|
||||
return formatBytes(this.$store.state.node.utilization.diskSpace.available);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted used disk space amount.
|
||||
*/
|
||||
public get used(): string {
|
||||
return formatBytes(this.$store.state.node.utilization.diskSpace.used);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted available disk space amount.
|
||||
*/
|
||||
public get free(): string {
|
||||
return formatBytes(
|
||||
this.$store.state.node.utilization.diskSpace.available -
|
||||
this.$store.state.node.utilization.diskSpace.used -
|
||||
this.$store.state.node.utilization.diskSpace.trash,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted trash disk space amount.
|
||||
*/
|
||||
public get trash(): string {
|
||||
return formatBytes(this.$store.state.node.utilization.diskSpace.trash);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.disk-stat-area {
|
||||
width: 339px;
|
||||
height: 336px;
|
||||
background-color: var(--block-background-color);
|
||||
border: 1px solid var(--block-border-color);
|
||||
border-radius: 11px;
|
||||
padding: 32px 30px;
|
||||
position: relative;
|
||||
|
||||
&__title {
|
||||
font-size: 14px;
|
||||
color: var(--regular-text-color);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&__amount {
|
||||
font-family: 'font_bold', sans-serif;
|
||||
font-size: 32px;
|
||||
line-height: 57px;
|
||||
color: var(--regular-text-color);
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
&__chart {
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
width: calc(50% - 30px);
|
||||
height: 220px;
|
||||
margin-top: 35px;
|
||||
}
|
||||
|
||||
&__info-area {
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
top: 57%;
|
||||
transform: translateY(-50%);
|
||||
width: calc(50% - 50px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 19px;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&__labels-area {
|
||||
display: flex;
|
||||
|
||||
&__circle {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
&__label {
|
||||
font-family: 'font_regular', sans-serif;
|
||||
font-size: 14px;
|
||||
color: var(--disk-stat-chart-text-color);
|
||||
}
|
||||
|
||||
&__amount {
|
||||
font-family: 'font_bold', sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: var(--disk-stat-chart-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.used {
|
||||
background: #0059d0;
|
||||
}
|
||||
|
||||
.free {
|
||||
background: #d6d6d6;
|
||||
}
|
||||
|
||||
.trash {
|
||||
background: #8fa7c6;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
|
||||
.disk-stat-area {
|
||||
width: calc(100% - 60px);
|
||||
|
||||
&__chart {
|
||||
width: 250px;
|
||||
height: 250px;
|
||||
margin-left: 100px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&__info-area {
|
||||
top: 60%;
|
||||
right: 120px;
|
||||
width: 185px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 780px) {
|
||||
|
||||
.disk-stat-area {
|
||||
|
||||
&__chart {
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
&__info-area {
|
||||
top: 60%;
|
||||
right: 90px;
|
||||
width: 140px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 640px) {
|
||||
|
||||
.disk-stat-area {
|
||||
|
||||
&__chart {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
&__info-area {
|
||||
top: 50%;
|
||||
right: 90px;
|
||||
width: 140px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 550px) {
|
||||
|
||||
.disk-stat-area {
|
||||
height: 414px;
|
||||
width: calc(100% - 36px);
|
||||
padding: 24px 18px;
|
||||
|
||||
&__chart {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__info-area {
|
||||
top: 70%;
|
||||
right: 50%;
|
||||
transform: translateX(50%);
|
||||
bottom: 10px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
36
web/storagenode/src/app/components/DoughnutChart.vue
Normal file
36
web/storagenode/src/app/components/DoughnutChart.vue
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2020 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<script lang="ts">
|
||||
import * as VueChart from 'vue-chartjs';
|
||||
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
|
||||
|
||||
import { DiskStatChartData } from '@/app/types/chartData';
|
||||
|
||||
@Component({
|
||||
extends: VueChart.Doughnut,
|
||||
})
|
||||
export default class DoughnutChart extends Vue {
|
||||
@Prop({default: () => new DiskStatChartData()})
|
||||
private readonly chartData: DiskStatChartData;
|
||||
|
||||
@Watch('chartData')
|
||||
private onDataChange(news: object, old: object): void {
|
||||
(this as any).renderChart(this.chartData, {
|
||||
hover: false,
|
||||
tooltips: {
|
||||
enabled: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public mounted(): void {
|
||||
(this as any).renderChart(this.chartData, {
|
||||
hover: false,
|
||||
tooltips: {
|
||||
enabled: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
@ -136,6 +136,7 @@ export default class EgressChart extends BaseChart {
|
||||
border-radius: 14px;
|
||||
color: #535f77;
|
||||
pointer-events: none;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
#egress-tooltip-arrow {
|
||||
|
@ -130,6 +130,7 @@ export default class IngressChart extends BaseChart {
|
||||
border-radius: 14px;
|
||||
color: #535f77;
|
||||
pointer-events: none;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
#ingress-tooltip-arrow {
|
||||
|
@ -68,58 +68,53 @@
|
||||
</a> on Storj forum.
|
||||
</p>
|
||||
</div>
|
||||
<p class="info-area__title">Utilization & Remaining</p>
|
||||
<div class="info-area__chart-area">
|
||||
<section>
|
||||
<div class="chart-container">
|
||||
<div class="chart-container__title-area disk-space-title">
|
||||
<p class="chart-container__title-area__title">Disk Space Used This Month</p>
|
||||
</div>
|
||||
<p class="chart-container__amount disk-space-amount"><b>{{ storageSummary }}*h</b></p>
|
||||
<div class="chart-container__chart">
|
||||
<DiskSpaceChart :height="chartHeight" :width="chartWidth" :is-dark-mode="isDarkMode"/>
|
||||
</div>
|
||||
</div>
|
||||
<BarInfo
|
||||
label="Disk Space Remaining"
|
||||
:amount="diskSpace.remaining"
|
||||
info-text="of disk space left"
|
||||
:current-bar-amount="diskSpace.used"
|
||||
:max-bar-amount="diskSpace.available"
|
||||
/>
|
||||
</section>
|
||||
<section>
|
||||
<div class="chart-container">
|
||||
<div class="chart-container__title-area">
|
||||
<p class="chart-container__title-area__title">Bandwidth Used This Month</p>
|
||||
<div class="chart-container__title-area__buttons-area">
|
||||
<div
|
||||
class="chart-container__title-area__chart-choice-item"
|
||||
:class="{ 'egress-chart-shown': isEgressChartShown }"
|
||||
@click.stop="toggleEgressChartShowing"
|
||||
>
|
||||
Egress
|
||||
</div>
|
||||
<div
|
||||
class="chart-container__title-area__chart-choice-item"
|
||||
:class="{ 'ingress-chart-shown': isIngressChartShown }"
|
||||
@click.stop="toggleIngressChartShowing"
|
||||
>
|
||||
Ingress
|
||||
</div>
|
||||
<p class="info-area__title">Bandwidth Utilization </p>
|
||||
<section>
|
||||
<div class="chart-container bandwidth-chart">
|
||||
<div class="chart-container__title-area">
|
||||
<p class="chart-container__title-area__title">Bandwidth Used This Month</p>
|
||||
<div class="chart-container__title-area__buttons-area">
|
||||
<div
|
||||
class="chart-container__title-area__chart-choice-item"
|
||||
:class="{ 'egress-chart-shown': isEgressChartShown }"
|
||||
@click.stop="toggleEgressChartShowing"
|
||||
>
|
||||
Egress
|
||||
</div>
|
||||
<div
|
||||
class="chart-container__title-area__chart-choice-item"
|
||||
:class="{ 'ingress-chart-shown': isIngressChartShown }"
|
||||
@click.stop="toggleIngressChartShowing"
|
||||
>
|
||||
Ingress
|
||||
</div>
|
||||
</div>
|
||||
<p class="chart-container__amount" v-if="isBandwidthChartShown"><b>{{ bandwidthSummary }}</b></p>
|
||||
<p class="chart-container__amount" v-if="isEgressChartShown"><b>{{ egressSummary }}</b></p>
|
||||
<p class="chart-container__amount" v-if="isIngressChartShown"><b>{{ ingressSummary }}</b></p>
|
||||
<div class="chart-container__chart" ref="chart" onresize="recalculateChartDimensions()" >
|
||||
<BandwidthChart v-if="isBandwidthChartShown" :height="chartHeight" :width="chartWidth" :is-dark-mode="isDarkMode"/>
|
||||
<EgressChart v-if="isEgressChartShown" :height="chartHeight" :width="chartWidth" :is-dark-mode="isDarkMode"/>
|
||||
<IngressChart v-if="isIngressChartShown" :height="chartHeight" :width="chartWidth" :is-dark-mode="isDarkMode"/>
|
||||
</div>
|
||||
</div>
|
||||
<p class="chart-container__amount" v-if="isBandwidthChartShown"><b>{{ bandwidthSummary }}</b></p>
|
||||
<p class="chart-container__amount" v-if="isEgressChartShown"><b>{{ egressSummary }}</b></p>
|
||||
<p class="chart-container__amount" v-if="isIngressChartShown"><b>{{ ingressSummary }}</b></p>
|
||||
<div class="chart-container__chart" ref="chart" onresize="recalculateChartDimensions()" >
|
||||
<BandwidthChart v-if="isBandwidthChartShown" :height="chartHeight" :width="chartWidth" :is-dark-mode="isDarkMode"/>
|
||||
<EgressChart v-if="isEgressChartShown" :height="chartHeight" :width="chartWidth" :is-dark-mode="isDarkMode"/>
|
||||
<IngressChart v-if="isIngressChartShown" :height="chartHeight" :width="chartWidth" :is-dark-mode="isDarkMode"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<p class="info-area__title">Disk Utilization & Remaining</p>
|
||||
<section class="info-area__chart-area">
|
||||
<section class="chart-container">
|
||||
<div class="chart-container__title-area disk-space-title">
|
||||
<p class="chart-container__title-area__title">Disk Space Used This Month</p>
|
||||
</div>
|
||||
<p class="chart-container__amount disk-space-amount"><b>{{ storageSummary }}*h</b></p>
|
||||
<div class="chart-container__chart" ref="diskSpaceChart" onresize="recalculateChartDimensions()" >
|
||||
<DiskSpaceChart :height="diskSpaceChartHeight" :width="diskSpaceChartWidth" :is-dark-mode="isDarkMode"/>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<section>
|
||||
<DiskStatChart />
|
||||
</section>
|
||||
</section>
|
||||
<div class="info-area__blurred-checks" v-if="!selectedSatellite.id">
|
||||
<p class="info-area__blurred-checks__title">Select a Specific Satellite to View Audit and Uptime Percentages</p>
|
||||
</div>
|
||||
@ -160,6 +155,7 @@ import BandwidthChart from '@/app/components/BandwidthChart.vue';
|
||||
import BarInfo from '@/app/components/BarInfo.vue';
|
||||
import ChecksArea from '@/app/components/ChecksArea.vue';
|
||||
import DiskSpaceChart from '@/app/components/DiskSpaceChart.vue';
|
||||
import DiskStatChart from '@/app/components/DiskStatChart.vue';
|
||||
import EgressChart from '@/app/components/EgressChart.vue';
|
||||
import IngressChart from '@/app/components/IngressChart.vue';
|
||||
import EstimationArea from '@/app/components/payments/EstimationArea.vue';
|
||||
@ -174,7 +170,7 @@ import LargeSuspensionIcon from '@/../static/images/largeSuspend.svg';
|
||||
import { RouteConfig } from '@/app/router';
|
||||
import { APPSTATE_ACTIONS } from '@/app/store/modules/appState';
|
||||
import { formatBytes } from '@/app/utils/converter';
|
||||
import { DiskSpaceInfo, SatelliteInfo } from '@/storagenode/dashboard';
|
||||
import { SatelliteInfo } from '@/storagenode/dashboard';
|
||||
|
||||
/**
|
||||
* Checks class holds info for Checks entity.
|
||||
@ -191,6 +187,7 @@ class Checks {
|
||||
|
||||
@Component ({
|
||||
components: {
|
||||
DiskStatChart,
|
||||
TotalPayoutArea,
|
||||
EstimationArea,
|
||||
EgressChart,
|
||||
@ -210,9 +207,12 @@ export default class SNOContentFilling extends Vue {
|
||||
public readonly PAYOUT_PATH: string = RouteConfig.Payout.path;
|
||||
public chartWidth: number = 0;
|
||||
public chartHeight: number = 0;
|
||||
public diskSpaceChartWidth: number = 0;
|
||||
public diskSpaceChartHeight: number = 0;
|
||||
|
||||
public $refs: {
|
||||
chart: HTMLElement;
|
||||
diskSpaceChart: HTMLElement;
|
||||
};
|
||||
|
||||
public get isDarkMode(): boolean {
|
||||
@ -225,6 +225,8 @@ export default class SNOContentFilling extends Vue {
|
||||
public recalculateChartDimensions(): void {
|
||||
this.chartWidth = this.$refs['chart'].clientWidth;
|
||||
this.chartHeight = this.$refs['chart'].clientHeight;
|
||||
this.diskSpaceChartWidth = this.$refs['diskSpaceChart'].clientWidth;
|
||||
this.diskSpaceChartHeight = this.$refs['diskSpaceChart'].clientHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -334,14 +336,6 @@ export default class SNOContentFilling extends Vue {
|
||||
return formatBytes(this.$store.state.node.storageSummary);
|
||||
}
|
||||
|
||||
/**
|
||||
* diskSpace - remaining amount of diskSpace from store.
|
||||
* @return DiskSpaceInfo - remaining amount of diskSpace
|
||||
*/
|
||||
public get diskSpace(): DiskSpaceInfo {
|
||||
return this.$store.state.node.utilization.diskSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks - uptime and audit checks statuses from store.
|
||||
* @return Checks - uptime and audit checks statuses
|
||||
@ -633,6 +627,10 @@ export default class SNOContentFilling extends Vue {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.bandwidth-chart {
|
||||
width: calc(100% - 60px);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
|
||||
.info-area {
|
||||
|
@ -263,7 +263,6 @@ export default class SNOContentTitle extends Vue {
|
||||
}
|
||||
|
||||
&__info-container {
|
||||
justify-content: flex-start;
|
||||
|
||||
&__info-item {
|
||||
padding: 12px 8px;
|
||||
@ -275,4 +274,14 @@ export default class SNOContentTitle extends Vue {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
|
||||
.title-area {
|
||||
|
||||
&__info-container {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -109,15 +109,16 @@ export default class SNOFooter extends Vue {
|
||||
|
||||
.footer {
|
||||
height: auto;
|
||||
padding: 25px 36px;
|
||||
padding: 10px 36px;
|
||||
min-height: 29px;
|
||||
|
||||
&__content-holder {
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
|
||||
&__links-area {
|
||||
margin-top: 25px;
|
||||
&__icon {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ export function makeNodeModule(api: SNOApi) {
|
||||
},
|
||||
diskSpace: {
|
||||
used: 0,
|
||||
remaining: 1,
|
||||
available: 1,
|
||||
trash: 0,
|
||||
},
|
||||
},
|
||||
satellites: new Array<SatelliteInfo>(),
|
||||
@ -82,8 +82,8 @@ export function makeNodeModule(api: SNOApi) {
|
||||
state.info.allowedVersion = nodeInfo.allowedVersion;
|
||||
state.info.wallet = nodeInfo.wallet;
|
||||
state.utilization.diskSpace.used = nodeInfo.diskSpace.used;
|
||||
state.utilization.diskSpace.remaining = nodeInfo.diskSpace.available - nodeInfo.diskSpace.used;
|
||||
state.utilization.diskSpace.available = nodeInfo.diskSpace.available;
|
||||
state.utilization.diskSpace.trash = nodeInfo.diskSpace.trash;
|
||||
state.utilization.bandwidth.used = nodeInfo.bandwidth.used;
|
||||
|
||||
state.disqualifiedSatellites = nodeInfo.satellites.filter((satellite: SatelliteInfo) => satellite.disqualified);
|
||||
|
@ -17,6 +17,26 @@ export class ChartData {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DiskStatChartData class holds info for Disk Stat Chart.
|
||||
*/
|
||||
export class DiskStatChartData {
|
||||
public constructor(
|
||||
public datasets: DiskStatDataSet[] = [new DiskStatDataSet()],
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* DiskStatDataSet describes all required data for disk stat chart dataset.
|
||||
*/
|
||||
export class DiskStatDataSet {
|
||||
public constructor(
|
||||
public label: string = '',
|
||||
public backgroundColor: string[] = ['#D6D6D6', '#0059D0', '#8FA7C6'],
|
||||
public data: number[] = [],
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* DataSets class holds info for chart's DataSets entity.
|
||||
*/
|
||||
|
@ -85,16 +85,16 @@ export class PayoutHttpApi implements PayoutApi {
|
||||
}
|
||||
|
||||
let held: number = 0;
|
||||
let earned: number = 0;
|
||||
let paid: number = 0;
|
||||
|
||||
data.forEach((paystub: any) => {
|
||||
held += (paystub.held - paystub.disposed) / this.PRICE_DIVIDER;
|
||||
earned += paystub.earned / this.PRICE_DIVIDER;
|
||||
paid += paystub.paid / this.PRICE_DIVIDER;
|
||||
});
|
||||
|
||||
return new TotalPayoutInfo(
|
||||
held,
|
||||
earned,
|
||||
paid,
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ export class SNOApi {
|
||||
return new SatelliteInfo(satellite.id, satellite.url, disqualified, suspended);
|
||||
});
|
||||
|
||||
const diskSpace: DiskSpaceInfo = new DiskSpaceInfo(json.diskSpace.used, json.diskSpace.available);
|
||||
const diskSpace: DiskSpaceInfo = new DiskSpaceInfo(json.diskSpace.used, json.diskSpace.available, json.diskSpace.trash);
|
||||
const bandwidth: BandwidthInfo = new BandwidthInfo(json.bandwidth.used);
|
||||
|
||||
return new Dashboard(json.nodeID, json.wallet, satellites, diskSpace, bandwidth,
|
||||
|
@ -35,14 +35,11 @@ export class SatelliteInfo {
|
||||
* DiskSpaceInfo stores all info about storage node disk space usage
|
||||
*/
|
||||
export class DiskSpaceInfo {
|
||||
public remaining: number;
|
||||
|
||||
public constructor(
|
||||
public used: number,
|
||||
public available: number,
|
||||
) {
|
||||
this.remaining = available - used;
|
||||
}
|
||||
public used: number = 0,
|
||||
public available: number = 0,
|
||||
public trash: number = 0,
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,6 +41,7 @@
|
||||
--egress-button-font-color: #2e5f46;
|
||||
--egress-font-color: #2e5f46;
|
||||
--egress-tooltip-info-background-color: rgba(211, 242, 204, 0.3);
|
||||
--disk-stat-chart-text-color: #657284;
|
||||
--tooltip-background-path: url('../../static/images/tooltipBack.png');
|
||||
--tooltip-arrow-path: url('../../static/images/tooltipArrow.png');
|
||||
--info-image-arrow-middle-path: url('../../static/images/Message.png');
|
||||
@ -88,6 +89,7 @@
|
||||
--egress-button-font-color: white;
|
||||
--egress-font-color: white;
|
||||
--egress-tooltip-info-background-color: #212329;
|
||||
--disk-stat-chart-text-color: white;
|
||||
--tooltip-background-path: url('../../static/images/tooltipBackDark.png');
|
||||
--tooltip-arrow-path: url('../../static/images/tooltipArrowDark.png');
|
||||
--info-image-arrow-middle-path: url('../../static/images/MessageDark.png');
|
||||
|
61
web/storagenode/tests/unit/components/DiskStatChart.spec.ts
Normal file
61
web/storagenode/tests/unit/components/DiskStatChart.spec.ts
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright (C) 2020 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
import Vuex from 'vuex';
|
||||
|
||||
import DiskStatChart from '@/app/components/DiskStatChart.vue';
|
||||
|
||||
import { makeNodeModule, NODE_ACTIONS } from '@/app/store/modules/node';
|
||||
import { SNOApi } from '@/storagenode/api/storagenode';
|
||||
import { BandwidthInfo, Dashboard, DiskSpaceInfo, SatelliteInfo } from '@/storagenode/dashboard';
|
||||
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
|
||||
const nodeApi = new SNOApi();
|
||||
const nodeModule = makeNodeModule(nodeApi);
|
||||
|
||||
const store = new Vuex.Store({ modules: { node: nodeModule }});
|
||||
|
||||
describe('DiskStatChart', (): void => {
|
||||
it('renders correctly', (): void => {
|
||||
const wrapper = shallowMount(DiskStatChart, {
|
||||
store,
|
||||
localVue,
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders correctly with actual values', async (): Promise<void> => {
|
||||
const wrapper = shallowMount(DiskStatChart, {
|
||||
store,
|
||||
localVue,
|
||||
});
|
||||
|
||||
jest.spyOn(nodeApi, 'dashboard').mockReturnValue(
|
||||
Promise.resolve(
|
||||
new Dashboard(
|
||||
'1',
|
||||
'2',
|
||||
[
|
||||
new SatelliteInfo('3', 'url1', null, null),
|
||||
new SatelliteInfo('4', 'url2', new Date(2020, 1, 1), new Date(2020, 0, 1)),
|
||||
],
|
||||
new DiskSpaceInfo(550000, 1000000, 22000),
|
||||
new BandwidthInfo(50),
|
||||
new Date(),
|
||||
new Date(2019, 3, 1),
|
||||
'0.1.1',
|
||||
'0.2.2',
|
||||
false,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await store.dispatch(NODE_ACTIONS.GET_NODE_INFO);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
@ -0,0 +1,63 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`DiskStatChart renders correctly 1`] = `
|
||||
<div class="disk-stat-area">
|
||||
<p class="disk-stat-area__title">Total Disk Space</p>
|
||||
<p class="disk-stat-area__amount">0KB</p>
|
||||
<doughnutchart-stub chartid="doughnut-chart" width="400" height="400" cssclasses="" plugins="" chartdata="[object Object]" class="disk-stat-area__chart"></doughnutchart-stub>
|
||||
<div class="disk-stat-area__info-area">
|
||||
<div class="disk-stat-area__info-area__item">
|
||||
<div class="disk-stat-area__info-area__item__labels-area">
|
||||
<div class="disk-stat-area__info-area__item__labels-area__circle used"></div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__label">Used</p>
|
||||
</div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__amount">0 Bytes</p>
|
||||
</div>
|
||||
<div class="disk-stat-area__info-area__item">
|
||||
<div class="disk-stat-area__info-area__item__labels-area">
|
||||
<div class="disk-stat-area__info-area__item__labels-area__circle free"></div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__label">Free</p>
|
||||
</div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__amount">0KB</p>
|
||||
</div>
|
||||
<div class="disk-stat-area__info-area__item">
|
||||
<div class="disk-stat-area__info-area__item__labels-area">
|
||||
<div class="disk-stat-area__info-area__item__labels-area__circle trash"></div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__label">Trash</p>
|
||||
</div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__amount">0 Bytes</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`DiskStatChart renders correctly with actual values 1`] = `
|
||||
<div class="disk-stat-area">
|
||||
<p class="disk-stat-area__title">Total Disk Space</p>
|
||||
<p class="disk-stat-area__amount">1MB</p>
|
||||
<doughnutchart-stub chartid="doughnut-chart" width="400" height="400" cssclasses="" plugins="" chartdata="[object Object]" class="disk-stat-area__chart"></doughnutchart-stub>
|
||||
<div class="disk-stat-area__info-area">
|
||||
<div class="disk-stat-area__info-area__item">
|
||||
<div class="disk-stat-area__info-area__item__labels-area">
|
||||
<div class="disk-stat-area__info-area__item__labels-area__circle used"></div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__label">Used</p>
|
||||
</div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__amount">550KB</p>
|
||||
</div>
|
||||
<div class="disk-stat-area__info-area__item">
|
||||
<div class="disk-stat-area__info-area__item__labels-area">
|
||||
<div class="disk-stat-area__info-area__item__labels-area__circle free"></div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__label">Free</p>
|
||||
</div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__amount">428KB</p>
|
||||
</div>
|
||||
<div class="disk-stat-area__info-area__item">
|
||||
<div class="disk-stat-area__info-area__item__labels-area">
|
||||
<div class="disk-stat-area__info-area__item__labels-area__circle trash"></div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__label">Trash</p>
|
||||
</div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__amount">22KB</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -48,7 +48,7 @@ describe('mutations', () => {
|
||||
new SatelliteInfo('3', 'url1', null, null),
|
||||
new SatelliteInfo('4', 'url2', new Date(2020, 1, 1), new Date(2020, 0, 1)),
|
||||
],
|
||||
new DiskSpaceInfo(99, 100),
|
||||
new DiskSpaceInfo(99, 100, 5),
|
||||
new BandwidthInfo(50),
|
||||
new Date(),
|
||||
new Date(2019, 3, 1),
|
||||
@ -61,7 +61,8 @@ describe('mutations', () => {
|
||||
|
||||
expect(state.node.info.id).toBe(dashboardInfo.nodeID);
|
||||
expect(state.node.utilization.bandwidth.used).toBe(dashboardInfo.bandwidth.used);
|
||||
expect(state.node.utilization.diskSpace.remaining).toBe(dashboardInfo.diskSpace.remaining);
|
||||
expect(state.node.utilization.diskSpace.used).toBe(dashboardInfo.diskSpace.used);
|
||||
expect(state.node.utilization.diskSpace.trash).toBe(dashboardInfo.diskSpace.trash);
|
||||
expect(state.node.satellites.length).toBe(dashboardInfo.satellites.length);
|
||||
expect(state.node.disqualifiedSatellites.length).toBe(1);
|
||||
expect(state.node.suspendedSatellites.length).toBe(1);
|
||||
@ -179,7 +180,7 @@ describe('actions', () => {
|
||||
new SatelliteInfo('3', 'url1', null, null),
|
||||
new SatelliteInfo('4', 'url2', new Date(2020, 1, 1), new Date(2020, 0, 1)),
|
||||
],
|
||||
new DiskSpaceInfo(99, 100),
|
||||
new DiskSpaceInfo(99, 100, 1),
|
||||
new BandwidthInfo(50),
|
||||
new Date(),
|
||||
new Date(2019, 3, 1),
|
||||
@ -194,7 +195,8 @@ describe('actions', () => {
|
||||
|
||||
expect(state.node.info.id).toBe('1');
|
||||
expect(state.node.utilization.bandwidth.used).toBe(50);
|
||||
expect(state.node.utilization.diskSpace.remaining).toBe(1);
|
||||
expect(state.node.utilization.diskSpace.used).toBe(99);
|
||||
expect(state.node.utilization.diskSpace.trash).toBe(1);
|
||||
expect(state.node.satellites.length).toBe(2);
|
||||
expect(state.node.disqualifiedSatellites.length).toBe(1);
|
||||
expect(state.node.suspendedSatellites.length).toBe(1);
|
||||
@ -288,7 +290,7 @@ describe('getters', () => {
|
||||
new SatelliteInfo('3', 'url1', null, null),
|
||||
new SatelliteInfo('4', 'url2', new Date(2020, 1, 1), new Date(2020, 0, 1)),
|
||||
],
|
||||
new DiskSpaceInfo(99, 100),
|
||||
new DiskSpaceInfo(99, 100, 4),
|
||||
new BandwidthInfo(50),
|
||||
new Date(),
|
||||
new Date(2019, 3, 1),
|
||||
|
Loading…
Reference in New Issue
Block a user