Sfoglia il codice sorgente

Angular: Integration Bootstrap Theme; Basic Layout & Routing

Christian Kahlau 3 anni fa
parent
commit
4ce25d1ab5

+ 4 - 1
ng/angular.json

@@ -25,7 +25,7 @@
             "inlineStyleLanguage": "scss",
             "assets": ["src/favicon.ico", "src/assets"],
             "styles": ["src/styles.scss"],
-            "scripts": []
+            "scripts": ["bootstrap-theme/dist/js/bootstrap.js"]
           },
           "configurations": {
             "production": {
@@ -93,5 +93,8 @@
         }
       }
     }
+  },
+  "cli": {
+    "analytics": false
   }
 }

+ 1 - 1
ng/package.json

@@ -3,7 +3,7 @@
   "version": "1.0.0",
   "scripts": {
     "ng": "ng",
-    "start": "ng serve",
+    "start": "ng serve --proxy-config proxy-conf.json",
     "build": "ng build",
     "watch": "ng build --watch --configuration development",
     "test": "ng test"

+ 7 - 0
ng/proxy-conf.json

@@ -0,0 +1,7 @@
+[
+  {
+    "context": ["/"],
+    "target": "http://10.8.0.1:8880",
+    "secure": false
+  }
+]

+ 3 - 2
ng/src/app/app-routing.module.ts

@@ -1,10 +1,11 @@
 import { NgModule } from '@angular/core';
 import { RouterModule, Routes } from '@angular/router';
+import { HomeComponent } from './pages/home/home.component';
 
-const routes: Routes = [];
+const routes: Routes = [{ path: '', pathMatch: 'full', component: HomeComponent }];
 
 @NgModule({
   imports: [RouterModule.forRoot(routes)],
   exports: [RouterModule]
 })
-export class AppRoutingModule { }
+export class AppRoutingModule {}

File diff suppressed because it is too large
+ 0 - 441
ng/src/app/app.component.html


+ 6 - 8
ng/src/app/app.module.ts

@@ -1,18 +1,16 @@
+import { HttpClientModule } from '@angular/common/http';
 import { NgModule } from '@angular/core';
 import { BrowserModule } from '@angular/platform-browser';
 
 import { AppRoutingModule } from './app-routing.module';
 import { AppComponent } from './app.component';
+import { HeaderComponent } from './components/header/header.component';
+import { HomeComponent } from './pages/home/home.component';
 
 @NgModule({
-  declarations: [
-    AppComponent
-  ],
-  imports: [
-    BrowserModule,
-    AppRoutingModule
-  ],
+  declarations: [AppComponent, HeaderComponent, HomeComponent],
+  imports: [AppRoutingModule, BrowserModule, HttpClientModule],
   providers: [],
   bootstrap: [AppComponent]
 })
-export class AppModule { }
+export class AppModule {}

+ 22 - 0
ng/src/app/components/header/header.component.html

@@ -0,0 +1,22 @@
+<nav class="navbar navbar-expand-lg navbar-light container-md">
+  <div class="container-fluid bg-light">
+    <a class="navbar-brand navbar-brand-logo" href="#">HostBBQ Monitoring</a>
+    <button
+      class="navbar-toggler"
+      type="button"
+      data-bs-toggle="collapse"
+      data-bs-target="#navbarSupportedContent"
+      aria-controls="navbarSupportedContent"
+      aria-expanded="false"
+      aria-label="Toggle navigation">
+      <span class="navbar-toggler-icon"></span>
+    </button>
+  </div>
+  <div class="collapse navbar-collapse justify-content-end" id="navbarSupportedContent">
+    <ul class="navbar-nav pull-right">
+      <li class="nav-item dropdown">
+        <a id="loginDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</a>
+      </li>
+    </ul>
+  </div>
+</nav>

+ 0 - 0
ng/src/app/components/header/header.component.scss


+ 23 - 0
ng/src/app/components/header/header.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HeaderComponent } from './header.component';
+
+describe('HeaderComponent', () => {
+  let component: HeaderComponent;
+  let fixture: ComponentFixture<HeaderComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ HeaderComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(HeaderComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 15 - 0
ng/src/app/components/header/header.component.ts

@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-header',
+  templateUrl: './header.component.html',
+  styleUrls: ['./header.component.scss']
+})
+export class HeaderComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit(): void {
+  }
+
+}

+ 16 - 0
ng/src/app/pages/home/home.component.html

