├── .gitignore ├── README.md ├── backend ├── go.mod └── server.go └── frontend ├── .editorconfig ├── .gitignore ├── README.md ├── angular.json ├── package-lock.json ├── package.json ├── src ├── app │ ├── about │ │ ├── about.component.scss │ │ ├── about.component.spec.ts │ │ └── about.component.ts │ ├── app.component.scss │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.config.ts │ ├── app.routes.ts │ ├── data.service.spec.ts │ ├── data.service.ts │ ├── disk │ │ ├── disk.component.scss │ │ ├── disk.component.spec.ts │ │ ├── disk.component.ts │ │ └── diskdata.ts │ ├── footer │ │ ├── footer.component.scss │ │ ├── footer.component.spec.ts │ │ └── footer.component.ts │ ├── header │ │ ├── header.component.scss │ │ ├── header.component.spec.ts │ │ └── header.component.ts │ ├── loading │ │ ├── loading.component.scss │ │ ├── loading.component.spec.ts │ │ └── loading.component.ts │ ├── logs │ │ ├── logs.component.scss │ │ ├── logs.component.spec.ts │ │ ├── logs.component.ts │ │ └── logsdata.ts │ ├── navigation-bar │ │ ├── navigation-bar.component.scss │ │ ├── navigation-bar.component.spec.ts │ │ └── navigation-bar.component.ts │ ├── network │ │ ├── network.component.scss │ │ ├── network.component.spec.ts │ │ ├── network.component.ts │ │ └── networkdata.ts │ └── system │ │ ├── system.component.scss │ │ ├── system.component.spec.ts │ │ ├── system.component.ts │ │ └── systemdata.ts ├── assets │ └── .gitkeep ├── favicon.ico ├── index.html ├── main.ts └── styles.scss ├── tsconfig.app.json ├── tsconfig.json └── tsconfig.spec.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Linux Dashboard 2 | 3 | Aplikacja służąca do monitorowania działania systemu operacyjnego Linux poprzez stronę internetową. 4 | 5 | ## Używane technologie 6 | - Frontend 7 | - Angular 8 | 9 | - Backend 10 | - Go 11 | 12 | ## Cel edukacyjne 13 | Tworząc ten projekt chciałbym przede wszystkim poznać/podszkolić się w następujących technologiach/technikach: 14 | 15 | - Angular 16 | - Lepiej poznać nowe funkcje wprowadzane do frameworka od wersji 15 17 | - Nowa składnia 18 | - Poznać i stosować Angular Material 19 | 20 | - Go 21 | - Poznać ten język programowania 22 | - Tworzyć Rest Api 23 | - Poznać protokoły komunikacji między frontendem a backendem(http, websocket) 24 | 25 | - Pisać testy jednostkowe 26 | - Stosować wzorce projektowe i dobre praktyki programowania 27 | 28 | --- 29 | *** README z czasem będzie aktualizowane -------------------------------------------------------------------------------- /backend/go.mod: -------------------------------------------------------------------------------- 1 | module server 2 | 3 | go 1.22.0 4 | -------------------------------------------------------------------------------- /backend/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | println("Here will be a main file for server app") 5 | } 6 | -------------------------------------------------------------------------------- /frontend/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | .vscode/ 23 | 24 | # Visual Studio Code 25 | .vscode/* 26 | !.vscode/settings.json 27 | !.vscode/tasks.json 28 | !.vscode/launch.json 29 | !.vscode/extensions.json 30 | .history/* 31 | 32 | # Miscellaneous 33 | /.angular/cache 34 | .sass-cache/ 35 | /connect.lock 36 | /coverage 37 | /libpeerconnection.log 38 | testem.log 39 | /typings 40 | 41 | # System files 42 | .DS_Store 43 | Thumbs.db 44 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # Frontend 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.2.2. 4 | 5 | ## Info 6 | 7 | An application used to monitor the performance of the Linux operating system. 8 | 9 | -------------------------------------------------------------------------------- /frontend/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "frontend": { 7 | "projectType": "application", 8 | "schematics": { 9 | "@schematics/angular:component": { 10 | "style": "scss" 11 | } 12 | }, 13 | "root": "", 14 | "sourceRoot": "src", 15 | "prefix": "app", 16 | "architect": { 17 | "build": { 18 | "builder": "@angular-devkit/build-angular:application", 19 | "options": { 20 | "outputPath": "dist/frontend", 21 | "index": "src/index.html", 22 | "browser": "src/main.ts", 23 | "polyfills": [ 24 | "zone.js" 25 | ], 26 | "tsConfig": "tsconfig.app.json", 27 | "inlineStyleLanguage": "scss", 28 | "assets": [ 29 | "src/favicon.ico", 30 | "src/assets" 31 | ], 32 | "styles": [ 33 | "@angular/material/prebuilt-themes/deeppurple-amber.css", 34 | "src/styles.scss" 35 | ], 36 | "scripts": [] 37 | }, 38 | "configurations": { 39 | "production": { 40 | "budgets": [ 41 | { 42 | "type": "initial", 43 | "maximumWarning": "500kb", 44 | "maximumError": "1mb" 45 | }, 46 | { 47 | "type": "anyComponentStyle", 48 | "maximumWarning": "2kb", 49 | "maximumError": "4kb" 50 | } 51 | ], 52 | "outputHashing": "all" 53 | }, 54 | "development": { 55 | "optimization": false, 56 | "extractLicenses": false, 57 | "sourceMap": true 58 | } 59 | }, 60 | "defaultConfiguration": "production" 61 | }, 62 | "serve": { 63 | "builder": "@angular-devkit/build-angular:dev-server", 64 | "configurations": { 65 | "production": { 66 | "buildTarget": "frontend:build:production" 67 | }, 68 | "development": { 69 | "buildTarget": "frontend:build:development" 70 | } 71 | }, 72 | "defaultConfiguration": "development" 73 | }, 74 | "extract-i18n": { 75 | "builder": "@angular-devkit/build-angular:extract-i18n", 76 | "options": { 77 | "buildTarget": "frontend:build" 78 | } 79 | }, 80 | "test": { 81 | "builder": "@angular-devkit/build-angular:karma", 82 | "options": { 83 | "polyfills": [ 84 | "zone.js", 85 | "zone.js/testing" 86 | ], 87 | "tsConfig": "tsconfig.spec.json", 88 | "inlineStyleLanguage": "scss", 89 | "assets": [ 90 | "src/favicon.ico", 91 | "src/assets" 92 | ], 93 | "styles": [ 94 | "@angular/material/prebuilt-themes/deeppurple-amber.css", 95 | "src/styles.scss" 96 | ], 97 | "scripts": [] 98 | } 99 | } 100 | } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve --live-reload=false", 7 | "build": "ng build", 8 | "watch": "ng build --watch --configuration development", 9 | "test": "ng test" 10 | }, 11 | "private": true, 12 | "dependencies": { 13 | "@angular/animations": "^17.2.0", 14 | "@angular/cdk": "^17.3.0", 15 | "@angular/common": "^17.2.0", 16 | "@angular/compiler": "^17.2.0", 17 | "@angular/core": "^17.2.0", 18 | "@angular/forms": "^17.2.0", 19 | "@angular/material": "^17.3.0", 20 | "@angular/platform-browser": "^17.2.0", 21 | "@angular/platform-browser-dynamic": "^17.2.0", 22 | "@angular/router": "^17.2.0", 23 | "rxjs": "~7.8.0", 24 | "tslib": "^2.3.0", 25 | "zone.js": "~0.14.3" 26 | }, 27 | "devDependencies": { 28 | "@angular-devkit/build-angular": "^17.2.2", 29 | "@angular/cli": "^17.2.2", 30 | "@angular/compiler-cli": "^17.2.0", 31 | "@types/jasmine": "~5.1.0", 32 | "jasmine-core": "~5.1.0", 33 | "karma": "~6.4.0", 34 | "karma-chrome-launcher": "~3.2.0", 35 | "karma-coverage": "~2.2.0", 36 | "karma-jasmine": "~5.1.0", 37 | "karma-jasmine-html-reporter": "~2.1.0", 38 | "typescript": "~5.3.2" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /frontend/src/app/about/about.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwalczak-dev/linux-dashboard/b1fddee2b27f8eef68f9f83324c6f1a1410b6031/frontend/src/app/about/about.component.scss -------------------------------------------------------------------------------- /frontend/src/app/about/about.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AboutComponent } from './about.component'; 4 | 5 | describe('AboutComponent', () => { 6 | let component: AboutComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [AboutComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(AboutComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/src/app/about/about.component.ts: -------------------------------------------------------------------------------- 1 | import {ChangeDetectionStrategy, Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-about', 5 | standalone: true, 6 | imports: [], 7 | template: ` 8 |

