Simple Managment webapp [LLM]
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
<div class="page-content">
|
||||
<div class="page-header">
|
||||
<h2>Clients</h2>
|
||||
<button nz-button (click)="loadClients()">
|
||||
<span nz-icon nzType="reload"></span>
|
||||
Refresh
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<nz-card>
|
||||
<nz-table
|
||||
#clientTable
|
||||
[nzData]="clients()"
|
||||
[nzLoading]="loading()"
|
||||
[nzShowPagination]="false"
|
||||
nzSize="middle"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th nzWidth="5%"></th>
|
||||
<th nzWidth="20%">Name</th>
|
||||
<th nzWidth="15%">Type</th>
|
||||
<th nzWidth="25%">Agent</th>
|
||||
<th nzWidth="20%">Created</th>
|
||||
<th nzWidth="15%">Client ID</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (client of clients(); track client.client_id) {
|
||||
<tr>
|
||||
<td>
|
||||
<span
|
||||
nz-icon
|
||||
[nzType]="getClientIcon(client.type)"
|
||||
nzTheme="outline"
|
||||
class="client-icon"
|
||||
></span>
|
||||
</td>
|
||||
<td>{{ client.name || '-' }}</td>
|
||||
<td>
|
||||
<nz-tag>{{ getClientTypeLabel(client.type) }}</nz-tag>
|
||||
</td>
|
||||
<td>
|
||||
<div class="agent-info">
|
||||
<span>{{ client.agent_model }}</span>
|
||||
<span class="agent-version">v{{ client.agent_version }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span nz-tooltip [nzTooltipTitle]="client.timestamp_created">
|
||||
{{ client.timestamp_created | relativeTime }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="mono client-id">{{ client.client_id }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
} @empty {
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<nz-empty nzNotFoundContent="No clients registered"></nz-empty>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</nz-table>
|
||||
</nz-card>
|
||||
</div>
|
||||
@@ -0,0 +1,30 @@
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.client-icon {
|
||||
font-size: 18px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.agent-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.agent-version {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.client-id {
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { Component, inject, signal, OnInit } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NzTableModule } from 'ng-zorro-antd/table';
|
||||
import { NzButtonModule } from 'ng-zorro-antd/button';
|
||||
import { NzIconModule } from 'ng-zorro-antd/icon';
|
||||
import { NzTagModule } from 'ng-zorro-antd/tag';
|
||||
import { NzEmptyModule } from 'ng-zorro-antd/empty';
|
||||
import { NzCardModule } from 'ng-zorro-antd/card';
|
||||
import { NzToolTipModule } from 'ng-zorro-antd/tooltip';
|
||||
import { ApiService } from '../../../core/services/api.service';
|
||||
import { AuthService } from '../../../core/services/auth.service';
|
||||
import { Client, ClientType, getClientTypeIcon } from '../../../core/models';
|
||||
import { RelativeTimePipe } from '../../../shared/pipes/relative-time.pipe';
|
||||
|
||||
@Component({
|
||||
selector: 'app-client-list',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
NzTableModule,
|
||||
NzButtonModule,
|
||||
NzIconModule,
|
||||
NzTagModule,
|
||||
NzEmptyModule,
|
||||
NzCardModule,
|
||||
NzToolTipModule,
|
||||
RelativeTimePipe,
|
||||
],
|
||||
templateUrl: './client-list.component.html',
|
||||
styleUrl: './client-list.component.scss'
|
||||
})
|
||||
export class ClientListComponent implements OnInit {
|
||||
private apiService = inject(ApiService);
|
||||
private authService = inject(AuthService);
|
||||
|
||||
clients = signal<Client[]>([]);
|
||||
loading = signal(false);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadClients();
|
||||
}
|
||||
|
||||
loadClients(): void {
|
||||
const userId = this.authService.getUserId();
|
||||
if (!userId) return;
|
||||
|
||||
this.loading.set(true);
|
||||
this.apiService.getClients(userId).subscribe({
|
||||
next: (response) => {
|
||||
this.clients.set(response.clients);
|
||||
this.loading.set(false);
|
||||
},
|
||||
error: () => {
|
||||
this.loading.set(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getClientIcon(type: ClientType): string {
|
||||
return getClientTypeIcon(type);
|
||||
}
|
||||
|
||||
getClientTypeLabel(type: ClientType): string {
|
||||
switch (type) {
|
||||
case 'ANDROID': return 'Android';
|
||||
case 'IOS': return 'iOS';
|
||||
case 'MACOS': return 'macOS';
|
||||
case 'WINDOWS': return 'Windows';
|
||||
case 'LINUX': return 'Linux';
|
||||
default: return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user