< div class = "flex flex-col flex-auto w-full p-8 xs:p-2" >
< div class = "flex flex-wrap w-full" >
< div class = "flex items-center justify-between w-full my-4 px-4 xs:pr-0" >
< div class = "mr-6" >
< h2 class = "m-0" > Drive Details - {{device | deviceTitle:config.dashboardDisplay}} < / h2 >
< div class = "text-secondary tracking-tight" > Dive into S.M.A.R.T data< / div >
< / div >
<!-- Action buttons -->
< div class = "flex items-center" >
< button class = "xs:hidden"
matTooltip="not yet implemented"
mat-stroked-button>
< mat-icon class = "icon-size-20"
[svgIcon]="'save'">< / mat-icon >
< span class = "ml-2" > Export< / span >
< / button >
< button class = "ml-2 xs:hidden"
(click)="openDialog()"
mat-stroked-button>
< mat-icon class = "icon-size-20 rotate-90 mirror"
[svgIcon]="'tune'">< / mat-icon >
< span class = "ml-2" > Settings< / span >
< / button >
<!-- Actions menu (visible on xs) -->
< div class = "hidden xs:flex" >
< button [ matMenuTriggerFor ] = " actionsMenu "
mat-icon-button>
< mat-icon [ svgIcon ] = " ' more_vert ' " > < / mat-icon >
< / button >
< mat-menu # actionsMenu = "matMenu" >
< button mat-menu-item
matTooltip="not yet implemented">
< mat-icon class = "icon-size-20"
[svgIcon]="'save'">< / mat-icon >
< span class = "ml-2" > Export< / span >
< / button >
< button mat-menu-item
(click)="openDialog()">
< mat-icon class = "icon-size-20 rotate-90 mirror"
[svgIcon]="'tune'">< / mat-icon >
< span class = "ml-2" > Settings< / span >
< / button >
< / mat-menu >
< / div >
< / div >
< / div >
<!-- Card -->
< div class = "flex flex-auto w-1/4 p-4 lt-md:w-full" >
< treo-card class = "flex flex-auto p-4 flex-col flex-auto filter-list" >
< div class = "flex flex-col grid grid-cols-2" >
< div * ngIf = "device" class = "my-2 col-span-2 lt-md:col-span-1" >
< div >
< span class = "inline-flex items-center font-bold text-xs px-2 py-2px rounded-full tracking-wide uppercase"
[ngClass]="{'red-200': device?.device_status != 0,
'green-200': device?.device_status == 0}">
< span class = "w-2 h-2 rounded-full mr-2"
[ngClass]="{'bg-red': device?.device_status != 0,
'bg-green': device?.device_status == 0}">< / span >
< span class = "pr-2px leading-relaxed whitespace-no-wrap" > {{device?.device_status | deviceStatus}}< / span >
< / span >
< / div >
< div class = "text-secondary text-md" > Status< / div >
< / div >
< div * ngIf = "device?.host_id" class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{device?.host_id}}< / div >
< div class = "text-secondary text-md" > Host ID< / div >
< / div >
< div * ngIf = "device?.device_uuid" class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{device?.device_uuid}}< / div >
< div class = "text-secondary text-md" > Device UUID< / div >
< / div >
< div * ngIf = "device?.device_label" class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{device?.device_label}}< / div >
< div class = "text-secondary text-md" > Device Label< / div >
< / div >
< div * ngIf = "device?.device_type && device?.device_type != 'ata' && device?.device_type != 'scsi'" class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{device?.device_type | uppercase}}< / div >
< div class = "text-secondary text-md" > Device Type< / div >
< / div >
< div * ngIf = "device?.manufacturer" class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{device?.manufacturer}}< / div >
< div class = "text-secondary text-md" > Model Family< / div >
< / div >
< div class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{device?.model_name}}< / div >
< div class = "text-secondary text-md" > Device Model< / div >
< / div >
< div class = "my-2 col-span-2 lt-md:col-span-1" >
< 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?.wwn}}< / div >
< div class = "text-secondary text-md" > LU WWN Device Id< / div >
< / div >
< div class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{device?.firmware}}< / div >
< div class = "text-secondary text-md" > Firmware Version< / div >
< / div >
< div class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{device?.capacity | fileSize}}< / div >
< div class = "text-secondary text-md" > Capacity< / div >
< / div >
< div * ngIf = "device?.rotational_speed" class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{device?.rotational_speed}} RPM< / div >
< div class = "text-secondary text-md" > Rotation Rate< / div >
< / div >
< div * ngIf = "device?.device_protocol" class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{device?.device_protocol}}< / div >
< div class = "text-secondary text-md" > Protocol< / div >
< / div >
< div class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{smart_results[0]?.power_cycle_count}}< / div >
< div class = "text-secondary text-md" > Power Cycle Count< / div >
< / div >
< div * ngIf = "smart_results[0]?.power_on_hours" class = "my-2 col-span-2 lt-md:col-span-1" >
< div matTooltip = "{{humanizeDuration(smart_results[0]?.power_on_hours * 60 * 60 * 1000, { conjunction: ' and ', serialComma: false })}}" > {{humanizeDuration(smart_results[0]?.power_on_hours *60 * 60 * 1000, { round: true, largest: 1, units: ['y', 'd', 'h'] })}}< / div >
< div class = "text-secondary text-md" > Powered On< / div >
< / div >
< div class = "my-2 col-span-2 lt-md:col-span-1" >
< div > {{smart_results[0]?.temp | temperature:config.temperatureUnit:true}}< / div >
< div class = "text-secondary text-md" > Temperature< / div >
< / div >
< / div >
< / treo-card >
< / div >
<!-- S.M.A.R.T. Data table -->
< div class = "flex flex-auto w-3/4 p-4 lt-md:w-full" >
< div class = "flex flex-col flex-auto w-full bg-card shadow-md rounded " >
< div class = "p-6" >
< div class = "font-bold text-md text-secondary uppercase tracking-wider" > S.M.A.R.T {{device?.device_protocol}} Attributes< / div >
< div class = "text-sm text-hint font-medium" > {{this.smartAttributeDataSource.data.length}} visible, {{getHiddenAttributes()}} hidden< / div >
< / div >
< div class = "overflow-auto" >
< table class = "w-full bg-transparent"
mat-table
matSort
multiTemplateDataRows
[dataSource]="smartAttributeDataSource"
[trackBy]="trackByFn"
#smartAttributeTable>
<!-- Status -->
< ng-container matColumnDef = "status" >
< th class = "bg-cool-gray-50 dark:bg-cool-gray-700 border-t"
mat-header-cell
mat-sort-header
*matHeaderCellDef>
< span class = "whitespace-no-wrap" >
Status
< / span >
< / th >
< td mat-cell
*matCellDef="let attribute">
< span class = "inline-flex items-center font-bold text-xs px-2 py-2px rounded-full tracking-wide uppercase"
[ngClass]="{'red-200': getAttributeStatusName(attribute.status) === 'failed',
'green-200': getAttributeStatusName(attribute.status) === 'passed',
'yellow-200': getAttributeStatusName(attribute.status) === 'warn'
}">
< span class = "w-2 h-2 rounded-full mr-2"
[ngClass]="{'bg-red': getAttributeStatusName(attribute.status) === 'failed',
'bg-green': getAttributeStatusName(attribute.status) === 'passed',
'bg-yellow': getAttributeStatusName(attribute.status) === 'warn'}">< / span >
< span class = "pr-2px leading-relaxed whitespace-no-wrap" matTooltip = "{{attribute.status_reason}}" > {{getAttributeStatusName(attribute.status)}}< / span >
< / span >
< / td >
< / ng-container >
<!-- ID -->
< ng-container matColumnDef = "id" >
< th class = "bg-cool-gray-50 dark:bg-cool-gray-700 border-t"
mat-header-cell
mat-sort-header
*matHeaderCellDef>
< span class = "whitespace-no-wrap" >
ID
< / span >
< / th >
< td mat-cell
*matCellDef="let attribute">
< span class = "pr-6 font-medium text-sm text-secondary whitespace-no-wrap" >
{{attribute.attribute_id}} ({{toHex(attribute.attribute_id)}})
< / span >
< / td >
< / ng-container >
<!-- Name -->
< ng-container matColumnDef = "name" >
< th class = "bg-cool-gray-50 dark:bg-cool-gray-700 border-t"
mat-header-cell
mat-sort-header
*matHeaderCellDef>
< span class = "whitespace-no-wrap" >
Name
< / span >
< / th >
< td mat-cell
*matCellDef="let attribute">
< span class = "pr-6 whitespace-no-wrap" matTooltip = "click for more details." >
{{getAttributeName(attribute)}} < mat-icon * ngIf = "getAttributeDescription(attribute)" class = "icon-size-10" [ svgIcon ] = " ' info ' " > < / mat-icon >
< / span >
< / td >
< / ng-container >
<!-- Value -->
< ng-container matColumnDef = "value" >
< th class = "bg-cool-gray-50 dark:bg-cool-gray-700 border-t"
mat-header-cell
mat-sort-header
*matHeaderCellDef>
< span class = "whitespace-no-wrap" >
Value
< / span >
< / th >
< td mat-cell
*matCellDef="let attribute">
< span class = "pr-6 whitespace-no-wrap" matTooltip = "{{getAttributeValueType(attribute)}}" >
{{getAttributeValue(attribute)}}
< / span >
< / td >
< / ng-container >
<!-- Worst -->
< ng-container matColumnDef = "worst" >
< th class = "bg-cool-gray-50 dark:bg-cool-gray-700 border-t"
mat-header-cell
mat-sort-header
*matHeaderCellDef>
< span class = "whitespace-no-wrap" >
Worst
< / span >
< / th >
< td mat-cell
*matCellDef="let attribute">
< span class = "pr-6 whitespace-no-wrap" >
{{getAttributeWorst(attribute)}}
< / span >
< / td >
< / ng-container >
<!-- Threshold -->
< ng-container matColumnDef = "thresh" >
< th class = "bg-cool-gray-50 dark:bg-cool-gray-700 border-t"
mat-header-cell
mat-sort-header
*matHeaderCellDef>
< span class = "whitespace-no-wrap" >
Threshold
< / span >
< / th >
< td mat-cell
*matCellDef="let attribute">
< span class = "pr-6 whitespace-no-wrap" >
{{getAttributeThreshold(attribute)}}
< / span >
< / td >
< / ng-container >
<!-- Ideal -->
< ng-container matColumnDef = "ideal" >
< th class = "bg-cool-gray-50 dark:bg-cool-gray-700 border-t"
mat-header-cell
mat-sort-header
*matHeaderCellDef>
< span class = "whitespace-no-wrap" >
Ideal
< / span >
< / th >
< td mat-cell
*matCellDef="let attribute">
< span class = "pr-6 font-medium whitespace-no-wrap" >
{{getAttributeIdeal(attribute) }}
< / span >
< / td >
< / ng-container >
<!-- Observed Failure Rate -->
< ng-container matColumnDef = "failure" >
< th class = "bg-cool-gray-50 dark:bg-cool-gray-700 border-t"
mat-header-cell
mat-sort-header
*matHeaderCellDef>
< span class = "whitespace-no-wrap" matTooltip = "Failure rate is based on data provided by BackBlaze. The current attribute value is matched against the observed failure categories and an annual failure rate is determined." >
Failure Rate < mat-icon [ svgIcon ] = " ' info ' " > < / mat-icon >
< / span >
< / th >
< td mat-cell
*matCellDef="let attribute">
< span class = "pr-6 font-medium whitespace-no-wrap" >
{{attribute.failure_rate | percent}}
< / span >
< / td >
< / ng-container >
<!-- History -->
< ng-container matColumnDef = "history" >
< th class = "bg-cool-gray-50 dark:bg-cool-gray-700 border-t"
mat-header-cell
mat-sort-header
*matHeaderCellDef>
< span class = "whitespace-no-wrap" >
History
< / span >
< / th >
< td mat-cell
*matCellDef="let attribute">
< span class = "font-medium whitespace-no-wrap" >
< apx-chart
[series]="attribute.chartData"
[chart]="commonSparklineOptions.chart"
[tooltip]="commonSparklineOptions.tooltip"
[stroke]="commonSparklineOptions.stroke"
[annotations]="attribute.chartDataReferenceLine"
>< / apx-chart >
< / span >
< / td >
< / ng-container >
<!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
< ng-container matColumnDef = "expandedDetail" >
< td mat-cell * matCellDef = "let attribute" [ attr . colspan ] = " smartAttributeTableColumns . length " >
< div class = "attribute-detail"
[@detailExpand]="attribute == expandedAttribute ? 'expanded' : 'collapsed'">
< div class = "flex flex-auto w-1/3 min-w-80 py-4" >
< div class = "flex flex-col flex-auto justify-end text-md pb-3" >
{{getAttributeDescription(attribute)}}
< / div >
< / div >
< div class = "flex flex-auto w-2/3 min-w-80" >
< div class = "flex flex-col flex-auto justify-end text-md px-6 pb-3" >
< div class = "flex items-center justify-between py-3 border-b last:border-b-0 ng-star-inserted" >
< div class = "flex items-center w-1/4" > Type< / div >
< div class = "flex items-center w-1/4" > Value< / div >
< div class = "flex items-center w-1/4" > Worst/Thresh< / div >
< div class = "flex items-center w-1/4" > Failure %< / div >
< / div >
< div class = "flex items-center justify-between py-3 border-b last:border-b-0 ng-star-inserted" >
< div class = "flex items-center w-1/4" >
< div class = "flex-shrink-0 w-2 h-2 mr-3 rounded-full"
[ngClass]="{'bg-red': getAttributeScrutinyStatusName(attribute.status) === 'failed',
'bg-green': getAttributeScrutinyStatusName(attribute.status) === 'passed',
'bg-yellow': getAttributeScrutinyStatusName(attribute.status) === 'warn'}">< / div >
< div class = "truncate" > Scrutiny< / div >
< / div >
< div class = "w-1/4 items-center font-medium" > {{getAttributeValue(attribute)}}< / div >
< div class = "w-1/4 items-center text-secondary" > --< / div >
< div class = "w-1/4 items-center text-secondary" > {{(attribute.failure_rate | percent) || '--'}}< / div >
< / div >
< div class = "flex items-center justify-between py-3 border-b last:border-b-0 ng-star-inserted" >
< div class = "flex items-center w-1/4" >
< div class = "flex-shrink-0 w-2 h-2 mr-3 rounded-full"
[ngClass]="{'bg-red': getAttributeSmartStatusName(attribute.status) === 'failed',
'bg-green': getAttributeSmartStatusName(attribute.status) === 'passed'}"
>< / div >
< div class = "truncate" > Normalized< / div >
< / div >
< div class = "w-1/4 items-center font-medium" > {{attribute.value}}< / div >
< div class = "w-1/4 items-center text-secondary" > {{getAttributeWorst(attribute) || '--' }}/{{getAttributeThreshold(attribute)}}< / div >
< div class = "w-1/4 items-center text-secondary" > --< / div >
< / div >
< div class = "flex items-center justify-between py-3 border-b last:border-b-0 ng-star-inserted" >
< div class = "flex items-center w-1/4" >
< div class = "flex-shrink-0 w-2 h-2 mr-3 rounded-full" > < / div >
< div class = "truncate" > Raw< / div >
< / div >
< div class = "w-1/4 items-center font-medium" > {{attribute.raw_value}}< / div >
< div class = "w-1/4 items-center text-secondary" > --< / div >
< div class = "w-1/4 items-center text-secondary" > --< / div >
< / div >
< / div >
< / div >
< / div >
< / td >
< / ng-container >
<!-- Footer -->
< ng-container matColumnDef = "recentOrdersTableFooter" >
< td class = "px-3 border-none"
mat-footer-cell
*matFooterCellDef
colspan="6">
< button mat-button
(click)="toggleOnlyCritical()"
[color]="'primary'">
< span * ngIf = "onlyCritical" > Show all attributes< / span >
< span * ngIf = "!onlyCritical" > Show critical attributes< / span >
< / button >
< / td >
< / ng-container >
< tr mat-header-row
*matHeaderRowDef="smartAttributeTableColumns">< / tr >
< tr class = "attribute-row h-16"
mat-row
[ngClass]="{'yellow-50': getAttributeCritical(row)}"
[class.attribute-expanded-row]="expandedAttribute === row"
(click)="expandedAttribute = expandedAttribute === row ? null : row"
*matRowDef="let row; columns: smartAttributeTableColumns;">< / tr >
< tr mat-row * matRowDef = "let row; columns: ['expandedDetail']" class = "attribute-detail-row" > < / tr >
< tr class = "h-16"
mat-footer-row
*matFooterRowDef="['recentOrdersTableFooter']">< / tr >
< / table >
< / div >
< / div >
< / div >
< / div >
< / div >