All checks were successful
Dev Build / build-test (pull_request) Successful in 1m57s
109 lines
3.3 KiB
HTML
109 lines
3.3 KiB
HTML
<!-- ============================================================================
|
|
Quick-Jump Drawer — Slide-out panel for fast agent switching
|
|
Per CUB-51: Slides from right, agent list with status badges,
|
|
search/filter input, closes via ESC or outside click.
|
|
============================================================================-->
|
|
|
|
<!-- Backdrop overlay -->
|
|
@if (isOpen()) {
|
|
<div
|
|
class="quick-jump-backdrop"
|
|
(click)="onBackdropClick($event)"
|
|
[@backdropEnter]
|
|
></div>
|
|
}
|
|
|
|
<!-- Drawer panel -->
|
|
<div
|
|
class="quick-jump-drawer"
|
|
[class.quick-jump-drawer--open]="isOpen()"
|
|
(keydown)="onDrawerKeydown($event)"
|
|
role="dialog"
|
|
aria-label="Quick jump to agent"
|
|
[attr.aria-hidden]="!isOpen()"
|
|
>
|
|
<!-- Drawer header -->
|
|
<div class="quick-jump-drawer__header">
|
|
<h2 class="quick-jump-drawer__title">Jump to Agent</h2>
|
|
<button
|
|
class="quick-jump-drawer__close-btn"
|
|
type="button"
|
|
aria-label="Close drawer"
|
|
(click)="close()"
|
|
>
|
|
✕
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Search input -->
|
|
<div class="quick-jump-drawer__search">
|
|
<span class="quick-jump-drawer__search-icon">search</span>
|
|
<input
|
|
#searchInput
|
|
type="text"
|
|
class="quick-jump-drawer__search-input"
|
|
placeholder="Search agents..."
|
|
[formControl]="searchControl"
|
|
autocomplete="off"
|
|
aria-label="Search agents"
|
|
/>
|
|
@if (searchControl.value) {
|
|
<button
|
|
class="quick-jump-drawer__search-clear"
|
|
type="button"
|
|
aria-label="Clear search"
|
|
(click)="searchControl.setValue('')"
|
|
>
|
|
✕
|
|
</button>
|
|
}
|
|
</div>
|
|
|
|
<!-- Agent list -->
|
|
<ul class="quick-jump-drawer__agent-list" role="listbox" aria-label="Agent list">
|
|
@for (agent of filteredAgents(); track agent.id; let i = $index) {
|
|
<li
|
|
[id]="'quick-jump-agent-' + i"
|
|
class="quick-jump-drawer__agent-item"
|
|
[class.quick-jump-drawer__agent-item--highlighted]="highlightedIndex() === i"
|
|
role="option"
|
|
[attr.aria-selected]="highlightedIndex() === i"
|
|
(click)="selectAgent(agent)"
|
|
(mouseenter)="highlightedIndex.set(i)"
|
|
(mouseleave)="highlightedIndex.set(-1)"
|
|
>
|
|
<!-- Status badge -->
|
|
<span
|
|
class="status-dot {{ getStatusClass(agent.status) }}"
|
|
[attr.aria-label]="getStatusLabel(agent.status)"
|
|
></span>
|
|
|
|
<!-- Agent info -->
|
|
<div class="quick-jump-drawer__agent-info">
|
|
<span class="quick-jump-drawer__agent-name">{{ agent.displayName }}</span>
|
|
<span class="quick-jump-drawer__agent-role">{{ agent.role }}</span>
|
|
</div>
|
|
|
|
<!-- Status label -->
|
|
<span class="quick-jump-drawer__agent-status-label" [class]="'status-label--' + agent.status">
|
|
{{ getStatusLabel(agent.status) }}
|
|
</span>
|
|
</li>
|
|
} @empty {
|
|
<li class="quick-jump-drawer__empty">
|
|
@if (searchControl.value) {
|
|
<span>No agents matching "{{ searchControl.value }}"</span>
|
|
} @else {
|
|
<span>No agents online</span>
|
|
}
|
|
</li>
|
|
}
|
|
</ul>
|
|
|
|
<!-- Footer hint -->
|
|
<div class="quick-jump-drawer__footer">
|
|
<span class="quick-jump-drawer__footer-hint">
|
|
<kbd>↑↓</kbd> Navigate <kbd>↵</kbd> Select <kbd>Esc</kbd> Close
|
|
</span>
|
|
</div>
|
|
</div> |