@@ -0,0 +1,16 @@
+<ng-container *ngIf="!!servers?.length; else nothing">
+  <ul>
+    <li *ngFor="let server of servers">
+      {{ server.title }}
+      <ul *ngIf="dataTypes?.[server.id]">
+        <li *ngFor="let type of dataTypes?.[server.id]">
+          {{ type.type }}
+          <ul *ngIf="type.subtypes?.length">
+            <li *ngFor="let sub of type.subtypes">{{ sub.type }}</li>
+          </ul>
+        </li>
+      </ul>
+    </li>
+  </ul>
+</ng-container>
+<ng-template #nothing> Nothing to display </ng-template>

+ 0 - 0
ng/src/app/pages/home/home.component.scss


+ 23 - 0
ng/src/app/pages/home/home.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HomeComponent } from './home.component';
+
+describe('HomeComponent', () => {
+  let component: HomeComponent;
+  let fixture: ComponentFixture<HomeComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ HomeComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(HomeComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 47 - 0
ng/src/app/pages/home/home.component.ts

@@ -0,0 +1,47 @@
+import { Component, OnInit } from '@angular/core';
+
+import { ServerApiService } from './../../services/server-api.service';
+
+@Component({
+  selector: 'app-home',
+  templateUrl: './home.component.html',
+  styleUrls: ['./home.component.scss']
+})
+export class HomeComponent implements OnInit {
+  public servers?: Server[];
+  public dataTypes?: { [id: number]: ServerDataTypesConfig[] };
+  public data?: { [id: number]: { [type: string]: ServerData[] } };
+
+  constructor(private serverApi: ServerApiService) {}
+
+  async ngOnInit(): Promise<void> {
+    try {
+      const end = new Date();
+      const start = new Date(end.getTime() - 1000 * 60 * 60 * 4);
+      this.servers = await this.serverApi.getAllServerConfigs();
+      this.dataTypes = {};
+      this.data = {};
+      for (const server of this.servers) {
+        this.dataTypes[server.id] = await this.serverApi.getServerDataTypes(server.id);
+
+        this.data[server.id] = {};
+        for (const dataType of this.dataTypes[server.id]) {
+          if (dataType.subtypes) {
+            for (const sub of dataType.subtypes) {
+              this.data[server.id][`${dataType.type}:${sub.type}`] = await this.serverApi.queryServerData(
+                server.id,
+                `${dataType.type}:${sub.type}`,
+                start,
+                end
+              );
+            }
+          } else {
+            this.data[server.id][dataType.type] = await this.serverApi.queryServerData(server.id, dataType.type, start, end);
+          }
+        }
+      }
+    } catch (err) {
+      console.error(err);
+    }
+  }
+}

+ 16 - 0
ng/src/app/services/server-api.service.spec.ts

@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { ServerApiService } from './server-api.service';
+
+describe('ServerApiService', () => {
+  let service: ServerApiService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(ServerApiService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});

+ 26 - 0
ng/src/app/services/server-api.service.ts

@@ -0,0 +1,26 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { firstValueFrom, map } from 'rxjs';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class ServerApiService {
+  constructor(private http: HttpClient) {}
+
+  public getAllServerConfigs() {
+    return firstValueFrom(this.http.get<Server[]>('/server'));
+  }
+
+  public getServerDataTypes(serverID: number) {
+    return firstValueFrom(this.http.get<ServerDataTypesConfig[]>(`/server/${serverID}/data/types`));
+  }
+
+  public queryServerData(serverID: number, type: string, start: Date, end: Date) {
+    return firstValueFrom(
+      this.http
+        .get<QueryResponse<ServerData>>(`/server/${serverID}/data`, { params: { type, start: start.toString(), end: end.toString() } })
+        .pipe(map(resp => resp.data.map(data => ({ ...data, time: new Date(data.time) }))))
+    );
+  }
+}

+ 11 - 11
ng/src/index.html

@@ -1,13 +1,13 @@
-<!doctype html>
+<!DOCTYPE html>
 <html lang="en">
-<head>
-  <meta charset="utf-8">
-  <title>Ng</title>
-  <base href="/">
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <link rel="icon" type="image/x-icon" href="favicon.ico">
-</head>
-<body>
-  <app-root></app-root>
-</body>
+  <head>
+    <meta charset="utf-8" />
+    <title>HostBBQ Monitoring Web UI</title>
+    <base href="/" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <link rel="icon" type="image/x-icon" href="favicon.ico" />
+  </head>
+  <body>
+    <app-root></app-root>
+  </body>
 </html>

+ 1 - 1
ng/src/styles.scss

@@ -1 +1 @@
-/* You can add global styles to this file, and also import other style files */
+@import '../bootstrap-theme/scss/bootstrap.scss';

Some files were not shown because too many files changed in this diff