src/app/core/admin/feedback/list-feedback/admin-list-feedback.component.html
<section class="page-header mb-3">
<div>
<h1 skipTo>System Feedback</h1>
View and manage system feedback.
</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 me-5">
<asy-search-input
placeholder="Search..."
[search]="dataSource.searchEvent$.value"
(applySearch)="dataSource.search($event)"
/>
</div>
<div class="mb-3 ms-auto">
<button
class="btn btn-outline-primary ms-auto"
type="button"
(click)="exportCurrentView()"
>
<span class="fa-solid fa-download"></span> Export
</button>
<button
class="btn btn-outline-primary font-weight-bold ms-3"
type="button"
ngbTooltip="Set Columns"
(click)="sidebar.toggle()"
>
<span class="fa-solid fa-columns"></span>
</button>
</div>
</div>
</div>
<div class="d-flex overflow-hidden">
<div class="table-content">
<table
class="table table-striped"
asyFilter
asySort
cdk-table
[dataSource]="dataSource"
>
<ng-container cdkColumnDef="creator.name">
<th cdk-header-cell *cdkHeaderCellDef>Submitted By</th>
<td class="hide-overflow" cdk-cell *cdkCellDef="let feedback">
{{ feedback.creator.name }}
</td>
</ng-container>
<ng-container cdkColumnDef="creator.username">
<th cdk-header-cell *cdkHeaderCellDef>Username</th>
<td class="hide-overflow" cdk-cell *cdkCellDef="let feedback">
{{ feedback.creator.username }}
</td>
</ng-container>
<ng-container cdkColumnDef="creator.email">
<th cdk-header-cell *cdkHeaderCellDef>Email</th>
<td class="hide-overflow" cdk-cell *cdkCellDef="let feedback">
{{ feedback.creator.email }}
</td>
</ng-container>
<ng-container cdkColumnDef="creator.organization">
<th cdk-header-cell *cdkHeaderCellDef>Organization</th>
<td class="hide-overflow" cdk-cell *cdkCellDef="let feedback">
{{ feedback.creator.organization }}
</td>
</ng-container>
<asy-ago-date-column name="created" header="Submitted Date" sortable />
<asy-ago-date-column name="updated" sortable />
<ng-container cdkColumnDef="type">
<th cdk-header-cell *cdkHeaderCellDef>
<asy-header-sort>Type</asy-header-sort>
</th>
<td class="text-nowrap" cdk-cell *cdkCellDef="let feedback">
{{ feedback.type | titlecase }}
</td>
</ng-container>
<ng-container cdkColumnDef="body">
<th cdk-header-cell *cdkHeaderCellDef>
Feedback
<asy-header-filter text-filter />
</th>
<td cdk-cell *cdkCellDef="let feedback">
{{ feedback.body }}
</td>
</ng-container>
<asy-text-column name="browser" sortable />
<asy-text-column name="os" sortable />
<asy-text-column name="url" header="Submitted From" sortable />
<ng-container cdkColumnDef="status">
<th cdk-header-cell *cdkHeaderCellDef>
<asy-header-sort> Status </asy-header-sort>
<asy-header-filter list-filter [options]="['New', 'Open', 'Closed']" />
</th>
<td cdk-cell *cdkCellDef="let feedback">
<button
class="btn btn-text dropdown-toggle p-0"
id="feedback-{{ feedback._id }}-status-menu-btn"
type="button"
attr.aria-controls="feedback-{{ feedback._id }}-status-menu"
[cdkMenuTriggerFor]="statusMenu"
>
{{ feedback.status }}
</button>
<ng-template #statusMenu>
<div
class="dropdown-menu"
id="feedback-{{ feedback._id }}-status-menu"
attr.aria-labelledby="feedback-{{ feedback._id }}-status-menu-btn"
cdkMenu
>
@if (feedback.status !== feedbackStatusOptions.OPEN) {
<button
class="dropdown-item"
type="button"
cdkMenuItem
(cdkMenuItemTriggered)="
updateFeedbackStatus(
feedback,
feedbackStatusOptions.OPEN
)
"
>
Open
</button>
}
@if (feedback.status !== feedbackStatusOptions.CLOSED) {
<button
class="dropdown-item"
type="button"
cdkMenuItem
(cdkMenuItemTriggered)="
updateFeedbackStatus(
feedback,
feedbackStatusOptions.CLOSED
)
"
>
Close
</button>
}
</div>
</ng-template>
</td>
</ng-container>
<ng-container cdkColumnDef="assignee">
<th cdk-header-cell *cdkHeaderCellDef>
<asy-header-sort>Assignee</asy-header-sort>
</th>
<td cdk-cell *cdkCellDef="let feedback">
<button
class="btn btn-text dropdown-toggle p-0"
id="feedback-{{ feedback._id }}-assignee-menu-btn"
type="button"
attr.aria-controls="feedback-{{ feedback._id }}-assignee-menu"
[cdkMenuTriggerFor]="assigneeMenu"
>
{{ feedback.assignee ?? 'None' }}
</button>
<ng-template #assigneeMenu>
<div
class="dropdown-menu"
id="feedback-{{ feedback._id }}-assignee-menu"
attr.aria-labelledby="feedback-{{ feedback._id }}-assignee-menu-btn"
cdkMenu
>
<button
class="dropdown-item"
type="button"
cdkMenuItem
(cdkMenuItemTriggered)="updateFeedbackAssignee(feedback)"
>
None
</button>
@for (username of assigneeUsernames(); track username) {
<button
class="dropdown-item"
type="button"
cdkMenuItem
(cdkMenuItemTriggered)="
updateFeedbackAssignee(feedback, username)
"
>
{{ username }}
</button>
}
</div>
</ng-template>
</td>
</ng-container>
<tr cdk-header-row *cdkHeaderRowDef="displayedColumns(); sticky: true"></tr>
<tr cdk-row *cdkRowDef="let team; columns: displayedColumns()"></tr>
</table>
<asy-table-empty-state
emptyText="No feedback is available."
filteredText="No feedback matched your search."
[dataSource]="dataSource"
(clearFilters)="clearFilters()"
/>
</div>
<asy-sidebar headerText="Columns" #sidebar>
<asy-column-chooser
[columns]="columns"
[storageKey]="dataSource.storageKey"
(columnsChange)="columnsChanged($event)"
/>
</asy-sidebar>
</div>
<div class="table-footer d-flex align-items-center">
<div class="table-footer-pager ms-auto">
<asy-paginator [dataSource]="dataSource" />
</div>
</div>
</section>