Identify drives by a Scrutiny UUID instead of wwn (#960)

* Generate a UUIDv5 from a random namespace  based on WWN, model name, and serial number
* Migrate sqlite and influxdb data accordingly
* Update frontend API routes and components
* Fixes #923
This commit is contained in:
Aram Akhavan
2026-03-25 20:16:17 -07:00
committed by GitHub
parent e4c40f7e80
commit c3b2eb2b4f
69 changed files with 815 additions and 402 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ export const appRoutes: Route[] = [
// Example
{path: 'dashboard', loadChildren: () => import('app/modules/dashboard/dashboard.module').then(m => m.DashboardModule)},
{path: 'device/:wwn', loadChildren: () => import('app/modules/detail/detail.module').then(m => m.DetailModule)}
{path: 'device/:scrutiny_uuid', loadChildren: () => import('app/modules/detail/detail.module').then(m => m.DetailModule)}
// 404 & Catch all
// {path: '404-not-found', pathMatch: 'full', loadChildren: () => import('app/modules/admin/pages/errors/error-404/error-404.module').then(m => m.Error404Module)},
@@ -1,6 +1,7 @@
// maps to webapp/backend/pkg/models/device.go
export interface DeviceModel {
archived?: boolean;
scrutiny_uuid: string;
wwn: string;
device_name?: string;
device_uuid?: string;
@@ -4,6 +4,7 @@ import {SmartAttributeModel} from './smart-attribute-model';
export interface SmartModel {
date: string;
device_wwn: string;
scrutiny_uuid: string;
device_protocol: string;
temp: number;
@@ -40,7 +40,7 @@ export class DetailsMockApi implements TreoMockApi
register(): void
{
this._treoMockApiService
.onGet('/api/device/0x5002538e40a22954/details')
.onGet('/api/device/ecfaaf20-d1f6-558b-b33a-3e8db19a6c2c/details')
.reply(() => {
return [
@@ -50,7 +50,7 @@ export class DetailsMockApi implements TreoMockApi
});
this._treoMockApiService
.onGet('/api/device/0x5000cca264eb01d7/details')
.onGet('/api/device/3ea22b35-682b-49fb-a655-abffed108e48/details')
.reply(() => {
return [
@@ -60,7 +60,7 @@ export class DetailsMockApi implements TreoMockApi
});
this._treoMockApiService
.onGet('/api/device/0x5000cca264ec3183/details')
.onGet('/api/device/42caca8a-9b95-5c75-b059-305771a2a193/details')
.reply(() => {
return [
@@ -70,7 +70,7 @@ export class DetailsMockApi implements TreoMockApi
});
this._treoMockApiService
.onGet('/api/device/0x5000cca252c859cc/details')
.onGet('/api/device/d8796fe7-2422-520c-8991-e970993dad3e/details')
.reply(() => {
return [
@@ -80,7 +80,17 @@ export class DetailsMockApi implements TreoMockApi
});
this._treoMockApiService
.onGet('/api/device/0x5000cca264ebc248/details')
.onGet('/api/device/00328b73-9f8a-53ad-8f20-8d0b1be00f47/details')
.reply(() => {
return [
200,
_.cloneDeep(sde)
];
});
this._treoMockApiService
.onGet('/api/device/e5ccc378-24fc-5a9d-b1ce-8732096a9ea5/details')
.reply(() => {
return [
@@ -5,6 +5,7 @@ export const sda = {
'UpdatedAt': '2021-10-24T16:37:56.981833-07:00',
'DeletedAt': null,
'wwn': '0x5002538e40a22954',
'scrutiny_uuid': 'ecfaaf20-d1f6-558b-b33a-3e8db19a6c2c',
'device_name': 'sda',
'manufacturer': 'ATA',
'model_name': 'Samsung_SSD_860_EVO_500GB',
@@ -26,6 +27,7 @@ export const sda = {
'smart_results': [{
'date': '2021-10-24T23:20:44Z',
'device_wwn': '0x5002538e40a22954',
'scrutiny_uuid': 'ecfaaf20-d1f6-558b-b33a-3e8db19a6c2c',
'device_protocol': 'NVMe',
'temp': 36,
'power_on_hours': 2401,
@@ -5,12 +5,13 @@ export const sdb = {
'UpdatedAt': '2021-10-24T17:06:39.436996-07:00',
'DeletedAt': null,
'wwn': '0x5000cca264eb01d7',
'scrutiny_uuid': '3ea22b35-682b-49fb-a655-abffed108e48',
'device_name': 'sdb',
'manufacturer': 'ATA',
'model_name': 'WDC_WD140EDFZ-11A0VA0',
'interface_type': 'SCSI',
'interface_speed': '',
'serial_number': '9RK1XXXXX',
'serial_number': '9RK1XXXX',
'firmware': '81.00A81',
'rotational_speed': 0,
'capacity': 14000519643136,
@@ -25,6 +26,7 @@ export const sdb = {
'smart_results': [{
'date': '2021-10-24T20:34:04Z',
'device_wwn': '0x5000cca264eb01d7',
'scrutiny_uuid': '3ea22b35-682b-49fb-a655-abffed108e48',
'device_protocol': 'ATA',
'temp': 32,
'power_on_hours': 1730,
@@ -245,6 +247,7 @@ export const sdb = {
}, {
'date': '2021-10-24T23:20:44Z',
'device_wwn': '0x5000cca264eb01d7',
'scrutiny_uuid': '3ea22b35-682b-49fb-a655-abffed108e48',
'device_protocol': 'ATA',
'temp': 32,
'power_on_hours': 1730,
@@ -5,6 +5,7 @@ export const sdc = {
'UpdatedAt': '2021-10-24T16:37:56.74865-07:00',
'DeletedAt': null,
'wwn': '0x5000cca264ec3183',
'scrutiny_uuid': '42caca8a-9b95-5c75-b059-305771a2a193',
'device_name': 'sdc',
'manufacturer': 'ATA',
'model_name': 'WDC_WD140EDFZ-11A0VA0',
@@ -25,6 +26,7 @@ export const sdc = {
'smart_results': [{
'date': '2021-10-24T23:20:44Z',
'device_wwn': '0x5000cca264ec3183',
'scrutiny_uuid': '42caca8a-9b95-5c75-b059-305771a2a193',
'device_protocol': 'ATA',
'temp': 25,
'power_on_hours': 65592,
@@ -5,6 +5,7 @@ export const sdd = {
'UpdatedAt': '2021-10-24T16:37:57.013758-07:00',
'DeletedAt': null,
'wwn': '0x5000cca252c859cc',
'scrutiny_uuid': 'd8796fe7-2422-520c-8991-e970993dad3e',
'device_name': 'sdd',
'manufacturer': 'ATA',
'model_name': 'WDC_WD80EFAX-68LHPN0',
@@ -25,6 +26,7 @@ export const sdd = {
'smart_results': [{
'date': '2021-10-24T23:20:44Z',
'device_wwn': '0x5000cca252c859cc',
'scrutiny_uuid': 'd8796fe7-2422-520c-8991-e970993dad3e',
'device_protocol': 'SCSI',
'temp': 34,
'power_on_hours': 43549,
@@ -5,6 +5,7 @@ export const sde = {
'UpdatedAt': '2021-10-24T16:40:16.495248-07:00',
'DeletedAt': null,
'wwn': '0x5000cca264ebc248',
'scrutiny_uuid': '00328b73-9f8a-53ad-8f20-8d0b1be00f47',
'device_name': 'sde',
'manufacturer': 'ATA',
'model_name': 'WDC_WD140EDFZ-11A0VA0',
@@ -25,6 +26,7 @@ export const sde = {
'smart_results': [{
'date': '2021-10-24T23:20:44Z',
'device_wwn': '0x5000cca264ebc248',
'scrutiny_uuid': '00328b73-9f8a-53ad-8f20-8d0b1be00f47',
'device_protocol': 'SCSI',
'temp': 31,
'power_on_hours': 5675,
@@ -5,6 +5,7 @@ export const sdf = {
'UpdatedAt': '2021-06-24T21:17:31.305246-07:00',
'DeletedAt': null,
'wwn': '0x50014ee20b2a72a9',
'scrutiny_uuid': 'e5ccc378-24fc-5a9d-b1ce-8732096a9ea5',
'device_name': 'sdf',
'manufacturer': 'ATA',
'model_name': 'WDC_WD60EFRX-68MYMN1',
@@ -4,12 +4,13 @@ import * as moment from 'moment';
export const summary = {
'data': {
'summary': {
'0x5000c500673e6b5f': {
'acfbce7d-0e19-579b-895e-85809dab63fb': {
'device': {
'CreatedAt': '2021-04-30T08:17:13.155217-07:00',
'UpdatedAt': '2021-04-30T08:17:13.155217-07:00',
'DeletedAt': null,
'wwn': '0x5000c500673e6b5f',
'scrutiny_uuid': 'acfbce7d-0e19-579b-895e-85809dab63fb',
'device_name': 'sdg',
'device_label': '14TB-WD-DRIVE2',
'device_uuid': '',
@@ -32,12 +33,13 @@ export const summary = {
'archived': false
}
},
'0x5000cca252c859cc': {
'd8796fe7-2422-520c-8991-e970993dad3e': {
'device': {
'CreatedAt': '2021-04-30T08:17:13.152705-07:00',
'UpdatedAt': '2021-05-02T14:22:50.357164-07:00',
'DeletedAt': null,
'wwn': '0x5000cca252c859cc',
'scrutiny_uuid': 'd8796fe7-2422-520c-8991-e970993dad3e',
'device_name': 'sdd',
'device_label': '14TB-WD-DRIVE1',
'device_uuid': '806cf4bc-d160-4d96-8ee9-3ab7cf2a2e1f',
@@ -69,21 +71,22 @@ export const summary = {
'temp': 34
}]
},
'0x5000cca264eb01d7': {
'3ea22b35-682b-49fb-a655-abffed108e48': {
'device': {
'CreatedAt': '2021-04-28T20:52:49.047154-07:00',
'UpdatedAt': '2021-05-02T14:22:49.86136-07:00',
'DeletedAt': null,
'wwn': '0x5000cca264eb01d7',
'scrutiny_uuid': '3ea22b35-682b-49fb-a655-abffed108e48',
'device_name': 'sdb',
'device_label': '14TB-WD-DRIVE5',
'device_uuid': '8125ec6d-a7e4-4950-ac84-72d6a4d67128',
'device_serial_id': 'ata-WDC_WD140EDFZ-11A0VA0-9RK1XXXXX',
'device_serial_id': 'ata-WDC_WD140EDFZ-11A0VA0-9RK1XXXX',
'manufacturer': 'ATA',
'model_name': 'WDC_WD140EDFZ-11A0VA0',
'interface_type': 'SCSI',
'interface_speed': '',
'serial_number': '9RK1XXXXX',
'serial_number': '9RK1XXXX',
'firmware': '81.00A81',
'rotational_speed': 0,
'capacity': 14000519643136,
@@ -106,12 +109,13 @@ export const summary = {
'temp': 32
}]
},
'0x5000cca264ebc248': {
'00328b73-9f8a-53ad-8f20-8d0b1be00f47': {
'device': {
'CreatedAt': '2021-04-30T08:17:13.153782-07:00',
'UpdatedAt': '2021-05-02T14:22:50.385282-07:00',
'DeletedAt': null,
'wwn': '0x5000cca264ebc248',
'scrutiny_uuid': '00328b73-9f8a-53ad-8f20-8d0b1be00f47',
'device_name': 'sde',
'device_label': '14TB-WD-DRIVE3',
'device_uuid': '9eb60cde-d6d0-4172-b520-b241a6a5477f',
@@ -134,12 +138,13 @@ export const summary = {
'archived': false
}
},
'0x5000cca264ec3183': {
'42caca8a-9b95-5c75-b059-305771a2a193': {
'device': {
'CreatedAt': '2021-04-30T08:17:13.151906-07:00',
'UpdatedAt': '2021-05-02T14:49:51.645012-07:00',
'DeletedAt': null,
'wwn': '0x5000cca264ec3183',
'scrutiny_uuid': '42caca8a-9b95-5c75-b059-305771a2a193',
'device_name': 'sdc',
'device_label': '14TB-WD-DRIVE6',
'device_uuid': 'e1378723-7861-49b9-8e01-0bd063f0ecdd',
@@ -555,12 +560,13 @@ export const summary = {
'temp': 39
}]
},
'0x50014ee20b2a72a9': {
'e5ccc378-24fc-5a9d-b1ce-8732096a9ea5': {
'device': {
'CreatedAt': '2021-04-30T08:17:13.15451-07:00',
'UpdatedAt': '2021-04-30T08:17:13.15451-07:00',
'DeletedAt': null,
'wwn': '0x50014ee20b2a72a9',
'scrutiny_uuid': 'e5ccc378-24fc-5a9d-b1ce-8732096a9ea5',
'device_name': 'sdf',
'device_label': '8.0TB-WD-4',
'device_uuid': 'fc684dcc-aa2f-44f3-a958-d302dc7dd46d',
@@ -583,12 +589,13 @@ export const summary = {
'archived': false
}
},
'0x5002538e40a22954': {
'ecfaaf20-d1f6-558b-b33a-3e8db19a6c2c': {
'device': {
'CreatedAt': '2021-04-30T08:17:13.150792-07:00',
'UpdatedAt': '2021-05-02T14:22:50.330706-07:00',
'DeletedAt': null,
'wwn': '0x5002538e40a22954',
'scrutiny_uuid': 'ecfaaf20-d1f6-558b-b33a-3e8db19a6c2c',
'device_name': 'sda',
'device_label': '',
'device_uuid': '',
@@ -28,7 +28,7 @@ describe('DashboardDeviceArchiveDialogComponent', () => {
],
providers: [
{provide: MatDialogRef, useValue: matDialogRefSpy},
{provide: MAT_DIALOG_DATA, useValue: {wwn: 'test-wwn', title: 'my-test-device-title'}},
{provide: MAT_DIALOG_DATA, useValue: {scrutiny_uuid: 'ecfaaf20-d1f6-558b-b33a-3e8db19a6c2c', title: 'my-test-device-title'}},
{provide: DashboardDeviceArchiveDialogService, useValue: dashboardDeviceArchiveDialogServiceSpy}
],
declarations: [DashboardDeviceArchiveDialogComponent]
@@ -56,7 +56,7 @@ describe('DashboardDeviceArchiveDialogComponent', () => {
dashboardDeviceArchiveDialogServiceSpy.archiveDevice.and.returnValue(of({'success': true}));
component.onArchiveClick()
expect(dashboardDeviceArchiveDialogServiceSpy.archiveDevice).toHaveBeenCalledWith('test-wwn');
expect(dashboardDeviceArchiveDialogServiceSpy.archiveDevice).toHaveBeenCalledWith('ecfaaf20-d1f6-558b-b33a-3e8db19a6c2c');
expect(dashboardDeviceArchiveDialogServiceSpy.archiveDevice.calls.count())
.withContext('one call')
.toBe(1);
@@ -11,7 +11,7 @@ export class DashboardDeviceArchiveDialogComponent implements OnInit {
constructor(
public dialogRef: MatDialogRef<DashboardDeviceArchiveDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: {wwn: string, title: string},
@Inject(MAT_DIALOG_DATA) public data: {scrutiny_uuid: string, title: string},
private _archiveService: DashboardDeviceArchiveDialogService,
) {
}
@@ -20,7 +20,7 @@ export class DashboardDeviceArchiveDialogComponent implements OnInit {
}
onArchiveClick(): void {
this._archiveService.archiveDevice(this.data.wwn)
this._archiveService.archiveDevice(this.data.scrutiny_uuid)
.subscribe((data) => {
this.dialogRef.close(data);
});
@@ -26,13 +26,13 @@ export class DashboardDeviceArchiveDialogService
// -----------------------------------------------------------------------------------------------------
archiveDevice(wwn: string): Observable<any>
archiveDevice(scrutiny_uid: string): Observable<any>
{
return this._httpClient.post( `${getBasePath()}/api/device/${wwn}/archive`, {});
return this._httpClient.post( `${getBasePath()}/api/device/${scrutiny_uid}/archive`, {});
}
unarchiveDevice(wwn: string): Observable<any>
unarchiveDevice(scrutiny_uid: string): Observable<any>
{
return this._httpClient.post( `${getBasePath()}/api/device/${wwn}/unarchive`, {});
return this._httpClient.post( `${getBasePath()}/api/device/${scrutiny_uid}/unarchive`, {});
}
}
@@ -28,7 +28,7 @@ describe('DashboardDeviceDeleteDialogComponent', () => {
],
providers: [
{provide: MatDialogRef, useValue: matDialogRefSpy},
{provide: MAT_DIALOG_DATA, useValue: {wwn: 'test-wwn', title: 'my-test-device-title'}},
{provide: MAT_DIALOG_DATA, useValue: {scrutiny_uuid: 'ecfaaf20-d1f6-558b-b33a-3e8db19a6c2c', title: 'my-test-device-title'}},
{provide: DashboardDeviceDeleteDialogService, useValue: dashboardDeviceDeleteDialogServiceSpy}
],
declarations: [DashboardDeviceDeleteDialogComponent]
@@ -56,7 +56,7 @@ describe('DashboardDeviceDeleteDialogComponent', () => {
dashboardDeviceDeleteDialogServiceSpy.deleteDevice.and.returnValue(of({'success': true}));
component.onDeleteClick()
expect(dashboardDeviceDeleteDialogServiceSpy.deleteDevice).toHaveBeenCalledWith('test-wwn');
expect(dashboardDeviceDeleteDialogServiceSpy.deleteDevice).toHaveBeenCalledWith('ecfaaf20-d1f6-558b-b33a-3e8db19a6c2c');
expect(dashboardDeviceDeleteDialogServiceSpy.deleteDevice.calls.count())
.withContext('one call')
.toBe(1);
@@ -11,7 +11,7 @@ export class DashboardDeviceDeleteDialogComponent implements OnInit {
constructor(
public dialogRef: MatDialogRef<DashboardDeviceDeleteDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: {wwn: string, title: string},
@Inject(MAT_DIALOG_DATA) public data: {scrutiny_uuid: string, title: string},
private _deleteService: DashboardDeviceDeleteDialogService,
) {
}
@@ -20,7 +20,7 @@ export class DashboardDeviceDeleteDialogComponent implements OnInit {
}
onDeleteClick(): void {
this._deleteService.deleteDevice(this.data.wwn)
this._deleteService.deleteDevice(this.data.scrutiny_uuid)
.subscribe((data) => {
this.dialogRef.close(data);
});
@@ -27,8 +27,8 @@ export class DashboardDeviceDeleteDialogService
// -----------------------------------------------------------------------------------------------------
deleteDevice(wwn: string): Observable<any>
deleteDevice(scrutiny_uuid: string): Observable<any>
{
return this._httpClient.delete( `${getBasePath()}/api/device/${wwn}`, {});
return this._httpClient.delete( `${getBasePath()}/api/device/${scrutiny_uuid}`, {});
}
}
@@ -16,7 +16,7 @@
</div>
<div class="flex items-center">
<div class="flex flex-col">
<a [routerLink]="'/device/'+ deviceSummary.device.wwn"
<a [routerLink]="'/device/'+ deviceSummary.device.scrutiny_uuid"
class="font-bold text-md text-secondary uppercase tracking-wider">{{deviceSummary.device | deviceTitle:config.dashboard_display}}</a>
<div [ngClass]="classDeviceLastUpdatedOn(deviceSummary)" class="font-medium text-sm" *ngIf="deviceSummary.smart">
Last Updated on {{deviceSummary.smart.collector_date | date:'MMMM dd, yyyy - HH:mm' }}
@@ -30,7 +30,7 @@
<mat-icon [svgIcon]="'more_vert'"></mat-icon>
</button>
<mat-menu #previousStatementMenu="matMenu">
<a mat-menu-item [routerLink]="'/device/'+ deviceSummary.device.wwn">
<a mat-menu-item [routerLink]="'/device/'+ deviceSummary.device.scrutiny_uuid">
<span class="flex items-center">
<mat-icon class="icon-size-20 mr-3"
[svgIcon]="'assessment'"></mat-icon>
@@ -75,22 +75,22 @@ export class DashboardDeviceComponent implements OnInit {
openArchiveDialog(): void {
if(this.deviceSummary.device.archived){
this._archiveService.unarchiveDevice(this.deviceSummary.device.wwn).subscribe((result) => {
this._archiveService.unarchiveDevice(this.deviceSummary.device.scrutiny_uuid).subscribe((result) => {
if(result) {
this.deviceUnarchived.emit(this.deviceSummary.device.wwn)
this.deviceUnarchived.emit(this.deviceSummary.device.scrutiny_uuid)
}
})
return;
}
const dialogRef = this.dialog.open(DashboardDeviceArchiveDialogComponent, {
data: {
wwn: this.deviceSummary.device.wwn,
scrutiny_uuid: this.deviceSummary.device.scrutiny_uuid,
title: DeviceTitlePipe.deviceTitleWithFallback(this.deviceSummary.device, this.config.dashboard_display)
}
});
dialogRef.afterClosed().subscribe(result => {
if(result) {
this.deviceArchived.emit(this.deviceSummary.device.wwn);
this.deviceArchived.emit(this.deviceSummary.device.scrutiny_uuid);
}
})
}
@@ -99,7 +99,7 @@ export class DashboardDeviceComponent implements OnInit {
const dialogRef = this.dialog.open(DashboardDeviceDeleteDialogComponent, {
// width: '250px',
data: {
wwn: this.deviceSummary.device.wwn,
scrutiny_uuid: this.deviceSummary.device.scrutiny_uuid,
title: DeviceTitlePipe.deviceTitleWithFallback(this.deviceSummary.device, this.config.dashboard_display)
}
});
@@ -107,7 +107,7 @@ export class DashboardDeviceComponent implements OnInit {
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed', result);
if (result.success) {
this.deviceDeleted.emit(this.deviceSummary.device.wwn)
this.deviceDeleted.emit(this.deviceSummary.device.scrutiny_uuid)
}
});
}
@@ -100,10 +100,10 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy
this.summaryData = data;
// generate group data.
for (const wwn in this.summaryData) {
const hostid = this.summaryData[wwn].device.host_id
for (const scrutiny_uuid in this.summaryData) {
const hostid = this.summaryData[scrutiny_uuid].device.host_id
const hostDeviceList = this.hostGroups[hostid] || []
hostDeviceList.push(wwn)
hostDeviceList.push(scrutiny_uuid)
this.hostGroups[hostid] = hostDeviceList
}
console.log(this.hostGroups)
@@ -145,8 +145,8 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy
console.log('DEVICE DATA SUMMARY', this.summaryData)
for (const wwn in this.summaryData) {
const deviceSummary = this.summaryData[wwn]
for (const scrutiny_uuid in this.summaryData) {
const deviceSummary = this.summaryData[scrutiny_uuid]
if (!deviceSummary.temp_history) {
continue
}
@@ -241,11 +241,11 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy
// @ Public methods
// -----------------------------------------------------------------------------------------------------
deviceSummariesForHostGroup(hostGroupWWNs: string[]): DeviceSummaryModel[] {
deviceSummariesForHostGroup(hostGroupScrutinyUUIDs: string[]): DeviceSummaryModel[] {
const deviceSummaries: DeviceSummaryModel[] = []
for (const wwn of hostGroupWWNs) {
if (this.summaryData[wwn]) {
deviceSummaries.push(this.summaryData[wwn])
for (const scrutiny_uuid of hostGroupScrutinyUUIDs) {
if (this.summaryData[scrutiny_uuid]) {
deviceSummaries.push(this.summaryData[scrutiny_uuid])
}
}
return deviceSummaries
@@ -259,16 +259,16 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy
});
}
onDeviceDeleted(wwn: string): void {
delete this.summaryData[wwn] // remove the device from the summary list.
onDeviceDeleted(scrutiny_uuid: string): void {
delete this.summaryData[scrutiny_uuid] // remove the device from the summary list.
}
onDeviceArchived(wwn: string): void {
this.summaryData[wwn].device.archived = true;
onDeviceArchived(scrutiny_uuid: string): void {
this.summaryData[scrutiny_uuid].device.archived = true;
}
onDeviceUnarchived(wwn: string): void {
this.summaryData[wwn].device.archived = false;
onDeviceUnarchived(scrutiny_uuid: string): void {
this.summaryData[scrutiny_uuid].device.archived = false;
}
/*
@@ -286,9 +286,9 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy
.subscribe((tempHistoryData) => {
// given a list of device temp history, override the data in the "summary" object.
for (const wwn in this.summaryData) {
// console.log(`Updating ${wwn}, length: ${this.data.data.summary[wwn].temp_history.length}`)
this.summaryData[wwn].temp_history = tempHistoryData[wwn] || []
for (const scrutiny_uuid in this.summaryData) {
// console.log(`Updating ${scrutiny_uuid}, length: ${this.data.data.summary[scrutiny_uuid].temp_history.length}`)
this.summaryData[scrutiny_uuid].temp_history = tempHistoryData[scrutiny_uuid] || []
}
// Prepare the chart series data
@@ -98,6 +98,10 @@
<div>{{device?.serial_number}}</div>
<div class="text-secondary text-md">Serial Number</div>
</div>
<div class="my-2 col-span-2 lt-md:col-span-1">
<div>{{device?.scrutiny_uuid}}</div>
<div class="text-secondary text-md">Scrutiny UUID</div>
</div>
<div class="my-2 col-span-2 lt-md:col-span-1">
<div>{{device?.wwn}}</div>
<div class="text-secondary text-md">LU WWN Device Id</div>
@@ -30,6 +30,6 @@ export class DetailResolver implements Resolve<any> {
* @param state
*/
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<DeviceDetailsResponseWrapper> {
return this._detailService.getData(route.params.wwn);
return this._detailService.getData(route.params.scrutiny_uuid);
}
}
@@ -42,8 +42,8 @@ export class DetailService {
/**
* Get data
*/
getData(wwn): Observable<DeviceDetailsResponseWrapper> {
return this._httpClient.get(getBasePath() + `/api/device/${wwn}/details`).pipe(
getData(scrutiny_uuid): Observable<DeviceDetailsResponseWrapper> {
return this._httpClient.get(getBasePath() + `/api/device/${scrutiny_uuid}/details`).pipe(
tap((response: DeviceDetailsResponseWrapper) => {
this._data.next(response);
})
@@ -37,7 +37,7 @@ export class DeviceTitlePipe implements PipeTransform {
}
static deviceTitleWithFallback(device: DeviceModel, titleType: string): string {
console.log(`Displaying Device ${device.wwn} with: ${titleType}`)
console.log(`Displaying Device ${device.scrutiny_uuid} with: ${titleType}`)
const titleParts = []
if (device.host_id) titleParts.push(device.host_id)