Merge pull request #9 from fabioformosa/#8_angular_migration

#8 angular migration
This commit is contained in:
Fabio Formosa
2020-05-08 01:13:53 +02:00
committed by GitHub
17 changed files with 126 additions and 96 deletions

View File

@@ -150,6 +150,9 @@ public class JwtTokenHelper {
return authHeader.substring(7);
}
if(request.getParameter("access_token") != null)
return request.getParameter("access_token");
return null;
}

View File

@@ -11,6 +11,7 @@
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"aot": true,
"outputPath": "../server/src/main/resources/static",
"index": "src/index.html",
"main": "src/main.ts",
@@ -27,6 +28,12 @@
},
"configurations": {
"production": {
"budgets": [
{
"type": "anyComponentStyle",
"maximumWarning": "6kb"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
@@ -119,7 +126,7 @@
"schematics": {
"@schematics/angular:component": {
"prefix": "app",
"styleext": "css"
"style": "css"
},
"@schematics/angular:directive": {
"prefix": "app"

View File

@@ -0,0 +1,12 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# You can see what browsers were selected by your queries by running:
# npx browserslist
> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.

View File

@@ -12,19 +12,19 @@
},
"private": true,
"dependencies": {
"@angular/animations": "7.2.13",
"@angular/cdk": "7.3.7",
"@angular/common": "7.2.13",
"@angular/compiler": "7.2.13",
"@angular/core": "7.2.13",
"@angular/flex-layout": "7.0.0-beta.24",
"@angular/forms": "7.2.13",
"@angular/http": "7.2.13",
"@angular/material": "7.3.7",
"@angular/platform-browser": "7.2.13",
"@angular/platform-browser-dynamic": "7.2.13",
"@angular/platform-server": "7.2.13",
"@angular/router": "7.2.13",
"@angular/animations": "9.1.4",
"@angular/cdk": "9.2.1",
"@angular/common": "9.1.4",
"@angular/compiler": "9.1.4",
"@angular/core": "9.1.4",
"@angular/flex-layout": "9.0.0-beta.29",
"@angular/forms": "9.1.4",
"@angular/material": "9.2.1",
"@angular/platform-browser": "9.1.4",
"@angular/platform-browser-dynamic": "9.1.4",
"@angular/platform-server": "9.1.4",
"@angular/router": "9.1.4",
"@auth0/angular-jwt": "^4.0.0",
"@fortawesome/fontawesome": "^1.1.4",
"@fortawesome/fontawesome-free-regular": "^5.0.8",
"@fortawesome/fontawesome-free-solid": "^5.0.8",
@@ -32,22 +32,22 @@
"core-js": "2.5.1",
"hammerjs": "2.0.8",
"net": "^1.0.2",
"rxjs": "6.4.0",
"rxjs": "6.5.5",
"stompjs": "^2.3.3",
"tslib": "^1.9.0",
"zone.js": "0.8.18"
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.13.0",
"@angular-devkit/core": "^0.2.0",
"@angular/cli": "7.3.7",
"@angular/compiler-cli": "7.2.13",
"@angular/language-service": "7.2.13",
"@angular-devkit/build-angular": "~0.901.4",
"@angular-devkit/core": "^9.1.4",
"@angular/cli": "9.1.4",
"@angular/compiler-cli": "9.1.4",
"@angular/language-service": "9.1.4",
"@types/hammerjs": "2.0.34",
"@types/jasmine": "2.5.54",
"@types/jasminewd2": "2.0.3",
"@types/node": "6.0.90",
"codelyzer": "4.2.1",
"@types/node": "^12.11.1",
"codelyzer": "^5.1.2",
"jasmine-core": "2.6.4",
"jasmine-spec-reporter": "4.1.1",
"karma": "1.7.1",
@@ -59,6 +59,6 @@
"protractor": "5.1.2",
"ts-node": "3.0.6",
"tslint": "5.7.0",
"typescript": "3.2.4"
"typescript": "3.8.3"
}
}

View File

@@ -1,22 +1,23 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER} from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { HttpClientModule } from '@angular/common/http';
import {JWT_OPTIONS, JwtModule} from "@auth0/angular-jwt";
// material
import {
MatButtonModule,
MatMenuModule,
MatIconModule,
MatToolbarModule,
MatTooltipModule,
MatCardModule,
MatChipsModule,
MatInputModule,
MatIconRegistry,
MatProgressSpinnerModule,
MatProgressBarModule,
} from '@angular/material';
import {MatIconRegistry} from '@angular/material/icon';
import {MatInputModule} from '@angular/material/input';
import {MatChipsModule} from '@angular/material/chips';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatProgressBarModule} from '@angular/material/progress-bar';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import {MatMenuModule} from '@angular/material/menu';
import {MatToolbarModule} from '@angular/material/toolbar';
import {MatIconModule} from '@angular/material/icon';
import {MatButtonModule} from '@angular/material/button';
import {MatCardModule} from '@angular/material/card';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FlexLayoutModule } from '@angular/flex-layout';
import { AppComponent } from './app.component';
@@ -77,6 +78,15 @@ export function initUserFactory(userService: UserService) {
// debug: true
// };
export function jwtOptionsFactory(apiService: ApiService) {
return {
tokenGetter: () => {
return apiService.getToken();
},
whitelistedDomains: ['localhost:8080', 'localhost:4200']
}
}
@NgModule({
declarations: [
AppComponent,
@@ -99,9 +109,15 @@ export function initUserFactory(userService: UserService) {
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
HttpClientModule,
AppRoutingModule,
JwtModule.forRoot({
jwtOptionsProvider: {
provide: JWT_OPTIONS,
useFactory: jwtOptionsFactory,
deps: [ApiService]
}
}),
MatMenuModule,
MatTooltipModule,
MatButtonModule,

View File

@@ -32,7 +32,7 @@
}
/deep/ {
::ng-deep {
.app-header-accountMenu.mat-menu-panel {
border-radius: 3px;
max-width: initial;

View File

@@ -4,11 +4,14 @@ export class SocketOption{
brokerName : string;
reconnectionTimeout : number = 30000
constructor(socketUrl : string, topicName : string, brokerName : string = null, reconnectionTimeout : number = 30000){
getAccessToken: Function = () => null;
constructor(socketUrl : string, topicName : string, getAccessToken?: Function, brokerName : string = null, reconnectionTimeout : number = 30000){
this.socketUrl = socketUrl;
this.topicName = topicName;
this.brokerName = brokerName;
this.reconnectionTimeout = reconnectionTimeout;
this.getAccessToken = getAccessToken || (() => null);
}
}

View File

@@ -41,6 +41,8 @@ export class ApiService {
this.jwtToken = token;
}
getToken = () => this.jwtToken;
get(path: string, args?: any): Observable<any> {
const options = {
headers: this.headers,
@@ -50,8 +52,8 @@ export class ApiService {
if (args)
options['params'] = serialize(args);
if(this.jwtToken)
options.headers = options.headers.set('Authorization', `Bearer ${this.jwtToken}`);
// if(this.jwtToken)
// options.headers = options.headers.set('Authorization', `Bearer ${this.jwtToken}`);
return this.http.get(path, options)
.pipe(catchError(this.checkError.bind(this)));
@@ -75,8 +77,8 @@ export class ApiService {
withCredentials: true
}
if(this.jwtToken)
options.headers = options.headers.append('Authorization', `Bearer ${this.jwtToken}`);
// if(this.jwtToken)
// options.headers = options.headers.append('Authorization', `Bearer ${this.jwtToken}`);
const req = new HttpRequest(method, path, body, options);

View File

@@ -1,12 +1,12 @@
import { Injectable, OnInit } from '@angular/core';
import { WebsocketService } from '.';
import { WebsocketService, ApiService } from '.';
import { SocketOption } from '../model/SocketOption.model';
Injectable()
@Injectable()
export class LogsWebsocketService extends WebsocketService {
constructor(){
super(new SocketOption('/quartz-manager/logs', '/topic/logs'))
constructor(private apiService: ApiService){
super(new SocketOption('/quartz-manager/logs', '/topic/logs', apiService.getToken))
}
}

View File

@@ -1,12 +1,12 @@
import { Injectable, OnInit } from '@angular/core';
import { WebsocketService } from '.';
import { WebsocketService, ApiService } from '.';
import { SocketOption } from '../model/SocketOption.model';
Injectable()
@Injectable()
export class ProgressWebsocketService extends WebsocketService {
constructor(){
super(new SocketOption('/quartz-manager/progress', '/topic/progress'))
constructor(private apiService: ApiService){
super(new SocketOption('/quartz-manager/progress', '/topic/progress', apiService.getToken))
}
}

View File

@@ -1,5 +1,4 @@
import { Injectable } from '@angular/core';
import { Headers } from '@angular/http';
import { ApiService } from './api.service';
@Injectable()

View File

@@ -1,5 +1,4 @@
import { Injectable } from '@angular/core';
import { Headers } from '@angular/http';
import { ApiService } from './api.service';
import { ConfigService } from './config.service';

View File

@@ -1,10 +1,4 @@
import { Injectable, OnInit } from '@angular/core';
import { Headers } from '@angular/http';
import { Observable } from 'rxjs';
import { ApiService } from './api.service';
import { SocketEndpoint } from '../model/SocketEndpoint.model'
@@ -39,10 +33,7 @@ export class WebsocketService {
this.observableStompConnection = new Observable((observer) => {
const subscriberIndex = this.subscriberIndex++;
this.addToSubscribers({ index: subscriberIndex, observer });
return () => {
const index = subscriberIndex;
this.removeFromSubscribers(index);
};
return () => this.removeFromSubscribers(subscriberIndex);
});
}
@@ -51,13 +42,9 @@ export class WebsocketService {
}
removeFromSubscribers = (index) => {
let subscribeFromIndex;
for (let i=0 ; i < this.subscribers.length; i++)
if(i === index){
subscribeFromIndex = this.subscribers[i];
this.subscribers.splice(i, 1);
break;
}
if(index > this.subscribers.length)
throw new Error(`Unexpected error removing subscriber from websocket, because index ${index} is greater than subscriber length ${this.subscribers.length}`);
this.subscribers.splice(index, 1);
}
getObservable = () => {
@@ -71,7 +58,7 @@ export class WebsocketService {
out.headers = {};
out.headers.messageId = data.headers["message-id"];
let messageIdIndex = this._messageIds.indexOf( out.headers.messageId);
let messageIdIndex = this._messageIds.indexOf(out.headers.messageId);
if ( messageIdIndex > -1) {
out.self = true;
this._messageIds = this._messageIds.splice(messageIdIndex, 1);
@@ -81,24 +68,20 @@ export class WebsocketService {
_socketListener = (frame) => {
console.log('Connected: ' + frame);
this._socket.stomp.subscribe(this._options.topicName, (data) => {
this.subscribers.forEach(subscriber => {
subscriber.observer.next(this.getMessage(data));
})
})
this._socket.stomp.subscribe(
this._options.topicName,
data => this.subscribers.forEach(subscriber => subscriber.observer.next(this.getMessage(data)))
);
}
_onSocketError = (errorMsg) => {
let out: any = {};
out.type = 'ERROR';
out.message = errorMsg;
this.subscribers.forEach(subscriber => {
subscriber.observer.error(out);
})
this.subscribers.forEach(subscriber => subscriber.observer.error(out));
this.scheduleReconnection();
}
scheduleReconnection = () => {
this.reconnectionPromise = setTimeout(() => {
console.log("Socket reconnecting... (if it fails, next attempt in " + this._options.reconnectionTimeout + " msec)");
@@ -126,7 +109,12 @@ export class WebsocketService {
connect = () => {
const headers = {};
this._socket.client = new SockJS(this._options.socketUrl);
let socketUrl = this._options.socketUrl;
if(this._options.getAccessToken())
socketUrl += `?access_token=${this._options.getAccessToken()}`
this._socket.client = new SockJS(socketUrl);
this._socket.stomp = Stomp.over(this._socket.client);
this._socket.stomp.connect(headers, this._socketListener, this._onSocketError);
this._socket.stomp.onclose = this.scheduleReconnection;

View File

@@ -2,12 +2,14 @@
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"module": "es2015",
"baseUrl": "",
"types": []
},
"exclude": [
"test.ts",
"**/*.spec.ts"
"files": [
"main.ts",
"polyfills.ts"
],
"include": [
"src/**/*.d.ts"
]
}

View File

@@ -2,8 +2,6 @@
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/spec",
"module": "commonjs",
"target": "es5",
"baseUrl": "",
"types": [
"jasmine",

View File

@@ -1,6 +1,7 @@
{
"compileOnSave": false,
"compilerOptions": {
"downlevelIteration": true,
"importHelpers": true,
"outDir": "./dist/out-tsc",
"baseUrl": "src",
@@ -9,7 +10,7 @@
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"target": "es2015",
"typeRoots": [
"node_modules/@types"
],
@@ -17,6 +18,6 @@
"es2016",
"dom"
],
"module": "es2015"
"module": "esnext"
}
}

View File

@@ -100,12 +100,12 @@
"directive-selector": [true, "attribute", "app", "camelCase"],
"component-selector": [true, "element", "app", "kebab-case"],
"use-input-property-decorator": true,
"use-output-property-decorator": true,
"use-host-property-decorator": true,
"no-inputs-metadata-property": true,
"no-outputs-metadata-property": true,
"no-host-metadata-property": true,
"no-input-rename": true,
"no-output-rename": true,
"use-life-cycle-interface": true,
"use-lifecycle-interface": true,
"use-pipe-transform-interface": true,
"component-class-suffix": true,
"directive-class-suffix": true,