diff --git a/.gitignore b/.gitignore index cd8fc9c3fd7ea2ef62b576d3a2127015c816989e..5756d0b8062c8e260d88eecf8642e71439a25a31 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ target/ .project .classpath .settings/ + +# Client +goofy-client/.vscode/ diff --git a/goofy-client/.editorconfig b/goofy-client/.editorconfig index 6e87a003da89defd554080af5af93600cc9f91fe..f7f630e3a7e355f96711a14c6d2e35f9122692ad 100644 --- a/goofy-client/.editorconfig +++ b/goofy-client/.editorconfig @@ -3,11 +3,23 @@ root = true [*] charset = utf-8 -indent_style = space -indent_size = 2 -insert_final_newline = true -trim_trailing_whitespace = true +indent_style = tab +indent_size = 4 +#insert_final_newline = true +#trim_trailing_whitespace = true +max_line_length = 150 +end_of_line = lf + +[*.ts] +quote_type = single + +[*.html] +quote_type = double [*.md] max_line_length = off trim_trailing_whitespace = false + +[*.scss] +indent_size = 2 +tab_width = 2 diff --git a/goofy-client/.prettierignore b/goofy-client/.prettierignore deleted file mode 100644 index d0b804da2a462044bb1c63364440b2c2164e86ad..0000000000000000000000000000000000000000 --- a/goofy-client/.prettierignore +++ /dev/null @@ -1,4 +0,0 @@ -# Add files here to ignore them from prettier formatting - -/dist -/coverage diff --git a/goofy-client/angular.json b/goofy-client/angular.json index 114f427d0a8e5353b0666345ab3fe6708b8214e7..22200ace8a75caf7b9f89d3e3236a0992d99a16b 100644 --- a/goofy-client/angular.json +++ b/goofy-client/angular.json @@ -21,13 +21,8 @@ "polyfills": "apps/goofy/src/polyfills.ts", "tsConfig": "apps/goofy/tsconfig.app.json", "aot": true, - "assets": [ - "apps/goofy/src/favicon.ico", - "apps/goofy/src/assets" - ], - "styles": [ - "apps/goofy/src/styles.scss" - ], + "assets": ["apps/goofy/src/favicon.ico", "apps/goofy/src/assets"], + "styles": ["apps/goofy/src/styles.scss"], "scripts": [] }, "configurations": { @@ -81,9 +76,7 @@ "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "apps/goofy/src/**/*.ts" - ] + "lintFilePatterns": ["apps/goofy/src/**/*.ts"] } }, "test": { @@ -116,9 +109,7 @@ "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "apps/goofy-e2e/**/*.{js,ts}" - ] + "lintFilePatterns": ["apps/goofy-e2e/**/*.{js,ts}"] } } } @@ -132,9 +123,7 @@ "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "libs/api-root-shared/src/**/*.ts" - ] + "lintFilePatterns": ["libs/api-root-shared/src/**/*.ts"] } }, "test": { @@ -160,9 +149,7 @@ "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "libs/environment-shared/src/**/*.ts" - ] + "lintFilePatterns": ["libs/environment-shared/src/**/*.ts"] } }, "test": { @@ -178,6 +165,32 @@ "style": "scss" } } + }, + "tech-shared": { + "projectType": "library", + "root": "libs/tech-shared", + "sourceRoot": "libs/tech-shared/src", + "prefix": "goofy-client", + "architect": { + "lint": { + "builder": "@nrwl/linter:eslint", + "options": { + "lintFilePatterns": ["libs/tech-shared/src/**/*.ts"] + } + }, + "test": { + "builder": "@nrwl/jest:jest", + "options": { + "jestConfig": "libs/tech-shared/jest.config.js", + "passWithNoTests": true + } + } + }, + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + } } }, "cli": { diff --git a/goofy-client/apps/goofy/src/app/app.component.html b/goofy-client/apps/goofy/src/app/app.component.html index 2ceaeafd46f66953d5d85e0466eaf23f81b17945..95ebefa0c4df786aefa4a9917b0ef95f2e9b764b 100644 --- a/goofy-client/apps/goofy/src/app/app.component.html +++ b/goofy-client/apps/goofy/src/app/app.component.html @@ -1,7 +1,7 @@ <ng-container *ngIf="apiRoot | async as _apiRoot"> - <div> - <p>Version: {{_apiRoot.version}}</p> - <p>BuildTime: {{_apiRoot.buildTime}}</p> - <p>JavaVersion: {{_apiRoot.javaVersion}}</p> - </div> + <div> + <p>Version: {{ _apiRoot.version }}</p> + <p>BuildTime: {{ _apiRoot.buildTime }}</p> + <p>JavaVersion: {{ _apiRoot.javaVersion }}</p> + </div> </ng-container> diff --git a/goofy-client/apps/goofy/src/app/app.component.spec.ts b/goofy-client/apps/goofy/src/app/app.component.spec.ts index 61180912ba0b1e72ba95dd7b645108c455333d94..ecc028d6d506227506845e80b088f259e5c6d6d4 100644 --- a/goofy-client/apps/goofy/src/app/app.component.spec.ts +++ b/goofy-client/apps/goofy/src/app/app.component.spec.ts @@ -2,30 +2,28 @@ import { TestBed } from '@angular/core/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [AppComponent], - }).compileComponents(); - }); + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [AppComponent], + }).compileComponents(); + }); - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); - it(`should have as title 'goofy'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('goofy'); - }); + it(`should have as title 'goofy'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('goofy'); + }); - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain( - 'Welcome to goofy!' - ); - }); + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('Welcome to goofy!'); + }); }); diff --git a/goofy-client/apps/goofy/src/app/app.component.ts b/goofy-client/apps/goofy/src/app/app.component.ts index 900b987596825e14acf80c36836d4f622658be6e..813686135dc9c67f16cb68903ea23577fe1adfdd 100644 --- a/goofy-client/apps/goofy/src/app/app.component.ts +++ b/goofy-client/apps/goofy/src/app/app.component.ts @@ -4,16 +4,16 @@ import { ApiRootResource } from 'libs/api-root-shared/src/lib/api-root-shared.mo import { Observable } from 'rxjs'; @Component({ - selector: 'goofy-client-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'], + selector: 'goofy-client-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], }) export class AppComponent { - title = 'goofy'; + title = 'goofy'; - apiRoot: Observable<ApiRootResource>; + apiRoot: Observable<ApiRootResource>; - constructor(apiRootFacade: ApiRootFacade) { - this.apiRoot = apiRootFacade.apiRoot; - } -} + constructor(apiRootFacade: ApiRootFacade) { + this.apiRoot = apiRootFacade.apiRoot; + } +} \ No newline at end of file diff --git a/goofy-client/apps/goofy/src/app/app.module.ts b/goofy-client/apps/goofy/src/app/app.module.ts index 048b708a06b9d707bdf0ee006d02c86b6f0ddfed..8b6a1ffd9a1e6dd027c75b74e992fa5123df1dff 100644 --- a/goofy-client/apps/goofy/src/app/app.module.ts +++ b/goofy-client/apps/goofy/src/app/app.module.ts @@ -1,25 +1,25 @@ -import { BrowserModule } from '@angular/platform-browser'; +import { HttpClientModule } from '@angular/common/http'; import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { ApiRootSharedModule } from '@goofy-client/api-root-shared'; +import { EnvironmentSharedModule } from '@goofy-client/environment-shared'; import { NgxsReduxDevtoolsPluginModule } from '@ngxs/devtools-plugin'; import { NgxsLoggerPluginModule } from '@ngxs/logger-plugin'; import { NgxsModule } from '@ngxs/store'; import { AppComponent } from './app.component'; -import { ApiRootSharedModule } from '@goofy-client/api-root-shared'; -import { HttpClientModule } from '@angular/common/http'; -import { EnvironmentSharedModule } from '@goofy-client/environment-shared'; @NgModule({ - declarations: [AppComponent], - imports: [ - BrowserModule, - NgxsModule.forRoot([], { developmentMode: true }), - NgxsReduxDevtoolsPluginModule.forRoot(), - NgxsLoggerPluginModule.forRoot(), - HttpClientModule, - ApiRootSharedModule, - EnvironmentSharedModule - ], - providers: [], - bootstrap: [AppComponent], + declarations: [AppComponent], + imports: [ + BrowserModule, + NgxsModule.forRoot([], { developmentMode: true }), + NgxsReduxDevtoolsPluginModule.forRoot(), + NgxsLoggerPluginModule.forRoot(), + HttpClientModule, + EnvironmentSharedModule, + ApiRootSharedModule, + ], + providers: [], + bootstrap: [AppComponent], }) -export class AppModule { } +export class AppModule {} diff --git a/goofy-client/apps/goofy/src/environments/environment.prod.ts b/goofy-client/apps/goofy/src/environments/environment.prod.ts index c9669790be176ac85a5d8c11278875c2f52dc507..2f53f97e178fc80def5229fe500b0f869d2bcb73 100644 --- a/goofy-client/apps/goofy/src/environments/environment.prod.ts +++ b/goofy-client/apps/goofy/src/environments/environment.prod.ts @@ -1,3 +1,4 @@ export const environment = { - production: true, + production: true, + environmentUrl: null, }; diff --git a/goofy-client/apps/goofy/src/environments/environment.ts b/goofy-client/apps/goofy/src/environments/environment.ts index 99c3763cad6f4ae7808a34e2aa4e5b90232c67fc..ac43653f6554a95eabed1752cd2fb674445b8099 100644 --- a/goofy-client/apps/goofy/src/environments/environment.ts +++ b/goofy-client/apps/goofy/src/environments/environment.ts @@ -3,7 +3,8 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false, + production: false, + environmentUrl: null, }; /* diff --git a/goofy-client/apps/goofy/src/index.html b/goofy-client/apps/goofy/src/index.html index 90055906cdccd6cec25b71c5418c019b406884cb..4ba11905320a68b3d6ce51fea7dd5b4257d79a7f 100644 --- a/goofy-client/apps/goofy/src/index.html +++ b/goofy-client/apps/goofy/src/index.html @@ -1,13 +1,13 @@ <!DOCTYPE html> <html lang="en"> - <head> - <meta charset="utf-8" /> - <title>Goofy</title> - <base href="/" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <link rel="icon" type="image/x-icon" href="favicon.ico" /> - </head> - <body> - <goofy-client-root></goofy-client-root> - </body> + <head> + <meta charset="utf-8" /> + <title>Goofy</title> + <base href="/" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <link rel="icon" type="image/x-icon" href="favicon.ico" /> + </head> + <body> + <goofy-client-root></goofy-client-root> + </body> </html> diff --git a/goofy-client/apps/goofy/src/main.ts b/goofy-client/apps/goofy/src/main.ts index d9a2e7e4a582e265db779363bd8b2492c43c141b..826c3546de04cbe0daca522562e4862a976d5185 100644 --- a/goofy-client/apps/goofy/src/main.ts +++ b/goofy-client/apps/goofy/src/main.ts @@ -1,13 +1,15 @@ import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; - +import { loadEnvironment } from '@goofy-client/environment-shared'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; -if (environment.production) { - enableProdMode(); -} +loadEnvironment(environment.environmentUrl).then((env) => { + if (env.production) { + enableProdMode(); + } -platformBrowserDynamic() - .bootstrapModule(AppModule) - .catch((err) => console.error(err)); + platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.log(err)); +}); \ No newline at end of file diff --git a/goofy-client/jest.config.js b/goofy-client/jest.config.js index 8c16dbee9dfb0652f9e4b6a596ec75b6fa56e0f9..4b34d0c1ff84cdfff5d6aaeef02c24101094acff 100644 --- a/goofy-client/jest.config.js +++ b/goofy-client/jest.config.js @@ -3,5 +3,6 @@ module.exports = { '<rootDir>/apps/goofy', '<rootDir>/libs/api-root-shared', '<rootDir>/libs/environment-shared', + '<rootDir>/libs/tech-shared', ], }; diff --git a/goofy-client/libs/api-root-shared/src/index.ts b/goofy-client/libs/api-root-shared/src/index.ts index 077b7d14d52de3d488fea5a690702ec8585d4a78..b50147d078361f7378386afb605834629b78c1e8 100644 --- a/goofy-client/libs/api-root-shared/src/index.ts +++ b/goofy-client/libs/api-root-shared/src/index.ts @@ -1,2 +1,4 @@ -export * from './lib/api-root-shared.module'; +export * from './lib/api-root-shared.actions'; export * from './lib/api-root-shared.facade'; +export * from './lib/api-root-shared.module'; + diff --git a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.actions.ts b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.actions.ts index 237cb62b4386be4fdb5e0829e71c3e79415c781f..9a48bf39c8447aa01f21152a43a778e4fca9677a 100644 --- a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.actions.ts +++ b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.actions.ts @@ -1,11 +1,7 @@ -import { ApiRootResource } from './api-root-shared.model'; +import { ResourceUri } from '@ngxp/rest'; export class LoadApiRootAction { - static readonly type = 'LOAD_API_ROOT' -} - -export class LoadApiRootSuccessAction { - static readonly type = 'LOAD_API_ROOT_SUCCESS'; - - constructor(public apiRoot: ApiRootResource) { } -} + static readonly type = '[System ApiRoot] Load'; + + constructor(public remoteHost: ResourceUri){} +} \ No newline at end of file diff --git a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.facade.ts b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.facade.ts index 5a0588afebafa82a6ee55890020c2492de2f76db..571c5665739c190db401ada3a238918c284ebb86 100644 --- a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.facade.ts +++ b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.facade.ts @@ -1,23 +1,23 @@ import { Injectable } from '@angular/core'; -import { Select, Store } from '@ngxs/store'; +import { StateResource } from '@goofy-client/tech-shared'; +import { Select } from '@ngxs/store'; import { Observable } from 'rxjs'; -import { filter, map } from 'rxjs/operators'; -import { LoadApiRootAction } from './api-root-shared.actions'; +import { map } from 'rxjs/operators'; import { ApiRootResource } from './api-root-shared.model'; import { ApiRootState } from './api-root-shared.state'; -import { doIfLoadingRequired, StateResource } from './api-root-shared.util'; -@Injectable({ providedIn: 'root' }) +@Injectable() export class ApiRootFacade { + + @Select(ApiRootState.apiRootSelector) + + private readonly apiRootSelector: Observable<StateResource<ApiRootResource>>; - @Select(ApiRootState.apiRootSelector) - private readonly apiRootSelector: Observable<StateResource<ApiRootResource>>; + constructor() {} - constructor(private store: Store) { } - - get apiRoot(): Observable<ApiRootResource> { - return this.apiRootSelector.pipe( - filter(apiRootStateResource => !doIfLoadingRequired(apiRootStateResource, () => this.store.dispatch(new LoadApiRootAction()))), - map(apiRootStateResource => apiRootStateResource.resource)) - } + get apiRoot(): Observable<ApiRootResource> { + return this.apiRootSelector.pipe( + map((apiRootStateResource: StateResource<ApiRootResource>) => apiRootStateResource.resource) + ); + } } diff --git a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.model.ts b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.model.ts index 5b18cc9f24a14c8dd07af20bfc0253a5ffb99a0f..017120b7c558a4f29debb4f9c29a543c5ae78dd5 100644 --- a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.model.ts +++ b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.model.ts @@ -1,9 +1,9 @@ import { Resource } from '@ngxp/rest'; export interface ApiRoot { - version: string, - buildTime: string - javaVersion: string, + version: string; + buildTime: string; + javaVersion: string; } -export interface ApiRootResource extends ApiRoot, Resource { } +export interface ApiRootResource extends ApiRoot, Resource {} diff --git a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.module.ts b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.module.ts index 0750e36d0a6496ae374637e9d7a3f482ee94003e..8d4b50364f66c791d31949f5254c7642fe9a04a5 100644 --- a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.module.ts +++ b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.module.ts @@ -1,26 +1,15 @@ import { NgModule } from '@angular/core'; -import { ApiRootService, REMOTE_HOST } from './api-root-shared.service'; +import { RestModule } from '@ngxp/rest'; import { NgxsModule } from '@ngxs/store'; +import { ApiRootFacade } from './api-root-shared.facade'; +import { ApiRootService } from './api-root-shared.service'; import { ApiRootState } from './api-root-shared.state'; -import { RestModule } from '@ngxp/rest'; -import { ENVIRONMENT_CONFIG } from '@goofy-client/environment-shared'; - -export function remoteHostFactory(environment: any) { - return environment.remoteHost; -} @NgModule({ - imports: [ - NgxsModule.forFeature([ApiRootState]), - RestModule - ], - providers: [ - ApiRootService, - { - provide: REMOTE_HOST, - useFactory: remoteHostFactory, - deps: [ENVIRONMENT_CONFIG] - } - ] + imports: [ + NgxsModule.forFeature([ApiRootState]), + RestModule + ], + providers: [ApiRootService, ApiRootFacade], }) -export class ApiRootSharedModule { } +export class ApiRootSharedModule {} diff --git a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.service.ts b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.service.ts index 3813a917f0d2d012fe0e7a73911d7bbe632ea9c7..7f6c2ded563751bbc29be94aa33ea4cef79317ef 100644 --- a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.service.ts +++ b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.service.ts @@ -1,16 +1,15 @@ -import { InjectionToken, Injectable, Inject } from '@angular/core'; +import { Injectable, InjectionToken } from '@angular/core'; +import { HttpService, ResourceUri } from '@ngxp/rest'; import { Observable } from 'rxjs'; import { ApiRootResource } from './api-root-shared.model'; -import { HttpService } from '@ngxp/rest'; export const REMOTE_HOST = new InjectionToken('remoteHost'); @Injectable() export class ApiRootService { + constructor(private httpService: HttpService) {} - constructor(private httpService: HttpService) { } - - get(): Observable<ApiRootResource> { - return <Observable<ApiRootResource>>this.httpService.get('http://localhost:8080/api');//TODO replace with environment host - } + get(remoteHost: ResourceUri): Observable<ApiRootResource> { + return <Observable<ApiRootResource>>this.httpService.get(remoteHost); + } } diff --git a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.state.ts b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.state.ts index 735bcde9374baa57baf921bdead49693b91f2ce9..16a8c584fdd74a0480085b3e071d3a412ec4d853 100644 --- a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.state.ts +++ b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.state.ts @@ -1,42 +1,43 @@ import { Injectable } from '@angular/core'; -import { State, Action, StateContext, Selector } from '@ngxs/store'; +import { createEmptyStateResource, createStateResource, StateResource } from '@goofy-client/tech-shared'; +import { Action, NgxsOnInit, Selector, State, StateContext } from '@ngxs/store'; +import { Environment } from 'libs/environment-shared/src/lib/environment-shared.model'; +import { getEnvironmentFactory } from 'libs/environment-shared/src/lib/environment-shared.util'; import { tap } from 'rxjs/operators'; import { LoadApiRootAction } from './api-root-shared.actions'; import { ApiRootResource } from './api-root-shared.model'; import { ApiRootService } from './api-root-shared.service'; -import { createEmptyStateObject, createStateObject, StateResource } from './api-root-shared.util'; const defaults: ApiRootStateModel = { - apiRoot: createEmptyStateObject() -} + apiRoot: createEmptyStateResource(), +}; export interface ApiRootStateModel { - apiRoot: StateResource<ApiRootResource> -} - -export interface ApiRootRootState { - apiRootRoot: ApiRootState; + apiRoot: StateResource<ApiRootResource>; } -@State<ApiRootStateModel>({ - name: 'apiRootRoot', defaults -}) +@State<ApiRootStateModel>({ name: 'apiRoot', defaults }) @Injectable() -export class ApiRootState { +export class ApiRootState implements NgxsOnInit{ + + @Selector() static apiRootSelector(state: ApiRootStateModel): StateResource<ApiRootResource> { + return state.apiRoot; + } - constructor(private service: ApiRootService) { } + constructor(private service: ApiRootService) {} - @Selector() static apiRootSelector(state: ApiRootStateModel): StateResource<ApiRootResource> { - return state.apiRoot; - } + ngxsOnInit(context: StateContext<any>): void { + getEnvironmentFactory().then((environment: Environment) => context.dispatch(new LoadApiRootAction(environment.remoteHost))); + } - @Action(LoadApiRootAction) - loadApiRoot(context: StateContext<ApiRootStateModel>) { - return this.service.get().pipe( - tap(apiRoot => { - context.patchState({ - apiRoot: createStateObject(apiRoot) - }); - })) - } -} + @Action(LoadApiRootAction) + loadApiRoot(context: StateContext<ApiRootStateModel>, action: LoadApiRootAction) { + return this.service.get(action.remoteHost).pipe( + tap((apiRoot) => { + context.patchState({ + apiRoot: createStateResource(apiRoot), + }); + }) + ); + } +} \ No newline at end of file diff --git a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.util.ts b/goofy-client/libs/api-root-shared/src/lib/api-root-shared.util.ts deleted file mode 100644 index d0c926bac2fa8b0c64a1fcd7455552716ea29ced..0000000000000000000000000000000000000000 --- a/goofy-client/libs/api-root-shared/src/lib/api-root-shared.util.ts +++ /dev/null @@ -1,31 +0,0 @@ -//CHECKME Util-lib anlegen?! -export interface StateResource<T> { - reload: boolean; - loaded: boolean; - loading: boolean; - resource: T; -} - -export function createEmptyStateObject<T>(loading: boolean = false): StateResource<T> { - return createStateObject(<T>null, loading); -} - -export function createStateObject<T>(resource: T, loading: boolean = false): StateResource<T> { - return { loading, loaded: !isNil(resource), reload: false, resource } -} - -export function doIfLoadingRequired(stateResource: StateResource<any>, runable: () => void): boolean { - if (stateResource != undefined && isLoadingRequired(stateResource)) { - runable(); - return true - }; - return false; -} - -export function isLoadingRequired(stateResource: StateResource<any>): boolean { - return !stateResource.loading && ((!stateResource.loaded) || stateResource.reload); -} - -export function isNil(value: any) { - return value === 'undefined' || value == null; -} diff --git a/goofy-client/libs/environment-shared/src/index.ts b/goofy-client/libs/environment-shared/src/index.ts index 21275cc22979961aadb352a142985f4eed11f1aa..2c1eaac076108baf14223984218a3de4352f7939 100644 --- a/goofy-client/libs/environment-shared/src/index.ts +++ b/goofy-client/libs/environment-shared/src/index.ts @@ -1,2 +1,2 @@ export * from './lib/environment-shared.module'; -export * from './lib/environment-shared.loader'; +export * from './lib/environment-shared.service'; diff --git a/goofy-client/libs/environment-shared/src/lib/environment-shared.actions.ts b/goofy-client/libs/environment-shared/src/lib/environment-shared.actions.ts new file mode 100644 index 0000000000000000000000000000000000000000..001a658f08f665d6ee9532c7896df22b4d77d5ff --- /dev/null +++ b/goofy-client/libs/environment-shared/src/lib/environment-shared.actions.ts @@ -0,0 +1,3 @@ +export class SetEnvironmentAction { + static readonly type = '[System Environment] Set'; +} \ No newline at end of file diff --git a/goofy-client/libs/environment-shared/src/lib/environment-shared.loader.ts b/goofy-client/libs/environment-shared/src/lib/environment-shared.loader.ts deleted file mode 100644 index 0e0237c5228cd2088003438de894cdf0b9f70837..0000000000000000000000000000000000000000 --- a/goofy-client/libs/environment-shared/src/lib/environment-shared.loader.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { InjectionToken } from '@angular/core'; -import 'whatwg-fetch'; - -export const ENVIRONMENT_CONFIG = new InjectionToken('environmentConfig'); - -export function getEnvironmentFactory(): any { - return window['__env__']; -} diff --git a/goofy-client/libs/environment-shared/src/lib/environment-shared.model.ts b/goofy-client/libs/environment-shared/src/lib/environment-shared.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..ce694ccd94f576b2b53e6c88c741e12e78c7c727 --- /dev/null +++ b/goofy-client/libs/environment-shared/src/lib/environment-shared.model.ts @@ -0,0 +1,6 @@ +import { ResourceUri } from '@ngxp/rest/lib/resource.model'; + +export interface Environment { + production: boolean, + remoteHost: ResourceUri +} \ No newline at end of file diff --git a/goofy-client/libs/environment-shared/src/lib/environment-shared.module.ts b/goofy-client/libs/environment-shared/src/lib/environment-shared.module.ts index 32b46585cc10e10de9bb2d896ef251fd02f702e5..3fc4aab5e770b933b3afe948c1bde576f7c890a4 100644 --- a/goofy-client/libs/environment-shared/src/lib/environment-shared.module.ts +++ b/goofy-client/libs/environment-shared/src/lib/environment-shared.module.ts @@ -1,19 +1,9 @@ import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { getEnvironmentFactory } from './environment-shared.loader'; +import { RestModule } from '@ngxp/rest'; import { NgxsModule } from '@ngxs/store'; -import { ENVIRONMENT_CONFIG } from './environment-shared.loader'; +import { EnvironmentState } from './environment-shared.state'; @NgModule({ - imports: [ - CommonModule, - NgxsModule - ], - providers: [ - { - provide: ENVIRONMENT_CONFIG, - useFactory: getEnvironmentFactory - } - ] + imports: [NgxsModule.forFeature([EnvironmentState]), RestModule] }) -export class EnvironmentSharedModule { } +export class EnvironmentSharedModule {} diff --git a/goofy-client/libs/environment-shared/src/lib/environment-shared.service.ts b/goofy-client/libs/environment-shared/src/lib/environment-shared.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..c378995551ded7e32be4e05c43b0b66bf8ec6c52 --- /dev/null +++ b/goofy-client/libs/environment-shared/src/lib/environment-shared.service.ts @@ -0,0 +1,15 @@ +import { InjectionToken } from '@angular/core'; +import { getBaseUrl } from '@goofy-client/tech-shared'; + +export const ENVIRONMENT_CONFIG = new InjectionToken('environmentConfig'); + +export async function loadEnvironment(url?: string): Promise<any> { + const envUrl = url ? url : `${getBaseUrl()}api/environment`; + const headers = new Headers({ 'X-Client': 'web' }); + + return window.fetch(envUrl, { headers }).then(response => { + const env = response.json(); + window['__env__'] = env; + return env; + }) +} \ No newline at end of file diff --git a/goofy-client/libs/environment-shared/src/lib/environment-shared.state.ts b/goofy-client/libs/environment-shared/src/lib/environment-shared.state.ts index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cac4c76c6518bfc0382249132eb7e1a90172613f 100644 --- a/goofy-client/libs/environment-shared/src/lib/environment-shared.state.ts +++ b/goofy-client/libs/environment-shared/src/lib/environment-shared.state.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@angular/core'; +import { Action, NgxsOnInit, State, StateContext } from '@ngxs/store'; +import { SetEnvironmentAction } from './environment-shared.actions'; +import { Environment } from './environment-shared.model'; +import { getEnvironmentFactory } from './environment-shared.util'; + +const defaults: EnvironmentStateModel = { + environment: null +}; + +export interface EnvironmentStateModel { + environment: Environment; +} + +@State<EnvironmentStateModel>({ name: 'environment', defaults }) +@Injectable() +export class EnvironmentState implements NgxsOnInit { + + constructor() {} + + ngxsOnInit(context: StateContext<EnvironmentStateModel>) { + context.dispatch(new SetEnvironmentAction()); + } + + @Action(SetEnvironmentAction) + loadEnvironment(context: StateContext<EnvironmentStateModel>) { + return getEnvironmentFactory().then((environment: Environment) => { + context.patchState({environment }); + }) + } +} \ No newline at end of file diff --git a/goofy-client/libs/environment-shared/src/lib/environment-shared.util.ts b/goofy-client/libs/environment-shared/src/lib/environment-shared.util.ts new file mode 100644 index 0000000000000000000000000000000000000000..4425fb937056f8204a88db97a635a3fd99eac5b0 --- /dev/null +++ b/goofy-client/libs/environment-shared/src/lib/environment-shared.util.ts @@ -0,0 +1,3 @@ +export function getEnvironmentFactory(): any { + return window['__env__']; +} \ No newline at end of file diff --git a/goofy-client/libs/tech-shared/.eslintrc.json b/goofy-client/libs/tech-shared/.eslintrc.json new file mode 100644 index 0000000000000000000000000000000000000000..54ac39535a2c03d4d0fc2eb6e52564638ae3b2e6 --- /dev/null +++ b/goofy-client/libs/tech-shared/.eslintrc.json @@ -0,0 +1 @@ +{ "extends": "../../.eslintrc.json", "ignorePatterns": ["!**/*"], "rules": {} } diff --git a/goofy-client/libs/tech-shared/README.md b/goofy-client/libs/tech-shared/README.md new file mode 100644 index 0000000000000000000000000000000000000000..23b5222769d3c502ce7d7eb22954dfcedacb90f7 --- /dev/null +++ b/goofy-client/libs/tech-shared/README.md @@ -0,0 +1,7 @@ +# tech-shared + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test tech-shared` to execute the unit tests. diff --git a/goofy-client/libs/tech-shared/jest.config.js b/goofy-client/libs/tech-shared/jest.config.js new file mode 100644 index 0000000000000000000000000000000000000000..71c6f2f74b641f6ebbc3090ac1e50e4fae4ada2c --- /dev/null +++ b/goofy-client/libs/tech-shared/jest.config.js @@ -0,0 +1,23 @@ +module.exports = { + displayName: 'tech-shared', + preset: '../../jest.preset.js', + setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'], + globals: { + 'ts-jest': { + tsConfig: '<rootDir>/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + astTransformers: { + before: [ + 'jest-preset-angular/build/InlineFilesTransformer', + 'jest-preset-angular/build/StripStylesTransformer', + ], + }, + }, + }, + coverageDirectory: '../../coverage/libs/tech-shared', + snapshotSerializers: [ + 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js', + 'jest-preset-angular/build/AngularSnapshotSerializer.js', + 'jest-preset-angular/build/HTMLCommentSerializer.js', + ], +}; diff --git a/goofy-client/libs/tech-shared/src/index.ts b/goofy-client/libs/tech-shared/src/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..8f509c7e9b45e39cfabd67d4a1f264d90bc352fa --- /dev/null +++ b/goofy-client/libs/tech-shared/src/index.ts @@ -0,0 +1,3 @@ +export * from './lib/resource/resource.util'; +export * from './lib/tech-shared.module'; +export * from './lib/tech-shared.util'; diff --git a/goofy-client/libs/tech-shared/src/lib/resource/resource.util.ts b/goofy-client/libs/tech-shared/src/lib/resource/resource.util.ts new file mode 100644 index 0000000000000000000000000000000000000000..3ab0f984f50fa7197ed983d245575a45e871b60e --- /dev/null +++ b/goofy-client/libs/tech-shared/src/lib/resource/resource.util.ts @@ -0,0 +1,28 @@ +import { isNil } from 'lodash-es'; + +export interface StateResource<T> { + reload: boolean; + loaded: boolean; + loading: boolean; + resource: T; +} + +export function createEmptyStateResource<T>(loading: boolean = false): StateResource<T> { + return createStateResource(<T>null, loading); +} + +export function createStateResource<T>(resource: T, loading: boolean = false): StateResource<T> { + return { loading, loaded: !isNil(resource), reload: false, resource }; +} + +export function doIfLoadingRequired(stateResource: StateResource<any>, runable: () => void): boolean { + if (stateResource != undefined && isLoadingRequired(stateResource)) { + runable(); + return true; + } + return false; +} + +export function isLoadingRequired(stateResource: StateResource<any>): boolean { + return !stateResource.loading && (!stateResource.loaded || stateResource.reload); +} \ No newline at end of file diff --git a/goofy-client/libs/tech-shared/src/lib/tech-shared.module.ts b/goofy-client/libs/tech-shared/src/lib/tech-shared.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..6b19edc602c1945b74e0455f9478a6c982f6b214 --- /dev/null +++ b/goofy-client/libs/tech-shared/src/lib/tech-shared.module.ts @@ -0,0 +1,7 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@NgModule({ + imports: [CommonModule], +}) +export class TechSharedModule {} diff --git a/goofy-client/libs/tech-shared/src/lib/tech-shared.util.ts b/goofy-client/libs/tech-shared/src/lib/tech-shared.util.ts new file mode 100644 index 0000000000000000000000000000000000000000..1a23b7fa71b6a86e9fbe8f910611a63beaa8d895 --- /dev/null +++ b/goofy-client/libs/tech-shared/src/lib/tech-shared.util.ts @@ -0,0 +1,6 @@ +export function getBaseUrl(): string { + const { protocol, host, } = window.location; + const basePath = `${protocol}//${host}`; + const url = basePath.endsWith('/') ? `${basePath}` : `${basePath}/`; + return url; +} \ No newline at end of file diff --git a/goofy-client/libs/tech-shared/src/test-setup.ts b/goofy-client/libs/tech-shared/src/test-setup.ts new file mode 100644 index 0000000000000000000000000000000000000000..8d88704e8ff09145a6310d3df98f124042268bfe --- /dev/null +++ b/goofy-client/libs/tech-shared/src/test-setup.ts @@ -0,0 +1 @@ +import 'jest-preset-angular'; diff --git a/goofy-client/libs/tech-shared/tsconfig.json b/goofy-client/libs/tech-shared/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..62ebbd946474cea997e774d20fffc4d585c184f3 --- /dev/null +++ b/goofy-client/libs/tech-shared/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/goofy-client/libs/tech-shared/tsconfig.lib.json b/goofy-client/libs/tech-shared/tsconfig.lib.json new file mode 100644 index 0000000000000000000000000000000000000000..d5befaafb6f871f62279559d6efec18a4a19e665 --- /dev/null +++ b/goofy-client/libs/tech-shared/tsconfig.lib.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "target": "es2015", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [], + "lib": ["dom", "es2018"] + }, + "angularCompilerOptions": { + "skipTemplateCodegen": true, + "strictMetadataEmit": true, + "enableResourceInlining": true + }, + "exclude": ["src/test-setup.ts", "**/*.spec.ts"], + "include": ["**/*.ts"] +} diff --git a/goofy-client/libs/tech-shared/tsconfig.spec.json b/goofy-client/libs/tech-shared/tsconfig.spec.json new file mode 100644 index 0000000000000000000000000000000000000000..cfff29a544fb49a8c26a7cbf9cd836c87efb7fe8 --- /dev/null +++ b/goofy-client/libs/tech-shared/tsconfig.spec.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["**/*.spec.ts", "**/*.d.ts"] +} diff --git a/goofy-client/nx.json b/goofy-client/nx.json index 711ee7882c8cc3c892d71304bc98a02a020d1ae8..e5a5c9d7130d4fccd03dc220dd5d98d8ea8f5ffe 100644 --- a/goofy-client/nx.json +++ b/goofy-client/nx.json @@ -35,6 +35,9 @@ }, "environment-shared": { "tags": [] + }, + "tech-shared": { + "tags": [] } } } diff --git a/goofy-client/package-lock.json b/goofy-client/package-lock.json index ac1cb6be079f38418912311039e2dbe3a3c1d0e7..82487de3c2d8bd477d7fbe3683c2987f4a63716b 100644 --- a/goofy-client/package-lock.json +++ b/goofy-client/package-lock.json @@ -27520,7 +27520,8 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "7.2.0", @@ -27626,13 +27627,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true + "dev": true, + "requires": {} }, "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "devOptional": true + "devOptional": true, + "requires": {} }, "alphanum-sort": { "version": "1.0.2", @@ -28720,7 +28723,8 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz", "integrity": "sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw==", - "dev": true + "dev": true, + "requires": {} }, "cjs-module-lexer": { "version": "0.6.0", @@ -33903,7 +33907,8 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-preset-angular": { "version": "8.3.1", @@ -42149,7 +42154,8 @@ "version": "7.3.1", "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", - "dev": true + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "3.0.0", diff --git a/goofy-client/package.json b/goofy-client/package.json index 310f839529508c8157f02fdb810d445bc16042dd..7230ec212b24f992fe1c514cfbdaa4edfc495944 100644 --- a/goofy-client/package.json +++ b/goofy-client/package.json @@ -6,7 +6,7 @@ "ng": "nx", "postinstall": "node ./decorate-angular-cli.js && ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points", "nx": "nx", - "start": "run-s \"ng -- serve --port 4200 --disable-host-check --proxy-config proxy.conf.json\" --", + "start": "run-s \"ng -- serve --port 4300 --disable-host-check --proxy-config proxy.conf.json\" --", "build": "ng build", "test": "ng test", "lint": "nx workspace-lint && ng lint", diff --git a/goofy-client/proxy.conf.json b/goofy-client/proxy.conf.json index d72109826befd18273e15007dc613c9df80707d7..245402a38c103dda6b94d339d6a47ad69e8443f5 100644 --- a/goofy-client/proxy.conf.json +++ b/goofy-client/proxy.conf.json @@ -1,6 +1,10 @@ { - "/api/*": { - "target": "http://localhost:8080", + "/api": { + "target": { + "host": "localhost", + "port": 8080, + "protocol": "http:" + }, "secure": false, "logLevel": "debug" } diff --git a/goofy-client/tsconfig.base.json b/goofy-client/tsconfig.base.json index 2e6ce146ce05a10aef57f6c890dbcec959bc796e..c7ff64f6bae6312f159d68a3cb5f1d40df402d3a 100644 --- a/goofy-client/tsconfig.base.json +++ b/goofy-client/tsconfig.base.json @@ -19,7 +19,8 @@ "@goofy-client/api-root-shared": ["libs/api-root-shared/src/index.ts"], "@goofy-client/environment-shared": [ "libs/environment-shared/src/index.ts" - ] + ], + "@goofy-client/tech-shared": ["libs/tech-shared/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] diff --git a/goofy-server/src/main/java/de/itvsh/goofy/EnvironmentController.java b/goofy-server/src/main/java/de/itvsh/goofy/EnvironmentController.java index d8372229e2bb28e7218b5acab3dc8b3af9f89ae2..370ec74fd973103ea16e875af79ca0b4b59d113e 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/EnvironmentController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/EnvironmentController.java @@ -3,6 +3,7 @@ package de.itvsh.goofy; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -14,6 +15,7 @@ public class EnvironmentController { @Value("${goofy.production}") private boolean production; + @CrossOrigin @GetMapping public FrontendEnvironment getFrontendEnvironment() { return FrontendEnvironment.builder()//