implement part 3
CureNetMulti/pipeline/head This commit looks good Details
CureNetMulti/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Sieciech 2021-08-31 17:16:16 +02:00
parent 1eb0ba32f1
commit c7707fc94a
15 changed files with 161 additions and 104 deletions

View File

@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
echo "> Configure cache" #echo "> Configure cache"
mkdir -p /tmp/app/vendor # mkdir -p /tmp/app/vendor
ln -s /tmp/app/vendor /web/backend/vendor # ln -s /tmp/app/vendor /web/backend/vendor
echo "> Configure user" echo "> Configure user"
useradd developer useradd developer
@ -14,10 +14,10 @@ echo "> Configure logs"
chown postgres:adm /var/log/postgresql -R chown postgres:adm /var/log/postgresql -R
chown root:postgres /var/log/postgresql chown root:postgres /var/log/postgresql
echo "> Configure volumes" #echo "> Configure volumes"
[ -e /web/frontend/node_modules ] || ln -s /web/node /web/frontend/node_modules # [ -e /web/frontend/node_modules ] || ln -s /web/node /web/frontend/node_modules
[ -e /web/backend/var ] || ln -s /web/var /web/backend/var # [ -e /web/backend/var ] || ln -s /web/var /web/backend/var
[ -e /web/backend/vendor ] || ln -s /web/vendor /web/backend/vendor # [ -e /web/backend/vendor ] || ln -s /web/vendor /web/backend/vendor
echo "> Starting php8.0-fpm server" echo "> Starting php8.0-fpm server"
[ -e /etc/php/8.0/fpm/conf.d/20-xdebug.ini ] && rm /etc/php/8.0/fpm/conf.d/20-xdebug.ini || echo OK [ -e /etc/php/8.0/fpm/conf.d/20-xdebug.ini ] && rm /etc/php/8.0/fpm/conf.d/20-xdebug.ini || echo OK

View File

@ -1,75 +1,77 @@
<app-loader *ngIf="!loaded"></app-loader>
<ng-template #toolbar> <ng-container *ngIf="loaded">
<mat-toolbar class="toolbar-background"> <ng-template #toolbar>
<button mat-icon-button (click)="toggleSidebar()"> <mat-toolbar class="toolbar-background">
<i class="fa fa-bars"></i> <button mat-icon-button (click)="toggleSidebar()">
</button> <i class="fa fa-bars"></i>
<span>{{ 'APP.NAME' | translate }}</span> </button>
<span class="flex-grow-1"></span> <span>{{ 'APP.NAME' | translate }}</span>
<div> <span class="flex-grow-1"></span>
<div *ngFor="let component of dynamicToolbarComponents">
<ng-container [ngComponentOutlet]="component"></ng-container>
</div>
</div>
</mat-toolbar>
</ng-template>
<ng-container *ngIf="!isMobile">
<ng-container *ngTemplateOutlet="toolbar"></ng-container>
</ng-container>
<mat-drawer-container class="flex-grow-1">
<mat-drawer [mode]="sidebarMode" [opened]="isSidebarOpen" (openedChange)="onSidebarOpenedChange($event)">
<div class="menu">
<div> <div>
<ng-container *ngFor="let route of appRoutes"> <div *ngFor="let component of dynamicToolbarComponents">
<ng-container *ngIf="route.menuEntries"> <ng-container [ngComponentOutlet]="component"></ng-container>
<ng-container </div>
*ngFor="let menu of route.menuEntries"> </div>
<div </mat-toolbar>
*ngIf="canShowMenuEntry(menu)" </ng-template>
class="menu-item" <ng-container *ngIf="!isMobile">
[attr.style]="menu.level ? 'margin-left: '+(menu.level * 20)+'px' : ''" <ng-container *ngTemplateOutlet="toolbar"></ng-container>
[routerLink]="menu.path ? menu.path : route.path" </ng-container>
routerLinkActive="active" <mat-drawer-container class="flex-grow-1">
[routerLinkActiveOptions]="{exact: menu.matchExact}"> <mat-drawer [mode]="sidebarMode" [opened]="isSidebarOpen" (openedChange)="onSidebarOpenedChange($event)">
<i [class]="menu.icon" [title]="menu.label | translate"></i> <div class="menu">
<span>{{ menu.label | translate }}</span> <div>
</div> <ng-container *ngFor="let route of appRoutes">
<ng-container *ngIf="route.menuEntries">
<ng-container
*ngFor="let menu of route.menuEntries">
<div
*ngIf="canShowMenuEntry(menu)"
class="menu-item"
[attr.style]="menu.level ? 'margin-left: '+(menu.level * 20)+'px' : ''"
[routerLink]="menu.path ? menu.path : route.path"
routerLinkActive="active"
[routerLinkActiveOptions]="{exact: menu.matchExact}">
<i [class]="menu.icon" [title]="menu.label | translate"></i>
<span>{{ menu.label | translate }}</span>
</div>
</ng-container>
</ng-container> </ng-container>
</ng-container> </ng-container>
</ng-container> </div>
</div> <div>
<div> <div class="d-flex user-box" *ngIf="user">
<div class="d-flex user-box" *ngIf="user"> <div class="avatar" [style.background-image]="url(user.avatar)"></div>
<div class="avatar" [style.background-image]="url(user.avatar)"></div> <div class="d-flex align-items-center flex-grow-1 p-2">{{ user.name }} {{ user.surname }}</div>
<div class="d-flex align-items-center flex-grow-1 p-2">{{ user.name }} {{ user.surname }}</div> <div class="user-menu-container">
<div class="user-menu-container"> <div class="user-menu">
<div class="user-menu"> <button mat-icon-button [matMenuTriggerFor]="usermenu">
<button mat-icon-button [matMenuTriggerFor]="usermenu"> <i class="fa fa-cog"></i>
<i class="fa fa-cog"></i> </button>
</button> </div>
<mat-menu #usermenu="matMenu" yPosition="above" xPosition="before" class="w-220">
<button mat-menu-item routerLink="/profile">
{{ 'APP.USER_SETTINGS' | translate }}
</button>
<button mat-menu-item routerLink="/profile/settings">
{{ 'APP.USER_SITE_SETTINGS' | translate }}
</button>
<button mat-menu-item (click)="logout()">
{{ 'APP.LOGOUT' | translate}}
</button>
</mat-menu>
</div> </div>
<mat-menu #usermenu="matMenu" yPosition="above" xPosition="before" class="w-220">
<button mat-menu-item routerLink="/profile">
{{ 'APP.USER_SETTINGS' | translate }}
</button>
<button mat-menu-item routerLink="/profile/settings">
{{ 'APP.USER_SITE_SETTINGS' | translate }}
</button>
<button mat-menu-item (click)="logout()">
{{ 'APP.LOGOUT' | translate}}
</button>
</mat-menu>
</div> </div>
</div> </div>
</div> </div>
</mat-drawer>
<ng-container *ngIf="isMobile">
<ng-container *ngTemplateOutlet="toolbar"></ng-container>
</ng-container>
<div class="content">
<router-outlet></router-outlet>
</div> </div>
</mat-drawer> </mat-drawer-container>
</ng-container>
<ng-container *ngIf="isMobile">
<ng-container *ngTemplateOutlet="toolbar"></ng-container>
</ng-container>
<div class="content">
<router-outlet></router-outlet>
</div>
</mat-drawer-container>

