Skip to content

Commit

Permalink
NAS-131217 / 25.04 / Display disk usage on app widget (#10708)
Browse files Browse the repository at this point in the history
* NAS-131073: Add apps widgets back

* NAS-131073: Add apps widgets back

* NAS-131217: Display disk usage on app widget

* NAS-131217: Display disk usage on app widget

* NAS-131217: Update tests

* NAS-131217: Display disk usage on app widget
  • Loading branch information
denysbutenko authored Sep 19, 2024
1 parent 54a4ddc commit 6dc7ab9
Show file tree
Hide file tree
Showing 9 changed files with 369 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@
display: inline-flex;
line-height: 1;
}

.mdi-alert-circle {
color: var(--yellow);
}
}
2 changes: 2 additions & 0 deletions src/app/pages/dashboard/dashboard.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import { widgetComponents } from 'app/pages/dashboard/widgets/all-widgets.consta
import { AppCardInfoComponent } from 'app/pages/dashboard/widgets/apps/common/app-card-info/app-card-info.component';
import { AppControlsComponent } from 'app/pages/dashboard/widgets/apps/common/app-controls/app-controls.component';
import { AppCpuInfoComponent } from 'app/pages/dashboard/widgets/apps/common/app-cpu-info/app-cpu-info.component';
import { AppDiskInfoComponent } from 'app/pages/dashboard/widgets/apps/common/app-disk-info/app-disk-info.component';
import { AppMemoryInfoComponent } from 'app/pages/dashboard/widgets/apps/common/app-memory-info/app-memory-info.component';
import { AppNetworkInfoComponent } from 'app/pages/dashboard/widgets/apps/common/app-network-info/app-network-info.component';
import { AppVersionPipe } from 'app/pages/dashboard/widgets/apps/common/utils/app-version.pipe';
Expand Down Expand Up @@ -108,6 +109,7 @@ import { PoolUsageGaugeComponent } from './widgets/storage/widget-pool/common/po
AppCpuInfoComponent,
AppMemoryInfoComponent,
AppNetworkInfoComponent,
AppDiskInfoComponent,
...widgetComponents,
],
providers: [
Expand Down
4 changes: 2 additions & 2 deletions src/app/pages/dashboard/services/widget-resources.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { subHours, subMinutes } from 'date-fns';
import {
Observable, Subject, catchError, combineLatestWith, debounceTime,
filter,
forkJoin, map, of, repeat, shareReplay, switchMap, take, timer,
forkJoin, map, of, repeat, shareReplay, switchMap, take, throttleTime, timer,
} from 'rxjs';
import { SystemUpdateStatus } from 'app/enums/system-update.enum';
import { LoadingState, toLoadingState } from 'app/helpers/operators/to-loading-state.helper';
Expand Down Expand Up @@ -160,8 +160,8 @@ export class WidgetResourcesService {
return this.ws.subscribe('app.stats').pipe(
filter(() => Boolean(appName)),
map((event) => event.fields.find((stats) => stats.app_name === appName)),
throttleTime(500),
toLoadingState(),
shareReplay({ bufferSize: 1, refCount: true }),
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<div class="chart-info">
<h4>{{ 'Block I/O' | translate }}</h4>
<div class="in-out">
<div class="in-out-row">
<span>{{ 'Read' | translate }}:</span>
<span *ixWithLoadingState="stats() as stats">
{{ stats.blkio.read | ixFileSize }}
</span>
</div>
<div class="in-out-row">
<span>{{ 'Write' | translate }}:</span>
<span *ixWithLoadingState="stats() as stats">
{{ stats.blkio.write | ixFileSize }}
</span>
</div>
</div>
<small>{{ '1m Average' | translate }}</small>
</div>
<div class="chart-graph">
@if (stats().isLoading) {
<ngx-skeleton-loader
class="skeleton"
[theme]="{
width: '292px',
height: '92px',
background: 'var(--alt-bg2)',
opacity: 0.25,
margin: 0,
}"
></ngx-skeleton-loader>
} @else {
<ix-network-chart
[showLegend]="false"
[data]="diskChartData()"
[aspectRatio]="3"
></ix-network-chart>
}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
:host {
.chart-info {
display: flex;
flex: 1;
flex-direction: column;
height: 100%;
justify-content: space-around;
padding: 6px 0 6px 8px;
width: 100%;

h4,
small {
color: var(--fg2);
}

small {
font-weight: 500;
opacity: 0.75;
}

.in-out {
font-size: 12px;
}

.in-out-row {
align-items: center;
display: flex;
gap: 4px;
white-space: nowrap;
}
}

.chart-graph {
.skeleton {
display: flex;
padding: 4px;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
import { fakeAsync } from '@angular/core/testing';
import { Spectator } from '@ngneat/spectator';
import { mockProvider, createComponentFactory } from '@ngneat/spectator/jest';
import { MockComponent } from 'ng-mocks';
import { LoadingState } from 'app/helpers/operators/to-loading-state.helper';
import { AppStats } from 'app/interfaces/app.interface';
import { FileSizePipe } from 'app/modules/pipes/file-size/file-size.pipe';
import { AppDiskInfoComponent } from 'app/pages/dashboard/widgets/apps/common/app-disk-info/app-disk-info.component';
import { NetworkChartComponent } from 'app/pages/dashboard/widgets/network/common/network-chart/network-chart.component';
import { ThemeService } from 'app/services/theme/theme.service';

describe('AppDiskInfoComponent', () => {
let spectator: Spectator<AppDiskInfoComponent>;
const createComponent = createComponentFactory({
component: AppDiskInfoComponent,
imports: [FileSizePipe],
declarations: [
MockComponent(NetworkChartComponent),
],
providers: [
mockProvider(ThemeService, {
currentTheme: () => ({ blue: '#0000FF', orange: '#FFA500' }),
}),
],
});

beforeEach(() => {
spectator = createComponent({
props: {
stats: {
isLoading: false,
error: null,
value: {
blkio: {
read: 1234567,
write: 2345678,
},
},
} as LoadingState<AppStats>,
},
});
});

it('checks title', () => {
const title = spectator.query('h4');
expect(title).toHaveText('Block I/O');
});

it('checks read-write rows', () => {
const readWriteRows = spectator.queryAll('.in-out-row');
expect(readWriteRows[0]).toHaveText('Read: 1.18 MiB');
expect(readWriteRows[1]).toHaveText('Write: 2.24 MiB');
});

it('checks network chart receives correct input', fakeAsync(() => {
const chartComponent = spectator.query(NetworkChartComponent);
expect(chartComponent).toBeTruthy();

spectator.tick(1);

expect(chartComponent.data).toEqual({
datasets: [
{
label: 'Read',
data: [
{ x: 0, y: 0 },
{ x: 1000, y: 0 },
{ x: 2000, y: 0 },
{ x: 3000, y: 0 },
{ x: 4000, y: 0 },
{ x: 5000, y: 0 },
{ x: 6000, y: 0 },
{ x: 7000, y: 0 },
{ x: 8000, y: 0 },
{ x: 9000, y: 0 },
{ x: 10000, y: 0 },
{ x: 11000, y: 0 },
{ x: 12000, y: 0 },
{ x: 13000, y: 0 },
{ x: 14000, y: 0 },
{ x: 15000, y: 0 },
{ x: 16000, y: 0 },
{ x: 17000, y: 0 },
{ x: 18000, y: 0 },
{ x: 19000, y: 0 },
{ x: 20000, y: 0 },
{ x: 21000, y: 0 },
{ x: 22000, y: 0 },
{ x: 23000, y: 0 },
{ x: 24000, y: 0 },
{ x: 25000, y: 0 },
{ x: 26000, y: 0 },
{ x: 27000, y: 0 },
{ x: 28000, y: 0 },
{ x: 29000, y: 0 },
{ x: 30000, y: 0 },
{ x: 31000, y: 0 },
{ x: 32000, y: 0 },
{ x: 33000, y: 0 },
{ x: 34000, y: 0 },
{ x: 35000, y: 0 },
{ x: 36000, y: 0 },
{ x: 37000, y: 0 },
{ x: 38000, y: 0 },
{ x: 39000, y: 0 },
{ x: 40000, y: 0 },
{ x: 41000, y: 0 },
{ x: 42000, y: 0 },
{ x: 43000, y: 0 },
{ x: 44000, y: 0 },
{ x: 45000, y: 0 },
{ x: 46000, y: 0 },
{ x: 47000, y: 0 },
{ x: 48000, y: 0 },
{ x: 49000, y: 0 },
{ x: 50000, y: 0 },
{ x: 51000, y: 0 },
{ x: 52000, y: 0 },
{ x: 53000, y: 0 },
{ x: 54000, y: 0 },
{ x: 55000, y: 0 },
{ x: 56000, y: 0 },
{ x: 57000, y: 0 },
{ x: 58000, y: 0 },
{ x: 59000, y: 1234567 },
],
borderColor: '#0000FF',
backgroundColor: '#0000FF',
pointBackgroundColor: '#0000FF',
pointRadius: 0,
tension: 0.2,
fill: true,
},
{
label: 'Write',
data: [
{ x: 0, y: -0 },
{ x: 1000, y: -0 },
{ x: 2000, y: -0 },
{ x: 3000, y: -0 },
{ x: 4000, y: -0 },
{ x: 5000, y: -0 },
{ x: 6000, y: -0 },
{ x: 7000, y: -0 },
{ x: 8000, y: -0 },
{ x: 9000, y: -0 },
{ x: 10000, y: -0 },
{ x: 11000, y: -0 },
{ x: 12000, y: -0 },
{ x: 13000, y: -0 },
{ x: 14000, y: -0 },
{ x: 15000, y: -0 },
{ x: 16000, y: -0 },
{ x: 17000, y: -0 },
{ x: 18000, y: -0 },
{ x: 19000, y: -0 },
{ x: 20000, y: -0 },
{ x: 21000, y: -0 },
{ x: 22000, y: -0 },
{ x: 23000, y: -0 },
{ x: 24000, y: -0 },
{ x: 25000, y: -0 },
{ x: 26000, y: -0 },
{ x: 27000, y: -0 },
{ x: 28000, y: -0 },
{ x: 29000, y: -0 },
{ x: 30000, y: -0 },
{ x: 31000, y: -0 },
{ x: 32000, y: -0 },
{ x: 33000, y: -0 },
{ x: 34000, y: -0 },
{ x: 35000, y: -0 },
{ x: 36000, y: -0 },
{ x: 37000, y: -0 },
{ x: 38000, y: -0 },
{ x: 39000, y: -0 },
{ x: 40000, y: -0 },
{ x: 41000, y: -0 },
{ x: 42000, y: -0 },
{ x: 43000, y: -0 },
{ x: 44000, y: -0 },
{ x: 45000, y: -0 },
{ x: 46000, y: -0 },
{ x: 47000, y: -0 },
{ x: 48000, y: -0 },
{ x: 49000, y: -0 },
{ x: 50000, y: -0 },
{ x: 51000, y: -0 },
{ x: 52000, y: -0 },
{ x: 53000, y: -0 },
{ x: 54000, y: -0 },
{ x: 55000, y: -0 },
{ x: 56000, y: -0 },
{ x: 57000, y: -0 },
{ x: 58000, y: -0 },
{ x: 59000, y: -2345678 },
],
borderColor: '#FFA500',
backgroundColor: '#FFA500',
pointBackgroundColor: '#FFA500',
pointRadius: 0,
tension: 0.2,
fill: true,
},
],
});
}));
});
Loading

0 comments on commit 6dc7ab9

Please sign in to comment.