Linux Dashboard

9 |

About project:

10 |

An application used to monitor the performance of the Linux operating system via a web browser.

11 | `, 12 | styleUrl: './about.component.scss', 13 | changeDetection: ChangeDetectionStrategy.OnPush 14 | }) 15 | export class AboutComponent { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /frontend/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | display: flex; 3 | box-sizing: border-box; 4 | padding: 0 16px; 5 | } 6 | 7 | .page-container { 8 | display: flex; 9 | flex-direction: column; 10 | height: 100vh; 11 | 12 | .center-container { 13 | flex-grow: 1; 14 | } 15 | 16 | .footer-container { 17 | background-color: #673ab7; 18 | justify-content: center; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /frontend/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async () => { 6 | await TestBed.configureTestingModule({ 7 | imports: [AppComponent], 8 | }).compileComponents(); 9 | }); 10 | 11 | it('should create the app', () => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.componentInstance; 14 | expect(app).toBeTruthy(); 15 | }); 16 | 17 | it(`should have the 'frontend' title`, () => { 18 | const fixture = TestBed.createComponent(AppComponent); 19 | const app = fixture.componentInstance; 20 | expect(app.title).toEqual('frontend'); 21 | }); 22 | 23 | it('should render title', () => { 24 | const fixture = TestBed.createComponent(AppComponent); 25 | fixture.detectChanges(); 26 | const compiled = fixture.nativeElement as HTMLElement; 27 | expect(compiled.querySelector('h1')?.textContent).toContain('Hello, frontend'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /frontend/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {ChangeDetectionStrategy, Component, OnInit, signal, ViewChild} from '@angular/core'; 2 | import { RouterOutlet } from '@angular/router'; 3 | import {NavigationBarComponent} from "./navigation-bar/navigation-bar.component"; 4 | import {HeaderComponent} from "./header/header.component"; 5 | import {FooterComponent} from "./footer/footer.component"; 6 | import {MatSidenav, MatSidenavContainer, MatSidenavContent} from "@angular/material/sidenav"; 7 | import {MatButton} from "@angular/material/button"; 8 | import {MatToolbar} from "@angular/material/toolbar"; 9 | import {LoadingComponent} from "./loading/loading.component"; 10 | 11 | @Component({ 12 | selector: 'app-root', 13 | standalone: true, 14 | imports: [RouterOutlet, NavigationBarComponent, HeaderComponent, FooterComponent, MatSidenavContainer, MatSidenavContent, MatSidenav, MatButton, MatToolbar, LoadingComponent], 15 | template: ` 16 | 17 | 18 | 21 | 22 | 23 |
24 | 25 | 26 | 27 |
28 |
29 | 30 |
31 |
32 | 35 | @if (showLoader()) { 36 | 37 | } 38 |
39 |
40 |
41 | `, 42 | styleUrl: './app.component.scss', 43 | changeDetection: ChangeDetectionStrategy.OnPush 44 | }) 45 | export class AppComponent implements OnInit { 46 | title = signal('Linux Dashboard'); 47 | showLoader = signal(true); 48 | 49 | get closeSidenavFunc() { 50 | return this.closeSidenav.bind(this); 51 | } 52 | 53 | @ViewChild('sidenav') sidenav!: MatSidenav; 54 | 55 | ngOnInit(): void { 56 | setInterval(() => { 57 | this.showLoader.update(() => false); 58 | }, 1000); 59 | } 60 | 61 | sidenavToggle(): void { 62 | this.sidenav.toggle(); 63 | } 64 | 65 | closeSidenav(): void { 66 | this.sidenav.close(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /frontend/src/app/app.config.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | 4 | import { routes } from './app.routes'; 5 | import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; 6 | 7 | export const appConfig: ApplicationConfig = { 8 | providers: [provideRouter(routes), provideAnimationsAsync()] 9 | }; 10 | -------------------------------------------------------------------------------- /frontend/src/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | import {SystemComponent} from "./system/system.component"; 3 | import {DiskComponent} from "./disk/disk.component"; 4 | import {NetworkComponent} from "./network/network.component"; 5 | import {LogsComponent} from "./logs/logs.component"; 6 | import {AboutComponent} from "./about/about.component"; 7 | 8 | export const routes: Routes = [ 9 | {path: 'system', component: SystemComponent}, 10 | {path: 'disk', component: DiskComponent}, 11 | {path: 'network', component: NetworkComponent}, 12 | {path: 'logs', component: LogsComponent}, 13 | {path: 'about', component: AboutComponent}, 14 | {path: '', component: SystemComponent} 15 | ]; 16 | -------------------------------------------------------------------------------- /frontend/src/app/data.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { DataService } from './data.service'; 4 | 5 | describe('DataService', () => { 6 | let service: DataService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(DataService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /frontend/src/app/data.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import {Observable, Subject} from "rxjs"; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class DataService { 8 | 9 | #cpuUsageData$ = new Subject(); 10 | #ramUsageData$ = new Subject(); 11 | #diskSpaceUsageData$ = new Subject(); 12 | #networkUsageData$ = new Subject(); 13 | 14 | getCpuUsageData(): Observable { 15 | return this.#cpuUsageData$.asObservable() 16 | } 17 | 18 | updateCpuUsageData(data: any): void { 19 | this.#cpuUsageData$.next(data) 20 | } 21 | 22 | getRamUsageData(): Observable { 23 | return this.#ramUsageData$.asObservable() 24 | } 25 | 26 | updateRamUsageData(data: any): void { 27 | this.#ramUsageData$.next(data) 28 | } 29 | 30 | getDiskSpaceUsageData(): Observable { 31 | return this.#diskSpaceUsageData$.asObservable() 32 | } 33 | 34 | updateDiskSpaceUsageData(data: any): void { 35 | this.#diskSpaceUsageData$.next(data) 36 | } 37 | 38 | getNetworkUsageData(): Observable { 39 | return this.#networkUsageData$.asObservable() 40 | } 41 | 42 | updateNetworkUsageData(data: any): void { 43 | this.#networkUsageData$.next(data) 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /frontend/src/app/disk/disk.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwalczak-dev/linux-dashboard/b1fddee2b27f8eef68f9f83324c6f1a1410b6031/frontend/src/app/disk/disk.component.scss -------------------------------------------------------------------------------- /frontend/src/app/disk/disk.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DiskComponent } from './disk.component'; 4 | 5 | describe('DiskComponent', () => { 6 | let component: DiskComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [DiskComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(DiskComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/src/app/disk/disk.component.ts: -------------------------------------------------------------------------------- 1 | import {ChangeDetectionStrategy, Component, signal} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-disk', 5 | standalone: true, 6 | imports: [], 7 | template: ` 8 |