View File

@ -63,12 +63,20 @@ export class AppComponent implements AfterContentInit {
} }
configureUserEvents(): void { configureUserEvents(): void {
this.authService.checkUser().then(user => {
this.setUser(user);
this.loaded = true;
}).catch(() => {
this.setUser(null);
this.loaded = true;
});
this.setUser(this.authService.getUser()); this.setUser(this.authService.getUser());
this.authService.userChange.subscribe(user => this.setUser(user)); this.authService.userChange.subscribe(user => {
this.setUser(user);
});
} }
setUser(user: UserModel): void { setUser(user: UserModel): void {
console.log({user, cuser: this.user});
if (!user && !this.user) { if (!user && !this.user) {
return; return;
} }

View File

@ -13,11 +13,11 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader'; import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { TokenInterceptor } from './modules/shared/interceptors/token/token.interceptor'; import { TokenInterceptor } from './modules/shared/interceptors/token/token.interceptor';
import { AuthTokenService } from './modules/shared/services/auth/auth-token.service'; import { AuthTokenService } from './modules/shared/services/auth/auth-token.service';
import { AuthService } from './modules/auth/services/auth/auth.service';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { ErrorHandlerInterceptor } from './modules/shared/interceptors/error-handler/error-handler.interceptor'; import { ErrorHandlerInterceptor } from './modules/shared/interceptors/error-handler/error-handler.interceptor';
import { NotificationService } from './modules/shared/notification/notification.service'; import { NotificationService } from './modules/shared/notification/notification.service';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import { SharedModule } from './modules/shared/shared.module';
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader { export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
return new TranslateHttpLoader(http, '/assets/lang/', '.json'); return new TranslateHttpLoader(http, '/assets/lang/', '.json');
@ -33,6 +33,7 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
AppRoutingModule, AppRoutingModule,
BrowserAnimationsModule, BrowserAnimationsModule,
MaterialModule, MaterialModule,
SharedModule,
FormsModule, FormsModule,
ReactiveFormsModule, ReactiveFormsModule,
HttpClientModule, HttpClientModule,
@ -50,7 +51,6 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
ThemeService, ThemeService,
BrowserStorageService, BrowserStorageService,
AuthTokenService, AuthTokenService,
AuthService,
NotificationService, NotificationService,
MatSnackBar, MatSnackBar,
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },

View File

@ -33,8 +33,5 @@ import { HttpClient } from '@angular/common/http';
} }
}), }),
], ],
providers: [
AuthService,
],
}) })
export class AuthModule { } export class AuthModule { }

