web/storagenode: online score added

Change-Id: I8c0fd1332354063941d62891ba79ca895074b6c8
This commit is contained in:
NickolaiYurchenko 2020-09-24 14:55:32 +03:00 committed by Nikolay Yurchenko
parent b3cf12f567
commit a1488e53a0
6 changed files with 87 additions and 20 deletions

View File

@ -6,17 +6,21 @@
<div class="audits-area__content">
<div class="audits-area__content__item" v-for="item in auditItems" :key="item.satelliteName">
<div class="audits-area__content__item__header">
<p class="audits-area__content__item__header__satellite-name">{{item.satelliteName}}</p>
<DisqualifyIcon v-if="item.statusClassName" :class="[ item.statusClassName ]" />
<p class="audits-area__content__item__header__satellite-name">{{ item.satelliteName }}</p>
<DisqualifyIcon v-if="item.iconClassName" :class="[ item.iconClassName ]" />
</div>
<div class="audits-area__content__item__divider"></div>
<div class="audits-area__content__item__info">
<p class="audits-area__content__item__info__label">Suspension</p>
<p class="audits-area__content__item__info__value" :class="[ item.statusClassName ]">{{item.suspensionScore}}</p>
<p class="audits-area__content__item__info__value" :class="[ item.suspensionScore.statusClassName ]">{{ item.suspensionScore.label }}</p>
</div>
<div class="audits-area__content__item__info">
<p class="audits-area__content__item__info__label">Audit</p>
<p class="audits-area__content__item__info__value" :class="[ item.statusClassName ]">{{item.auditScore}}</p>
<p class="audits-area__content__item__info__value" :class="[ item.auditScore.statusClassName ]">{{ item.auditScore.label }}</p>
</div>
<div class="audits-area__content__item__info">
<p class="audits-area__content__item__info__label">Online</p>
<p class="audits-area__content__item__info__value" :class="[ item.onlineScore.statusClassName ]">{{ item.onlineScore.label }}</p>
</div>
</div>
</div>

View File

@ -120,6 +120,7 @@ export class SNOApi {
scoreInfo.satelliteName,
scoreInfo.auditScore,
scoreInfo.suspensionScore,
scoreInfo.onlineScore,
);
});

View File

