add admin interface, angular migration

This commit is contained in:
_Bastler
2025-11-09 01:58:54 +01:00
parent ff94ca05ce
commit 1acaf07825
100 changed files with 7129 additions and 50 deletions
@@ -0,0 +1,49 @@
<h2 mat-dialog-title>{{ (isEditMode ? 'admin.user_aliases.edit' : 'admin.user_aliases.create') | i18n }}</h2>
<mat-dialog-content>
<form [formGroup]="form">
<mat-form-field appearance="outline">
<mat-label>{{ 'admin.user_aliases.target' | i18n }}</mat-label>
<input matInput type="number" formControlName="target" [placeholder]="'admin.user_aliases.target' | i18n" required>
@if (form.get('target')?.hasError('required')) {
<mat-error>
{{ 'admin.user_aliases.target_required' | i18n }}
</mat-error>
}
<mat-hint>{{ 'admin.user_aliases.target_hint' | i18n }}</mat-hint>
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>{{ 'admin.user_aliases.alias' | i18n }}</mat-label>
<input matInput formControlName="alias" [placeholder]="'admin.user_aliases.alias' | i18n" required>
@if (form.get('alias')?.hasError('required')) {
<mat-error>
{{ 'admin.user_aliases.alias_required' | i18n }}
</mat-error>
}
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>{{ 'admin.user_aliases.visibility' | i18n }}</mat-label>
<mat-select formControlName="visibility" required>
@for (visibility of visibilityOptions; track visibility) {
<mat-option [value]="visibility">
{{ visibility }}
</mat-option>
}
</mat-select>
@if (form.get('visibility')?.hasError('required')) {
<mat-error>
{{ 'admin.user_aliases.visibility_required' | i18n }}
</mat-error>
}
</mat-form-field>
</form>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button (click)="onCancel()">{{ 'admin.cancel' | i18n }}</button>
<button mat-raised-button color="primary" (click)="onSubmit()" [disabled]="!form.valid">
{{ (isEditMode ? 'admin.save' : 'admin.create') | i18n }}
</button>
</mat-dialog-actions>
@@ -0,0 +1,53 @@
import { Component, Inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { UserAliasManagementService } from '../../../services/admin/useralias.management.service';
@Component({
standalone: false,
selector: 'admin-user-alias-edit-dialog',
templateUrl: './user-alias.edit.html',
styleUrls: ['../admin.scss']
})
export class AdminUserAliasEditDialog implements OnInit {
form: FormGroup;
isEditMode: boolean = false;
visibilityOptions = ['PRIVATE', 'PROTECTED', 'PUBLIC'];
constructor(
private fb: FormBuilder,
private userAliasManagementService: UserAliasManagementService,
public dialogRef: MatDialogRef<AdminUserAliasEditDialog>,
@Inject(MAT_DIALOG_DATA) public data: any
) {
this.isEditMode = !!data?.userAlias;
this.form = this.fb.group({
id: [data?.userAlias?.id || null],
target: [data?.userAlias?.target || null, Validators.required],
alias: [data?.userAlias?.alias || '', Validators.required],
visibility: [data?.userAlias?.visibility || 'PROTECTED', Validators.required]
});
}
ngOnInit(): void {}
onSubmit(): void {
if (this.form.valid) {
const userAlias = this.form.value;
this.userAliasManagementService.createOrUpdateAlias(userAlias).subscribe({
next: (result) => {
this.dialogRef.close(result);
},
error: (error) => {
console.error('Error saving user alias:', error);
}
});
}
}
onCancel(): void {
this.dialogRef.close();
}
}
@@ -0,0 +1,55 @@
<header>
<h3>{{'admin.user_aliases' | i18n}}</h3>
<span class="spacer"></span>
<button mat-raised-button color="primary" (click)="createAlias()">
<mat-icon>add</mat-icon>
{{'admin.user_aliases.create' | i18n}}
</button>
</header>
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource" matSort (matSortChange)="onSortChange($event)">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{'admin.user_aliases.id' | i18n}}</th>
<td mat-cell *matCellDef="let alias">{{alias.id}}</td>
</ng-container>
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{'admin.user_aliases.alias' | i18n}}</th>
<td mat-cell *matCellDef="let alias">{{alias.alias}}</td>
</ng-container>
<ng-container matColumnDef="target">
<th mat-header-cell *matHeaderCellDef>{{'admin.user_aliases.target' | i18n}}</th>
<td mat-cell *matCellDef="let alias">{{alias.target}}</td>
</ng-container>
<ng-container matColumnDef="visibility">
<th mat-header-cell *matHeaderCellDef>{{'admin.user_aliases.visibility' | i18n}}</th>
<td mat-cell *matCellDef="let alias">{{alias.visibility}}</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>{{'admin.actions' | i18n}}</th>
<td mat-cell *matCellDef="let alias">
<button mat-icon-button (click)="editAlias(alias)" [title]="'admin.user_aliases.edit' | i18n">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button (click)="deleteAlias(alias)" [title]="'admin.user_aliases.delete' | i18n">
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator
[length]="totalElements"
[pageSize]="pageSize"
[pageSizeOptions]="[5, 10, 25, 50, 100]"
(page)="onPageChange($event)"
showFirstLastButtons>
</mat-paginator>
</div>
@@ -0,0 +1,109 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { MatDialog } from '@angular/material/dialog';
import { I18nService } from 'src/app/services/i18n.service';
import { UserAliasManagementService } from 'src/app/services/admin/useralias.management.service';
import { ConfirmDialog } from 'src/app/ui/confirm/confirm.component';
import { AdminUserAliasEditDialog } from './user-alias.edit';
@Component({
standalone: false,
selector: 'app-admin-user-aliases',
templateUrl: './user-aliases.component.html',
styleUrls: ['../admin.scss']
})
export class AdminUserAliasesComponent implements OnInit {
displayedColumns: string[] = ['id', 'alias', 'target', 'visibility', 'actions'];
dataSource: MatTableDataSource<any>;
totalElements = 0;
pageSize = 10;
pageIndex = 0;
@ViewChild(MatPaginator) paginator!: MatPaginator;
@ViewChild(MatSort) sort!: MatSort;
constructor(
private userAliasManagementService: UserAliasManagementService,
private i18n: I18nService,
private dialog: MatDialog
) {
this.dataSource = new MatTableDataSource();
}
ngOnInit(): void {
this.loadAliases();
}
loadAliases(): void {
this.userAliasManagementService.getAliases(this.pageIndex, this.pageSize).subscribe(
(data: any) => {
this.dataSource.data = data.content || data;
this.totalElements = data.totalElements || data.length;
},
error => {
console.error('Error loading user aliases:', error);
}
);
}
onPageChange(event: PageEvent): void {
this.pageIndex = event.pageIndex;
this.pageSize = event.pageSize;
this.loadAliases();
}
onSortChange(sort: any): void {
// Sorting can be implemented when backend supports it
console.log('Sort change:', sort);
}
deleteAlias(alias: any): void {
const dialogRef = this.dialog.open(ConfirmDialog, {
data: {
'label': 'admin.user_aliases.confirm_delete',
'args': [alias.source]
}
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.userAliasManagementService.deleteAlias(alias.id).subscribe(
() => {
this.loadAliases();
},
error => {
console.error('Error deleting alias:', error);
}
);
}
});
}
createAlias(): void {
const dialogRef = this.dialog.open(AdminUserAliasEditDialog, {
width: '600px',
data: {}
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.loadAliases();
}
});
}
editAlias(alias: any): void {
const dialogRef = this.dialog.open(AdminUserAliasEditDialog, {
width: '600px',
data: { userAlias: alias }
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.loadAliases();
}
});
}
}