Add audit logs.
ci-cd-vm / ci-cd (push) Successful in 4m2s

This commit is contained in:
Chris Chen
2026-06-23 12:13:47 -07:00
parent 870eeec82a
commit 62592c29ae
106 changed files with 2522 additions and 311 deletions
@@ -0,0 +1,75 @@
<div class="page">
<div class="flex flex-wrap gap-3 items-end mb-4">
<label class="flex flex-col gap-1">
Search / 搜尋
<kendo-textbox placeholder="Message / category" [(ngModel)]="search"
(keydown.enter)="applyFilter()"></kendo-textbox>
</label>
<label class="flex flex-col gap-1">
Min Level / 最低等級
<kendo-dropdownlist [data]="levels" textField="label" valueField="value" [valuePrimitive]="true"
[(ngModel)]="minLevel" [defaultItem]="{ value: null, label: 'All Levels/全部等級' }">
</kendo-dropdownlist>
</label>
<label class="flex flex-col gap-1">
From / 起
<kendo-datepicker [(ngModel)]="from"></kendo-datepicker>
</label>
<label class="flex flex-col gap-1">
To / 迄
<kendo-datepicker [(ngModel)]="to"></kendo-datepicker>
</label>
<button kendoButton themeColor="primary" (click)="applyFilter()">Apply / 套用</button>
</div>
<kendo-grid [data]="{ data: rows, total: total }" [loading]="loading" [pageable]="true" [skip]="skip"
[pageSize]="pageSize" (pageChange)="onPageChange($event)">
<kendo-grid-column title="Time / 時間" [width]="170">
<ng-template kendoGridCellTemplate let-dataItem>{{ dataItem.timestamp | date:'short' }}</ng-template>
</kendo-grid-column>
<kendo-grid-column title="Level / 等級" [width]="110">
<ng-template kendoGridCellTemplate let-dataItem>
<span [class]="levelClass(dataItem.level)">{{ dataItem.level }}</span>
</ng-template>
</kendo-grid-column>
<kendo-grid-column field="category" title="Source / 來源" [width]="240"></kendo-grid-column>
<kendo-grid-column title="Message / 訊息">
<ng-template kendoGridCellTemplate let-dataItem>
<span class="msg">{{ dataItem.message }}</span>
<span *ngIf="dataItem.hasException" class="exc-flag" title="Has exception"></span>
</ng-template>
</kendo-grid-column>
<kendo-grid-column field="statusCode" title="Status" [width]="90"></kendo-grid-column>
<kendo-grid-column title="" [width]="90">
<ng-template kendoGridCellTemplate let-dataItem>
<button kendoButton fillMode="flat" themeColor="primary" (click)="view(dataItem)">View</button>
</ng-template>
</kendo-grid-column>
</kendo-grid>
<!-- Detail dialog -->
<kendo-dialog *ngIf="detail" title="System Log #{{ detail.id }}" [width]="720" (close)="detail = null">
<div class="p-2 flex flex-col gap-2 text-sm">
<div class="grid grid-cols-2 gap-2">
<div><strong>Time:</strong> {{ detail.timestamp | date:'medium' }}</div>
<div><strong>Level:</strong> <span [class]="levelClass(detail.level)">{{ detail.level }}</span></div>
<div class="col-span-2"><strong>Source:</strong> {{ detail.category }}</div>
<div *ngIf="detail.httpMethod"><strong>Request:</strong> {{ detail.httpMethod }} {{ detail.requestPath }}</div>
<div *ngIf="detail.statusCode"><strong>Status:</strong> {{ detail.statusCode }}</div>
<div *ngIf="detail.userId"><strong>User:</strong> {{ detail.userId }}</div>
<div *ngIf="detail.ipAddress"><strong>IP:</strong> {{ detail.ipAddress }}</div>
<div class="col-span-2" *ngIf="detail.correlationId"><strong>Correlation:</strong> {{ detail.correlationId }}</div>
</div>
<div><strong>Message</strong></div>
<pre class="detail-block">{{ detail.message }}</pre>
<ng-container *ngIf="detail.exception">
<div><strong>Exception / Stack Trace</strong></div>
<pre class="detail-block detail-block--exc">{{ detail.exception }}</pre>
</ng-container>
</div>
<kendo-dialog-actions>
<button kendoButton (click)="detail = null">Close / 關閉</button>
</kendo-dialog-actions>
</kendo-dialog>
</div>