Simple Managment webapp [LLM]

This commit is contained in:
2025-12-03 17:20:50 +01:00
parent b521f74951
commit e7f613b5dc
76 changed files with 20009 additions and 1 deletions
@@ -0,0 +1,160 @@
<div class="page-content">
<div class="page-header">
<h2>Subscriptions</h2>
<div class="header-actions">
<button nz-button (click)="loadSubscriptions()">
<span nz-icon nzType="reload"></span>
Refresh
</button>
<button nz-button nzType="primary" (click)="openCreateModal()">
<span nz-icon nzType="plus"></span>
Subscribe
</button>
</div>
</div>
<nz-card>
<nz-tabset (nzSelectedIndexChange)="onTabChange($event)">
<nz-tab nzTitle="All"></nz-tab>
<nz-tab nzTitle="Outgoing"></nz-tab>
<nz-tab nzTitle="Incoming"></nz-tab>
</nz-tabset>
<nz-table
#subscriptionTable
[nzData]="subscriptions()"
[nzLoading]="loading()"
[nzShowPagination]="false"
nzSize="middle"
>
<thead>
<tr>
<th nzWidth="15%">Direction</th>
<th nzWidth="25%">Channel</th>
<th nzWidth="20%">Subscriber / Owner</th>
<th nzWidth="15%">Status</th>
<th nzWidth="15%">Created</th>
<th nzWidth="10%">Actions</th>
</tr>
</thead>
<tbody>
@for (sub of subscriptions(); track sub.subscription_id) {
<tr>
<td>
<nz-tag [nzColor]="isOutgoing(sub) ? 'blue' : 'purple'">
{{ getDirectionLabel(sub) }}
</nz-tag>
</td>
<td>
<span class="mono">{{ sub.channel_internal_name }}</span>
</td>
<td>
@if (isOutgoing(sub)) {
<span class="label">Owner:</span>
<span class="mono">{{ sub.channel_owner_user_id }}</span>
} @else {
<span class="label">Subscriber:</span>
<span class="mono">{{ sub.subscriber_user_id }}</span>
}
</td>
<td>
<nz-tag [nzColor]="getStatusInfo(sub).color">
{{ getStatusInfo(sub).label }}
</nz-tag>
</td>
<td>
<span nz-tooltip [nzTooltipTitle]="sub.timestamp_created">
{{ sub.timestamp_created | relativeTime }}
</span>
</td>
<td>
<div class="action-buttons">
@if (!sub.confirmed && isOwner(sub)) {
<!-- Incoming unconfirmed: can accept or deny -->
<button
nz-button
nzSize="small"
nzType="primary"
nz-tooltip
nzTooltipTitle="Accept"
(click)="acceptSubscription(sub)"
>
<span nz-icon nzType="check"></span>
</button>
<button
nz-button
nzSize="small"
nzDanger
nz-tooltip
nzTooltipTitle="Deny"
nz-popconfirm
nzPopconfirmTitle="Deny this subscription request?"
(nzOnConfirm)="denySubscription(sub)"
>
<span nz-icon nzType="close"></span>
</button>
} @else {
<!-- Confirmed or outgoing: can revoke -->
<button
nz-button
nzSize="small"
nzDanger
nz-tooltip
nzTooltipTitle="Revoke"
nz-popconfirm
nzPopconfirmTitle="Revoke this subscription?"
(nzOnConfirm)="revokeSubscription(sub)"
>
<span nz-icon nzType="delete"></span>
</button>
}
</div>
</td>
</tr>
} @empty {
<tr>
<td colspan="6">
<nz-empty nzNotFoundContent="No subscriptions found"></nz-empty>
</td>
</tr>
}
</tbody>
</nz-table>
</nz-card>
</div>
<!-- Create Subscription Modal -->
<nz-modal
[(nzVisible)]="showCreateModal"
nzTitle="Subscribe to Channel"
(nzOnCancel)="closeCreateModal()"
(nzOnOk)="createSubscription()"
[nzOkLoading]="creating()"
[nzOkDisabled]="!newChannelOwner.trim() || !newChannelName.trim()"
>
<ng-container *nzModalContent>
<p class="modal-hint">Enter the channel owner's User ID and the channel name to subscribe.</p>
<nz-form-item>
<nz-form-label>Channel Owner User ID</nz-form-label>
<nz-form-control>
<input
type="text"
nz-input
placeholder="e.g., USR12345"
[(ngModel)]="newChannelOwner"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item class="mb-0">
<nz-form-label>Channel Name</nz-form-label>
<nz-form-control>
<input
type="text"
nz-input
placeholder="e.g., main"
[(ngModel)]="newChannelName"
/>
</nz-form-control>
</nz-form-item>
</ng-container>
</nz-modal>