{{componentHeader()}}

9 |

Disk partitions

10 | 11 | 12 | 13 | `, 14 | styleUrl: './disk.component.scss', 15 | changeDetection: ChangeDetectionStrategy.OnPush 16 | }) 17 | export class DiskComponent { 18 | componentHeader = signal('Disk information') 19 | 20 | } 21 | -------------------------------------------------------------------------------- /frontend/src/app/disk/diskdata.ts: -------------------------------------------------------------------------------- 1 | export interface Diskdata { 2 | } 3 | -------------------------------------------------------------------------------- /frontend/src/app/footer/footer.component.scss: -------------------------------------------------------------------------------- 1 | p { 2 | a { 3 | text-decoration: none; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /frontend/src/app/footer/footer.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FooterComponent } from './footer.component'; 4 | 5 | describe('FooterComponent', () => { 6 | let component: FooterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [FooterComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(FooterComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/src/app/footer/footer.component.ts: -------------------------------------------------------------------------------- 1 | import {ChangeDetectionStrategy, Component, input} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-footer', 5 | standalone: true, 6 | imports: [], 7 | template: ` 8 |

{{ title() }} | 100commitow.pl

9 | `, 10 | styleUrl: './footer.component.scss', 11 | changeDetection: ChangeDetectionStrategy.OnPush 12 | }) 13 | export class FooterComponent { 14 | title = input(''); 15 | } 16 | -------------------------------------------------------------------------------- /frontend/src/app/header/header.component.scss: -------------------------------------------------------------------------------- 1 | .header-container { 2 | display: flex; 3 | align-items: center; 4 | 5 | button.menu-button { 6 | border: 1px solid lightgray; 7 | 8 | .menu-button-icon { 9 | margin: 0; 10 | } 11 | } 12 | 13 | h1 { 14 | margin: 0 40px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /frontend/src/app/header/header.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HeaderComponent } from './header.component'; 4 | 5 | describe('HeaderComponent', () => { 6 | let component: HeaderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [HeaderComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(HeaderComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/src/app/header/header.component.ts: -------------------------------------------------------------------------------- 1 | import {ChangeDetectionStrategy, Component, EventEmitter, input, Output} from '@angular/core'; 2 | import {MatButtonModule} from "@angular/material/button"; 3 | import {MatIcon} from "@angular/material/icon"; 4 | 5 | @Component({ 6 | selector: 'app-header', 7 | standalone: true, 8 | imports: [ 9 | MatButtonModule, MatIcon 10 | ], 11 | template: ` 12 |
13 | 14 |

