Remove specs + eslind on front

This commit is contained in:
2023-01-06 11:55:01 +01:00
parent 0daf0c582a
commit 42006caaf2
28 changed files with 2953 additions and 185 deletions

46
Frontend/.eslintrc.json Normal file
View File

@@ -0,0 +1,46 @@
{
"root": true,
"ignorePatterns": [
"projects/**/*"
],
"overrides": [
{
"files": [
"*.ts"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "app",
"style": "camelCase"
}
],
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "app",
"style": "kebab-case"
}
]
}
},
{
"files": [
"*.html"
],
"extends": [
"plugin:@angular-eslint/template/recommended"
],
"rules": {}
}
]
}

View File

@@ -109,11 +109,23 @@
],
"scripts": []
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
}
}
}
}
},
"cli": {
"analytics": "9583f9e0-88e2-44e8-bc34-c8c6a9fddedd"
"analytics": "9583f9e0-88e2-44e8-bc34-c8c6a9fddedd",
"schematicCollections": [
"@angular-eslint/schematics"
]
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,8 @@
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
"test": "ng test",
"lint": "ng lint"
},
"private": true,
"dependencies": {
@@ -32,10 +33,18 @@
},
"devDependencies": {
"@angular-devkit/build-angular": "^15.0.3",
"@angular-eslint/builder": "15.1.0",
"@angular-eslint/eslint-plugin": "15.1.0",
"@angular-eslint/eslint-plugin-template": "15.1.0",
"@angular-eslint/schematics": "15.1.0",
"@angular-eslint/template-parser": "15.1.0",
"@angular/cli": "~15.0.3",
"@angular/compiler-cli": "^15.0.3",
"@types/jasmine": "^4.3.1",
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "5.44.0",
"@typescript-eslint/parser": "5.44.0",
"eslint": "^8.28.0",
"jasmine-core": "^4.5.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.1.0",
@@ -45,4 +54,4 @@
"tslib": "^2.4.1",
"typescript": "^4.8.4"
}
}
}

View File

