Compare commits

...

10 Commits

Author SHA1 Message Date
Developer 02
bf2356e10a feat: RefreshService hinzugefügt und in der Navigation integriert
- Implementiert den RefreshService zur Verwaltung und Ausführung von Aktionen.
- Aktualisiert den Konstruktor, um RefreshService zu nutzen.
- Hinzugefügt einen Button zur Ausführung aller Aktionen des RefreshService mit einer Rotationsanimation im Navbar.
2024-07-23 18:03:10 +02:00
Developer 02
95d2832ef8 fix: Fehlerbehebung bei HTTP-Anfragen durch Umleitung statt Login-Öffnen im canActivate 2024-07-23 16:59:48 +02:00
Developer 02
7f04bb16d3 cleanup: Überflüssigen Kommentar entfernt 2024-07-23 16:37:32 +02:00
Developer 02
b35026f186 refactor: api_url in environment.prod.ts in default_api_url umbenannt 2024-07-23 15:11:35 +02:00
Developer 02
cf619fb982 refactor: Verwendung von Umgebungsvariablen für Spaltennamen im Konstruktor 2024-07-23 15:06:37 +02:00
Developer 02
0405c9722b feat: Angular Material-Thema angepasst 2024-07-23 13:20:32 +02:00
Developer 02
b880a3245d refactor: UrlService auf Lazy Loading umgestellt 2024-07-23 13:13:32 +02:00
Developer 02
f502a47090 feat: ConfigService implementiert und Konfiguration mit useFactory geladen 2024-07-23 10:10:59 +02:00
Developer 02
f329340c7f Reapply "refactor: API_URL Token und Injektion entfernt"
This reverts commit a509583210.
2024-07-23 09:46:45 +02:00
Developer 02
a509583210 Revert "refactor: API_URL Token und Injektion entfernt"
This reverts commit 3a3df2e7f1.
2024-07-23 09:30:56 +02:00
17 changed files with 222 additions and 24 deletions

View File

