From fc6cf6169868e60c189e4b243330c3717ff159f3 Mon Sep 17 00:00:00 2001
From: Gregor Kleen <gkleen@yggdrasil.li>
Date: Thu, 26 May 2022 13:58:07 +0200
Subject: ...

---
 .../spm/frontend/src/app/app-routing.module.ts     | 17 ++++++
 overlays/spm/frontend/src/app/app.component.html   |  7 +++
 overlays/spm/frontend/src/app/app.component.sass   |  0
 overlays/spm/frontend/src/app/app.component.ts     | 21 ++++++++
 overlays/spm/frontend/src/app/app.module.ts        | 32 +++++++++++
 .../spm/frontend/src/app/color-scheme.service.ts   | 62 ++++++++++++++++++++++
 .../page-not-found/page-not-found.component.html   |  5 ++
 .../page-not-found/page-not-found.component.sass   |  0
 .../app/page-not-found/page-not-found.component.ts | 15 ++++++
 .../spm/frontend/src/app/spm/spm.component.html    |  3 ++
 .../spm/frontend/src/app/spm/spm.component.sass    |  0
 overlays/spm/frontend/src/app/spm/spm.component.ts | 24 +++++++++
 overlays/spm/frontend/src/assets/.gitkeep          |  0
 overlays/spm/frontend/src/custom-theme.scss        | 51 ++++++++++++++++++
 .../frontend/src/environments/environment.prod.ts  |  3 ++
 .../spm/frontend/src/environments/environment.ts   | 16 ++++++
 overlays/spm/frontend/src/index.html               | 12 +++++
 overlays/spm/frontend/src/main.ts                  | 12 +++++
 overlays/spm/frontend/src/polyfills.ts             | 53 ++++++++++++++++++
 overlays/spm/frontend/src/styles.sass              |  2 +
 overlays/spm/frontend/src/test.ts                  | 26 +++++++++
 21 files changed, 361 insertions(+)
 create mode 100644 overlays/spm/frontend/src/app/app-routing.module.ts
 create mode 100644 overlays/spm/frontend/src/app/app.component.html
 create mode 100644 overlays/spm/frontend/src/app/app.component.sass
 create mode 100644 overlays/spm/frontend/src/app/app.component.ts
 create mode 100644 overlays/spm/frontend/src/app/app.module.ts
 create mode 100644 overlays/spm/frontend/src/app/color-scheme.service.ts
 create mode 100644 overlays/spm/frontend/src/app/page-not-found/page-not-found.component.html
 create mode 100644 overlays/spm/frontend/src/app/page-not-found/page-not-found.component.sass
 create mode 100644 overlays/spm/frontend/src/app/page-not-found/page-not-found.component.ts
 create mode 100644 overlays/spm/frontend/src/app/spm/spm.component.html
 create mode 100644 overlays/spm/frontend/src/app/spm/spm.component.sass
 create mode 100644 overlays/spm/frontend/src/app/spm/spm.component.ts
 create mode 100644 overlays/spm/frontend/src/assets/.gitkeep
 create mode 100644 overlays/spm/frontend/src/custom-theme.scss
 create mode 100644 overlays/spm/frontend/src/environments/environment.prod.ts
 create mode 100644 overlays/spm/frontend/src/environments/environment.ts
 create mode 100644 overlays/spm/frontend/src/index.html
 create mode 100644 overlays/spm/frontend/src/main.ts
 create mode 100644 overlays/spm/frontend/src/polyfills.ts
 create mode 100644 overlays/spm/frontend/src/styles.sass
 create mode 100644 overlays/spm/frontend/src/test.ts

(limited to 'overlays/spm/frontend/src')