@ -197,32 +197,65 @@ export class Satellites {
) {}
}
// TODO: move and create domain types.
/**
* Holds information about audit and suspension scores by satellite.
*/
export class SatelliteScores {
public auditScore: string;
public suspensionScore: string;
public auditScore: Score;
public suspensionScore: Score;
public onlineScore: Score;
public iconClassName: string = '';
private readonly WARNING_CLASSNAME: string = 'warning';
private readonly DISQUALIFICATION_CLASSNAME: string = 'disqualification';
public constructor(
public satelliteName: string = 'satellite-name',
auditScore: number = 0,
unknownScore: number = 0,
onlineScore: number = 0,
) {
this.auditScore = new Score(auditScore);
this.suspensionScore = new Score(unknownScore);
this.onlineScore = new Score(onlineScore);
const scores = [this.auditScore, this.onlineScore, this.suspensionScore];
if (scores.some(score => score.statusClassName === this.DISQUALIFICATION_CLASSNAME)) {
this.iconClassName = this.DISQUALIFICATION_CLASSNAME;
return;
}
if (scores.some(score => score.statusClassName === this.WARNING_CLASSNAME)) {
this.iconClassName = this.WARNING_CLASSNAME;
}
}
}
/**
* Score in percents and className for view.
*/
export class Score {
public label: string;
public statusClassName: string;
private readonly WARNING_MINIMUM_SCORE: number = 0.95;
private readonly WARNING_CLASSNAME: string = 'warning';
private readonly DISQUALIFICATION_MINIMUM_SCORE: number = 0.6;
private readonly DISQUALIFICATION_CLASSNAME: string = 'disqualification';
public constructor(
public satelliteName: string = 'satellite-name',
score: number = 0,
unknownScore: number = 0,
) {
this.auditScore = `${score * 100} %`;
this.suspensionScore = `${unknownScore * 100} %`;
this.label = `${parseFloat((score * 100).toFixed(2))} %`;
switch (true) {
case (score < this.DISQUALIFICATION_MINIMUM_SCORE || unknownScore < this.DISQUALIFICATION_MINIMUM_SCORE):
case (score < this.DISQUALIFICATION_MINIMUM_SCORE):
this.statusClassName = this.DISQUALIFICATION_CLASSNAME;
break;
case (score < this.WARNING_MINIMUM_SCORE || unknownScore < this.WARNING_MINIMUM_SCORE):
case (score < this.WARNING_MINIMUM_SCORE):
this.statusClassName = this.WARNING_CLASSNAME;
break;

View File

@ -28,9 +28,9 @@ describe('AllSatellitesAuditsArea', (): void => {
const satellites = new Satellites();
satellites.satellitesScores = [
new SatelliteScores('name1', 1, 1),
new SatelliteScores('name2', 0.5, 1),
new SatelliteScores('name3', 0.7, 1),
new SatelliteScores('name1', 1, 1, 0.5),
new SatelliteScores('name2', 0.5, 1, 0.7),
new SatelliteScores('name3', 0.7, 1, 1),
];
jest.spyOn(nodeApi, 'satellites').mockReturnValue(Promise.resolve(satellites));

View File

@ -6,7 +6,7 @@ exports[`AllSatellitesAuditsArea renders correctly with actual values 1`] = `
<div class="audits-area__content__item">
<div class="audits-area__content__item__header">
<p class="audits-area__content__item__header__satellite-name">name1</p>
<!---->
<disqualifyicon-stub class="disqualification"></disqualifyicon-stub>
</div>
<div class="audits-area__content__item__divider"></div>
<div class="audits-area__content__item__info">
@ -17,6 +17,10 @@ exports[`AllSatellitesAuditsArea renders correctly with actual values 1`] = `
<p class="audits-area__content__item__info__label">Audit</p>
<p class="audits-area__content__item__info__value">100 %</p>
</div>
<div class="audits-area__content__item__info">
<p class="audits-area__content__item__info__label">Online</p>
<p class="audits-area__content__item__info__value disqualification">50 %</p>
</div>
</div>
<div class="audits-area__content__item">
<div class="audits-area__content__item__header">
@ -26,12 +30,16 @@ exports[`AllSatellitesAuditsArea renders correctly with actual values 1`] = `
<div class="audits-area__content__item__divider"></div>
<div class="audits-area__content__item__info">
<p class="audits-area__content__item__info__label">Suspension</p>
<p class="audits-area__content__item__info__value disqualification">100 %</p>
<p class="audits-area__content__item__info__value">100 %</p>
</div>
<div class="audits-area__content__item__info">
<p class="audits-area__content__item__info__label">Audit</p>
<p class="audits-area__content__item__info__value disqualification">50 %</p>
</div>
<div class="audits-area__content__item__info">
<p class="audits-area__content__item__info__label">Online</p>
<p class="audits-area__content__item__info__value warning">70 %</p>
</div>
</div>
<div class="audits-area__content__item">
<div class="audits-area__content__item__header">
@ -41,12 +49,16 @@ exports[`AllSatellitesAuditsArea renders correctly with actual values 1`] = `
<div class="audits-area__content__item__divider"></div>
<div class="audits-area__content__item__info">
<p class="audits-area__content__item__info__label">Suspension</p>
<p class="audits-area__content__item__info__value warning">100 %</p>
<p class="audits-area__content__item__info__value">100 %</p>
</div>
<div class="audits-area__content__item__info">
<p class="audits-area__content__item__info__label">Audit</p>
<p class="audits-area__content__item__info__value warning">70 %</p>
</div>
<div class="audits-area__content__item__info">
<p class="audits-area__content__item__info__label">Online</p>
<p class="audits-area__content__item__info__value">100 %</p>
</div>
</div>
</div>
<!---->

View File

@ -19,7 +19,7 @@ import {
IngressUsed,
Metric,
Satellite,
Satellites,
Satellites, SatelliteScores,
Stamp,
} from '@/storagenode/satellite';
import { createLocalVue } from '@vue/test-utils';
@ -103,10 +103,17 @@ describe('mutations', () => {
it('selects all satellites', () => {
const satelliteInfo = new Satellites();
satelliteInfo.satellitesScores = [
new SatelliteScores('name1', 0.7, 0.9, 1),
new SatelliteScores('name1', 0.8, 0.8, 0.8),
];
store.commit(NODE_MUTATIONS.SELECT_ALL_SATELLITES, satelliteInfo);
expect(state.node.selectedSatellite.id).toBe('');
expect(state.node.satellitesScores.length).toBe(satelliteInfo.satellitesScores.length);
expect(state.node.satellitesScores[0].auditScore.label).toBe('70 %');
expect(state.node.satellitesScores[0].iconClassName).toBe('warning');
});
it('sets daily data', () => {
@ -272,13 +279,23 @@ describe('actions', () => {
});
it('success fetch all satellites info', async () => {
const satellitesInfo = new Satellites();
satellitesInfo.satellitesScores = [
new SatelliteScores('name1', 0.7, 0.9, 1),
new SatelliteScores('name1', 0.8, 0.8, 0.8),
];
jest.spyOn(nodeApi, 'satellites').mockReturnValue(
Promise.resolve(new Satellites()),
Promise.resolve(satellitesInfo),
);
await store.dispatch(NODE_ACTIONS.SELECT_SATELLITE);
expect(state.node.selectedSatellite.id).toBe('');
expect(state.node.satellitesScores.length).toBe(satellitesInfo.satellitesScores.length);
expect(state.node.satellitesScores[0].onlineScore.label).toBe('100 %');
expect(state.node.satellitesScores[0].auditScore.statusClassName).toBe('warning');
expect(state.node.satellitesScores[1].auditScore.label).toBe('80 %');
});
});