Init webapp
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# RossaTechCli
|
||||
# RossaTechApp
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 15.1.6.
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.1.1.
|
||||
|
||||
## Development server
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"outputPath": "dist/rossa-tech-cli",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": ["zone.js"],
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
@@ -32,7 +32,7 @@
|
||||
"output": "./assets"
|
||||
}
|
||||
],
|
||||
"styles": ["src/styles.scss"],
|
||||
"styles": ["src/custom-theme.scss", "src/styles.scss"],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
@@ -40,22 +40,22 @@
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
"maximumWarning": "100mb",
|
||||
"maximumError": "300mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
"maximumWarning": "50mb",
|
||||
"maximumError": "100mb"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all",
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
]
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
@@ -70,10 +70,6 @@
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "rossa-tech-cli:build",
|
||||
"proxyConfig": "src/proxy.conf.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "rossa-tech-cli:build:production"
|
||||
@@ -93,8 +89,10 @@
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": ["zone.js", "zone.js/testing"],
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": ["src/favicon.ico", "src/assets"],
|
||||
"styles": ["src/styles.scss"],
|
||||
@@ -103,5 +101,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
}
|
||||
}
|
||||
|
||||
44
rossa-tech-cli/karma.conf.sj
Normal file
44
rossa-tech-cli/karma.conf.sj
Normal file
@@ -0,0 +1,44 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true // removes the duplicated traces
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: require('path').join(__dirname, './coverage/rossa-tech'),
|
||||
subdir: '.',
|
||||
reporters: [
|
||||
{ type: 'html' },
|
||||
{ type: 'text-summary' }
|
||||
]
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
||||
1554
rossa-tech-cli/package-lock.json
generated
1554
rossa-tech-cli/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -10,25 +10,25 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^15.1.0",
|
||||
"@angular/cdk": "^15.2.4",
|
||||
"@angular/common": "^15.1.0",
|
||||
"@angular/compiler": "^15.1.0",
|
||||
"@angular/core": "^15.1.0",
|
||||
"@angular/forms": "^15.1.0",
|
||||
"@angular/material": "^15.2.4",
|
||||
"@angular/platform-browser": "^15.1.0",
|
||||
"@angular/platform-browser-dynamic": "^15.1.0",
|
||||
"@angular/router": "^15.1.0",
|
||||
"@angular/animations": "^15.2.9",
|
||||
"@angular/cdk": "~15.2.4",
|
||||
"@angular/common": "^15.2.9",
|
||||
"@angular/compiler": "^15.2.9",
|
||||
"@angular/core": "^15.2.9",
|
||||
"@angular/forms": "^15.2.9",
|
||||
"@angular/material": "~15.2.4",
|
||||
"@angular/platform-browser": "^15.2.9",
|
||||
"@angular/platform-browser-dynamic": "^15.2.9",
|
||||
"@angular/router": "^15.2.9",
|
||||
"@mdi/angular-material": "^7.2.96",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^15.1.6",
|
||||
"@angular/cli": "~15.1.6",
|
||||
"@angular/compiler-cli": "^15.1.0",
|
||||
"@angular-devkit/build-angular": "^15.2.8",
|
||||
"@angular/cli": "~15.2.8",
|
||||
"@angular/compiler-cli": "^15.2.9",
|
||||
"@types/jasmine": "~4.3.0",
|
||||
"jasmine-core": "~4.5.0",
|
||||
"karma": "~6.4.0",
|
||||
@@ -36,6 +36,6 @@
|
||||
"karma-coverage": "~2.2.0",
|
||||
"karma-jasmine": "~5.1.0",
|
||||
"karma-jasmine-html-reporter": "~2.0.0",
|
||||
"typescript": "~4.9.4"
|
||||
"typescript": "~4.9.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { DashboardComponent } from 'src/app/components/dashboard/dashboard.component';
|
||||
import { LoginComponent } from './components/login/login.component';
|
||||
// import { AuthGuard } from "./auth/auth.guard";
|
||||
import { NgModule, inject } from "@angular/core";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
import { LoginComponent } from "./components/loginPage/login.component";
|
||||
import { IndexComponent } from "./components/indexPage/index.component";
|
||||
import { DashboardComponent } from "./components/dashboard/dashboard.component";
|
||||
import { AuthService } from "./auth/auth.service";
|
||||
import { AuthGuard } from "./auth/auth.guard";
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: 'dashboard', component: DashboardComponent },
|
||||
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
|
||||
{ path: '**', redirectTo: '/dashboard', pathMatch: 'full' },
|
||||
// { path: 'login', component: LoginComponent },
|
||||
// { path: '', component: LoginComponent },
|
||||
{ path: "login", component: LoginComponent },
|
||||
// { path: "index", component: IndexComponent, canActivate: [AuthGuard] },
|
||||
{
|
||||
path: "dashboard",
|
||||
component: DashboardComponent,
|
||||
canActivate: [AuthGuard],
|
||||
},
|
||||
{ path: "", redirectTo: "/dashboard", pathMatch: "full" },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
0
rossa-tech-cli/src/app/app.component.css
Normal file
0
rossa-tech-cli/src/app/app.component.css
Normal file
@@ -1,3 +1,3 @@
|
||||
<app-loader></app-loader>
|
||||
<app-header></app-header>
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
@@ -1,35 +1,33 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
import { TestBed } from "@angular/core/testing";
|
||||
import { RouterTestingModule } from "@angular/router/testing";
|
||||
import { AppComponent } from "./app.component";
|
||||
|
||||
describe('AppComponent', () => {
|
||||
describe("AppComponent", () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [
|
||||
RouterTestingModule
|
||||
],
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [RouterTestingModule],
|
||||
declarations: [AppComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
it("should create the app", () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should have as title 'rossa-tech-cli'`, () => {
|
||||
it(`should have as title 'rossa-tech'`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('rossa-tech-cli');
|
||||
expect(app.title).toEqual("rossa-tech");
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
it("should render title", () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('.content span')?.textContent).toContain('rossa-tech-cli app is running!');
|
||||
expect(compiled.querySelector(".content span")?.textContent).toContain(
|
||||
"rossa-tech app is running!"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss']
|
||||
selector: "app-root",
|
||||
templateUrl: "./app.component.html",
|
||||
styleUrls: ["./app.component.css"],
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'rossa-tech-cli';
|
||||
title = "rossa-tech";
|
||||
}
|
||||
|
||||
@@ -1,60 +1,59 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule, DomSanitizer } from '@angular/platform-browser';
|
||||
import { NgModule } from "@angular/core";
|
||||
import { BrowserModule, DomSanitizer } from "@angular/platform-browser";
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { DashboardComponent } from './components/dashboard/dashboard.component';
|
||||
import { MetersComponent } from './components/meters/meters.component';
|
||||
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { MatIconModule, MatIconRegistry } from '@angular/material/icon';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { LoaderComponent } from './components/loader/loader.component';
|
||||
import { HeaderComponent } from './components/header/header.component';
|
||||
import { MeterDataListComponent } from './components/subcomponents/meter-data-list/meter-data-list.component';
|
||||
import { MatGridListModule } from '@angular/material/grid-list';
|
||||
import { ConsumptionLastYearComponent } from './components/subcomponents/consumption-last-year/consumption-last-year.component';
|
||||
import { MeterDataWrapperComponent } from './components/subcomponents/meter-data-wrapper/meter-data-wrapper.component';
|
||||
import { MeterDataAddDialogComponent } from './components/dialogs/meter-data-add-dialog/meter-data-add-dialog.component';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatNativeDateModule } from '@angular/material/core';
|
||||
import { LoginComponent } from './components/login/login.component';
|
||||
import { LogoutComponent } from './components/logout/logout.component';
|
||||
// import { HttpInterceptorService } from './components/interceptors/httpInterceptor.service';
|
||||
import { AppRoutingModule } from "./app-routing.module";
|
||||
import { HttpClientModule } from "@angular/common/http";
|
||||
import { AppComponent } from "./app.component";
|
||||
import { LoginComponent } from "./components/loginPage/login.component";
|
||||
import { IndexComponent } from "./components/indexPage/index.component";
|
||||
import { DashboardComponent } from "./components/dashboard/dashboard.component";
|
||||
import { MeterDataListComponent } from "./components/subcomponents/meter-data-list/meter-data-list.component";
|
||||
import { ConsumptionLastYearComponent } from "./components/subcomponents/consumption-last-year/consumption-last-year.component";
|
||||
import { MeterDataWrapperComponent } from "./components/subcomponents/meter-data-wrapper/meter-data-wrapper.component";
|
||||
import { HeaderComponent } from "./components/header/header.component";
|
||||
import { LoaderComponent } from "./components/loader/loader.component";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
|
||||
import { MatCardModule } from "@angular/material/card";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatSelectModule } from "@angular/material/select";
|
||||
import { MatTableModule } from "@angular/material/table";
|
||||
import { MatProgressBarModule } from "@angular/material/progress-bar";
|
||||
import { MatToolbarModule } from "@angular/material/toolbar";
|
||||
import { MatSidenavModule } from "@angular/material/sidenav";
|
||||
import { MatIconModule, MatIconRegistry } from "@angular/material/icon";
|
||||
import { MatListModule } from "@angular/material/list";
|
||||
import { MatGridListModule } from "@angular/material/grid-list";
|
||||
import { MatDialogModule } from "@angular/material/dialog";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
import { MatDatepickerModule } from "@angular/material/datepicker";
|
||||
import { MatNativeDateModule } from "@angular/material/core";
|
||||
import { MeterDataAddDialogComponent } from "./dialogs/meter-data-add-dialog/meter-data-add-dialog.component";
|
||||
import { SnackbarComponent } from "./components/snackbar/snackbar.component";
|
||||
import { MatSnackBarModule } from "@angular/material/snack-bar";
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
LoginComponent,
|
||||
IndexComponent,
|
||||
DashboardComponent,
|
||||
MetersComponent,
|
||||
LoaderComponent,
|
||||
HeaderComponent,
|
||||
MeterDataListComponent,
|
||||
ConsumptionLastYearComponent,
|
||||
MeterDataWrapperComponent,
|
||||
MeterDataAddDialogComponent,
|
||||
LoginComponent,
|
||||
LogoutComponent,
|
||||
SnackbarComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
HttpClientModule,
|
||||
BrowserAnimationsModule,
|
||||
FormsModule,
|
||||
AppRoutingModule,
|
||||
HttpClientModule,
|
||||
FormsModule,
|
||||
BrowserAnimationsModule,
|
||||
MatCardModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
@@ -71,6 +70,7 @@ import { LogoutComponent } from './components/logout/logout.component';
|
||||
ReactiveFormsModule,
|
||||
MatDatepickerModule,
|
||||
MatNativeDateModule,
|
||||
MatSnackBarModule,
|
||||
],
|
||||
providers: [
|
||||
MatDatepickerModule,
|
||||
@@ -85,7 +85,7 @@ import { LogoutComponent } from './components/logout/logout.component';
|
||||
export class AppModule {
|
||||
constructor(matIconRegistry: MatIconRegistry, domSanitizer: DomSanitizer) {
|
||||
matIconRegistry.addSvgIconSet(
|
||||
domSanitizer.bypassSecurityTrustResourceUrl('./assets/mdi.svg')
|
||||
domSanitizer.bypassSecurityTrustResourceUrl("./assets/mdi.svg")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
32
rossa-tech-cli/src/app/auth/auth.guard.ts
Normal file
32
rossa-tech-cli/src/app/auth/auth.guard.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { Observable } from "rxjs";
|
||||
import { Injectable } from "@angular/core";
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
Router,
|
||||
RouterStateSnapshot,
|
||||
} from "@angular/router";
|
||||
import { AuthService } from "./auth.service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class AuthGuard {
|
||||
constructor(private router: Router, private authService: AuthService) {}
|
||||
|
||||
canActivate(
|
||||
next: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot
|
||||
): Observable<boolean> | Promise<boolean> | boolean {
|
||||
console.log("authGuard");
|
||||
|
||||
if (this.authService.checkUserLoggedIn()) {
|
||||
console.log("logged in");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
console.log("not logged in");
|
||||
this.router.navigate(["/login"]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
rossa-tech-cli/src/app/auth/auth.service.ts
Normal file
30
rossa-tech-cli/src/app/auth/auth.service.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class AuthService {
|
||||
constructor() {}
|
||||
|
||||
public checkUserLoggedIn(): Boolean {
|
||||
let retVal: Boolean = false,
|
||||
currUserObj: any = null,
|
||||
currUser: any;
|
||||
if (sessionStorage.getItem("currentUser") != null) {
|
||||
currUserObj = sessionStorage.getItem("currentUser");
|
||||
if (
|
||||
currUserObj != null &&
|
||||
currUserObj.toString() != null &&
|
||||
currUserObj.toString().trim() !== ""
|
||||
) {
|
||||
currUser = JSON.parse(currUserObj.toString());
|
||||
if (currUser && currUser.userId && currUser.userId.trim() !== "") {
|
||||
retVal =
|
||||
currUser.tokenValue != null && currUser.tokenValue.trim() !== "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
99
rossa-tech-cli/src/app/auth/login.service.ts
Normal file
99
rossa-tech-cli/src/app/auth/login.service.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { HttpClient, HttpHeaders } from "@angular/common/http";
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import { LoginUser } from "../dataModels/loginUser.type";
|
||||
import { environment } from "../../environments/environment";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class LoginService {
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
public login(userToLogin: LoginUser): Observable<any> {
|
||||
return this.http.post<any>(
|
||||
environment.apiBaseUrl + "/authenticate",
|
||||
userToLogin
|
||||
);
|
||||
}
|
||||
|
||||
public signout(): Observable<any> {
|
||||
let jwtToken: String = this.getUserSecurityToken(),
|
||||
headers: HttpHeaders = new HttpHeaders({
|
||||
authorization: "bearer " + jwtToken,
|
||||
}),
|
||||
options = { headers: headers };
|
||||
return this.http.post<any>(
|
||||
environment.apiBaseUrl + "/signOut",
|
||||
null,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
public setSessionCurrentUser(userToAdd: any): void {
|
||||
if (
|
||||
userToAdd != null &&
|
||||
userToAdd.userId &&
|
||||
userToAdd.userId.trim() !== "" &&
|
||||
userToAdd.tokenValue &&
|
||||
userToAdd.tokenValue.trim() !== ""
|
||||
) {
|
||||
if (sessionStorage.getItem("currentUser") != null) {
|
||||
sessionStorage.removeItem("currentUser");
|
||||
}
|
||||
|
||||
sessionStorage.setItem("currentUser", JSON.stringify(userToAdd));
|
||||
}
|
||||
}
|
||||
|
||||
public removeSessionCurrentUser(): void {
|
||||
if (sessionStorage.getItem("currentUser") != null) {
|
||||
sessionStorage.removeItem("currentUser");
|
||||
}
|
||||
}
|
||||
|
||||
public getLoggedinUser(): any | null {
|
||||
let retVal: any | null = null,
|
||||
currUser: any | null = null,
|
||||
currUserObj: any = null;
|
||||
|
||||
if (sessionStorage.getItem("currentUser") != null) {
|
||||
currUserObj = sessionStorage.getItem("currentUser");
|
||||
if (
|
||||
currUserObj != null &&
|
||||
currUserObj.toString() != null &&
|
||||
currUserObj.toString().trim() !== ""
|
||||
) {
|
||||
currUser = JSON.parse(currUserObj.toString());
|
||||
if (currUser && currUser.userId && currUser.userId.trim() !== "") {
|
||||
retVal = currUser;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public getUserSecurityToken(): String {
|
||||
let retVal: String = "",
|
||||
currUser: any | null = null,
|
||||
currUserObj: any = null;
|
||||
|
||||
if (sessionStorage.getItem("currentUser") != null) {
|
||||
currUserObj = sessionStorage.getItem("currentUser");
|
||||
if (
|
||||
currUserObj != null &&
|
||||
currUserObj.toString() != null &&
|
||||
currUserObj.toString().trim() !== ""
|
||||
) {
|
||||
currUser = JSON.parse(currUserObj.toString());
|
||||
if (currUser && currUser.userId && currUser.userId.trim() !== "") {
|
||||
retVal = currUser.tokenValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,25 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { LoaderService } from 'src/app/components/loader/loader.service';
|
||||
import { MeterDataAddDialogComponent } from 'src/app/components/dialogs/meter-data-add-dialog/meter-data-add-dialog.component';
|
||||
import { DatabaseService } from 'src/app/services/database.service';
|
||||
import { GlobalService } from 'src/app/services/global.service';
|
||||
import { UsageType } from 'src/app/models/UsageType';
|
||||
import { MeterData } from 'src/app/models/Meterdata';
|
||||
import { HttpErrorResponse } from "@angular/common/http";
|
||||
import { Component } from "@angular/core";
|
||||
import { MatDialog } from "@angular/material/dialog";
|
||||
import { LoaderService } from "src/app/components/loader/loader.service";
|
||||
import { MeterData } from "src/app/dataModels/Meterdata";
|
||||
import { UsageType } from "src/app/dataModels/UsageType";
|
||||
import { MeterDataAddDialogComponent } from "src/app/dialogs/meter-data-add-dialog/meter-data-add-dialog.component";
|
||||
import { DatabaseService } from "src/app/services/database.service";
|
||||
import { ErrorService } from "src/app/services/error.service";
|
||||
import { GlobalService } from "src/app/services/global.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
templateUrl: './dashboard.component.html',
|
||||
styleUrls: ['./dashboard.component.scss'],
|
||||
selector: "app-dashboard",
|
||||
templateUrl: "./dashboard.component.html",
|
||||
styleUrls: ["./dashboard.component.scss"],
|
||||
})
|
||||
export class DashboardComponent {
|
||||
usageTypes = UsageType;
|
||||
|
||||
// meterDataEnergy1Hem: MeterData[] = [];
|
||||
// meterDataEnergy1Log: MeterData[] = [];
|
||||
meterDataEnergy: MeterData[] = [];
|
||||
meterDataWater: MeterData[] = [];
|
||||
|
||||
// meterDataEnergyDTO1Log: MeterData[] = [];
|
||||
// meterDataEnergyDTO1Hem: MeterData[] = [];
|
||||
meterDataEnergyDTO: MeterData[] = [];
|
||||
meterDataWaterDTO: MeterData[] = [];
|
||||
|
||||
@@ -29,12 +27,13 @@ export class DashboardComponent {
|
||||
energyAverageAmountLastYear1Hem: number = 0;
|
||||
waterAverageAmountLastYear: number = 0;
|
||||
|
||||
displayedColumns: string[] = ['date', 'amount', 'meter'];
|
||||
displayedColumns: string[] = ["date", "amount", "meter"];
|
||||
|
||||
constructor(
|
||||
private dataService: DatabaseService,
|
||||
private loaderService: LoaderService,
|
||||
private globalService: GlobalService,
|
||||
private errorService: ErrorService,
|
||||
private dialog: MatDialog
|
||||
) {
|
||||
this.loadMeterData();
|
||||
@@ -46,11 +45,11 @@ export class DashboardComponent {
|
||||
next: (data) => {
|
||||
this.splitMeterData(data);
|
||||
this.loaderService.hide();
|
||||
console.log('Meter data:', data);
|
||||
console.log("Meter data:", data);
|
||||
},
|
||||
error: (err) => {
|
||||
error: (error: HttpErrorResponse) => {
|
||||
this.errorService.handleError(error);
|
||||
this.loaderService.hide();
|
||||
console.error(err);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -70,16 +69,6 @@ export class DashboardComponent {
|
||||
}
|
||||
|
||||
initEnergyMeterData(): void {
|
||||
// this.meterDataEnergy1Log = this.globalService.sortMeterData(
|
||||
// this.meterDataEnergy1Log
|
||||
// );
|
||||
// this.meterDataEnergy1Hem = this.globalService.sortMeterData(
|
||||
// this.meterDataEnergy1Hem
|
||||
// );
|
||||
|
||||
// this.meterDataEnergyDTO1Log = this.meterDataEnergy1Log;
|
||||
// this.meterDataEnergyDTO1Hem = this.meterDataEnergy1Hem;
|
||||
|
||||
this.meterDataEnergy = this.globalService.sortMeterData(
|
||||
this.meterDataEnergy
|
||||
);
|
||||
@@ -103,8 +92,9 @@ export class DashboardComponent {
|
||||
next: (meterData: MeterData) => {
|
||||
console.log({ meterData });
|
||||
},
|
||||
error: (err) => {
|
||||
console.log('add meterData error', { err });
|
||||
error: (error: HttpErrorResponse) => {
|
||||
this.errorService.handleError(error);
|
||||
this.loaderService.hide();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<div class="header-wrapper">
|
||||
<div class="header-wrapper" *ngIf="userLoggedIn">
|
||||
<div class="logo">
|
||||
rossa-tech
|
||||
</div>
|
||||
|
||||
<div class="nav">
|
||||
|
||||
<button type="button" class="btn btn-link" routerLink="/index">home</button>
|
||||
<button type="button" class="btn btn-link" routerLink="/dashboard">dashboard</button>
|
||||
</div>
|
||||
|
||||
<div class="account">
|
||||
<button mat-button>logout</button>
|
||||
<button mat-button (click)="onClickLogout()">logout</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,10 +1,76 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { HttpErrorResponse } from "@angular/common/http";
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { AuthService } from "src/app/auth/auth.service";
|
||||
import { LoginService } from "src/app/auth/login.service";
|
||||
import { ErrorService } from "src/app/services/error.service";
|
||||
import { PageSecurityService } from "src/app/services/pageSecurity.service";
|
||||
import { LoaderService } from "../loader/loader.service";
|
||||
import { NotificationService } from "src/app/services/notification.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-header',
|
||||
templateUrl: './header.component.html',
|
||||
styleUrls: ['./header.component.scss']
|
||||
selector: "app-header",
|
||||
templateUrl: "./header.component.html",
|
||||
styleUrls: ["./header.component.scss"],
|
||||
})
|
||||
export class HeaderComponent {
|
||||
export class HeaderComponent implements OnInit {
|
||||
userLoggedIn: Boolean = false;
|
||||
|
||||
constructor(
|
||||
private loginService: LoginService,
|
||||
private pageSecurityService: PageSecurityService,
|
||||
private errorService: ErrorService,
|
||||
private loaderService: LoaderService,
|
||||
private notificationService: NotificationService,
|
||||
private authService: AuthService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.userLoggedIn = this.authService.checkUserLoggedIn();
|
||||
}
|
||||
|
||||
public onClickLogout(): void {
|
||||
this.loaderService.hide();
|
||||
|
||||
this.loginService.signout().subscribe({
|
||||
next: (resp: any) => {
|
||||
if (resp != null) {
|
||||
if (resp.successful) {
|
||||
// alert("Signed out successfully"); /// XXX
|
||||
this.notificationService.showSnackbar(
|
||||
"Signed out successfully",
|
||||
3000,
|
||||
"snackbar-success",
|
||||
true,
|
||||
"check"
|
||||
);
|
||||
this.loginService.removeSessionCurrentUser();
|
||||
this.pageSecurityService.gotoLoginPage();
|
||||
} else {
|
||||
// alert("Signed out failed with error. " + resp.detailedMessage); /// XXX
|
||||
this.notificationService.showSnackbar(
|
||||
"Signed out failed with error. " + resp.detailedMessage,
|
||||
3000,
|
||||
"snackbar-warning",
|
||||
true,
|
||||
"information-slab-circle-outline"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// alert("Signed out failed with error. Unknown error."); /// XXX
|
||||
this.notificationService.showSnackbar(
|
||||
"Signed out failed with error. Unknown error.",
|
||||
3000,
|
||||
"snackbar-warning",
|
||||
true,
|
||||
"information-slab-circle-outline"
|
||||
);
|
||||
}
|
||||
this.loaderService.hide();
|
||||
},
|
||||
error: (error: HttpErrorResponse) => {
|
||||
this.errorService.handleError(error);
|
||||
this.loaderService.hide();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.link_click {
|
||||
cursor:pointer;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">Game Title</th>
|
||||
<th scope="col">Publisher</th>
|
||||
<th scope="col">Developed by</th>
|
||||
<th scope="col">Publishing Year</th>
|
||||
<th scope="col">Retail Price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let title of allTitles; let i = index">
|
||||
<td>{{i}}</td>
|
||||
<td>{{title.gameTitleValue}}</td>
|
||||
<td>{{title.publisherValue}}</td>
|
||||
<td>{{title.devStudioNameValue}}</td>
|
||||
<td>{{title.publishingYearValue}}</td>
|
||||
<td>${{title.retailPriceValue}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,90 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { HttpErrorResponse } from "@angular/common/http";
|
||||
// import { PageSecurityService } from "../common/pageSecurity.service";
|
||||
import { GameTitlesService } from "../../services/gameTitles.service";
|
||||
import { LoginService } from "../../auth/login.service";
|
||||
import { GameTitle } from "../../dataModels/gameTitle.type";
|
||||
import { PageSecurityService } from "src/app/services/pageSecurity.service";
|
||||
import { AuthService } from "src/app/auth/auth.service";
|
||||
|
||||
@Component({
|
||||
selector: "app-root",
|
||||
templateUrl: "./index.component.html",
|
||||
styleUrls: ["./index.component.css"],
|
||||
})
|
||||
export class IndexComponent implements OnInit {
|
||||
private _allTitles: Array<GameTitle> = [];
|
||||
public testArray: Array<String> = [];
|
||||
|
||||
constructor(
|
||||
private loginService: LoginService,
|
||||
private pageSecurityService: PageSecurityService,
|
||||
private gameTitlesService: GameTitlesService,
|
||||
private authService: AuthService
|
||||
) {
|
||||
this.testArray.push("Test1");
|
||||
this.testArray.push("Test2");
|
||||
this.testArray.push("Test3");
|
||||
this.testArray.push("Test4");
|
||||
this.testArray.push("Test5");
|
||||
}
|
||||
|
||||
public get allTitles(): Array<GameTitle> {
|
||||
return this._allTitles;
|
||||
}
|
||||
|
||||
public set allTitles(val: Array<GameTitle>) {
|
||||
this._allTitles = val;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
// let userLoggedIn: Boolean = this.authService.checkUserLoggedIn();
|
||||
// if (!userLoggedIn) {
|
||||
// this.pageSecurityService.gotoLoginPage();
|
||||
// } else {
|
||||
this.loadAllGameTitles();
|
||||
// }
|
||||
}
|
||||
|
||||
private loadAllGameTitles(): void {
|
||||
let self = this;
|
||||
self.gameTitlesService.getAllGameTitles().subscribe(
|
||||
(resp: any) => {
|
||||
if (resp && resp.length > 0) {
|
||||
for (var itm of resp) {
|
||||
if (itm) {
|
||||
let titleToAdd: GameTitle = new GameTitle(
|
||||
itm.gameTitle,
|
||||
itm.publisher,
|
||||
itm.devStudioName,
|
||||
itm.publishingYear,
|
||||
itm.retailPrice
|
||||
);
|
||||
self._allTitles.push(titleToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
(error: HttpErrorResponse) => {
|
||||
if (error != null) {
|
||||
if (error.status === 0) {
|
||||
// XXX
|
||||
console.log("Client error.");
|
||||
} else if (error.status === 401 || error.status === 403) {
|
||||
// XXX
|
||||
alert("You are not authorized.");
|
||||
console.log("You are not authorized.");
|
||||
self.loginService.removeSessionCurrentUser();
|
||||
self.pageSecurityService.gotoLoginPage();
|
||||
} else if (error.status === 500) {
|
||||
alert("Server error.");
|
||||
console.log("Server error occurred.");
|
||||
} else {
|
||||
alert("Unknown error.");
|
||||
console.log("Unknown error: " + error.status);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<div class="login-form-wrapper">
|
||||
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<form [formGroup]="loginForm" (ngSubmit)="login()">
|
||||
<h2>Log In</h2>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Email" formControlName="userName" name="username" required>
|
||||
<mat-error>
|
||||
Please provide a valid email address
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" placeholder="Password" formControlName="userPass" name="password" required>
|
||||
<mat-error>
|
||||
Please provide a valid password
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<button mat-raised-button color="primary" [disabled]="!loginForm.valid">Login</button>
|
||||
</form>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
@@ -0,0 +1,17 @@
|
||||
mat-card {
|
||||
max-width: 400px;
|
||||
margin: 2em auto;
|
||||
text-align: center;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
|
||||
login-form-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { HttpErrorResponse } from "@angular/common/http";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { LoginUser } from "../../dataModels/loginUser.type";
|
||||
import { LoginService } from "../../auth/login.service";
|
||||
import { FormsService } from "../../services/forms.service";
|
||||
import { AuthService } from "src/app/auth/auth.service";
|
||||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||
import { LoaderService } from "../loader/loader.service";
|
||||
import { NotificationService } from "src/app/services/notification.service";
|
||||
|
||||
@Component({
|
||||
selector: "app-root",
|
||||
templateUrl: "./login.component.html",
|
||||
styleUrls: ["./login.component.scss"],
|
||||
})
|
||||
export class LoginComponent implements OnInit {
|
||||
loginForm: FormGroup = new FormGroup({
|
||||
userName: new FormControl("", Validators.required),
|
||||
userPass: new FormControl("", Validators.required),
|
||||
});
|
||||
|
||||
constructor(
|
||||
private loginService: LoginService,
|
||||
private formsService: FormsService,
|
||||
private authService: AuthService,
|
||||
private loaderService: LoaderService,
|
||||
private notificationService: NotificationService,
|
||||
private router: Router
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
let userLoggedIn: Boolean = this.authService.checkUserLoggedIn();
|
||||
if (userLoggedIn) {
|
||||
this.router.navigate(["/index"]);
|
||||
}
|
||||
}
|
||||
|
||||
public resetForm(): void {
|
||||
this.loginForm.reset();
|
||||
this.formsService.makeFormFieldsClean(this.loginForm);
|
||||
}
|
||||
|
||||
public login(): void {
|
||||
this.formsService.makeFormFieldsDirty(this.loginForm);
|
||||
|
||||
if (this.loginForm.valid) {
|
||||
this.loaderService.show();
|
||||
|
||||
let userToLogin: LoginUser = new LoginUser(
|
||||
this.loginForm.value.userName,
|
||||
this.loginForm.value.userPass
|
||||
);
|
||||
|
||||
this.loginService.login(userToLogin).subscribe({
|
||||
next: (resp: any) => {
|
||||
if (
|
||||
resp != null &&
|
||||
resp.userId != null &&
|
||||
resp.userId.trim() !== "" &&
|
||||
resp.tokenValue != null &&
|
||||
resp.tokenValue.trim() !== ""
|
||||
) {
|
||||
this.loginService.setSessionCurrentUser(resp);
|
||||
this.router.navigate(["/"]);
|
||||
}
|
||||
},
|
||||
error: (error: HttpErrorResponse) => {
|
||||
if (error != null) {
|
||||
if (error.status === 0) {
|
||||
console.log("Client error.");
|
||||
this.notificationService.showSnackbar(
|
||||
"Client error",
|
||||
3000,
|
||||
"snackbar-warning",
|
||||
true,
|
||||
"alert-circle-outline"
|
||||
);
|
||||
} else if (error.status === 401 || error.status === 403) {
|
||||
this.loginForm.reset();
|
||||
this.formsService.makeFormFieldsClean(this.loginForm);
|
||||
console.log("You are not authorized.");
|
||||
} else if (error.status === 500) {
|
||||
console.log("Server error occurred.");
|
||||
} else {
|
||||
console.log("Unknown error: " + error.status);
|
||||
}
|
||||
this.loaderService.hide();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
snack-bar-container.mat-mdc-snack-bar-container {
|
||||
background-color: white;
|
||||
padding: 10px 16px 10px 12px;
|
||||
border-radius: 3px;
|
||||
box-shadow: 1px 2px 10px 2px rgba(0, 0, 0, 0.12);
|
||||
min-width: 352px;
|
||||
max-width: 544px;
|
||||
}
|
||||
|
||||
div.snackbar {
|
||||
color: #595959;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
mat-icon.snackbar-icon {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
span.snackbar-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
mat-icon.snackbar-btn {
|
||||
color: #595959;
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
cursor: pointer;
|
||||
margin-left: 72px;
|
||||
}
|
||||
|
||||
&.snackbar-warning {
|
||||
color: red;
|
||||
}
|
||||
|
||||
&.snackbar-success {
|
||||
color: green;
|
||||
}
|
||||
|
||||
&.snackbar-primary {
|
||||
color: blue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<div class="snackbar" [ngClass]="data?.className">
|
||||
<mat-icon class="snackbar-icon" svgIcon="{{data?.iconName}}" *ngIf="data?.icon"></mat-icon>
|
||||
<span class="snackbar-text">
|
||||
{{data?.message}}
|
||||
</span>
|
||||
<mat-icon svgIcon="close" class="snackbar-btn" (click)="snackBar.dismiss()"></mat-icon>
|
||||
</div>
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Component, Inject } from "@angular/core";
|
||||
import { MAT_SNACK_BAR_DATA, MatSnackBar } from "@angular/material/snack-bar";
|
||||
|
||||
@Component({
|
||||
selector: "app-snackbar",
|
||||
templateUrl: "./snackbar.component.html",
|
||||
styleUrls: ["snackbar-component.scss"],
|
||||
})
|
||||
export class SnackbarComponent {
|
||||
/*
|
||||
* data = {
|
||||
* message: string; snackbar text
|
||||
* className: string; snackbar class
|
||||
* btnLabel: string; Button label text
|
||||
* icon: boolean; show icon
|
||||
* iconName: string; name of the icon
|
||||
* }
|
||||
*
|
||||
* icons:
|
||||
* check
|
||||
* alert-circle-outline
|
||||
* information-slab-circle-outline
|
||||
* server-off
|
||||
*
|
||||
*/
|
||||
constructor(
|
||||
@Inject(MAT_SNACK_BAR_DATA) public data: any,
|
||||
public snackBar: MatSnackBar
|
||||
) {}
|
||||
}
|
||||
@@ -1,20 +1,43 @@
|
||||
<ng-container *ngIf="type == usageTypes.ENERGY; else water">
|
||||
<div style="display: flex; flex-direction: column">
|
||||
|
||||
<div>energy</div>
|
||||
<div style="display: flex; flex-direction: row;">
|
||||
<div>{{averageEnergy1Log}} kWh</div>
|
||||
<div>{{averageEnergy1Hem}} kWh</div>
|
||||
</div>
|
||||
<h2>{{type}}</h2>
|
||||
|
||||
<mat-grid-list cols="2" rowHeight="50px">
|
||||
<mat-grid-tile>
|
||||
1LOG - Hausstrom
|
||||
</mat-grid-tile>
|
||||
<mat-grid-tile>
|
||||
1HEM - Heizstrom
|
||||
</mat-grid-tile>
|
||||
<mat-grid-tile>
|
||||
<div>{{averageEnergy1Log}} kWh</div>
|
||||
</mat-grid-tile>
|
||||
<mat-grid-tile>
|
||||
<div>{{averageEnergy1Hem}} kWh</div>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
</div>
|
||||
|
||||
|
||||
</ng-container>
|
||||
|
||||
<ng-template #water>
|
||||
<div style="display: flex; flex-direction: column">
|
||||
|
||||
<h2>{{type}}</h2>
|
||||
|
||||
<mat-grid-list cols="2" rowHeight="50px">
|
||||
<mat-grid-tile>
|
||||
Wasser
|
||||
</mat-grid-tile>
|
||||
<mat-grid-tile>
|
||||
Abwasser
|
||||
</mat-grid-tile>
|
||||
<mat-grid-tile>
|
||||
<div>xxxxx</div>
|
||||
</mat-grid-tile>
|
||||
<mat-grid-tile>
|
||||
<div>xxxxx</div>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
|
||||
<!-- <ng-container *ngIf="amount > 0; else noData">{{amount}} kWh</ng-container>
|
||||
<ng-template #noData>keine Daten vorhanden</ng-template> -->
|
||||
@@ -1,44 +1,46 @@
|
||||
import { Component, Input, OnChanges } from '@angular/core';
|
||||
import { Meters } from 'src/app/models/Meter';
|
||||
import { MeterData } from 'src/app/models/Meterdata';
|
||||
import { UsageType } from 'src/app/models/UsageType';
|
||||
import { GlobalService } from 'src/app/services/global.service';
|
||||
import { Component, Input, OnChanges } from "@angular/core";
|
||||
import { Meters } from "src/app/dataModels/Meter";
|
||||
import { MeterData } from "src/app/dataModels/Meterdata";
|
||||
import { UsageType } from "src/app/dataModels/UsageType";
|
||||
import { GlobalService } from "src/app/services/global.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-consumption-last-year',
|
||||
templateUrl: './consumption-last-year.component.html',
|
||||
styleUrls: ['./consumption-last-year.component.scss'],
|
||||
selector: "app-consumption-last-year",
|
||||
templateUrl: "./consumption-last-year.component.html",
|
||||
styleUrls: ["./consumption-last-year.component.scss"],
|
||||
})
|
||||
export class ConsumptionLastYearComponent implements OnChanges {
|
||||
@Input() meterData: MeterData[];
|
||||
@Input() type: UsageType;
|
||||
@Input()
|
||||
meterData!: MeterData[];
|
||||
@Input()
|
||||
type!: UsageType;
|
||||
|
||||
usageTypes = UsageType;
|
||||
meters = Meters;
|
||||
|
||||
meterDataEnergy1Hem: MeterData[] = [];
|
||||
averageEnergy1Hem: number;
|
||||
averageEnergy1Hem!: number;
|
||||
|
||||
meterDataEnergy1Log: MeterData[] = [];
|
||||
averageEnergy1Log: number;
|
||||
averageEnergy1Log!: number;
|
||||
|
||||
meterDataWasser: MeterData[] = [];
|
||||
averageWasser: number;
|
||||
averageWasser!: number;
|
||||
|
||||
meterDataAbwasser: MeterData[] = [];
|
||||
averageDirtyAbwasser: number;
|
||||
averageDirtyAbwasser!: number;
|
||||
|
||||
constructor(private globalService: GlobalService) {}
|
||||
|
||||
ngOnChanges(): void {
|
||||
if (this.type && this.type === this.usageTypes.ENERGY) {
|
||||
console.log('count energy');
|
||||
console.log("count energy");
|
||||
|
||||
if (this.meterData) {
|
||||
this.meterData.forEach((data) => {
|
||||
if (data.meter.name === this.meters['1LOG']) {
|
||||
if (data.meter.name === this.meters["1LOG"]) {
|
||||
this.meterDataEnergy1Log.push(data);
|
||||
} else if (data.meter.name === this.meters['1HEM']) {
|
||||
} else if (data.meter.name === this.meters["1HEM"]) {
|
||||
this.meterDataEnergy1Hem.push(data);
|
||||
}
|
||||
});
|
||||
@@ -61,13 +63,13 @@ export class ConsumptionLastYearComponent implements OnChanges {
|
||||
);
|
||||
}
|
||||
} else if (this.type && this.type === this.usageTypes.WATER) {
|
||||
console.log('count water');
|
||||
console.log("count water");
|
||||
|
||||
if (this.meterData) {
|
||||
this.meterData.forEach((data) => {
|
||||
if (data.meter.name === this.meters['WASSER']) {
|
||||
if (data.meter.name === this.meters["WASSER"]) {
|
||||
this.meterDataWasser.push(data);
|
||||
} else if (data.meter.name === this.meters['ABWASSER']) {
|
||||
} else if (data.meter.name === this.meters["ABWASSER"]) {
|
||||
this.meterDataAbwasser.push(data);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
<h2>{{type}}</h2>
|
||||
|
||||
<div class="meter-data-list-wrapper">
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import { Component, Input, OnChanges, OnInit } from '@angular/core';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { UsageType } from 'src/app/models/UsageType';
|
||||
import { MeterData } from 'src/app/models/Meterdata';
|
||||
import { Component, Input, OnChanges, OnInit } from "@angular/core";
|
||||
import { MatTableDataSource } from "@angular/material/table";
|
||||
import { UsageType } from "src/app/dataModels/UsageType";
|
||||
import { MeterData } from "src/app/dataModels/Meterdata";
|
||||
|
||||
@Component({
|
||||
selector: 'app-meter-data-list',
|
||||
templateUrl: './meter-data-list.component.html',
|
||||
styleUrls: ['./meter-data-list.component.scss'],
|
||||
selector: "app-meter-data-list",
|
||||
templateUrl: "./meter-data-list.component.html",
|
||||
styleUrls: ["./meter-data-list.component.scss"],
|
||||
})
|
||||
export class MeterDataListComponent implements OnInit, OnChanges {
|
||||
@Input() meterData: MeterData[];
|
||||
@Input() type: UsageType;
|
||||
@Input()
|
||||
meterData: MeterData[] = [];
|
||||
@Input()
|
||||
type: UsageType = UsageType.ENERGY;
|
||||
|
||||
displayedColumns: string[] = ['id', 'date', 'amount', 'meter'];
|
||||
displayedColumns: string[] = ["id", "date", "amount", "meter"];
|
||||
|
||||
dataSource = new MatTableDataSource<MeterData>();
|
||||
// dataSource = [
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { Component, Input, OnChanges } from '@angular/core';
|
||||
import { MeterData } from 'src/app/models/Meterdata';
|
||||
import { UsageType } from 'src/app/models/UsageType';
|
||||
import { GlobalService } from 'src/app/services/global.service';
|
||||
import { Component, Input, OnChanges } from "@angular/core";
|
||||
import { MeterData } from "src/app/dataModels/Meterdata";
|
||||
import { UsageType } from "src/app/dataModels/UsageType";
|
||||
import { GlobalService } from "src/app/services/global.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-meter-data-wrapper',
|
||||
templateUrl: './meter-data-wrapper.component.html',
|
||||
styleUrls: ['./meter-data-wrapper.component.scss'],
|
||||
selector: "app-meter-data-wrapper",
|
||||
templateUrl: "./meter-data-wrapper.component.html",
|
||||
styleUrls: ["./meter-data-wrapper.component.scss"],
|
||||
})
|
||||
export class MeterDataWrapperComponent /* implements OnChanges */ {
|
||||
@Input() meterData: MeterData[];
|
||||
@Input() type: UsageType;
|
||||
@Input()
|
||||
meterData: MeterData[] = [];
|
||||
@Input()
|
||||
type: UsageType = UsageType.ENERGY;
|
||||
|
||||
// usageTypes = UsageType;
|
||||
// averageConsumptionLastYear: number;
|
||||
|
||||
16
rossa-tech-cli/src/app/dataModels/Meter.ts
Normal file
16
rossa-tech-cli/src/app/dataModels/Meter.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export class Meter {
|
||||
id: number;
|
||||
name: '1LOG' | '1HEM' | 'WASSER' | 'ABWASSER';
|
||||
|
||||
constructor(id: number, name: '1LOG' | '1HEM' | 'WASSER' | 'ABWASSER') {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
export enum Meters {
|
||||
'1LOG' = '1LOG',
|
||||
'1HEM' = '1HEM',
|
||||
'WASSER' = 'WASSER',
|
||||
'ABWASSER' = 'ABWASSER',
|
||||
}
|
||||
23
rossa-tech-cli/src/app/dataModels/Meterdata.ts
Normal file
23
rossa-tech-cli/src/app/dataModels/Meterdata.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Meter } from "./Meter";
|
||||
|
||||
export class MeterData {
|
||||
id?: number;
|
||||
type: "ENERGY" | "WATER";
|
||||
date: Date;
|
||||
amount: number;
|
||||
meter: Meter;
|
||||
|
||||
constructor(
|
||||
type: "ENERGY" | "WATER",
|
||||
date: Date,
|
||||
amount: number,
|
||||
meter: Meter,
|
||||
id?: number
|
||||
) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.date = date;
|
||||
this.amount = amount;
|
||||
this.meter = meter;
|
||||
}
|
||||
}
|
||||
4
rossa-tech-cli/src/app/dataModels/UsageType.ts
Normal file
4
rossa-tech-cli/src/app/dataModels/UsageType.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export enum UsageType {
|
||||
ENERGY = 'ENERGY',
|
||||
WATER = 'WATER'
|
||||
}
|
||||
49
rossa-tech-cli/src/app/dataModels/gameTitle.type.ts
Normal file
49
rossa-tech-cli/src/app/dataModels/gameTitle.type.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
export class GameTitle {
|
||||
constructor(
|
||||
private gameTitle: String,
|
||||
private publisher: String,
|
||||
private devStudioName: String,
|
||||
private publishingYear: Number,
|
||||
private retailPrice: Number
|
||||
) {}
|
||||
|
||||
public get gameTitleValue(): String {
|
||||
return this.gameTitle;
|
||||
}
|
||||
|
||||
public set gameTitleValue(val: String) {
|
||||
this.gameTitle = val;
|
||||
}
|
||||
|
||||
public get publisherValue(): String {
|
||||
return this.publisher;
|
||||
}
|
||||
|
||||
public set publisherValue(val: String) {
|
||||
this.publisher = val;
|
||||
}
|
||||
|
||||
public get devStudioNameValue(): String {
|
||||
return this.devStudioName;
|
||||
}
|
||||
|
||||
public set devStudioNameValue(val: String) {
|
||||
this.devStudioName = val;
|
||||
}
|
||||
|
||||
public get publishingYearValue(): Number {
|
||||
return this.publishingYear;
|
||||
}
|
||||
|
||||
public set publishingYearValue(val: Number) {
|
||||
this.publishingYearValue = val;
|
||||
}
|
||||
|
||||
public get retailPriceValue(): Number {
|
||||
return this.retailPrice;
|
||||
}
|
||||
|
||||
public set retailPriceValue(val: Number) {
|
||||
this.retailPrice = val;
|
||||
}
|
||||
}
|
||||
15
rossa-tech-cli/src/app/dataModels/info.md
Normal file
15
rossa-tech-cli/src/app/dataModels/info.md
Normal file
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE meter (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE meterdata (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
type ENUM('energy', 'water') NOT NULL,
|
||||
date DATETIME NOT NULL,
|
||||
amount FLOAT NOT NULL,
|
||||
meter_id INT NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (meter_id) REFERENCES meter(id)
|
||||
);
|
||||
19
rossa-tech-cli/src/app/dataModels/loginUser.type.ts
Normal file
19
rossa-tech-cli/src/app/dataModels/loginUser.type.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
export class LoginUser {
|
||||
constructor(private userName: String, private userPass: String) {}
|
||||
|
||||
public get userNameValue() {
|
||||
return this.userName;
|
||||
}
|
||||
|
||||
public set userNameValue(val: String) {
|
||||
this.userName = val;
|
||||
}
|
||||
|
||||
public get userPassValue() {
|
||||
return this.userPass;
|
||||
}
|
||||
|
||||
public set userPassValue(val: String) {
|
||||
this.userPass = val;
|
||||
}
|
||||
}
|
||||
19
rossa-tech-cli/src/app/dataModels/userRole.type.ts
Normal file
19
rossa-tech-cli/src/app/dataModels/userRole.type.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
export class UserRole {
|
||||
constructor(private roleId: String, private roleName: String) {}
|
||||
|
||||
public get roleIdValue(): String {
|
||||
return this.roleId;
|
||||
}
|
||||
|
||||
public set roleIdValue(val: String) {
|
||||
this.roleId = val;
|
||||
}
|
||||
|
||||
public get roleNameValue(): String {
|
||||
return this.roleName;
|
||||
}
|
||||
|
||||
public set roleNameValue(val: String) {
|
||||
this.roleName = val;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<h1 mat-dialog-title>Neuer Eintrag - Typ: {{usageType}}</h1>
|
||||
<form [formGroup]="form">
|
||||
<div mat-dialog-content>
|
||||
<mat-form-field>
|
||||
<input matInput [matDatepicker]="picker" formControlName="date">
|
||||
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #picker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Meter</mat-label>
|
||||
<mat-select formControlName="meter" (valueChange)="setUsageType($event.name)">
|
||||
<mat-option *ngFor="let el of meters" [value]="el">{{el.name}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput type="number" formControlName="amount">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-raised-button color="primary" (click)="submit()">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MeterDataAddDialogComponent } from './meter-data-add-dialog.component';
|
||||
|
||||
describe('MeterDataAddDialogComponent', () => {
|
||||
let component: MeterDataAddDialogComponent;
|
||||
let fixture: ComponentFixture<MeterDataAddDialogComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ MeterDataAddDialogComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(MeterDataAddDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||
import { MatDialogRef } from "@angular/material/dialog";
|
||||
import { Meter, Meters } from "src/app/dataModels/Meter";
|
||||
import { MeterData } from "src/app/dataModels/Meterdata";
|
||||
import { UsageType } from "src/app/dataModels/UsageType";
|
||||
import { DatabaseService } from "src/app/services/database.service";
|
||||
|
||||
@Component({
|
||||
selector: "app-meter-data-add-dialog",
|
||||
templateUrl: "./meter-data-add-dialog.component.html",
|
||||
styleUrls: ["./meter-data-add-dialog.component.scss"],
|
||||
})
|
||||
export class MeterDataAddDialogComponent implements OnInit {
|
||||
meters: Meter[] = [];
|
||||
usageTypes = UsageType;
|
||||
usageType: UsageType = UsageType.ENERGY;
|
||||
|
||||
form: FormGroup = this.fb.group({
|
||||
date: [new Date(), Validators.required],
|
||||
meter: ["", Validators.required],
|
||||
amount: ["", Validators.required],
|
||||
});
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private dialogRef: MatDialogRef<MeterDataAddDialogComponent>,
|
||||
private dataService: DatabaseService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.dataService.getMeters().subscribe({
|
||||
next: (meters: Meter[]) => {
|
||||
console.log({ meters });
|
||||
this.meters = meters;
|
||||
},
|
||||
error: (err) => {
|
||||
console.log("get meters error", { err });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
submit() {
|
||||
if (this.form.valid) {
|
||||
const formValues = this.form.value;
|
||||
const newMeterData: MeterData = {
|
||||
amount: formValues.amount,
|
||||
date: formValues.date,
|
||||
meter: formValues.meter,
|
||||
type: this.usageType,
|
||||
};
|
||||
|
||||
this.dialogRef.close(newMeterData);
|
||||
}
|
||||
}
|
||||
|
||||
setUsageType(meterName: string): void {
|
||||
if (meterName === Meters["1HEM"] || meterName === Meters["1LOG"]) {
|
||||
this.usageType = this.usageTypes.ENERGY;
|
||||
} else if (meterName === Meters.ABWASSER || meterName === Meters.WASSER) {
|
||||
this.usageType = this.usageTypes.WATER;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,34 @@
|
||||
import { MeterData } from './../models/Meterdata';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { Meter } from 'src/app/models/Meter';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { Injectable } from "@angular/core";
|
||||
import {
|
||||
HttpClient,
|
||||
HttpErrorResponse,
|
||||
HttpHeaders,
|
||||
} from "@angular/common/http";
|
||||
import { Observable, throwError } from "rxjs";
|
||||
import { catchError } from "rxjs/operators";
|
||||
import { environment } from "src/environments/environment";
|
||||
import { MeterData } from "../dataModels/Meterdata";
|
||||
import { Meter } from "../dataModels/Meter";
|
||||
import { LoginService } from "../auth/login.service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
providedIn: "root",
|
||||
})
|
||||
export class DatabaseService {
|
||||
private baseUrl = environment.hostUrl + '/v1';
|
||||
private baseUrl = environment.apiBaseUrl;
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
constructor(private http: HttpClient, private userService: LoginService) {}
|
||||
|
||||
getMeterData(): Observable<MeterData[]> {
|
||||
const url = `${this.baseUrl}/meter-data`;
|
||||
return this.http.get<MeterData[]>(url).pipe(catchError(this.handleError));
|
||||
let jwtToken: String = this.userService.getUserSecurityToken(),
|
||||
headers: HttpHeaders = new HttpHeaders({
|
||||
authorization: "bearer " + jwtToken,
|
||||
}),
|
||||
options = { headers: headers };
|
||||
return this.http
|
||||
.get<MeterData[]>(url, options)
|
||||
.pipe(catchError(this.handleError));
|
||||
}
|
||||
|
||||
getMeterDataByType(usageType: string): Observable<MeterData[]> {
|
||||
@@ -41,7 +53,7 @@ export class DatabaseService {
|
||||
|
||||
if (error.error instanceof ErrorEvent) {
|
||||
// A client-side or network error occurred. Handle it accordingly.
|
||||
console.error('An error occurred:', error.error.message);
|
||||
console.error("An error occurred:", error.error.message);
|
||||
} else {
|
||||
// The backend returned an unsuccessful response code.
|
||||
// The response body may contain clues as to what went wrong.
|
||||
|
||||
63
rossa-tech-cli/src/app/services/error.service.ts
Normal file
63
rossa-tech-cli/src/app/services/error.service.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { HttpErrorResponse } from "@angular/common/http";
|
||||
import { NotificationService } from "./notification.service";
|
||||
import { LoginService } from "../auth/login.service";
|
||||
import { PageSecurityService } from "./pageSecurity.service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class ErrorService {
|
||||
constructor(
|
||||
private notificationService: NotificationService,
|
||||
private loginService: LoginService,
|
||||
private pageSecurityService: PageSecurityService
|
||||
) {}
|
||||
|
||||
handleError(error: HttpErrorResponse): void {
|
||||
if (error != null) {
|
||||
if (error.status === 0) {
|
||||
console.log("Client error.");
|
||||
this.notificationService.showSnackbar(
|
||||
"Client error",
|
||||
3000,
|
||||
"snackbar-warning",
|
||||
true,
|
||||
"alert-circle-outline"
|
||||
);
|
||||
} else if (error.status === 401 || error.status === 403) {
|
||||
console.log("You are not authorized.");
|
||||
// todo: redirect to login page?
|
||||
|
||||
this.loginService.removeSessionCurrentUser();
|
||||
this.pageSecurityService.gotoLoginPage();
|
||||
|
||||
this.notificationService.showSnackbar(
|
||||
"You are not authorized",
|
||||
3000,
|
||||
"snackbar-warning",
|
||||
true,
|
||||
"cancel"
|
||||
);
|
||||
} else if (error.status === 500) {
|
||||
console.log("Server error occurred.");
|
||||
this.notificationService.showSnackbar(
|
||||
"Server error occurred",
|
||||
3000,
|
||||
"snackbar-warning",
|
||||
true,
|
||||
"server-off"
|
||||
);
|
||||
} else {
|
||||
console.log("Unknown error: " + error.status);
|
||||
this.notificationService.showSnackbar(
|
||||
"Unknown error",
|
||||
3000,
|
||||
"snackbar-warning",
|
||||
true,
|
||||
"alert-circle-outline"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
rossa-tech-cli/src/app/services/forms.service.ts
Normal file
23
rossa-tech-cli/src/app/services/forms.service.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class FormsService {
|
||||
public makeFormFieldsClean(formToCheck: any): void {
|
||||
if (formToCheck != null) {
|
||||
Object.keys(formToCheck.controls).forEach((key) => {
|
||||
formToCheck.controls[key].markAsUntouched({});
|
||||
formToCheck.controls[key].markAsPristine();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public makeFormFieldsDirty(formToCheck: any): void {
|
||||
if (formToCheck != null) {
|
||||
Object.keys(formToCheck.controls).forEach((key) => {
|
||||
formToCheck.controls[key].markAsDirty();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
25
rossa-tech-cli/src/app/services/gameTitles.service.ts
Normal file
25
rossa-tech-cli/src/app/services/gameTitles.service.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { HttpClient, HttpHeaders } from "@angular/common/http";
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import { environment } from "../../environments/environment";
|
||||
import { LoginService } from "../auth/login.service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class GameTitlesService {
|
||||
constructor(private http: HttpClient, private userService: LoginService) {}
|
||||
|
||||
public getAllGameTitles(): Observable<any> {
|
||||
let jwtToken: String = this.userService.getUserSecurityToken(),
|
||||
headers: HttpHeaders = new HttpHeaders({
|
||||
authorization: "bearer " + jwtToken,
|
||||
}),
|
||||
options = { headers: headers };
|
||||
return this.http.get<any>(
|
||||
environment.apiBaseUrl + "secure/allGameTitles",
|
||||
options
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MeterData } from '../models/Meterdata';
|
||||
import { Injectable } from "@angular/core";
|
||||
import { MeterData } from "../dataModels/Meterdata";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
providedIn: "root",
|
||||
})
|
||||
export class GlobalService {
|
||||
constructor() {}
|
||||
|
||||
71
rossa-tech-cli/src/app/services/notification.service.ts
Normal file
71
rossa-tech-cli/src/app/services/notification.service.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { Injectable, OnDestroy } from "@angular/core";
|
||||
import { MatSnackBar } from "@angular/material/snack-bar";
|
||||
import { Subscription } from "rxjs";
|
||||
import { SnackbarComponent } from "../components/snackbar/snackbar.component";
|
||||
|
||||
interface SnackbarData {
|
||||
message: string;
|
||||
className?: string;
|
||||
icon?: boolean;
|
||||
iconName?: string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class NotificationService implements OnDestroy {
|
||||
// Configuration api subscription
|
||||
private configState!: Subscription;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param toast MatSnackBar
|
||||
*/
|
||||
constructor(private toast: MatSnackBar) {}
|
||||
|
||||
/**
|
||||
* Unsubscribe from the config state
|
||||
* when the component is destroyed, and remove
|
||||
* the in-memory parameters.
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.configState.unsubscribe();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a MatSnackbar notification and return the reference.
|
||||
* @param message string
|
||||
* @param durationTime number in milliceconds
|
||||
* @param className string snackbar-warning, snackbar-success, snackbar-primary
|
||||
* @param icon boolean
|
||||
* @param iconName string name of the icon
|
||||
*/
|
||||
showSnackbar(
|
||||
message: string,
|
||||
durationTime?: number,
|
||||
className?: string,
|
||||
icon?: boolean,
|
||||
iconName?: string
|
||||
): void {
|
||||
const duration = durationTime || 8000;
|
||||
|
||||
const data: SnackbarData = {
|
||||
message,
|
||||
};
|
||||
|
||||
if (icon && iconName) {
|
||||
data.icon = icon;
|
||||
data.iconName = iconName;
|
||||
}
|
||||
if (className) {
|
||||
data.className = className;
|
||||
}
|
||||
|
||||
this.toast.openFromComponent(SnackbarComponent, {
|
||||
data,
|
||||
duration,
|
||||
horizontalPosition: "left",
|
||||
verticalPosition: "bottom",
|
||||
});
|
||||
}
|
||||
}
|
||||
28
rossa-tech-cli/src/app/services/pageSecurity.service.ts
Normal file
28
rossa-tech-cli/src/app/services/pageSecurity.service.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { HttpErrorResponse } from "@angular/common/http";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class PageSecurityService {
|
||||
constructor(private router: Router) {}
|
||||
|
||||
public gotoLoginPage() {
|
||||
this.router.navigate(["/login"]);
|
||||
}
|
||||
|
||||
public checkPageSecurityError(httpError: HttpErrorResponse) {
|
||||
if (!httpError || httpError.status == null) {
|
||||
throw new Error("Invalid http error object.");
|
||||
}
|
||||
|
||||
if (httpError.status === 401) {
|
||||
this.gotoLoginPage();
|
||||
}
|
||||
|
||||
if (httpError.status === 403) {
|
||||
this.router.navigate(["/accessDenied"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
146
rossa-tech-cli/src/custom-theme.scss
Normal file
146
rossa-tech-cli/src/custom-theme.scss
Normal file
@@ -0,0 +1,146 @@
|
||||
@use "@angular/material" as mat;
|
||||
|
||||
@import "https://fonts.googleapis.com/icon?family=Material+Icons";
|
||||
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500&display=swap");
|
||||
|
||||
$mat-primary: (
|
||||
50: #e0edf7,
|
||||
100: #b3d2ec,
|
||||
200: #80b4df,
|
||||
300: #4d96d2,
|
||||
400: #2680c9,
|
||||
500: #0069bf,
|
||||
600: #0061b9,
|
||||
700: #0056b1,
|
||||
800: #004ca9,
|
||||
900: #003b9b,
|
||||
A100: #c6d7ff,
|
||||
A200: #93b3ff,
|
||||
A400: #6090ff,
|
||||
A700: #477eff,
|
||||
contrast: (
|
||||
50: #333333,
|
||||
100: #333333,
|
||||
200: #333333,
|
||||
300: #333333,
|
||||
400: #ffffff,
|
||||
500: #ffffff,
|
||||
600: #ffffff,
|
||||
700: #ffffff,
|
||||
800: #ffffff,
|
||||
900: #ffffff,
|
||||
A100: #333333,
|
||||
A200: #333333,
|
||||
A400: #333333,
|
||||
A700: #ffffff,
|
||||
),
|
||||
);
|
||||
|
||||
$mat-accent: (
|
||||
50: #f1f8e5,
|
||||
100: #ddedbf,
|
||||
200: #c6e194,
|
||||
300: #afd469,
|
||||
400: #9dcb49,
|
||||
500: #8cc229,
|
||||
600: #84bc24,
|
||||
700: #79b41f,
|
||||
800: #6fac19,
|
||||
900: #5c9f0f,
|
||||
A100: #e7ffcf,
|
||||
A200: #cdff9c,
|
||||
A400: #b3ff69,
|
||||
A700: #a6ff4f,
|
||||
contrast: (
|
||||
50: #333333,
|
||||
100: #333333,
|
||||
200: #333333,
|
||||
300: #333333,
|
||||
400: #333333,
|
||||
500: #333333,
|
||||
600: #333333,
|
||||
700: #333333,
|
||||
800: #333333,
|
||||
900: #ffffff,
|
||||
A100: #333333,
|
||||
A200: #333333,
|
||||
A400: #333333,
|
||||
A700: #333333,
|
||||
),
|
||||
);
|
||||
|
||||
$mat-warn: (
|
||||
50: #fde8e8,
|
||||
100: #f9c6c6,
|
||||
200: #f6a0a0,
|
||||
300: #f27a7a,
|
||||
400: #ef5e5e,
|
||||
500: #ec4141,
|
||||
600: #ea3b3b,
|
||||
700: #e73232,
|
||||
800: #e42a2a,
|
||||
900: #df1c1c,
|
||||
A100: #ffffff,
|
||||
A200: #ffe0e0,
|
||||
A400: #ffadad,
|
||||
A700: #ff9494,
|
||||
contrast: (
|
||||
50: #333333,
|
||||
100: #333333,
|
||||
200: #333333,
|
||||
300: #333333,
|
||||
400: #333333,
|
||||
500: #ffffff,
|
||||
600: #ffffff,
|
||||
700: #ffffff,
|
||||
800: #ffffff,
|
||||
900: #ffffff,
|
||||
A100: #333333,
|
||||
A200: #333333,
|
||||
A400: #333333,
|
||||
A700: #333333,
|
||||
),
|
||||
);
|
||||
|
||||
// http://material-angular-dashboard.creativeit.io/
|
||||
$rossa-tech-typography: mat.define-typography-config(
|
||||
$font-family: "Open Sans",
|
||||
$body-1: mat.define-typography-level(14px, 20px, 400, $letter-spacing: normal),
|
||||
$button: mat.define-typography-level(16px, 20px, 400, $letter-spacing: normal),
|
||||
);
|
||||
|
||||
// $fontConfig: (
|
||||
// display-4: mat.define-typography-level(112px, 112px, 300, 'Open Sans', -0.0134em),
|
||||
// display-3: mat.define-typography-level(56px, 56px, 400, 'Open Sans', -0.0089em),
|
||||
// display-2: mat.define-typography-level(45px, 48px, 400, 'Open Sans', 0.0000em),
|
||||
// display-1: mat.define-typography-level(34px, 40px, 400, 'Open Sans', 0.0074em),
|
||||
// headline: mat.define-typography-level(24px, 32px, 400, 'Open Sans', 0.0000em),
|
||||
// title: mat.define-typography-level(20px, 32px, 500, 'Open Sans', 0.0075em),
|
||||
// subheading-2: mat.define-typography-level(16px, 28px, 400, 'Open Sans', 0.0094em),
|
||||
// subheading-1: mat.define-typography-level(15px, 24px, 500, 'Open Sans', 0.0067em),
|
||||
// body-2: mat.define-typography-level(14px, 24px, 500, 'Open Sans', 0.0179em),
|
||||
// body-1: mat.define-typography-level(14px, 20px, 400, 'Open Sans', 0.0179em),
|
||||
// button: mat.define-typography-level(14px, 14px, 500, 'Open Sans', 0.0893em),
|
||||
// caption: mat.define-typography-level(12px, 20px, 400, 'Open Sans', 0.0333em),
|
||||
// input: mat.define-typography-level(inherit, 1.125, 400, 'Open Sans', 1.5px)
|
||||
// );
|
||||
|
||||
$rossa-tech-primary: mat.define-palette($mat-primary);
|
||||
$rossa-tech-accent: mat.define-palette($mat-accent);
|
||||
$rossa-tech-warn: mat.define-palette($mat-warn);
|
||||
|
||||
$rossa-tech-theme: mat.define-light-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $rossa-tech-primary,
|
||||
accent: $rossa-tech-accent,
|
||||
warn: $rossa-tech-warn,
|
||||
),
|
||||
typography: $rossa-tech-typography,
|
||||
)
|
||||
);
|
||||
|
||||
@include mat.core();
|
||||
|
||||
@include mat.core-theme($rossa-tech-theme);
|
||||
@include mat.all-component-themes($rossa-tech-theme);
|
||||
@@ -1,5 +1,5 @@
|
||||
export const environment = {
|
||||
production: true,
|
||||
env: 'prod',
|
||||
hostUrl: 'http://192.168.178.21:8182/api',
|
||||
env: "prod",
|
||||
apiBaseUrl: "http://192.168.178.21:8182/api",
|
||||
};
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
|
||||
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
|
||||
// The list of file replacements can be found in `angular.json`.
|
||||
|
||||
export const environment = {
|
||||
production: true,
|
||||
env: 'prod',
|
||||
hostUrl: 'http://localhost:8080/',
|
||||
production: false,
|
||||
env: "local",
|
||||
apiBaseUrl: "http://localhost:8080",
|
||||
};
|
||||
|
||||
/*
|
||||
* 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`.
|
||||
@@ -14,4 +15,4 @@ export const environment = {
|
||||
* 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/dist/zone-error'; // Included with Angular CLI.
|
||||
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>RossaTechCli</title>
|
||||
<title>Rossa-Tech</title>
|
||||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body class="mat-typography">
|
||||
|
||||
@@ -1,7 +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));
|
||||
|
||||
53
rossa-tech-cli/src/polyfills.ts
Normal file
53
rossa-tech-cli/src/polyfills.ts
Normal file
@@ -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
|
||||
*/
|
||||
@@ -1,151 +1,3 @@
|
||||
@use '@angular/material' as mat;
|
||||
|
||||
@import 'https://fonts.googleapis.com/icon?family=Material+Icons';
|
||||
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500&display=swap');
|
||||
|
||||
$mat-primary: (
|
||||
50: #e0edf7,
|
||||
100: #b3d2ec,
|
||||
200: #80b4df,
|
||||
300: #4d96d2,
|
||||
400: #2680c9,
|
||||
500: #0069bf,
|
||||
600: #0061b9,
|
||||
700: #0056b1,
|
||||
800: #004ca9,
|
||||
900: #003b9b,
|
||||
A100: #c6d7ff,
|
||||
A200: #93b3ff,
|
||||
A400: #6090ff,
|
||||
A700: #477eff,
|
||||
contrast: (
|
||||
50: #333333,
|
||||
100: #333333,
|
||||
200: #333333,
|
||||
300: #333333,
|
||||
400: #ffffff,
|
||||
500: #ffffff,
|
||||
600: #ffffff,
|
||||
700: #ffffff,
|
||||
800: #ffffff,
|
||||
900: #ffffff,
|
||||
A100: #333333,
|
||||
A200: #333333,
|
||||
A400: #333333,
|
||||
A700: #ffffff,
|
||||
),
|
||||
);
|
||||
|
||||
$mat-accent: (
|
||||
50: #f1f8e5,
|
||||
100: #ddedbf,
|
||||
200: #c6e194,
|
||||
300: #afd469,
|
||||
400: #9dcb49,
|
||||
500: #8cc229,
|
||||
600: #84bc24,
|
||||
700: #79b41f,
|
||||
800: #6fac19,
|
||||
900: #5c9f0f,
|
||||
A100: #e7ffcf,
|
||||
A200: #cdff9c,
|
||||
A400: #b3ff69,
|
||||
A700: #a6ff4f,
|
||||
contrast: (
|
||||
50: #333333,
|
||||
100: #333333,
|
||||
200: #333333,
|
||||
300: #333333,
|
||||
400: #333333,
|
||||
500: #333333,
|
||||
600: #333333,
|
||||
700: #333333,
|
||||
800: #333333,
|
||||
900: #ffffff,
|
||||
A100: #333333,
|
||||
A200: #333333,
|
||||
A400: #333333,
|
||||
A700: #333333,
|
||||
),
|
||||
);
|
||||
|
||||
$mat-warn: (
|
||||
50: #fde8e8,
|
||||
100: #f9c6c6,
|
||||
200: #f6a0a0,
|
||||
300: #f27a7a,
|
||||
400: #ef5e5e,
|
||||
500: #ec4141,
|
||||
600: #ea3b3b,
|
||||
700: #e73232,
|
||||
800: #e42a2a,
|
||||
900: #df1c1c,
|
||||
A100: #ffffff,
|
||||
A200: #ffe0e0,
|
||||
A400: #ffadad,
|
||||
A700: #ff9494,
|
||||
contrast: (
|
||||
50: #333333,
|
||||
100: #333333,
|
||||
200: #333333,
|
||||
300: #333333,
|
||||
400: #333333,
|
||||
500: #ffffff,
|
||||
600: #ffffff,
|
||||
700: #ffffff,
|
||||
800: #ffffff,
|
||||
900: #ffffff,
|
||||
A100: #333333,
|
||||
A200: #333333,
|
||||
A400: #333333,
|
||||
A700: #333333,
|
||||
),
|
||||
);
|
||||
|
||||
// http://material-angular-dashboard.creativeit.io/
|
||||
|
||||
// define-typography-level(font-size, line-height, font-weight, letter-spacing)
|
||||
$typography: mat.define-typography-config(
|
||||
$font-family: 'Open Sans',
|
||||
$body-1: mat.define-typography-level(14px, 20px, 400, $letter-spacing: normal),
|
||||
$button: mat.define-typography-level(16px, 20px, 400, $letter-spacing: normal),
|
||||
);
|
||||
|
||||
// $fontConfig: (
|
||||
// display-4: mat.define-typography-level(112px, 112px, 300, 'Open Sans', -0.0134em),
|
||||
// display-3: mat.define-typography-level(56px, 56px, 400, 'Open Sans', -0.0089em),
|
||||
// display-2: mat.define-typography-level(45px, 48px, 400, 'Open Sans', 0.0000em),
|
||||
// display-1: mat.define-typography-level(34px, 40px, 400, 'Open Sans', 0.0074em),
|
||||
// headline: mat.define-typography-level(24px, 32px, 400, 'Open Sans', 0.0000em),
|
||||
// title: mat.define-typography-level(20px, 32px, 500, 'Open Sans', 0.0075em),
|
||||
// subheading-2: mat.define-typography-level(16px, 28px, 400, 'Open Sans', 0.0094em),
|
||||
// subheading-1: mat.define-typography-level(15px, 24px, 500, 'Open Sans', 0.0067em),
|
||||
// body-2: mat.define-typography-level(14px, 24px, 500, 'Open Sans', 0.0179em),
|
||||
// body-1: mat.define-typography-level(14px, 20px, 400, 'Open Sans', 0.0179em),
|
||||
// button: mat.define-typography-level(14px, 14px, 500, 'Open Sans', 0.0893em),
|
||||
// caption: mat.define-typography-level(12px, 20px, 400, 'Open Sans', 0.0333em),
|
||||
// input: mat.define-typography-level(inherit, 1.125, 400, 'Open Sans', 1.5px)
|
||||
// );
|
||||
|
||||
$primary: mat.define-palette($mat-primary);
|
||||
$accent: mat.define-palette($mat-accent);
|
||||
$warn: mat.define-palette($mat-warn);
|
||||
|
||||
$theme: mat.define-light-theme(
|
||||
(
|
||||
color: (
|
||||
primary: $primary,
|
||||
accent: $accent,
|
||||
warn: $warn,
|
||||
),
|
||||
typography: $typography,
|
||||
)
|
||||
);
|
||||
|
||||
@include mat.core();
|
||||
@include mat.core-theme($theme);
|
||||
@include mat.all-component-themes($theme);
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
@@ -161,7 +13,7 @@ html.cdk-global-scrollblock {
|
||||
|
||||
body {
|
||||
// margin: 0;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
font-family: "Open Sans", sans-serif;
|
||||
// height: 100vh;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -199,248 +51,3 @@ div.mat-grid-tile-content {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
/*--------------------------------------------------*/
|
||||
|
||||
// /**
|
||||
// * Generated theme by Material Theme Generator
|
||||
// * https://materialtheme.arcsine.dev
|
||||
// * Fork at: https://materialtheme.arcsine.dev/?c=YHBhbGV0dGU$YHByaW1hcnk$YF48IzQ0NDQ0NCIsIj9lcjwjYzdjN2M3IiwiO2VyPCMyZDJkMmR$LCIlPmBePCMyYTdhYWIiLCI~ZXI8I2JmZDdlNiIsIjtlcjwjMTk1ZDkxfiwid2Fybj5gXjwjZjE4ZTU0IiwiP2VyPCNmYmRkY2MiLCI7ZXI8I2ViNzEzYX4sIj9UZXh0PCMyYzJjMmMiLCI~PTwjZTllNGU0IiwiO1RleHQ8I2U5ZTRlNCIsIjs9PCMyYzJjMmN$LCJmb250cz5bYEA8KC00IiwiZmFtaWx5PE9wZW4gU2Fuc34sYEA8KC0zIiwiZmFtaWx5PE9wZW4gU2Fuc34sYEA8KC0yIiwiZmFtaWx5PE9wZW4gU2Fuc34sYEA8KC0xIiwiZmFtaWx5PE9wZW4gU2Fuc34sYEA8aGVhZGxpbmUiLCJmYW1pbHk8T3BlbiBTYW5zfixgQDx0aXRsZSIsImZhbWlseTxPcGVuIFNhbnN$LGBAPHN1YiktMiIsImZhbWlseTxPcGVuIFNhbnN$LGBAPHN1YiktMSIsImZhbWlseTxPcGVuIFNhbnN$LGBAPGJvZHktMiIsImZhbWlseTxPcGVuIFNhbnN$LGBAPGJvZHktMSIsImZhbWlseTxPcGVuIFNhbnN$LGBAPGJ1dHRvbiIsImZhbWlseTxPcGVuIFNhbnN$LGBAPGNhcHRpb24iLCJmYW1pbHk8T3BlbiBTYW5zfixgQDxpbnB1dCIsImZhbWlseTxPcGVuIFNhbnMiLCJzaXplPm51bGx9XSwiaWNvbnM8RmlsbGVkIiwiP25lc3M$ZmFsc2UsInZlcnNpb24$MTN9
|
||||
// */
|
||||
|
||||
// @use '@angular/material' as mat;
|
||||
|
||||
// // 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.
|
||||
|
||||
// // Fonts
|
||||
|
||||
// // Foreground Elements
|
||||
|
||||
// // Light Theme Text
|
||||
// $dark-text: #2c2c2c;
|
||||
// $dark-primary-text: rgba($dark-text, 0.87);
|
||||
// $dark-accent-text: rgba($dark-primary-text, 0.54);
|
||||
// $dark-disabled-text: rgba($dark-primary-text, 0.38);
|
||||
// $dark-dividers: rgba($dark-primary-text, 0.12);
|
||||
// $dark-focused: rgba($dark-primary-text, 0.12);
|
||||
|
||||
// $mat-light-theme-foreground: (
|
||||
// base: black,
|
||||
// divider: $dark-dividers,
|
||||
// dividers: $dark-dividers,
|
||||
// disabled: $dark-disabled-text,
|
||||
// disabled-button: rgba($dark-text, 0.26),
|
||||
// disabled-text: $dark-disabled-text,
|
||||
// elevation: black,
|
||||
// secondary-text: $dark-accent-text,
|
||||
// hint-text: $dark-disabled-text,
|
||||
// accent-text: $dark-accent-text,
|
||||
// icon: $dark-accent-text,
|
||||
// icons: $dark-accent-text,
|
||||
// text: $dark-primary-text,
|
||||
// slider-min: $dark-primary-text,
|
||||
// slider-off: rgba($dark-text, 0.26),
|
||||
// slider-off-active: $dark-disabled-text,
|
||||
// );
|
||||
|
||||
// // Dark Theme text
|
||||
// $light-text: #e9e4e4;
|
||||
// $light-primary-text: $light-text;
|
||||
// $light-accent-text: rgba($light-primary-text, 0.7);
|
||||
// $light-disabled-text: rgba($light-primary-text, 0.5);
|
||||
// $light-dividers: rgba($light-primary-text, 0.12);
|
||||
// $light-focused: rgba($light-primary-text, 0.12);
|
||||
|
||||
// $mat-dark-theme-foreground: (
|
||||
// base: $light-text,
|
||||
// divider: $light-dividers,
|
||||
// dividers: $light-dividers,
|
||||
// disabled: $light-disabled-text,
|
||||
// disabled-button: rgba($light-text, 0.3),
|
||||
// disabled-text: $light-disabled-text,
|
||||
// elevation: black,
|
||||
// hint-text: $light-disabled-text,
|
||||
// secondary-text: $light-accent-text,
|
||||
// accent-text: $light-accent-text,
|
||||
// icon: $light-text,
|
||||
// icons: $light-text,
|
||||
// text: $light-text,
|
||||
// slider-min: $light-text,
|
||||
// slider-off: rgba($light-text, 0.3),
|
||||
// slider-off-active: rgba($light-text, 0.3),
|
||||
// );
|
||||
|
||||
// // Background config
|
||||
// // Light bg
|
||||
// $light-background: #e9e4e4;
|
||||
// $light-bg-darker-5: darken($light-background, 5%);
|
||||
// $light-bg-darker-10: darken($light-background, 10%);
|
||||
// $light-bg-darker-20: darken($light-background, 20%);
|
||||
// $light-bg-darker-30: darken($light-background, 30%);
|
||||
// $light-bg-lighter-5: lighten($light-background, 5%);
|
||||
// $dark-bg-tooltip: lighten(#2c2c2c, 20%);
|
||||
// $dark-bg-alpha-4: rgba(#2c2c2c, 0.04);
|
||||
// $dark-bg-alpha-12: rgba(#2c2c2c, 0.12);
|
||||
|
||||
// $mat-light-theme-background: (
|
||||
// background: $light-background,
|
||||
// status-bar: $light-bg-darker-20,
|
||||
// app-bar: $light-bg-darker-5,
|
||||
// hover: $dark-bg-alpha-4,
|
||||
// card: $light-bg-lighter-5,
|
||||
// dialog: $light-bg-lighter-5,
|
||||
// tooltip: $dark-bg-tooltip,
|
||||
// disabled-button: $dark-bg-alpha-12,
|
||||
// raised-button: $light-bg-lighter-5,
|
||||
// focused-button: $dark-focused,
|
||||
// selected-button: $light-bg-darker-20,
|
||||
// selected-disabled-button: $light-bg-darker-30,
|
||||
// disabled-button-toggle: $light-bg-darker-10,
|
||||
// unselected-chip: $light-bg-darker-10,
|
||||
// disabled-list-option: $light-bg-darker-10,
|
||||
// );
|
||||
|
||||
// // Dark bg
|
||||
// $dark-background: #2c2c2c;
|
||||
// $dark-bg-lighter-5: lighten($dark-background, 5%);
|
||||
// $dark-bg-lighter-10: lighten($dark-background, 10%);
|
||||
// $dark-bg-lighter-20: lighten($dark-background, 20%);
|
||||
// $dark-bg-lighter-30: lighten($dark-background, 30%);
|
||||
// $light-bg-alpha-4: rgba(#e9e4e4, 0.04);
|
||||
// $light-bg-alpha-12: rgba(#e9e4e4, 0.12);
|
||||
|
||||
// // Background palette for dark themes.
|
||||
// $mat-dark-theme-background: (
|
||||
// background: $dark-background,
|
||||
// status-bar: $dark-bg-lighter-20,
|
||||
// app-bar: $dark-bg-lighter-5,
|
||||
// hover: $light-bg-alpha-4,
|
||||
// card: $dark-bg-lighter-5,
|
||||
// dialog: $dark-bg-lighter-5,
|
||||
// tooltip: $dark-bg-lighter-20,
|
||||
// disabled-button: $light-bg-alpha-12,
|
||||
// raised-button: $dark-bg-lighter-5,
|
||||
// focused-button: $light-focused,
|
||||
// selected-button: $dark-bg-lighter-20,
|
||||
// selected-disabled-button: $dark-bg-lighter-30,
|
||||
// disabled-button-toggle: $dark-bg-lighter-10,
|
||||
// unselected-chip: $dark-bg-lighter-20,
|
||||
// disabled-list-option: $dark-bg-lighter-10,
|
||||
// );
|
||||
|
||||
// // Compute font config
|
||||
// @include mat.core();
|
||||
// // @include mat.core($fontConfig);
|
||||
|
||||
// // Theme Config
|
||||
|
||||
// body {
|
||||
// --primary-color: #444444;
|
||||
// --primary-lighter-color: #c7c7c7;
|
||||
// --primary-darker-color: #2d2d2d;
|
||||
// --text-primary-color: #{$light-primary-text};
|
||||
// --text-primary-lighter-color: #{$dark-primary-text};
|
||||
// --text-primary-darker-color: #{$light-primary-text};
|
||||
// }
|
||||
// $mat-primary: (
|
||||
// main: #444444,
|
||||
// lighter: #c7c7c7,
|
||||
// darker: #2d2d2d,
|
||||
// 200: #444444, // For slide toggle,
|
||||
// contrast : (
|
||||
// main: $light-primary-text,
|
||||
// lighter: $dark-primary-text,
|
||||
// darker: $light-primary-text,
|
||||
// )
|
||||
// );
|
||||
// $theme-primary: mat.define-palette($mat-primary, main, lighter, darker);
|
||||
|
||||
// body {
|
||||
// --accent-color: #2a7aab;
|
||||
// --accent-lighter-color: #bfd7e6;
|
||||
// --accent-darker-color: #195d91;
|
||||
// --text-accent-color: #{$light-primary-text};
|
||||
// --text-accent-lighter-color: #{$dark-primary-text};
|
||||
// --text-accent-darker-color: #{$light-primary-text};
|
||||
// }
|
||||
// $mat-accent: (
|
||||
// main: #2a7aab,
|
||||
// lighter: #bfd7e6,
|
||||
// darker: #195d91,
|
||||
// 200: #2a7aab, // For slide toggle,
|
||||
// contrast : (
|
||||
// main: $light-primary-text,
|
||||
// lighter: $dark-primary-text,
|
||||
// darker: $light-primary-text,
|
||||
// )
|
||||
// );
|
||||
// $theme-accent: mat.define-palette($mat-accent, main, lighter, darker);
|
||||
|
||||
// body {
|
||||
// --warn-color: #f18e54;
|
||||
// --warn-lighter-color: #fbddcc;
|
||||
// --warn-darker-color: #eb713a;
|
||||
// --text-warn-color: #{$dark-primary-text};
|
||||
// --text-warn-lighter-color: #{$dark-primary-text};
|
||||
// --text-warn-darker-color: #{$dark-primary-text};
|
||||
// }
|
||||
// $mat-warn: (
|
||||
// main: #f18e54,
|
||||
// lighter: #fbddcc,
|
||||
// darker: #eb713a,
|
||||
// 200: #f18e54, // For slide toggle,
|
||||
// contrast : (
|
||||
// main: $dark-primary-text,
|
||||
// lighter: $dark-primary-text,
|
||||
// darker: $dark-primary-text,
|
||||
// )
|
||||
// );
|
||||
// $theme-warn: mat.define-palette($mat-warn, main, lighter, darker);
|
||||
// ;
|
||||
|
||||
// $theme: (
|
||||
// primary: $theme-primary,
|
||||
// accent: $theme-accent,
|
||||
// warn: $theme-warn,
|
||||
// is-dark: true,
|
||||
// foreground: $mat-dark-theme-foreground,
|
||||
// background: $mat-dark-theme-background,
|
||||
// );
|
||||
// $altTheme: (
|
||||
// primary: $theme-primary,
|
||||
// accent: $theme-accent,
|
||||
// warn: $theme-warn,
|
||||
// is-dark: false,
|
||||
// foreground: $mat-light-theme-foreground,
|
||||
// background: $mat-light-theme-background,
|
||||
// );
|
||||
|
||||
// // Theme Init
|
||||
// @include mat.all-component-themes($theme);
|
||||
|
||||
// .theme-alternate {
|
||||
// @include mat.all-component-themes($altTheme);
|
||||
// }
|
||||
|
||||
// // Specific component overrides, pieces that are not in line with the general theming
|
||||
|
||||
// // Handle buttons appropriately, with respect to line-height
|
||||
// .mat-raised-button, .mat-stroked-button, .mat-flat-button {
|
||||
// padding: 0 1.15em;
|
||||
// margin: 0 .65em;
|
||||
// min-width: 3em;
|
||||
// line-height: 36.4px
|
||||
// }
|
||||
|
||||
// .mat-standard-chip {
|
||||
// padding: .5em .85em;
|
||||
// min-height: 2.5em;
|
||||
// }
|
||||
|
||||
// .material-icons {
|
||||
// font-size: 24px;
|
||||
// font-family: 'Material Icons', 'Material Icons';
|
||||
// .mat-badge-content {
|
||||
// font-family: 'Open Sans';
|
||||
// }
|
||||
// }
|
||||
|
||||
14
rossa-tech-cli/src/test.ts
Normal file
14
rossa-tech-cli/src/test.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
// 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';
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting(),
|
||||
);
|
||||
@@ -6,7 +6,8 @@
|
||||
"types": []
|
||||
},
|
||||
"files": [
|
||||
"src/main.ts"
|
||||
"src/main.ts",
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.d.ts"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
@@ -17,10 +16,12 @@
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"useDefineForClassFields": false,
|
||||
"lib": ["ES2022", "dom"],
|
||||
"strictPropertyInitialization": false
|
||||
"module": "es2020",
|
||||
"lib": [
|
||||
"es2020",
|
||||
"dom"
|
||||
],
|
||||
"useDefineForClassFields": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts",
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.d.ts"
|
||||
|
||||
Reference in New Issue
Block a user