{{ title() }}

15 |
16 | `, 17 | styleUrl: './header.component.scss', 18 | changeDetection: ChangeDetectionStrategy.OnPush 19 | }) 20 | export class HeaderComponent { 21 | title = input(''); 22 | 23 | @Output() menuButtonClick = new EventEmitter(); 24 | 25 | toggle(): void { 26 | this.menuButtonClick.emit(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /frontend/src/app/loading/loading.component.scss: -------------------------------------------------------------------------------- 1 | .loader-overlay { 2 | position: absolute; 3 | z-index: 99999; 4 | width: 100%; 5 | height: 100%; 6 | display: flex; 7 | justify-content: center; 8 | align-items: center; 9 | left: 0; 10 | top: 0; 11 | background-color: black; 12 | opacity: 0.3; 13 | } 14 | -------------------------------------------------------------------------------- /frontend/src/app/loading/loading.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LoadingComponent } from './loading.component'; 4 | 5 | describe('LoadingComponent', () => { 6 | let component: LoadingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [LoadingComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(LoadingComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/src/app/loading/loading.component.ts: -------------------------------------------------------------------------------- 1 | import {ChangeDetectionStrategy, Component} from '@angular/core'; 2 | import {MatProgressSpinner} from "@angular/material/progress-spinner"; 3 | 4 | @Component({ 5 | selector: 'app-loading', 6 | standalone: true, 7 | imports: [ 8 | MatProgressSpinner 9 | ], 10 | template: ` 11 |
12 | 13 |
14 | `, 15 | styleUrl: './loading.component.scss', 16 | changeDetection: ChangeDetectionStrategy.OnPush 17 | }) 18 | export class LoadingComponent { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /frontend/src/app/logs/logs.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwalczak-dev/linux-dashboard/b1fddee2b27f8eef68f9f83324c6f1a1410b6031/frontend/src/app/logs/logs.component.scss -------------------------------------------------------------------------------- /frontend/src/app/logs/logs.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LogsComponent } from './logs.component'; 4 | 5 | describe('LogsComponent', () => { 6 | let component: LogsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [LogsComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(LogsComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/src/app/logs/logs.component.ts: -------------------------------------------------------------------------------- 1 | import {ChangeDetectionStrategy, Component, signal} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-logs', 5 | standalone: true, 6 | imports: [], 7 | template: ` 8 |

