web/multinode: disk space usage and stat charts
Change-Id: Ib2b1d6f2b78d57bd43ae1152921d98a1d6c31243
This commit is contained in:
parent
b900f6b4f9
commit
1230cde317
@ -25,6 +25,10 @@ export class BandwidthClient extends APIClient {
|
||||
public async fetch(satelliteId: string | null, nodeId: string | null): Promise<BandwidthTraffic> {
|
||||
let path = `${this.ROOT_PATH}`;
|
||||
|
||||
if (!satelliteId && !nodeId) {
|
||||
path += '/';
|
||||
}
|
||||
|
||||
if (satelliteId) {
|
||||
path += `/satellites/${satelliteId}`;
|
||||
}
|
||||
@ -40,9 +44,10 @@ export class BandwidthClient extends APIClient {
|
||||
}
|
||||
|
||||
const traffic = await response.json();
|
||||
const daily = traffic.bandwidthDaily || [];
|
||||
|
||||
return new BandwidthTraffic(
|
||||
traffic.bandwidthDaily.map(daily => {
|
||||
daily.map(daily => {
|
||||
return new BandwidthRollup(
|
||||
new Egress(daily.egress.repair, daily.egress.audit, daily.egress.usage),
|
||||
new Ingress(daily.ingress.repair, daily.ingress.usage),
|
||||
|
@ -33,6 +33,13 @@ export class StorageClient extends APIClient {
|
||||
path += `/${nodeId}`;
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const year = now.getUTCFullYear();
|
||||
const month = now.getUTCMonth() + 1;
|
||||
const period = `${year}-${month > 9 ? month : `0${month}`}`;
|
||||
|
||||
path += `?period=${period}`;
|
||||
|
||||
const response = await this.http.get(path);
|
||||
|
||||
if (!response.ok) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// Copyright (C) 2021 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<template>
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// Copyright (C) 2021 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<template>
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// Copyright (C) 2021 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<template>
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// Copyright (C) 2021 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<script lang="ts">
|
||||
|
36
web/multinode/src/app/components/common/DoughnutChart.vue
Normal file
36
web/multinode/src/app/components/common/DoughnutChart.vue
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2021 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/chart';
|
||||
|
||||
@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>
|
@ -4,7 +4,7 @@
|
||||
<template>
|
||||
<div class="add-new-node">
|
||||
<v-button :with-plus="true" label="New Node" :on-press="openModal" width="152px" />
|
||||
<v-modal v-if="isAddNewNodeModalShown" @close="closeModal">
|
||||
<v-modal v-if="isAddNewNodeModalShown" @onClose="closeModal">
|
||||
<h2 slot="header">Add New Node</h2>
|
||||
<div class="add-new-node__body" slot="body">
|
||||
<headered-input
|
||||
|
143
web/multinode/src/app/components/storage/DiskSpaceChart.vue
Normal file
143
web/multinode/src/app/components/storage/DiskSpaceChart.vue
Normal file
@ -0,0 +1,143 @@
|
||||
// Copyright (C) 2021 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<template>
|
||||
<div class="chart">
|
||||
<p class="disk-space-chart__data-dimension">{{ chartDataDimension }}*h</p>
|
||||
<VChart
|
||||
id="disk-space-chart"
|
||||
:chart-data="chartData"
|
||||
:width="chartWidth"
|
||||
:height="chartHeight"
|
||||
:tooltip-constructor="diskSpaceTooltip"
|
||||
:key="chartKey"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component } from 'vue-property-decorator';
|
||||
|
||||
import BaseChart from '@/app/components/common/BaseChart.vue';
|
||||
|
||||
import { ChartData, Tooltip, TooltipParams } from '@/app/types/chart';
|
||||
import { Chart as ChartUtils } from '@/app/utils/chart';
|
||||
import { Size } from '@/private/memory/size';
|
||||
import { Stamp } from '@/storage';
|
||||
|
||||
/**
|
||||
* stores stamp data for disc space chart's tooltip
|
||||
*/
|
||||
class StampTooltip {
|
||||
public atRestTotal: string;
|
||||
public date: string;
|
||||
|
||||
public constructor(stamp: Stamp) {
|
||||
this.atRestTotal = Size.toBase10String(stamp.atRestTotal);
|
||||
this.date = stamp.intervalStart.toUTCString().slice(0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
@Component
|
||||
export default class DiskSpaceChart extends BaseChart {
|
||||
|
||||
private get allStamps(): Stamp[] {
|
||||
return ChartUtils.populateEmptyStamps(this.$store.state.storage.usage);
|
||||
}
|
||||
|
||||
public get chartDataDimension(): string {
|
||||
if (!this.$store.state.storage.usage.length) {
|
||||
return 'Bytes';
|
||||
}
|
||||
|
||||
return ChartUtils.getChartDataDimension(this.allStamps.map((elem) => {
|
||||
return elem.atRestTotal;
|
||||
}));
|
||||
}
|
||||
|
||||
public get chartData(): ChartData {
|
||||
let data: number[] = [0];
|
||||
const daysCount = ChartUtils.daysDisplayedOnChart();
|
||||
const chartBackgroundColor = '#4F97F7';
|
||||
const chartBorderColor = '#1F49A3';
|
||||
const chartBorderWidth = 1;
|
||||
|
||||
if (this.allStamps.length) {
|
||||
data = ChartUtils.normalizeChartData(this.allStamps.map(elem => elem.atRestTotal));
|
||||
}
|
||||
|
||||
return new ChartData(daysCount, chartBackgroundColor, chartBorderColor, chartBorderWidth, data);
|
||||
}
|
||||
|
||||
public diskSpaceTooltip(tooltipModel): void {
|
||||
const tooltipParams = new TooltipParams(tooltipModel, 'disk-space-chart', 'disk-space-tooltip', 'disk-space-tooltip-point', this.tooltipMarkUp(tooltipModel),
|
||||
125, 89, 6, 4, `#1f49a3`);
|
||||
|
||||
Tooltip.custom(tooltipParams);
|
||||
}
|
||||
|
||||
private tooltipMarkUp(tooltipModel: any): string {
|
||||
if (!tooltipModel.dataPoints) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const dataIndex = tooltipModel.dataPoints[0].index;
|
||||
const dataPoint = new StampTooltip(this.allStamps[dataIndex]);
|
||||
|
||||
return `<div class='tooltip-body'>
|
||||
<p class='tooltip-body__data'><b>${dataPoint.atRestTotal}*h</b></p>
|
||||
<p class='tooltip-body__footer'>${dataPoint.date}</p>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.disk-space-chart {
|
||||
z-index: 102;
|
||||
|
||||
&__data-dimension {
|
||||
font-size: 13px;
|
||||
color: var(--c-title);
|
||||
margin: 0 0 5px 31px !important;
|
||||
font-family: 'font_medium', sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
#disk-space-tooltip {
|
||||
background: white;
|
||||
border: 1px solid var(--c-gray--light);
|
||||
width: 180px;
|
||||
height: 90px;
|
||||
font-size: 12px;
|
||||
border-radius: 14px;
|
||||
color: var(--c-title);
|
||||
pointer-events: none;
|
||||
z-index: 9999;
|
||||
font-family: 'font_bold', sans-serif;
|
||||
}
|
||||
|
||||
.tooltip-body {
|
||||
|
||||
&__data {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 11px 44px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
font-size: 12px;
|
||||
width: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
275
web/multinode/src/app/components/storage/DiskStatChart.vue
Normal file
275
web/multinode/src/app/components/storage/DiskStatChart.vue
Normal file
@ -0,0 +1,275 @@
|
||||
// Copyright (C) 2021 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">{{ diskSpace.allocated | bytesToBase10String }}</p>
|
||||
<doughnut-chart 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">{{ diskSpace.usedPieces | bytesToBase10String }}</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">{{ diskSpace.free | bytesToBase10String }}</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">{{ diskSpace.usedTrash | bytesToBase10String }}</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 overused"></div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__label">Overused</p>
|
||||
</div>
|
||||
<p class="disk-stat-area__info-area__item__labels-area__amount">{{ diskSpace.overused | bytesToBase10String }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
|
||||
import DoughnutChart from '@/app/components/common/DoughnutChart.vue';
|
||||
|
||||
import { DiskStatChartData, DiskStatDataSet } from '@/app/types/chart';
|
||||
import { DiskSpace } from '@/storage';
|
||||
|
||||
@Component({
|
||||
components: { DoughnutChart },
|
||||
})
|
||||
export default class DiskStatChart extends Vue {
|
||||
/**
|
||||
* Holds datasets for chart.
|
||||
*/
|
||||
public get chartData(): DiskStatChartData {
|
||||
return new DiskStatChartData([
|
||||
new DiskStatDataSet(
|
||||
'',
|
||||
['#D6D6D6', '#0059D0', '#8FA7C6', '#EB5757'],
|
||||
[
|
||||
this.diskSpace.free,
|
||||
this.diskSpace.usedPieces,
|
||||
this.diskSpace.usedTrash,
|
||||
this.diskSpace.overused,
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns disk space information from store.
|
||||
*/
|
||||
public get diskSpace(): DiskSpace {
|
||||
return this.$store.state.storage.diskSpace;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.disk-stat-area {
|
||||
width: 400px;
|
||||
height: 336px;
|
||||
background-color: white;
|
||||
border: 1px solid var(--c-gray--light);
|
||||
border-radius: 11px;
|
||||
padding: 32px 20px;
|
||||
position: relative;
|
||||
|
||||
&__title {
|
||||
font-family: 'font_regular', sans-serif;
|
||||
font-size: 14px;
|
||||
color: var(--c-gray);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&__amount {
|
||||
font-family: 'font_bold', sans-serif;
|
||||
font-size: 32px;
|
||||
line-height: 57px;
|
||||
color: var(--c-title);
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
&__chart {
|
||||
position: absolute;
|
||||
width: calc(58% - 25px);
|
||||
height: 220px;
|
||||
top: 135px;
|
||||
}
|
||||
|
||||
&__info-area {
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
top: 60%;
|
||||
transform: translateY(-50%);
|
||||
width: calc(40% - 35px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
margin-top: 19px;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&__labels-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&__circle {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
&__label {
|
||||
font-family: 'font_regular', sans-serif;
|
||||
font-size: 14px;
|
||||
color: #586474;
|
||||
}
|
||||
|
||||
&__amount {
|
||||
font-family: 'font_bold', sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: var(--c-title);
|
||||
margin-left: 22px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.used {
|
||||
background: #0059d0;
|
||||
}
|
||||
|
||||
.free {
|
||||
background: #d6d6d6;
|
||||
}
|
||||
|
||||
.trash {
|
||||
background: #8fa7c6;
|
||||
}
|
||||
|
||||
.overused {
|
||||
background: #eb5757;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
|
||||
.disk-stat-area {
|
||||
width: calc(100% - 60px);
|
||||
|
||||
&__chart {
|
||||
width: 250px;
|
||||
height: 250px;
|
||||
margin-left: 100px;
|
||||
top: 100px;
|
||||
}
|
||||
|
||||
&__info-area {
|
||||
right: 120px;
|
||||
width: 185px;
|
||||
|
||||
&__item {
|
||||
flex-direction: row;
|
||||
|
||||
&__labels-area__amount {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 780px) {
|
||||
|
||||
.disk-stat-area {
|
||||
|
||||
&__chart {
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
&__info-area {
|
||||
right: 90px;
|
||||
width: 140px;
|
||||
|
||||
&__item {
|
||||
flex-direction: row;
|
||||
|
||||
&__labels-area__amount {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 640px) {
|
||||
|
||||
.disk-stat-area {
|
||||
|
||||
&__chart {
|
||||
top: 125px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
&__info-area {
|
||||
top: 55%;
|
||||
right: 90px;
|
||||
width: 140px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 550px) {
|
||||
|
||||
.disk-stat-area {
|
||||
height: 414px;
|
||||
width: calc(100% - 36px);
|
||||
padding: 24px 18px;
|
||||
|
||||
&__chart {
|
||||
top: 100px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__info-area {
|
||||
top: 70%;
|
||||
right: 50%;
|
||||
transform: translateX(50%);
|
||||
bottom: 10px;
|
||||
height: 100px;
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -8,7 +8,7 @@
|
||||
<node-selection-dropdown />
|
||||
<satellite-selection-dropdown />
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<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">
|
||||
@ -42,11 +42,25 @@
|
||||
<p class="chart-container__amount" v-else-if="isIngressChartShown"><b>{{ bandwidth.ingressSummary | bytesToBase10String }}</b></p>
|
||||
<p class="chart-container__amount" v-else><b>{{ bandwidth.bandwidthSummary | bytesToBase10String }}</b></p>
|
||||
<div class="chart-container__chart" ref="chart" onresize="recalculateChartDimensions()" >
|
||||
<EgressChart v-if="isEgressChartShown" :height="chartHeight" :width="chartWidth"/>
|
||||
<IngressChart v-else-if="isIngressChartShown" :height="chartHeight" :width="chartWidth"/>
|
||||
<BandwidthChart v-else :height="chartHeight" :width="chartWidth"/>
|
||||
<egress-chart v-if="isEgressChartShown" :height="chartHeight" :width="chartWidth"/>
|
||||
<ingress-chart v-else-if="isIngressChartShown" :height="chartHeight" :width="chartWidth"/>
|
||||
<bandwidth-chart v-else :height="chartHeight" :width="chartWidth"/>
|
||||
</div>
|
||||
</div>
|
||||
<section class="bandwidth__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>{{ 0 | bytesToBase10String }}*h</b></p>
|
||||
<div class="chart-container__chart" ref="diskSpaceChart" onresize="recalculateChartDimensions()" >
|
||||
<disk-space-chart :height="diskSpaceChartHeight" :width="diskSpaceChartWidth"/>
|
||||
</div>
|
||||
</section>
|
||||
<section class="disk-stat-chart">
|
||||
<disk-stat-chart />
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -58,12 +72,16 @@ import EgressChart from '@/app/components/bandwidth/EgressChart.vue';
|
||||
import IngressChart from '@/app/components/bandwidth/IngressChart.vue';
|
||||
import NodeSelectionDropdown from '@/app/components/common/NodeSelectionDropdown.vue';
|
||||
import SatelliteSelectionDropdown from '@/app/components/common/SatelliteSelectionDropdown.vue';
|
||||
import DiskSpaceChart from '@/app/components/storage/DiskSpaceChart.vue';
|
||||
import DiskStatChart from '@/app/components/storage/DiskStatChart.vue';
|
||||
|
||||
import { UnauthorizedError } from '@/api';
|
||||
import { BandwidthTraffic } from '@/bandwidth';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
DiskStatChart,
|
||||
DiskSpaceChart,
|
||||
EgressChart,
|
||||
IngressChart,
|
||||
BandwidthChart,
|
||||
@ -74,6 +92,8 @@ import { BandwidthTraffic } from '@/bandwidth';
|
||||
export default class BandwidthPage extends Vue {
|
||||
public chartWidth: number = 0;
|
||||
public chartHeight: number = 0;
|
||||
public diskSpaceChartWidth: number = 0;
|
||||
public diskSpaceChartHeight: number = 0;
|
||||
public isEgressChartShown: boolean = false;
|
||||
public isIngressChartShown: boolean = false;
|
||||
public $refs: {
|
||||
@ -90,6 +110,8 @@ export default class BandwidthPage 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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,14 +131,14 @@ export default class BandwidthPage extends Vue {
|
||||
// TODO: notify error
|
||||
}
|
||||
|
||||
await this.fetchBandwidth();
|
||||
await this.fetchTraffic();
|
||||
|
||||
// Subscribes on period or satellite change
|
||||
this.$store.subscribe(async (mutation) => {
|
||||
const watchedMutations = [ 'nodes/setSelectedNode', 'nodes/setSelectedSatellite' ];
|
||||
|
||||
if (watchedMutations.includes(mutation.type)) {
|
||||
await this.fetchBandwidth();
|
||||
await this.fetchTraffic();
|
||||
}
|
||||
});
|
||||
|
||||
@ -156,9 +178,9 @@ export default class BandwidthPage extends Vue {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches bandwidth information.
|
||||
* Fetches bandwidth and disk space information.
|
||||
*/
|
||||
private async fetchBandwidth(): Promise<void> {
|
||||
private async fetchTraffic(): Promise<void> {
|
||||
try {
|
||||
await this.$store.dispatch('bandwidth/fetch');
|
||||
} catch (error) {
|
||||
@ -168,6 +190,26 @@ export default class BandwidthPage extends Vue {
|
||||
|
||||
// TODO: notify error
|
||||
}
|
||||
|
||||
try {
|
||||
await this.$store.dispatch('storage/usage');
|
||||
} catch (error) {
|
||||
if (error instanceof UnauthorizedError) {
|
||||
// TODO: redirect to login screen.
|
||||
}
|
||||
|
||||
// TODO: notify error
|
||||
}
|
||||
|
||||
try {
|
||||
await this.$store.dispatch('storage/diskSpace');
|
||||
} catch (error) {
|
||||
if (error instanceof UnauthorizedError) {
|
||||
// TODO: redirect to login screen.
|
||||
}
|
||||
|
||||
// TODO: notify error
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -203,7 +245,7 @@ export default class BandwidthPage extends Vue {
|
||||
|
||||
& .chart-container {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
width: 65%;
|
||||
height: 401px;
|
||||
background-color: white;
|
||||
border: 1px solid var(--c-gray--light);
|
||||
@ -263,5 +305,25 @@ export default class BandwidthPage extends Vue {
|
||||
height: 240px;
|
||||
}
|
||||
}
|
||||
|
||||
&__chart-area {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.disk-space-amount {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.bandwidth-chart {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.disk-stat-chart {
|
||||
margin: 20px 0 13px 0;
|
||||
width: auto;
|
||||
}
|
||||
</style>
|
||||
|
@ -7,7 +7,7 @@ exports[`BandwidthPage renders correctly 1`] = `
|
||||
<node-selection-dropdown-stub></node-selection-dropdown-stub>
|
||||
<satellite-selection-dropdown-stub></satellite-selection-dropdown-stub>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<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"><button name="Show Bandwidth Chart" class="chart-container__title-area__chart-choice-item active">
|
||||
@ -20,9 +20,23 @@ exports[`BandwidthPage renders correctly 1`] = `
|
||||
</div>
|
||||
<p class="chart-container__amount"><b>0.7GB</b></p>
|
||||
<div onresize="recalculateChartDimensions()" class="chart-container__chart">
|
||||
<bandwidthchart-stub width="0" height="0"></bandwidthchart-stub>
|
||||
<bandwidth-chart-stub width="0" height="0"></bandwidth-chart-stub>
|
||||
</div>
|
||||
</div>
|
||||
<section class="bandwidth__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>0B*h</b></p>
|
||||
<div onresize="recalculateChartDimensions()" class="chart-container__chart">
|
||||
<disk-space-chart-stub width="0" height="0"></disk-space-chart-stub>
|
||||
</div>
|
||||
</section>
|
||||
<section class="disk-stat-chart">
|
||||
<disk-stat-chart-stub></disk-stat-chart-stub>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@ -33,7 +47,7 @@ exports[`BandwidthPage renders correctly with egress chart 1`] = `
|
||||
<node-selection-dropdown-stub></node-selection-dropdown-stub>
|
||||
<satellite-selection-dropdown-stub></satellite-selection-dropdown-stub>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<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"><button name="Show Bandwidth Chart" class="chart-container__title-area__chart-choice-item">
|
||||
@ -46,9 +60,23 @@ exports[`BandwidthPage renders correctly with egress chart 1`] = `
|
||||
</div>
|
||||
<p class="chart-container__amount"><b>577.7GB</b></p>
|
||||
<div onresize="recalculateChartDimensions()" class="chart-container__chart">
|
||||
<egresschart-stub width="0" height="0"></egresschart-stub>
|
||||
<egress-chart-stub width="0" height="0"></egress-chart-stub>
|
||||
</div>
|
||||
</div>
|
||||
<section class="bandwidth__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>0B*h</b></p>
|
||||
<div onresize="recalculateChartDimensions()" class="chart-container__chart">
|
||||
<disk-space-chart-stub width="0" height="0"></disk-space-chart-stub>
|
||||
</div>
|
||||
</section>
|
||||
<section class="disk-stat-chart">
|
||||
<disk-stat-chart-stub></disk-stat-chart-stub>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@ -59,7 +87,7 @@ exports[`BandwidthPage renders correctly with ingress chart 1`] = `
|
||||
<node-selection-dropdown-stub></node-selection-dropdown-stub>
|
||||
<satellite-selection-dropdown-stub></satellite-selection-dropdown-stub>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<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"><button name="Show Bandwidth Chart" class="chart-container__title-area__chart-choice-item">
|
||||
@ -72,8 +100,22 @@ exports[`BandwidthPage renders correctly with ingress chart 1`] = `
|
||||
</div>
|
||||
<p class="chart-container__amount"><b>5MB</b></p>
|
||||
<div onresize="recalculateChartDimensions()" class="chart-container__chart">
|
||||
<ingresschart-stub width="0" height="0"></ingresschart-stub>
|
||||
<ingress-chart-stub width="0" height="0"></ingress-chart-stub>
|
||||
</div>
|
||||
</div>
|
||||
<section class="bandwidth__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>0B*h</b></p>
|
||||
<div onresize="recalculateChartDimensions()" class="chart-container__chart">
|
||||
<disk-space-chart-stub width="0" height="0"></disk-space-chart-stub>
|
||||
</div>
|
||||
</section>
|
||||
<section class="disk-stat-chart">
|
||||
<disk-stat-chart-stub></disk-stat-chart-stub>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
`;
|
||||
|
Loading…
Reference in New Issue
Block a user