up
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Sprint 4601_0001_0001 · Keyboard Shortcuts for Triage UI
|
# Sprint 4601_0001_0001 · Keyboard Shortcuts for Triage UI
|
||||||
|
|
||||||
**Status:** DOING
|
**Status:** DONE
|
||||||
**Priority:** P1 - HIGH
|
**Priority:** P1 - HIGH
|
||||||
**Module:** Web (Angular)
|
**Module:** Web (Angular)
|
||||||
**Working Directory:** `src/Web/StellaOps.Web/src/app/features/triage/`
|
**Working Directory:** `src/Web/StellaOps.Web/src/app/features/triage/`
|
||||||
|
|||||||
@@ -535,25 +535,24 @@
|
|||||||
aria-label="Previous page"
|
aria-label="Previous page"
|
||||||
>
|
>
|
||||||
← Previous
|
← Previous
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Page number buttons (show max 5) -->
|
<!-- Page number buttons (show max 5) -->
|
||||||
@for (page of [].constructor(Math.min(5, totalPages())); track $index; let i = $index) {
|
@for (page of [].constructor(Math.min(5, totalPages())); track $index; let i = $index) {
|
||||||
@let pageNum = currentPage() < 2 ? i : Math.min(currentPage() - 2 + i, totalPages() - 1);
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
class="pagination-btn pagination-btn--number"
|
||||||
class="pagination-btn pagination-btn--number"
|
[class.active]="currentPage() === getPageNumberForIndex(i)"
|
||||||
[class.active]="currentPage() === pageNum"
|
(click)="goToPage(getPageNumberForIndex(i))"
|
||||||
(click)="goToPage(pageNum)"
|
[attr.aria-current]="currentPage() === getPageNumberForIndex(i) ? 'page' : null"
|
||||||
[attr.aria-current]="currentPage() === pageNum ? 'page' : null"
|
aria-label="Page {{ getPageNumberForIndex(i) + 1 }}"
|
||||||
aria-label="Page {{ pageNum + 1 }}"
|
>
|
||||||
>
|
{{ getPageNumberForIndex(i) + 1 }}
|
||||||
{{ pageNum + 1 }}
|
</button>
|
||||||
</button>
|
}
|
||||||
}
|
|
||||||
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
|
||||||
class="pagination-btn"
|
class="pagination-btn"
|
||||||
[disabled]="!hasNextPage()"
|
[disabled]="!hasNextPage()"
|
||||||
(click)="nextPage()"
|
(click)="nextPage()"
|
||||||
|
|||||||
@@ -171,12 +171,21 @@ export class EvidencePanelComponent {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Whether there are more pages
|
// Whether there are more pages
|
||||||
readonly hasNextPage = computed(() => this.currentPage() < this.totalPages() - 1);
|
readonly hasNextPage = computed(() => this.currentPage() < this.totalPages() - 1);
|
||||||
readonly hasPreviousPage = computed(() => this.currentPage() > 0);
|
readonly hasPreviousPage = computed(() => this.currentPage() > 0);
|
||||||
|
|
||||||
// Active filter count for badge
|
getPageNumberForIndex(i: number): number {
|
||||||
readonly activeFilterCount = computed(() => {
|
const totalPages = this.totalPages();
|
||||||
const f = this.filters();
|
if (totalPages <= 0) return 0;
|
||||||
|
|
||||||
|
const current = this.currentPage();
|
||||||
|
const base = current < 2 ? i : current - 2 + i;
|
||||||
|
return Math.min(base, totalPages - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Active filter count for badge
|
||||||
|
readonly activeFilterCount = computed(() => {
|
||||||
|
const f = this.filters();
|
||||||
let count = 0;
|
let count = 0;
|
||||||
if (f.sources.length > 0) count++;
|
if (f.sources.length > 0) count++;
|
||||||
if (f.severityBucket !== 'all') count++;
|
if (f.severityBucket !== 'all') count++;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import {
|
|||||||
type TabId = 'overview' | 'reachability' | 'policy' | 'attestations';
|
type TabId = 'overview' | 'reachability' | 'policy' | 'attestations';
|
||||||
|
|
||||||
const TAB_ORDER: readonly TabId[] = ['overview', 'reachability', 'policy', 'attestations'];
|
const TAB_ORDER: readonly TabId[] = ['overview', 'reachability', 'policy', 'attestations'];
|
||||||
const REACHABILITY_VIEW_ORDER: readonly Array<'path-list' | 'compact-graph' | 'textual-proof'> = [
|
const REACHABILITY_VIEW_ORDER: readonly ('path-list' | 'compact-graph' | 'textual-proof')[] = [
|
||||||
'path-list',
|
'path-list',
|
||||||
'compact-graph',
|
'compact-graph',
|
||||||
'textual-proof',
|
'textual-proof',
|
||||||
|
|||||||
@@ -159,25 +159,28 @@ export class VexDecisionModalComponent {
|
|||||||
});
|
});
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
effect(() => {
|
effect(
|
||||||
const existing = this.existingDecision();
|
() => {
|
||||||
if (existing) {
|
const existing = this.existingDecision();
|
||||||
this.status.set(existing.status);
|
if (existing) {
|
||||||
this.justificationType.set(existing.justificationType);
|
this.status.set(existing.status);
|
||||||
this.justificationText.set(existing.justificationText ?? '');
|
this.justificationType.set(existing.justificationType);
|
||||||
this.environmentsText.set(existing.scope?.environments?.join(', ') ?? '');
|
this.justificationText.set(existing.justificationText ?? '');
|
||||||
this.projectsText.set(existing.scope?.projects?.join(', ') ?? '');
|
this.environmentsText.set(existing.scope?.environments?.join(', ') ?? '');
|
||||||
this.notBefore.set(toLocalDateTimeValue(existing.validFor?.notBefore ?? new Date().toISOString()));
|
this.projectsText.set(existing.scope?.projects?.join(', ') ?? '');
|
||||||
this.notAfter.set(toLocalDateTimeValue(existing.validFor?.notAfter ?? ''));
|
this.notBefore.set(toLocalDateTimeValue(existing.validFor?.notBefore ?? new Date().toISOString()));
|
||||||
this.evidenceRefs.set(existing.evidenceRefs ?? []);
|
this.notAfter.set(toLocalDateTimeValue(existing.validFor?.notAfter ?? ''));
|
||||||
return;
|
this.evidenceRefs.set(existing.evidenceRefs ?? []);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const initialStatus = this.initialStatus();
|
const initialStatus = this.initialStatus();
|
||||||
if (initialStatus) {
|
if (initialStatus) {
|
||||||
this.status.set(initialStatus);
|
this.status.set(initialStatus);
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
{ allowSignalWrites: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user