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