{{componentHeader()}}

9 |

System log data

10 | 11 | 12 | 13 | `, 14 | styleUrl: './logs.component.scss', 15 | changeDetection: ChangeDetectionStrategy.OnPush 16 | }) 17 | export class LogsComponent { 18 | componentHeader = signal('Logs information') 19 | 20 | } 21 | -------------------------------------------------------------------------------- /frontend/src/app/logs/logsdata.ts: -------------------------------------------------------------------------------- 1 | export interface Logsdata { 2 | } 3 | -------------------------------------------------------------------------------- /frontend/src/app/navigation-bar/navigation-bar.component.scss: -------------------------------------------------------------------------------- 1 | .navigation-list { 2 | list-style: none; 3 | padding: 0; 4 | width: 280px; 5 | 6 | .navigation-element { 7 | padding: 10px; 8 | border-bottom: 1px solid lightgray; 9 | 10 | &:hover { 11 | background-color: lavender; 12 | cursor: pointer; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /frontend/src/app/navigation-bar/navigation-bar.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NavigationBarComponent } from './navigation-bar.component'; 4 | 5 | describe('NavigationBarComponent', () => { 6 | let component: NavigationBarComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [NavigationBarComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(NavigationBarComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/src/app/navigation-bar/navigation-bar.component.ts: -------------------------------------------------------------------------------- 1 | import {ChangeDetectionStrategy, Component, Input} from '@angular/core'; 2 | import {NgFor} from '@angular/common'; 3 | import {RouterLink} from "@angular/router"; 4 | 5 | @Component({ 6 | selector: 'app-navigation-bar', 7 | standalone: true, 8 | imports: [NgFor, RouterLink], 9 | template: ` 10 | 15 | `, 16 | styleUrl: './navigation-bar.component.scss', 17 | changeDetection: ChangeDetectionStrategy.OnPush 18 | }) 19 | export class NavigationBarComponent { 20 | tabs: string[] = ['System', 'Disk', 'Network', 'Logs', 'About']; 21 | 22 | @Input() closeSidenavFunc!: Function; 23 | 24 | onNavItemClick(): void { 25 | this.closeSidenavFunc(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /frontend/src/app/network/network.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwalczak-dev/linux-dashboard/b1fddee2b27f8eef68f9f83324c6f1a1410b6031/frontend/src/app/network/network.component.scss -------------------------------------------------------------------------------- /frontend/src/app/network/network.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NetworkComponent } from './network.component'; 4 | 5 | describe('NetworkComponent', () => { 6 | let component: NetworkComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [NetworkComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(NetworkComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/src/app/network/network.component.ts: -------------------------------------------------------------------------------- 1 | import {ChangeDetectionStrategy, Component, signal} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-network', 5 | standalone: true, 6 | imports: [], 7 | template: ` 8 |

