Asymmetrik/ngx-starter

View on GitHub
src/app/core/audit/list-audit-entries/list-audit-entries.component.html

Summary

Maintainability
Test Coverage
<section class="page-header mb-3">
    <div>
        <h1 skipTo>Audit Logs</h1>
        Browse and search audit logs.
    </div>
    <system-alert />
</section>

<section class="page-body anchored-page-body">
    <div class="table-header d-flex align-items-center">
        <div class="table-actions d-flex flex-wrap flex-grow-1">
            <div class="mb-3 ms-auto">
                <button class="btn btn-outline-primary" type="button" (click)="exportCurrentView()">
                    <span class="fa-solid fa-download"></span> Export
                </button>
            </div>
        </div>
    </div>
    <div class="table-content">
        <table class="table table-striped" asyFilter asySort cdk-table [dataSource]="dataSource">
            <ng-container cdkColumnDef="audit.actor">
                <th cdk-header-cell *cdkHeaderCellDef>
                    <asy-header-sort sortId="audit.actor.name">
                        <span class="fa-solid fa-user"></span>
                        Actor
                    </asy-header-sort>
                    <asy-header-filter audit-actor-filter typeahead-filter />
                </th>
                <td class="text-nowrap" cdk-cell *cdkCellDef="let entry">
                    {{ entry.audit.actor?.username }}
                </td>
            </ng-container>
            <ng-container cdkColumnDef="created">
                <th cdk-header-cell *cdkHeaderCellDef>
                    <asy-header-sort>
                        <span class="fa-solid fa-clock"></span>
                        Timestamp
                    </asy-header-sort>
                    <asy-header-filter date-filter />
                </th>
                <td class="text-nowrap" cdk-cell *cdkCellDef="let entry">
                    {{ entry.created | utcDate }}
                </td>
            </ng-container>
            <ng-container cdkColumnDef="audit.action">
                <th cdk-header-cell *cdkHeaderCellDef>
                    <asy-header-sort>
                        <span class="fa-solid fa-mouse-pointer"></span>
                        Action
                    </asy-header-sort>
                    <asy-header-filter audit-distinct-value-filter list-filter showSearch />
                </th>
                <td class="text-nowrap" cdk-cell *cdkCellDef="let entry">
                    {{ entry.audit.action }}
                </td>
            </ng-container>
            <ng-container cdkColumnDef="audit.auditType">
                <th cdk-header-cell *cdkHeaderCellDef>
                    <asy-header-sort>
                        <span class="fa-solid fa-tag"></span>
                        Type
                    </asy-header-sort>
                    <asy-header-filter audit-distinct-value-filter list-filter showSearch />
                </th>
                <td class="text-nowrap" cdk-cell *cdkCellDef="let entry">
                    {{ entry.audit.auditType }}
                </td>
            </ng-container>
            <ng-container cdkColumnDef="audit.object">
                <th cdk-header-cell *cdkHeaderCellDef><asy-header-sort>Object</asy-header-sort></th>
                <td class="hide-overflow" cdk-cell *cdkCellDef="let entry">
                    @if (entry.audit.object?.after) {
                        {{ entry.audit.object.after | json }}
                    } @else {
                        {{ entry.audit.object | json }}
                        <div>
                            <button
                                class="btn btn-link btn-sm ps-0 pe-3"
                                type="button"
                                container="body"
                                ngbTooltip="See details of the update"
                                placement="bottom"
                                (click)="viewMore(entry, 'viewDetails')"
                            >
                                <span class="fa-solid fa-eye"></span>View Details
                            </button>
                        </div>
                    }
                </td>
            </ng-container>
            <ng-container cdkColumnDef="before">
                <th cdk-header-cell *cdkHeaderCellDef>
                    <asy-header-sort>
                        <span class="fa-solid fa-history"></span>
                        Before
                    </asy-header-sort>
                </th>
                <td class="hide-overflow" cdk-cell *cdkCellDef="let entry">
                    @if (entry.audit.object?.before) {
                        {{ entry.audit.object?.before | json }}
                        <div>
                            <button
                                class="btn btn-link btn-sm ps-0"
                                type="button"
                                container="body"
                                ngbTooltip="See details of the update"
                                placement="bottom"
                                (click)="viewMore(entry, 'viewChanges')"
                            >
                                <span class="fa-solid fa-eye"></span><span>View Details</span>
                            </button>
                        </div>
                    }
                </td>
            </ng-container>
            <ng-container cdkColumnDef="message">
                <th cdk-header-cell *cdkHeaderCellDef>
                    <asy-header-sort>
                        <span class="fa-solid fa-file-text"></span>
                        Message
                    </asy-header-sort>
                </th>
                <td class="text-nowrap" cdk-cell *cdkCellDef="let entry">
                    {{ entry?.message }}
                </td>
            </ng-container>
            <ng-container cdkColumnDef="audit.masqueradingUser">
                <th cdk-header-cell *cdkHeaderCellDef>
                    <span class="fa-solid fa-user-secret"></span>
                    Masquerading User
                </th>
                <td class="text-nowrap" cdk-cell *cdkCellDef="let entry">
                    {{ entry?.audit.masqueradingUser }}
                </td>
            </ng-container>
            <tr cdk-header-row *cdkHeaderRowDef="displayedColumns(); sticky: true"></tr>
            <tr cdk-row *cdkRowDef="let item; columns: displayedColumns()"></tr>
        </table>

        <asy-table-empty-state
            emptyText="No audit logs are available."
            filteredText="No audit logs matched your search."
            [dataSource]="dataSource"
            (clearFilters)="clearFilters()"
        />
    </div>

    <div class="table-footer d-flex align-items-center">
        <div class="table-footer-pager ms-auto">
            <asy-paginator [dataSource]="dataSource" />
        </div>
    </div>
</section>