adding device protocl and type to the. Adding class for parsing smartctl --scan json output, for device detection. added an example/test file for smartctl -x -j added a placeholder settings panel. moved dashboard & details compoonent out of "Admin" directory.
This commit is contained in:
@@ -23,6 +23,18 @@ type BaseCollector struct {
|
|||||||
|
|
||||||
func (c *BaseCollector) DetectStorageDevices() ([]models.Device, error) {
|
func (c *BaseCollector) DetectStorageDevices() ([]models.Device, error) {
|
||||||
|
|
||||||
|
//availableDisksJson, err := c.ExecCmd("smartctl", []string{"-j", "--scan"}, "", os.Environ())
|
||||||
|
//if err != nil {
|
||||||
|
// c.logger.Errorf("Error getting block storage info: %v", err)
|
||||||
|
// return nil, err
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//var smartctlScan models.Scan
|
||||||
|
//err = json.Unmarshal([]byte(availableDisksJson), &smartctlScan)
|
||||||
|
//if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
//}
|
||||||
|
|
||||||
block, err := ghw.Block()
|
block, err := ghw.Block()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Errorf("Error getting block storage info: %v", err)
|
c.logger.Errorf("Error getting block storage info: %v", err)
|
||||||
@@ -83,7 +95,6 @@ func (c *BaseCollector) DetectStorageDevices() ([]models.Device, error) {
|
|||||||
|
|
||||||
approvedDisks = append(approvedDisks, diskModel)
|
approvedDisks = append(approvedDisks, diskModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
return approvedDisks, nil
|
return approvedDisks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ type Device struct {
|
|||||||
Capacity int64 `json:"capacity"`
|
Capacity int64 `json:"capacity"`
|
||||||
FormFactor string `json:"form_factor"`
|
FormFactor string `json:"form_factor"`
|
||||||
SmartSupport bool `json:"smart_support"`
|
SmartSupport bool `json:"smart_support"`
|
||||||
|
DeviceProtocol string `json:"device_protocol"` //protocol determines which smart attribute types are available (ATA, NVMe, SCSI)
|
||||||
|
DeviceType string `json:"device_type"` //device type is used for querying with -d/t flag, should only be used by collector.
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeviceWrapper struct {
|
type DeviceWrapper struct {
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
type Scan struct {
|
||||||
|
JSONFormatVersion []int `json:"json_format_version"`
|
||||||
|
Smartctl struct {
|
||||||
|
Version []int `json:"version"`
|
||||||
|
SvnRevision string `json:"svn_revision"`
|
||||||
|
PlatformInfo string `json:"platform_info"`
|
||||||
|
BuildInfo string `json:"build_info"`
|
||||||
|
Argv []string `json:"argv"`
|
||||||
|
ExitStatus int `json:"exit_status"`
|
||||||
|
} `json:"smartctl"`
|
||||||
|
Devices []struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
InfoName string `json:"info_name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
} `json:"devices"`
|
||||||
|
}
|
||||||
+15
-1
@@ -34,7 +34,6 @@ disks:
|
|||||||
# - /dev/sdb
|
# - /dev/sdb
|
||||||
|
|
||||||
notify:
|
notify:
|
||||||
level: 'warn' # 'warn' or 'error'
|
|
||||||
urls:
|
urls:
|
||||||
- "discord://token@channel"
|
- "discord://token@channel"
|
||||||
- "telegram://token@telegram?channels=channel-1[,channel-2,...]"
|
- "telegram://token@telegram?channels=channel-1[,channel-2,...]"
|
||||||
@@ -52,6 +51,21 @@ notify:
|
|||||||
- "script:///file/path/on/disk"
|
- "script:///file/path/on/disk"
|
||||||
- "https://www.example.com/path"
|
- "https://www.example.com/path"
|
||||||
|
|
||||||
|
limits:
|
||||||
|
ata:
|
||||||
|
critical:
|
||||||
|
error: 10
|
||||||
|
standard:
|
||||||
|
error: 20
|
||||||
|
warn: 10
|
||||||
|
scsi:
|
||||||
|
critical: true
|
||||||
|
standard: true
|
||||||
|
nvme:
|
||||||
|
critical: true
|
||||||
|
standard: true
|
||||||
|
|
||||||
|
|
||||||
collect:
|
collect:
|
||||||
metric:
|
metric:
|
||||||
enable: true
|
enable: true
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ type Device struct {
|
|||||||
Capacity int64 `json:"capacity"`
|
Capacity int64 `json:"capacity"`
|
||||||
FormFactor string `json:"form_factor"`
|
FormFactor string `json:"form_factor"`
|
||||||
SmartSupport bool `json:"smart_support"`
|
SmartSupport bool `json:"smart_support"`
|
||||||
DeviceProtocol string `json:"device_protocol"`
|
DeviceProtocol string `json:"device_protocol"` //protocol determines which smart attribute types are available (ATA, NVMe, SCSI)
|
||||||
DeviceType string `json:"device_type"` //device type is used for querying with -d/t flag
|
DeviceType string `json:"device_type"` //device type is used for querying with -d/t flag, should only be used by collector.
|
||||||
SmartResults []Smart `gorm:"foreignkey:DeviceWWN" json:"smart_results"`
|
SmartResults []Smart `gorm:"foreignkey:DeviceWWN" json:"smart_results"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1708
File diff suppressed because it is too large
Load Diff
@@ -26,8 +26,8 @@ export const appRoutes: Route[] = [
|
|||||||
children : [
|
children : [
|
||||||
|
|
||||||
// Example
|
// Example
|
||||||
{path: 'dashboard', loadChildren: () => import('app/modules/admin/dashboard/dashboard.module').then(m => m.DashboardModule)},
|
{path: 'dashboard', loadChildren: () => import('app/modules/dashboard/dashboard.module').then(m => m.DashboardModule)},
|
||||||
{path: 'device/:wwn', loadChildren: () => import('app/modules/admin/detail/detail.module').then(m => m.DetailModule)}
|
{path: 'device/:wwn', loadChildren: () => import('app/modules/detail/detail.module').then(m => m.DetailModule)}
|
||||||
|
|
||||||
// 404 & Catch all
|
// 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)},
|
// {path: '404-not-found', pathMatch: 'full', loadChildren: () => import('app/modules/admin/pages/errors/error-404/error-404.module').then(m => m.Error404Module)},
|
||||||
|
|||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
<h2 mat-dialog-title>Scrutiny Settings</h2>
|
||||||
|
<mat-dialog-content class="mat-typography">
|
||||||
|
|
||||||
|
<form class="flex flex-col p-8 pb-0 overflow-hidden">
|
||||||
|
<div class="flex flex-col gt-xs:flex-row">
|
||||||
|
<mat-form-field class="flex-auto gt-xs:pr-3">
|
||||||
|
<mat-label>Sort By</mat-label>
|
||||||
|
<mat-select>
|
||||||
|
<mat-option value="option1">Status</mat-option>
|
||||||
|
<mat-option value="option2" disabled>Name</mat-option>
|
||||||
|
<mat-option value="option3" disabled>Label</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
<mat-tab-group mat-align-tabs="start">
|
||||||
|
<mat-tab label="Ata">
|
||||||
|
|
||||||
|
<div class="flex flex-col mt-5 gt-md:flex-row">
|
||||||
|
<mat-form-field class="flex-auto gt-md:pr-3">
|
||||||
|
<mat-label>Critical Error Threshold</mat-label>
|
||||||
|
<input matInput>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="flex-auto gt-md:pl-3">
|
||||||
|
<mat-label>Critical Warning Threshold</mat-label>
|
||||||
|
<input matInput>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gt-md:flex-row">
|
||||||
|
<mat-form-field class="flex-auto gt-md:pr-3">
|
||||||
|
<mat-label>Error Threshold</mat-label>
|
||||||
|
<input matInput>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="flex-auto gt-md:pl-3">
|
||||||
|
<mat-label>Warning Threshold</mat-label>
|
||||||
|
<input matInput>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</mat-tab>
|
||||||
|
<mat-tab label="NVMe">
|
||||||
|
|
||||||
|
<div class="flex flex-col mt-5 gt-md:flex-row">
|
||||||
|
<mat-form-field class="flex-auto gt-md:pr-3">
|
||||||
|
<mat-label>Critical Error Threshold</mat-label>
|
||||||
|
<input matInput>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="flex-auto gt-md:pl-3">
|
||||||
|
<mat-label>Critical Warning Threshold</mat-label>
|
||||||
|
<input matInput>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</mat-tab>
|
||||||
|
<mat-tab label="SCSI">
|
||||||
|
<div class="flex flex-col mt-5 gt-md:flex-row">
|
||||||
|
<mat-form-field class="flex-auto gt-md:pr-3">
|
||||||
|
<mat-label>Critical Error Threshold</mat-label>
|
||||||
|
<input matInput>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="flex-auto gt-md:pl-3">
|
||||||
|
<mat-label>Critical Warning Threshold</mat-label>
|
||||||
|
<input matInput>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</mat-tab>
|
||||||
|
</mat-tab-group>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</mat-dialog-content>
|
||||||
|
<mat-dialog-actions align="end">
|
||||||
|
<button mat-button mat-dialog-close>Cancel</button>
|
||||||
|
<button mat-button [mat-dialog-close]="true" cdkFocusInitial>Save</button>
|
||||||
|
</mat-dialog-actions>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Copyright 2020 Google LLC. All Rights Reserved.
|
||||||
|
Use of this source code is governed by an MIT-style license that
|
||||||
|
can be found in the LICENSE file at http://angular.io/license -->
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DashboardSettingsComponent } from './dashboard-settings.component';
|
||||||
|
|
||||||
|
describe('DashboardSettingsComponent', () => {
|
||||||
|
let component: DashboardSettingsComponent;
|
||||||
|
let fixture: ComponentFixture<DashboardSettingsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ DashboardSettingsComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(DashboardSettingsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-dashboard-settings',
|
||||||
|
templateUrl: './dashboard-settings.component.html',
|
||||||
|
styleUrls: ['./dashboard-settings.component.scss']
|
||||||
|
})
|
||||||
|
export class DashboardSettingsComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
formatLabel(value: number) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule } from '@angular/router';
|
||||||
|
import { Overlay } from '@angular/cdk/overlay';
|
||||||
|
import { MAT_AUTOCOMPLETE_SCROLL_STRATEGY, MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { SharedModule } from 'app/shared/shared.module';
|
||||||
|
import {DashboardSettingsComponent} from 'app/layout/common/dashboard-settings/dashboard-settings.component'
|
||||||
|
import { MatDialogModule } from "@angular/material/dialog";
|
||||||
|
import { MatButtonToggleModule} from "@angular/material/button-toggle";
|
||||||
|
import {MatTabsModule} from "@angular/material/tabs";
|
||||||
|
import {MatSliderModule} from "@angular/material/slider";
|
||||||
|
import {MatSlideToggleModule} from "@angular/material/slide-toggle";
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
DashboardSettingsComponent
|
||||||
|
],
|
||||||
|
imports : [
|
||||||
|
RouterModule.forChild([]),
|
||||||
|
MatAutocompleteModule,
|
||||||
|
MatDialogModule,
|
||||||
|
MatButtonModule,
|
||||||
|
MatSelectModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatIconModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatButtonToggleModule,
|
||||||
|
MatTabsModule,
|
||||||
|
MatSliderModule,
|
||||||
|
MatSlideToggleModule,
|
||||||
|
SharedModule
|
||||||
|
],
|
||||||
|
exports : [
|
||||||
|
DashboardSettingsComponent
|
||||||
|
],
|
||||||
|
providers : []
|
||||||
|
})
|
||||||
|
export class DashboardSettingsModule
|
||||||
|
{
|
||||||
|
}
|
||||||
+3
-6
@@ -10,15 +10,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- Action buttons -->
|
<!-- Action buttons -->
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<button class="xs:hidden"
|
<button matTooltip="not yet implemented" class="xs:hidden" mat-stroked-button>
|
||||||
matTooltip="not yet implemented"
|
|
||||||
mat-stroked-button>
|
|
||||||
<mat-icon class="icon-size-20"
|
<mat-icon class="icon-size-20"
|
||||||
[svgIcon]="'save'"></mat-icon>
|
[svgIcon]="'save'"></mat-icon>
|
||||||
<span class="ml-2">Export</span>
|
<span class="ml-2">Export</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="ml-2 xs:hidden"
|
<button class="ml-2 xs:hidden"
|
||||||
matTooltip="not yet implemented"
|
(click)="openDialog()"
|
||||||
mat-stroked-button>
|
mat-stroked-button>
|
||||||
<mat-icon class="icon-size-20 rotate-90 mirror"
|
<mat-icon class="icon-size-20 rotate-90 mirror"
|
||||||
[svgIcon]="'tune'"></mat-icon>
|
[svgIcon]="'tune'"></mat-icon>
|
||||||
@@ -38,8 +36,7 @@
|
|||||||
[svgIcon]="'save'"></mat-icon>
|
[svgIcon]="'save'"></mat-icon>
|
||||||
<span class="ml-2">Export</span>
|
<span class="ml-2">Export</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item
|
<button mat-menu-item (click)="openDialog()">
|
||||||
matTooltip="not yet implemented">
|
|
||||||
<mat-icon class="icon-size-20 rotate-90 mirror"
|
<mat-icon class="icon-size-20 rotate-90 mirror"
|
||||||
[svgIcon]="'tune'"></mat-icon>
|
[svgIcon]="'tune'"></mat-icon>
|
||||||
<span class="ml-2">Settings</span>
|
<span class="ml-2">Settings</span>
|
||||||
+13
-2
@@ -4,8 +4,10 @@ import { MatTableDataSource } from '@angular/material/table';
|
|||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
import { ApexOptions } from 'ng-apexcharts';
|
import { ApexOptions } from 'ng-apexcharts';
|
||||||
import { DashboardService } from 'app/modules/admin/dashboard/dashboard.service';
|
import { DashboardService } from 'app/modules/dashboard/dashboard.service';
|
||||||
import * as moment from "moment";
|
import * as moment from "moment";
|
||||||
|
import {MatDialog} from '@angular/material/dialog';
|
||||||
|
import { DashboardSettingsComponent } from 'app/layout/common/dashboard-settings/dashboard-settings.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'example',
|
selector : 'example',
|
||||||
@@ -28,7 +30,8 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy
|
|||||||
* @param {SmartService} _smartService
|
* @param {SmartService} _smartService
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private _smartService: DashboardService
|
private _smartService: DashboardService,
|
||||||
|
public dialog: MatDialog
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Set the private defaults
|
// Set the private defaults
|
||||||
@@ -153,6 +156,14 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy
|
|||||||
// @ Public methods
|
// @ Public methods
|
||||||
// -----------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
openDialog() {
|
||||||
|
const dialogRef = this.dialog.open(DashboardSettingsComponent);
|
||||||
|
|
||||||
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
|
console.log(`Dialog result: ${result}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Track by function for ngFor loops
|
* Track by function for ngFor loops
|
||||||
*
|
*
|
||||||
+5
-3
@@ -1,8 +1,8 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { SharedModule } from 'app/shared/shared.module';
|
import { SharedModule } from 'app/shared/shared.module';
|
||||||
import { DashboardComponent } from 'app/modules/admin/dashboard/dashboard.component';
|
import { DashboardComponent } from 'app/modules/dashboard/dashboard.component';
|
||||||
import { dashboardRoutes } from 'app/modules/admin/dashboard/dashboard.routing';
|
import { dashboardRoutes } from 'app/modules/dashboard/dashboard.routing';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatDividerModule } from '@angular/material/divider';
|
import { MatDividerModule } from '@angular/material/divider';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
@@ -12,6 +12,7 @@ import { MatSortModule } from '@angular/material/sort';
|
|||||||
import { MatTableModule } from '@angular/material/table';
|
import { MatTableModule } from '@angular/material/table';
|
||||||
import { NgApexchartsModule } from 'ng-apexcharts';
|
import { NgApexchartsModule } from 'ng-apexcharts';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip'
|
import { MatTooltipModule } from '@angular/material/tooltip'
|
||||||
|
import { DashboardSettingsModule } from "app/layout/common/dashboard-settings/dashboard-settings.module";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@@ -28,7 +29,8 @@ import { MatTooltipModule } from '@angular/material/tooltip'
|
|||||||
MatSortModule,
|
MatSortModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
NgApexchartsModule,
|
NgApexchartsModule,
|
||||||
SharedModule
|
SharedModule,
|
||||||
|
DashboardSettingsModule
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class DashboardModule
|
export class DashboardModule
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { DashboardService } from 'app/modules/admin/dashboard/dashboard.service';
|
import { DashboardService } from 'app/modules/dashboard/dashboard.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { Route } from '@angular/router';
|
import { Route } from '@angular/router';
|
||||||
import { DashboardComponent } from 'app/modules/admin/dashboard/dashboard.component';
|
import { DashboardComponent } from 'app/modules/dashboard/dashboard.component';
|
||||||
import {DashboardResolver} from "./dashboard.resolvers";
|
import {DashboardResolver} from "./dashboard.resolvers";
|
||||||
|
|
||||||
export const dashboardRoutes: Route[] = [
|
export const dashboardRoutes: Route[] = [
|
||||||
+2
-2
@@ -3,9 +3,9 @@ import {ApexOptions} from "ng-apexcharts";
|
|||||||
import {MatTableDataSource} from "@angular/material/table";
|
import {MatTableDataSource} from "@angular/material/table";
|
||||||
import {MatSort} from "@angular/material/sort";
|
import {MatSort} from "@angular/material/sort";
|
||||||
import {Subject} from "rxjs";
|
import {Subject} from "rxjs";
|
||||||
import {DetailService} from "../detail/detail.service";
|
import {DetailService} from "./detail.service";
|
||||||
import {takeUntil} from "rxjs/operators";
|
import {takeUntil} from "rxjs/operators";
|
||||||
import {fadeOut} from "../../../../@treo/animations/fade";
|
import {fadeOut} from "../../../@treo/animations/fade";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'detail',
|
selector: 'detail',
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { SharedModule } from 'app/shared/shared.module';
|
import { SharedModule } from 'app/shared/shared.module';
|
||||||
import { DetailComponent } from 'app/modules/admin/detail/detail.component';
|
import { DetailComponent } from 'app/modules/detail/detail.component';
|
||||||
import { detailRoutes } from 'app/modules/admin/detail/detail.routing';
|
import { detailRoutes } from 'app/modules/detail/detail.routing';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatDividerModule } from '@angular/material/divider';
|
import { MatDividerModule } from '@angular/material/divider';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { DetailService } from 'app/modules/admin/detail/detail.service';
|
import { DetailService } from 'app/modules/detail/detail.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { Route } from '@angular/router';
|
import { Route } from '@angular/router';
|
||||||
import { DetailComponent } from 'app/modules/admin/detail/detail.component';
|
import { DetailComponent } from 'app/modules/detail/detail.component';
|
||||||
import {DetailResolver} from "./detail.resolvers";
|
import {DetailResolver} from "./detail.resolvers";
|
||||||
|
|
||||||
export const detailRoutes: Route[] = [
|
export const detailRoutes: Route[] = [
|
||||||
Reference in New Issue
Block a user