{{componentHeader()}}

9 |

Network interfaces

10 | 11 | 12 | 13 | `, 14 | styleUrl: './network.component.scss', 15 | changeDetection: ChangeDetectionStrategy.OnPush 16 | }) 17 | export class NetworkComponent { 18 | componentHeader = signal('Network information') 19 | } 20 | -------------------------------------------------------------------------------- /frontend/src/app/network/networkdata.ts: -------------------------------------------------------------------------------- 1 | export interface Networkdata { 2 | } 3 | -------------------------------------------------------------------------------- /frontend/src/app/system/system.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwalczak-dev/linux-dashboard/b1fddee2b27f8eef68f9f83324c6f1a1410b6031/frontend/src/app/system/system.component.scss -------------------------------------------------------------------------------- /frontend/src/app/system/system.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SystemComponent } from './system.component'; 4 | 5 | describe('SystemComponent', () => { 6 | let component: SystemComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [SystemComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(SystemComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/src/app/system/system.component.ts: -------------------------------------------------------------------------------- 1 | import {ChangeDetectionStrategy, Component, signal} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-system', 5 | standalone: true, 6 | imports: [], 7 | template: ` 8 |

{{componentHeader()}}

9 |

General info

10 | 11 | 12 | 13 | 14 | 15 |

Memory info

16 | 17 | 18 | 19 | 20 | 21 |

CPU info

22 | 23 | 24 | 25 | 26 | `, 27 | styleUrl: './system.component.scss', 28 | changeDetection: ChangeDetectionStrategy.OnPush 29 | }) 30 | export class SystemComponent { 31 | componentHeader = signal('System information') 32 | 33 | } 34 | -------------------------------------------------------------------------------- /frontend/src/app/system/systemdata.ts: -------------------------------------------------------------------------------- 1 | export interface Systemdata { 2 | } 3 | -------------------------------------------------------------------------------- /frontend/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwalczak-dev/linux-dashboard/b1fddee2b27f8eef68f9f83324c6f1a1410b6031/frontend/src/assets/.gitkeep -------------------------------------------------------------------------------- /frontend/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwalczak-dev/linux-dashboard/b1fddee2b27f8eef68f9f83324c6f1a1410b6031/frontend/src/favicon.ico -------------------------------------------------------------------------------- /frontend/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Frontend 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /frontend/src/main.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapApplication } from '@angular/platform-browser'; 2 | import { appConfig } from './app/app.config'; 3 | import { AppComponent } from './app/app.component'; 4 | 5 | bootstrapApplication(AppComponent, appConfig) 6 | .catch((err) => console.error(err)); 7 | -------------------------------------------------------------------------------- /frontend/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | html, body { height: 100%; } 4 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } 5 | -------------------------------------------------------------------------------- /frontend/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /frontend/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "outDir": "./dist/out-tsc", 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "noImplicitOverride": true, 9 | "noPropertyAccessFromIndexSignature": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "skipLibCheck": true, 13 | "esModuleInterop": true, 14 | "sourceMap": true, 15 | "declaration": false, 16 | "experimentalDecorators": true, 17 | "moduleResolution": "node", 18 | "importHelpers": true, 19 | "target": "ES2022", 20 | "module": "ES2022", 21 | "useDefineForClassFields": false, 22 | "lib": [ 23 | "ES2022", 24 | "dom" 25 | ] 26 | }, 27 | "angularCompilerOptions": { 28 | "enableI18nLegacyMessageIdFormat": false, 29 | "strictInjectionParameters": true, 30 | "strictInputAccessModifiers": true, 31 | "strictTemplates": true 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /frontend/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "include": [ 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | --------------------------------------------------------------------------------