View File

@ -1,5 +1,5 @@
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { EventEmitter, Injectable, ModuleWithProviders } from '@angular/core';
import { Observable, Subject } from 'rxjs'; import { Observable, Subject } from 'rxjs';
import { LoginModel } from '../../models/login.model'; import { LoginModel } from '../../models/login.model';
import { RegisterModel } from '../../models/register.model'; import { RegisterModel } from '../../models/register.model';
@ -8,19 +8,20 @@ import { UserModel } from '../../models/user.model';
import { AuthTokenService } from '../../../shared/services/auth/auth-token.service'; import { AuthTokenService } from '../../../shared/services/auth/auth-token.service';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
@Injectable() @Injectable({
providedIn: 'root',
})
export class AuthService { export class AuthService {
private static updateAgent: any; private static updateAgent: any;
private user: UserModel | null = null; private user: UserModel | null = null;
public userChange = new Subject<UserModel | null>(); public userChange = new EventEmitter<UserModel | null>();
constructor( constructor(
private http: HttpClient, private http: HttpClient,
private authTokenService: AuthTokenService, private authTokenService: AuthTokenService,
private router: Router, private router: Router,
) { ) {
this.checkUser();
this.userChange.subscribe(user => { this.userChange.subscribe(user => {
this.user = user; this.user = user;
}); });
@ -31,10 +32,9 @@ export class AuthService {
} }
checkUser(): Promise<UserModel> { checkUser(): Promise<UserModel> {
return new Promise<UserModel>((resolve) => { return new Promise<UserModel>((resolve, reject) => {
this.http.post<UserModel>('/api/user-check', {}).subscribe(user => { this.http.post<UserModel>('/api/user-check', {}).subscribe(user => {
console.log({user}); this.userChange.emit(user);
this.userChange.next(user);
if (AuthService.updateAgent) { if (AuthService.updateAgent) {
clearTimeout(AuthService.updateAgent); clearTimeout(AuthService.updateAgent);
} }
@ -42,8 +42,11 @@ export class AuthService {
this.checkUser(); this.checkUser();
}, 2000) as any; }, 2000) as any;
resolve(user); resolve(user);
}, () => { }, err => {
this.logout(); if (err.status === 401) {
this.logout();
}
reject(err);
}); });
}); });
} }
@ -75,7 +78,7 @@ export class AuthService {
clearTimeout(AuthService.updateAgent); clearTimeout(AuthService.updateAgent);
} }
this.authTokenService.removeToken(); this.authTokenService.removeToken();
this.userChange.next(null); this.userChange.emit(null);
this.router.navigate(['/auth']); this.router.navigate(['/auth']);
} }
} }

View File

@ -39,7 +39,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="flex-grow-1 main-background" *ngIf="user !== null"> <div class="flex-grow-1 main-background" *ngIf="user !== null && loaded === true">
<div class="h-100"> <div class="h-100">
<router-outlet (activate)="activated($event)" (deactivate)="deactivated($event)"></router-outlet> <router-outlet (activate)="activated($event)" (deactivate)="deactivated($event)"></router-outlet>
</div> </div>

View File