@@ -1,35 +0,0 @@
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'Diuna'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('Diuna');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('.content span')?.textContent).toContain('Diuna app is running!');
});
});

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
import { CanActivate, Router, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
@@ -11,10 +11,7 @@ export class AuthGuard implements CanActivate {
private auth$: AuthService,
private router$: Router
) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
canActivate(): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (this.auth$.user && this.auth$.user.googleCredentials) {
return true;
} else {

View File

@@ -1,6 +1,5 @@
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { environment } from 'src/environments/environment';
import { User } from '../models/user.model';
@@ -18,7 +17,7 @@ export class AuthService {
ping() {
return new Promise((resolve, reject) => {
this.http$.get<any>(`${environment.api.url}/ping/ping`).subscribe({
this.http$.get<string>(`${environment.api.url}/ping/ping`).subscribe({
next: (data) => {
resolve(data);
},
@@ -34,6 +33,7 @@ export class AuthService {
getAPIToken(credentials: string): Promise<void> {
return new Promise((resolve, reject) => {
const header = new HttpHeaders().set('Content-type', 'application/json');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.http$.post<any>(`${environment.api.url}/auth/apiToken`, JSON.stringify(credentials), { headers: header }).subscribe({
next: (data) => {
this.user.id = data.id;

View File

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

View File

@@ -1,11 +1,9 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Component, NgZone, OnInit } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Router } from '@angular/router';
import jwt_decode from "jwt-decode";
import { AuthService } from 'src/app/auth/auth.service';
import { User } from 'src/app/models/user.model';
import { DataService } from 'src/app/services/data.service';
import { environment } from 'src/environments/environment';
@Component({
@@ -22,12 +20,14 @@ export class LoginPageComponent implements OnInit {
private snackBar$: MatSnackBar
) { }
loading: boolean = false;
loading = false;
ngOnInit(): void {
this.snackBar$.open("", "", { duration: 1 });
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
window.onGoogleLibraryLoad = () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
google.accounts.id.initialize({
client_id: environment.google.clientId,
@@ -35,19 +35,24 @@ export class LoginPageComponent implements OnInit {
auto_select: true,
cancel_on_tap_outside: true
});
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
google.accounts.id.renderButton(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
document.getElementById("google-button"),
{ theme: "outline", size: "large", width: "100%" }
);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
google.accounts.id.prompt((notification: PromptMomentNotification) => { });
google.accounts.id.prompt();
};
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async handleCredentialResponse(response: any) {
try {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const responsePayload: any = jwt_decode(response.credential);
this.auth$.user = new User({
googleCredentials: response.credential,
@@ -60,6 +65,7 @@ export class LoginPageComponent implements OnInit {
this.ngZone$.run(() => {
this.router$.navigate(['/app']);
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
this.loading = false;
if (e.status === 401) {

View File

@@ -11,7 +11,7 @@ import { DataService } from '../services/data.service';
@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
private tasks: number = 0;
private tasks = 0;
constructor(
private data$: DataService

View File

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

View File

@@ -6,7 +6,6 @@ import * as moment from 'moment';
import packageInfo from 'package.json';
import { delay } from 'rxjs';
import { AuthService } from '../auth/auth.service';
import { User } from '../models/user.model';
import { DataService } from '../services/data.service';
import { DeviceService } from '../services/device.service';
@@ -20,8 +19,8 @@ export class MainViewComponent {
appVersion = packageInfo.version;
currentDate = moment().toDate();
flipPhone: boolean = false;
loading: boolean = false;
flipPhone = false;
loading = false;
constructor(
public data$: DataService,
@@ -51,6 +50,7 @@ export class MainViewComponent {
document.location.reload();
}
logout() {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
google.accounts.id.disableAutoSelect();
this.reloadApp();

View File

@@ -14,7 +14,7 @@ import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatListModule } from '@angular/material/list';
import { MatMenuModule } from '@angular/material/menu';
import { MatPaginatorIntl, MatPaginatorModule } from '@angular/material/paginator';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatRadioModule } from '@angular/material/radio';

View File

@@ -18,6 +18,7 @@ export class Base implements Deserializable, Serializable {
Object.assign(this, data);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
deserialize(input: any): this {
if (input.createdAt) { input.createdAt = moment(input.createdAt).utc(true); }
if (input.modifiedAt) { input.modifiedAt = moment(input.modifiedAt).utc(true); }
@@ -27,6 +28,7 @@ export class Base implements Deserializable, Serializable {
return this;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
serialize() : any {
return Object.assign({}, this);
}

View File

@@ -1,3 +1,4 @@
export interface Deserializable {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
deserialize(input: any): this;
}

View File

@@ -6,6 +6,7 @@ import { map } from 'rxjs';
import { Record } from 'src/app/models/record.model';
export class Layer extends Base {
// eslint-disable-next-line @typescript-eslint/ban-types
number?: Number;
source?: string;
name?: string;
@@ -16,6 +17,7 @@ export class Layer extends Base {
super();
Object.assign(this, data);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
override deserialize(input: any): this {
Object.assign(this, Object.assign(this, super.deserialize(input)));
if (this.records) { this.records = this.records.map(x => new Record().deserialize(x)); }
@@ -47,7 +49,7 @@ export class Layer extends Base {
});
}
loadForm(form: UntypedFormGroup) {
for (let field of Object.keys(form.controls)) {
for (const field of Object.keys(form.controls)) {
this[field as keyof Layer] = form.controls[field].value;
}
this.createdBy = undefined;
@@ -63,6 +65,7 @@ export class Layer extends Base {
);
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static getList(_http: HttpClient): any {
return new Promise((resolve, reject) => {
_http.get<Layer[]>(`${environment.api.url}/layers`)
@@ -81,7 +84,7 @@ export class Layer extends Base {
})
});
}
static parseFile(file: any, _http: HttpClient): Promise<Layer[]> {
static parseFile(file: File, _http: HttpClient): Promise<Layer[]> {
const formData = new FormData();
formData.append(file.name, file);
return new Promise((resolve, reject) => {

View File

@@ -1,9 +1,4 @@
import { Base } from './base.model';
import { UntypedFormBuilder, Validators, UntypedFormGroup, FormControl } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { DataService } from '../services/data.service';
import { map } from 'rxjs';
export class Record extends Base {
code?: string;
@@ -19,6 +14,7 @@ export class Record extends Base {
Object.assign(this, data);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
override deserialize(input: any): this {
Object.assign(this, Object.assign(this, super.deserialize(input)));
return this;

View File

@@ -1,3 +1,4 @@
export interface Serializable {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
serialize(input: this): any;
}

View File

@@ -4,6 +4,7 @@ export class User {
userName!: string;
googleCredentials!: string;
avatar?: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
constructor(input: any) {
Object.assign(this, input)
}

View File

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

View File

@@ -1,19 +1,14 @@
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import moment, { Moment } from 'moment';
import { Component } from '@angular/core';
import { DeviceService } from 'src/app/services/device.service';
import { environment } from 'src/environments/environment';
@Component({
selector: 'diunaBI-board',
selector: 'app-board',
templateUrl: './board.component.html',
styleUrls: ['./board.component.scss']
})
export class BoardComponent {
constructor(
public _device: DeviceService
) { }
}

View File

@@ -1,6 +1,6 @@
import { DatePipe } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Component, ViewChild } from '@angular/core';
import { Component, OnInit, ViewChild } from '@angular/core';
import { UntypedFormGroup, UntypedFormBuilder } from '@angular/forms';
import { MatPaginator } from '@angular/material/paginator';
import { MatSnackBar } from '@angular/material/snack-bar';
@@ -12,11 +12,11 @@ import { Layer } from 'src/app/models/layer.model';
import { Record } from 'src/app/models/record.model';
@Component({
selector: 'diunaBI-layer-detail',
selector: 'app-layer-detail',
templateUrl: './layer-detail.component.html',
styleUrls: ['./layer-detail.component.scss']
})
export class LayerDetailComponent {
export class LayerDetailComponent implements OnInit {
public form!: UntypedFormGroup;
public document!: Layer;

View File

@@ -1,7 +1,6 @@
import { HttpClient } from '@angular/common/http';
import { Component, OnInit, ViewChild } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
@@ -13,7 +12,7 @@ import { Record } from 'src/app/models/record.model';
import { v4 as uuidv4 } from 'uuid';
@Component({
selector: 'diunaBI-layer-edit',
selector: 'app-layer-edit',
templateUrl: './layer-edit.component.html',
styleUrls: ['./layer-edit.component.scss']
})
@@ -52,8 +51,10 @@ export class LayerEditComponent implements OnInit {
const id = await Layer.add(this.document, this.http$);
this.router$.navigate(['../../Detail', id], { relativeTo: this.route$ });
}
async onFileSelected(event: any) {
const file = event.target.files[0];
async onFileSelected(event: Event) {
const input = event.target as HTMLInputElement;
if (!input.files?.length) { return; }
const file = input.files[0];
this.document.records = await Layer.parseFile(file, this.http$);
this.dataSource = new MatTableDataSource(this.document.records);
this.dataSource.paginator = this.paginator;

View File

@@ -6,7 +6,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { Layer } from 'src/app/models/layer.model';
@Component({
selector: 'diunaBI-layers-list',
selector: 'app-layers-list',
templateUrl: './layers-list.component.html',
styleUrls: ['./layers-list.component.scss']
})

View File

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

View File

@@ -1,12 +1,9 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { User } from '../models/user.model';
@Injectable({
providedIn: 'root'
})
export class DataService {
public showLoader: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
constructor() { }
}

View File

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

View File

@@ -10,7 +10,7 @@ export class DeviceService {
private DESKTOP_WIDTH = 1400;
public orientation?: "landscape" | "portraid";
public flipPhone: boolean = false;
public flipPhone = false;
public width?: number;
constructor(