diff --git a/overlays/spm/frontend/src/app/app-routing.module.ts b/overlays/spm/frontend/src/app/app-routing.module.ts
new file mode 100644
index 00000000..2da97cea
--- /dev/null
+++ b/overlays/spm/frontend/src/app/app-routing.module.ts
@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+
+import { SpmComponent } from './spm/spm.component';
+import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
+
+const routes: Routes = [
+  { path: 'spm', component: SpmComponent },
+  { path: '', redirectTo: '/spm', pathMatch: 'full' },
+  { path: '**', component: PageNotFoundComponent }
+];
+
+@NgModule({
+  imports: [RouterModule.forRoot(routes)],
+  exports: [RouterModule]
+})
+export class AppRoutingModule { }
diff --git a/overlays/spm/frontend/src/app/app.component.html b/overlays/spm/frontend/src/app/app.component.html
new file mode 100644
index 00000000..f9b5b8fc
--- /dev/null
+++ b/overlays/spm/frontend/src/app/app.component.html
@@ -0,0 +1,7 @@
+<mat-toolbar color="primary">
+  <div>
+    <a mat-button routerLink="/spm" routerLinkActive="active">spm</a>
+  </div>
+</mat-toolbar>
+<!-- The routed views render in the <router-outlet> -->
+<router-outlet></router-outlet>
diff --git a/overlays/spm/frontend/src/app/app.component.sass b/overlays/spm/frontend/src/app/app.component.sass
new file mode 100644
index 00000000..e69de29b
diff --git a/overlays/spm/frontend/src/app/app.component.ts b/overlays/spm/frontend/src/app/app.component.ts
new file mode 100644
index 00000000..7c231203
--- /dev/null
+++ b/overlays/spm/frontend/src/app/app.component.ts
@@ -0,0 +1,21 @@
+import { Component, OnInit, OnDestroy } from '@angular/core';
+
+import { ColorSchemeService } from './color-scheme.service';
+
+@Component({
+  selector: 'app-root',
+  templateUrl: './app.component.html',
+  styleUrls: ['./app.component.sass']
+})
+export class AppComponent implements OnInit, OnDestroy {
+  title = 'spm-frontend';
+
+  constructor(private colorSchemeService: ColorSchemeService) {}
+
+  ngOnInit() {
+    this.colorSchemeService.init();
+  }
+  ngOnDestroy() {
+    this.colorSchemeService.destroy();
+  }
+}
diff --git a/overlays/spm/frontend/src/app/app.module.ts b/overlays/spm/frontend/src/app/app.module.ts
new file mode 100644
index 00000000..914f73a2
--- /dev/null
+++ b/overlays/spm/frontend/src/app/app.module.ts
@@ -0,0 +1,32 @@
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+
+import { AppRoutingModule } from './app-routing.module';
+import { AppComponent } from './app.component';
+import { SpmComponent } from './spm/spm.component';
+import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { MatIconModule } from '@angular/material/icon';
+import { HttpClientModule } from "@angular/common/http";
+import { MatToolbarModule } from '@angular/material/toolbar';
+import { MatButtonModule } from '@angular/material/button';
+
+@NgModule({
+  declarations: [
+    AppComponent,
+    SpmComponent,
+    PageNotFoundComponent
+  ],
+  imports: [
+    BrowserModule,
+    AppRoutingModule,
+    BrowserAnimationsModule,
+    MatIconModule,
+    HttpClientModule,
+    MatToolbarModule,
+    MatButtonModule
+  ],
+  providers: [],
+  bootstrap: [AppComponent]
+})
+export class AppModule { }
diff --git a/overlays/spm/frontend/src/app/color-scheme.service.ts b/overlays/spm/frontend/src/app/color-scheme.service.ts
new file mode 100644
index 00000000..c56e9c23
--- /dev/null
+++ b/overlays/spm/frontend/src/app/color-scheme.service.ts
@@ -0,0 +1,62 @@
+import { Injectable, Renderer2, RendererFactory2 } from '@angular/core';
+import { MediaMatcher } from '@angular/cdk/layout';
+import { LocalStorage } from 'ngx-webstorage';
+
+type ColorScheme = "dark" | "light";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class ColorSchemeService {
+  private renderer: Renderer2;
+  matcher!: MediaQueryList;
+
+  @LocalStorage('prefers-color-scheme')
+  public colorSchemeOverride: ColorScheme;
+
+  public activeColorScheme: BehaviorSubject<ColorScheme> = new BehaviorSubject("light");
+
+  constructor(rendererFactory: RendererFactory2,
+              mediaMatcher: MediaMatcher
+             ) {
+    // Create new renderer from renderFactory, to make it possible to use renderer2 in a service
+    this.renderer = rendererFactory.createRenderer(null, null);
+    this.matcher = mediaMatcher.matchMedia('(prefers-color-scheme: dark)');
+
+    this._listener = this._listener.bind(this);
+  }
+
+  init() {
+    this.matcher.addEventListener('change', this._listener);
+    this.load();
+  }
+
+  _listener(event: { matches: any; }) {
+    this.activeColorScheme.next(event.matches ? 'dark' : 'light');
+  }
+
+  destroy() {
+    this.matcher.removeEventListener('change', this._listener);
+  }
+
+  _getColorScheme() {
+    if (this.colorSchemeOverride) {
+      this.colorSchemeOverride
+    } else {
+      this.matcher.matches ? 'dark' : 'light'
+    }
+  }
+
+  load() {
+    this.activeColorScheme.next(this._getColorScheme());
+  }
+
+  update(scheme: ColorScheme) {
+    this.colorSchemeOverride = scheme;
+    this.activeColorScheme.next(scheme);
+  }
+
+  currentActive() {
+    return this.colorScheme;
+  }
+}
diff --git a/overlays/spm/frontend/src/app/page-not-found/page-not-found.component.html b/overlays/spm/frontend/src/app/page-not-found/page-not-found.component.html
new file mode 100644
index 00000000..26a283ed
--- /dev/null
+++ b/overlays/spm/frontend/src/app/page-not-found/page-not-found.component.html
@@ -0,0 +1,5 @@
+<div style="margin: 1rem;">
+  <h1>
+    No Such Component
+  </h1>
+</div>
diff --git a/overlays/spm/frontend/src/app/page-not-found/page-not-found.component.sass b/overlays/spm/frontend/src/app/page-not-found/page-not-found.component.sass
new file mode 100644
index 00000000..e69de29b
diff --git a/overlays/spm/frontend/src/app/page-not-found/page-not-found.component.ts b/overlays/spm/frontend/src/app/page-not-found/page-not-found.component.ts
new file mode 100644
index 00000000..2d1091ce
--- /dev/null
+++ b/overlays/spm/frontend/src/app/page-not-found/page-not-found.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-page-not-found',
+  templateUrl: './page-not-found.component.html',
+  styleUrls: ['./page-not-found.component.sass']
+})
+export class PageNotFoundComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit(): void {
+  }
+
+}
diff --git a/overlays/spm/frontend/src/app/spm/spm.component.html b/overlays/spm/frontend/src/app/spm/spm.component.html
new file mode 100644
index 00000000..d1339d95
--- /dev/null
+++ b/overlays/spm/frontend/src/app/spm/spm.component.html
@@ -0,0 +1,3 @@
+<p>spm works!</p>
+
+<mat-icon aria-hidden="false" aria-label="Thumbs up" svgIcon="thumb_up"></mat-icon>
diff --git a/overlays/spm/frontend/src/app/spm/spm.component.sass b/overlays/spm/frontend/src/app/spm/spm.component.sass
new file mode 100644
index 00000000..e69de29b
diff --git a/overlays/spm/frontend/src/app/spm/spm.component.ts b/overlays/spm/frontend/src/app/spm/spm.component.ts
new file mode 100644
index 00000000..7d172052
--- /dev/null
+++ b/overlays/spm/frontend/src/app/spm/spm.component.ts
@@ -0,0 +1,24 @@
+import { Component, OnInit } from '@angular/core';
+import { MatIconRegistry, MatIconModule } from '@angular/material/icon';
+import { DomSanitizer } from "@angular/platform-browser";
+
+@Component({
+  selector: 'app-spm',
+  templateUrl: './spm.component.html',
+  styleUrls: ['./spm.component.sass']
+})
+export class SpmComponent implements OnInit {
+
+  constructor(private matIconRegistry: MatIconRegistry,
+              private domSanitizer: DomSanitizer
+             ) {
+    this.matIconRegistry.addSvgIcon(
+      `thumb_up`,
+      this.domSanitizer.bypassSecurityTrustResourceUrl(`icons/thumb_up/baseline.svg`)
+    );
+  }
+
+  ngOnInit(): void {
+  }
+
+}
diff --git a/overlays/spm/frontend/src/assets/.gitkeep b/overlays/spm/frontend/src/assets/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/overlays/spm/frontend/src/custom-theme.scss b/overlays/spm/frontend/src/custom-theme.scss
new file mode 100644
index 00000000..5c2d48aa
--- /dev/null
+++ b/overlays/spm/frontend/src/custom-theme.scss
@@ -0,0 +1,51 @@
+
+// Custom Theming for Angular Material
+// For more information: https://material.angular.io/guide/theming
+@use '@angular/material' as mat;
+// Plus imports for other components in your app.
+
+// Include the common styles for Angular Material. We include this here so that you only
+// have to load a single css file for Angular Material in your app.
+// Be sure that you only ever include this mixin once!
+@include mat.core();
+
+// Define the palettes for your theme using the Material Design palettes available in palette.scss
+// (imported above). For each palette, you can optionally specify a default, lighter, and darker
+// hue. Available color palettes: https://material.io/design/color/
+$spm-frontend-primary: mat.define-palette(mat.$indigo-palette);
+$spm-frontend-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
+
+// The warn palette is optional (defaults to red).
+$spm-frontend-warn: mat.define-palette(mat.$red-palette);
+
+// Create the theme object. A theme consists of configurations for individual
+// theming systems such as "color" or "typography".
+$spm-frontend-light-theme: mat.define-light-theme((
+  color: (
+    primary: $spm-frontend-primary,
+    accent: $spm-frontend-accent,
+    warn: $spm-frontend-warn,
+  )
+));
+
+$spm-frontend-dark-theme: mat.define-dark-theme((
+  color: (
+    primary: $spm-frontend-primary,
+    accent: $spm-frontend-accent,
+    warn: $spm-frontend-warn,
+  )
+));
+
+
+// Include theme styles for core and each component used in your app.
+// Alternatively, you can import and @include the theme mixins for each component
+// that you are using.
+@include mat.all-component-themes($spm-frontend-dark-theme);
+
+[data-color-scheme="light"] {
+  @include mat.all-component-colors($spm-frontend-light-theme);
+}
+
+
+html, body { height: 100%; }
+body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
diff --git a/overlays/spm/frontend/src/environments/environment.prod.ts b/overlays/spm/frontend/src/environments/environment.prod.ts
new file mode 100644
index 00000000..3612073b
--- /dev/null
+++ b/overlays/spm/frontend/src/environments/environment.prod.ts
@@ -0,0 +1,3 @@
+export const environment = {
+  production: true
+};
diff --git a/overlays/spm/frontend/src/environments/environment.ts b/overlays/spm/frontend/src/environments/environment.ts
new file mode 100644
index 00000000..f56ff470
--- /dev/null
+++ b/overlays/spm/frontend/src/environments/environment.ts
@@ -0,0 +1,16 @@
+// This file can be replaced during build by using the `fileReplacements` array.
+// `ng build` replaces `environment.ts` with `environment.prod.ts`.
+// The list of file replacements can be found in `angular.json`.
+
+export const environment = {
+  production: false
+};
+
+/*
+ * For easier debugging in development mode, you can import the following file
+ * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
+ *
+ * This import should be commented out in production mode because it will have a negative impact
+ * on performance if an error is thrown.
+ */
+// import 'zone.js/plugins/zone-error';  // Included with Angular CLI.
diff --git a/overlays/spm/frontend/src/index.html b/overlays/spm/frontend/src/index.html
new file mode 100644
index 00000000..8bd1bc7f
--- /dev/null
+++ b/overlays/spm/frontend/src/index.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <title>spm</title>
+  <base href="/">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+</head>
+<body class="mat-typography mat-app-background">
+  <app-root></app-root>
+</body>
+</html>
diff --git a/overlays/spm/frontend/src/main.ts b/overlays/spm/frontend/src/main.ts
new file mode 100644
index 00000000..c7b673cf
--- /dev/null
+++ b/overlays/spm/frontend/src/main.ts
@@ -0,0 +1,12 @@
+import { enableProdMode } from '@angular/core';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { AppModule } from './app/app.module';
+import { environment } from './environments/environment';
+
+if (environment.production) {
+  enableProdMode();
+}
+
+platformBrowserDynamic().bootstrapModule(AppModule)
+  .catch(err => console.error(err));
diff --git a/overlays/spm/frontend/src/polyfills.ts b/overlays/spm/frontend/src/polyfills.ts
new file mode 100644
index 00000000..429bb9ef
--- /dev/null
+++ b/overlays/spm/frontend/src/polyfills.ts
@@ -0,0 +1,53 @@
+/**
+ * This file includes polyfills needed by Angular and is loaded before the app.
+ * You can add your own extra polyfills to this file.
+ *
+ * This file is divided into 2 sections:
+ *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
+ *   2. Application imports. Files imported after ZoneJS that should be loaded before your main
+ *      file.
+ *
+ * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
+ * automatically update themselves. This includes recent versions of Safari, Chrome (including
+ * Opera), Edge on the desktop, and iOS and Chrome on mobile.
+ *
+ * Learn more in https://angular.io/guide/browser-support
+ */
+
+/***************************************************************************************************
+ * BROWSER POLYFILLS
+ */
+
+/**
+ * By default, zone.js will patch all possible macroTask and DomEvents
+ * user can disable parts of macroTask/DomEvents patch by setting following flags
+ * because those flags need to be set before `zone.js` being loaded, and webpack
+ * will put import in the top of bundle, so user need to create a separate file
+ * in this directory (for example: zone-flags.ts), and put the following flags
+ * into that file, and then add the following code before importing zone.js.
+ * import './zone-flags';
+ *
+ * The flags allowed in zone-flags.ts are listed here.
+ *
+ * The following flags will work for all browsers.
+ *
+ * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
+ * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
+ * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
+ *
+ *  in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
+ *  with the following flag, it will bypass `zone.js` patch for IE/Edge
+ *
+ *  (window as any).__Zone_enable_cross_context_check = true;
+ *
+ */
+
+/***************************************************************************************************
+ * Zone JS is required by default for Angular itself.
+ */
+import 'zone.js';  // Included with Angular CLI.
+
+
+/***************************************************************************************************
+ * APPLICATION IMPORTS
+ */
diff --git a/overlays/spm/frontend/src/styles.sass b/overlays/spm/frontend/src/styles.sass
new file mode 100644
index 00000000..4f2cb82a
--- /dev/null
+++ b/overlays/spm/frontend/src/styles.sass
@@ -0,0 +1,2 @@
+/* You can add global styles to this file, and also import other style files */
+@import @fontsource/roboto
diff --git a/overlays/spm/frontend/src/test.ts b/overlays/spm/frontend/src/test.ts
new file mode 100644
index 00000000..00025daf
--- /dev/null
+++ b/overlays/spm/frontend/src/test.ts
@@ -0,0 +1,26 @@
+// This file is required by karma.conf.js and loads recursively all the .spec and framework files
+
+import 'zone.js/testing';
+import { getTestBed } from '@angular/core/testing';
+import {
+  BrowserDynamicTestingModule,
+  platformBrowserDynamicTesting
+} from '@angular/platform-browser-dynamic/testing';
+
+declare const require: {
+  context(path: string, deep?: boolean, filter?: RegExp): {
+    <T>(id: string): T;
+    keys(): string[];
+  };
+};
+
+// First, initialize the Angular testing environment.
+getTestBed().initTestEnvironment(
+  BrowserDynamicTestingModule,
+  platformBrowserDynamicTesting(),
+);
+
+// Then we find all the tests.
+const context = require.context('./', true, /\.spec\.ts$/);
+// And load the modules.
+context.keys().map(context);
-- 
cgit v1.2.3