@ -1,4 +1,4 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser'; import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
import { ActivatedRoute, ActivatedRouteSnapshot, ActivationStart, Data, Router, RoutesRecognized } from '@angular/router'; import { ActivatedRoute, ActivatedRouteSnapshot, ActivationStart, Data, Router, RoutesRecognized } from '@angular/router';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
@ -19,7 +19,7 @@ interface ProfileTab {
templateUrl: './profile-edit.component.html', templateUrl: './profile-edit.component.html',
styleUrls: ['./profile-edit.component.scss'] styleUrls: ['./profile-edit.component.scss']
}) })
export class ProfileEditComponent implements OnInit { export class ProfileEditComponent implements AfterViewInit {
scrollSubscriptions: Subscription[] = []; scrollSubscriptions: Subscription[] = [];
scrolled = 0; scrolled = 0;
@ -29,7 +29,7 @@ export class ProfileEditComponent implements OnInit {
selectedIndex = 0; selectedIndex = 0;
defaultProfileTab = ProfileTabEnum.Basics; defaultProfileTab = ProfileTabEnum.Basics;
loaded = false; loaded = false;
@ViewChild('headerContent') headerContent: ElementRef; @ViewChild('headerContent', {static: false}) headerContent: ElementRef;
tabs: ProfileTab[] = [ tabs: ProfileTab[] = [
{ {
tab: ProfileTabEnum.Basics, tab: ProfileTabEnum.Basics,
@ -76,7 +76,8 @@ export class ProfileEditComponent implements OnInit {
}); });
} }
ngOnInit(): void { ngAfterViewInit(): void {
this.loaded = true;
} }
activated(component): void { activated(component): void {
@ -104,7 +105,6 @@ export class ProfileEditComponent implements OnInit {
if (data?.tab) { if (data?.tab) {
const tab = data.tab as ProfileTabEnum; const tab = data.tab as ProfileTabEnum;
const tabIndex = this.tabs.findIndex(i => i.tab === tab); const tabIndex = this.tabs.findIndex(i => i.tab === tab);
console.log({tab, tabIndex});
if (tabIndex !== -1) { if (tabIndex !== -1) {
this.selectedIndex = tabIndex; this.selectedIndex = tabIndex;
this.currentTabName = this.tabs[tabIndex].label; this.currentTabName = this.tabs[tabIndex].label;
@ -118,7 +118,6 @@ export class ProfileEditComponent implements OnInit {
} }
selectedIndexChange(index: number): void { selectedIndexChange(index: number): void {
console.log({index});
this.selectedIndex = index; this.selectedIndex = index;
this.currentTabName = undefined; this.currentTabName = undefined;
const tab = this.tabs[index]; const tab = this.tabs[index];

View File

@ -3,7 +3,6 @@ import { CommonModule } from '@angular/common';
import { ProfileRoutingModule } from './profile-routing.module'; import { ProfileRoutingModule } from './profile-routing.module';
import { ProfileEditComponent } from './components/profile-edit/profile-edit.component'; import { ProfileEditComponent } from './components/profile-edit/profile-edit.component';
import { MaterialModule } from '../material/material.module'; import { MaterialModule } from '../material/material.module';
import { AuthService } from '../auth/services/auth/auth.service';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { HttpLoaderFactory } from 'src/app/app.module'; import { HttpLoaderFactory } from 'src/app/app.module';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
@ -42,7 +41,6 @@ import { CountryService } from '../shared/services/country/country.service';
}), }),
], ],
providers: [ providers: [
AuthService,
CountryService, CountryService,
], ],
}) })

View File

@ -0,0 +1,5 @@
<div class="loader-container">
<div class="loader-box">
<i class="fa fa-2x fa-spin fa-spinner"></i>
</div>
</div>

View File

@ -0,0 +1,22 @@
.loader-container{
position: absolute;
z-index: 100;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: var(--main-background);
.loader-box{
display: flex;
align-items: center;
justify-content: center;
border-radius: 3px;
width: 100px;
height: 60px;
background: var(--toolbar-background);
color: var(--toolbar-color);
}
}

View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-loader',
templateUrl: './loader.component.html',
styleUrls: ['./loader.component.scss']
})
export class LoaderComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@ -45,7 +45,6 @@ export class ErrorHandlerInterceptor implements HttpInterceptor {
} }
displayNotificationIfValidationError(response): void { displayNotificationIfValidationError(response): void {
console.log({response});
if (response?.error?.data) { if (response?.error?.data) {
this.notificationService.error(response.error.data); this.notificationService.error(response.error.data);
} }

View File

@ -8,7 +8,7 @@ export class BrowserStorageService {
constructor() { constructor() {
this.storage = localStorage; this.storage = localStorage;
this.namespace = 'default'; this.namespace = 'app';
} }
setNamespace(namespace: string): void { setNamespace(namespace: string): void {

View File

@ -1,14 +1,23 @@
import { NgModule } from '@angular/core'; import { NgModule, Type } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NotFoundComponent } from './components/not-found/not-found.component'; import { NotFoundComponent } from './components/not-found/not-found.component';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { HttpLoaderFactory } from 'src/app/app.module'; import { HttpLoaderFactory } from 'src/app/app.module';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { MaterialModule } from '../material/material.module'; import { MaterialModule } from '../material/material.module';
import { LoaderComponent } from './components/loader/loader.component';
const componentList: (any[] | Type<any>)[] = [
LoaderComponent,
];
@NgModule({ @NgModule({
declarations: [ declarations: [
NotFoundComponent NotFoundComponent,
...componentList,
],
exports: [
...componentList,
], ],
imports: [ imports: [
CommonModule, CommonModule,