@@ -32,7 +32,8 @@
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.scss"
"src/styles.scss",
"src/dd-mat-theme.scss"
],
"scripts": [
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
@@ -106,7 +107,8 @@
"styles": [
"@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.scss",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/dd-mat-theme.scss"
],
"scripts": [
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"

View File

@@ -1,4 +1,4 @@
import { ApplicationConfig } from '@angular/core';
import { APP_INITIALIZER, ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideClientHydration } from '@angular/platform-browser';
@@ -6,6 +6,7 @@ import { provideAnimationsAsync } from '@angular/platform-browser/animations/asy
import { provideHttpClient, withFetch } from '@angular/common/http';
import { APP_BASE_HREF } from '@angular/common';
import { UrlService } from './services/url.service';
import { API_URL } from './tokens';
export const appConfig: ApplicationConfig = {
providers: [
@@ -17,6 +18,16 @@ export const appConfig: ApplicationConfig = {
provide: APP_BASE_HREF,
useFactory: (urlService: UrlService) => urlService.getBaseHref(),
deps: [UrlService]
},
{
provide: API_URL,
useFactory: (urlService: UrlService) => urlService.getApiUrl(),
deps: [UrlService]
},
{
provide: API_URL,
useFactory: (urlService: UrlService) => urlService.getApiUrl(),
deps: [UrlService]
}
]
};

View File

@@ -23,12 +23,11 @@ export class AuthGuard implements CanActivate {
const isAuthenticated = await this.authService.isAuthenticated();
if (!isAuthenticated) {
this.openLogin();
this.router.navigate(['/']);
}
return isAuthenticated;
} catch (error) {
// Hata durumunda false döndür
return false;
}
}

View File

@@ -6,6 +6,7 @@ import { GroupTableComponent } from '../tables/group-table/group-table.component
import { UserRepService } from '../../services/user-representation.service';
import Swal from 'sweetalert2';
import { MatTabsModule, MatTabGroup } from '@angular/material/tabs';
import { env } from '../../../environments/environment';
@Component({
standalone: true,
@@ -28,9 +29,9 @@ export class UserRepresentationComponent {
initWithoutData = () => { }
constructor(userRepService: UserRepService, @Inject('GROUP_REP_TABLE_COLUMNS') groupRepCols: Array<GuiColumn>, @Inject('GROUP_RIGHT_TABLE_COLUMNS') groupRightColumns: Array<GuiColumn>) {
this.groupRepCols = groupRepCols;
this.groupRightColumns = groupRightColumns;
constructor(userRepService: UserRepService) {
this.groupRepCols = env.columnNames.group.representative;
this.groupRightColumns = env.columnNames.group.right;
this.userRepService = userRepService;
}

View File

@@ -92,4 +92,17 @@ html {
.bd-mode-toggle .dropdown-menu .active .bi {
display: block !important;
}
.mat-icon:hover {
animation: rotate 1s ease forwards;
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@@ -30,6 +30,9 @@
<!-- Right menu -->
<div class="navbar-collapse justify-content-end me-5">
<a class="navbar-brand" [routerLink]="['/']">User Manager Portal</a>
<button class="btn" (click)="refreshService.executeAll()">
<mat-icon>sync</mat-icon>
</button>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse"
aria-label="Toggle navigation" [attr.aria-expanded]="isExpanded" (click)="toggle()">
<span class="navbar-toggler-icon"></span>

View File

@@ -7,10 +7,12 @@ import { LoginComponent } from '../login/login.component';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { ColorModeBttnComponent } from '../components/common/color-mode-bttn/color-mode-bttn.component';
import { MatIconModule } from '@angular/material/icon';
import { RefreshService } from '../services/refresh.service';
@Component({
standalone: true,
imports: [RouterModule, CommonModule, ColorModeBttnComponent],
imports: [RouterModule, CommonModule, ColorModeBttnComponent, MatIconModule],
selector: 'app-nav-menu',
templateUrl: './nav-menu.component.html',
styleUrls: ['./nav-menu.component.css']
@@ -21,7 +23,7 @@ export class NavMenuComponent {
}
isExpanded = false;
constructor(public dialog: MatDialog, private authService: AuthenticationService) {
constructor(public dialog: MatDialog, private authService: AuthenticationService, public refreshService: RefreshService) {
this.authService.isAuthenticated().then().catch()
}

View File

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

View File

@@ -0,0 +1,15 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { firstValueFrom } from 'rxjs/internal/firstValueFrom';
import { env } from '../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class ConfigService {
constructor(private http: HttpClient) { }
async getConfig(): Promise<any> {
return await firstValueFrom(this.http.get(env.config_url));
}
}

View File

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

View File

@@ -0,0 +1,23 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class RefreshService {
constructor() { }
private actions: Array<() => void> = [];
add(action: () => void): void {
this.actions.push(action);
}
removeAll(): void {
this.actions = [];
}
executeAll(): void {
this.actions.forEach(action => action());
}
}

View File

@@ -7,21 +7,30 @@ import { env } from '../../environments/environment';
providedIn: 'root'
})
export class UrlService {
document: Document;
meta: Meta;
constructor() {
this.document = inject(DOCUMENT)
this.meta = inject(Meta)
}
private loaded:boolean = false;
private base_href: any;
private api_url: any;
constructor(@Inject(DOCUMENT) private document: Document, @Inject(Meta) private meta: Meta) {}
private lazyLoad(){
if(this.loaded)
return;
this.base_href = this.document!.querySelector('base')?.getAttribute('href') || '/';
this.api_url = (this.meta!.getTag('name="api-url"')?.content ?? env.default_api_url);
this.loaded = true;
}
getBaseHref(): string {
const baseElement = this.document.querySelector('base');
return baseElement?.getAttribute('href') || '/';
this.lazyLoad()
return this.base_href;
}
getApiUrl(route: string = ""): string {
return env.api_url + route;
this.lazyLoad()
return this.api_url + route;
}
readonly apiRoute = {

View File

@@ -1 +1,3 @@
import { InjectionToken } from '@angular/core';
import { InjectionToken } from '@angular/core';
export const API_URL = new InjectionToken<string>('API_URL');

View File

@@ -0,0 +1,3 @@
{
"apiUrl": "/api"
}

View File

@@ -0,0 +1,81 @@
@use '@angular/material' as mat;
@include mat.core();
$palette: (
50: #e8eaf6,
100: #c5cae9,
200: #9fa8da,
300: #7986cb,
400: #5c6bc0,
500: #3f51b5,
600: #3949ab,
700: #303f9f,
800: #283593,
900: #1a237e,
A100: #8c9eff,
A200: #3143a3,
A400: #213083,
A700: #10173f,
contrast: (
50: rgba(black, 0.87),
100: rgba(black, 0.87),
200: rgba(black, 0.87),
300: white,
400: white,
500: white,
600: white,
700: white,
800: white,
900: white,
A100: black,
A200: black,
A400: black,
A700: black,
)
);
$dark-palette: mat.$amber-palette;
$light-palette: mat.$blue-grey-palette;
$typography: mat.define-typography-config(
$font-family: 'Roboto, sans-serif',
$headline-1: mat.define-typography-level(32px, 48px, 700),
$body-1: mat.define-typography-level(16px, 24px, 400)
);
$dark-primary: mat.define-palette($dark-palette);
$dark-accent: mat.define-palette($dark-palette);
$dark-warn: mat.define-palette($dark-palette);
$dark-theme: mat.define-dark-theme((
color: (
primary: $dark-primary,
accent: $dark-accent,
warn: $dark-warn,
),
typography: $typography,
density: 0,
));
// Define a light theme
$light-primary: mat.define-palette($light-palette);
$light-accent: mat.define-palette($light-palette);
$light-warn: mat.define-palette($light-palette);
$light-theme: mat.define-dark-theme((
color: (
primary: $light-primary,
accent: $light-accent,
warn: $light-warn,
),
typography: $typography,
density: 0,
));
.mat-color-scheme-light{
@include mat.all-component-themes($light-theme);
}
.mat-color-scheme-dark{
@include mat.all-component-themes($dark-theme);
}

View File

@@ -1,6 +1,6 @@
export const env = {
production: false,
api_url: "/api",
default_api_url: "/api",
routes: {
user: "/user",
group: "/group",
@@ -115,5 +115,6 @@ export const env = {
field: (ur: any) => ur.repUser?.username
},
]
}
},
config_url: "/assets/config.json"
};

View File

@@ -1,6 +1,6 @@
export const env = {
production: false,
api_url: "/api",
default_api_url: "/api",
routes: {
user: "/user",
group: "/group",
@@ -115,5 +115,6 @@ export const env = {
field: (ur: any) => ur.repUser?.username
},
]
}
},
config_url: "/assets/config.json"
};