-
+
diff --git a/apps/web/src/app/dirt/reports/reports-layout.component.ts b/apps/web/src/app/dirt/reports/reports-layout.component.ts
index a6d84ccb037..136b70c81e4 100644
--- a/apps/web/src/app/dirt/reports/reports-layout.component.ts
+++ b/apps/web/src/app/dirt/reports/reports-layout.component.ts
@@ -1,4 +1,14 @@
-import { Component } from "@angular/core";
+import { Overlay, OverlayRef } from "@angular/cdk/overlay";
+import { TemplatePortal } from "@angular/cdk/portal";
+import {
+ AfterViewInit,
+ Component,
+ inject,
+ OnDestroy,
+ TemplateRef,
+ viewChild,
+ ViewContainerRef,
+} from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { NavigationEnd, Router } from "@angular/router";
import { filter } from "rxjs/operators";
@@ -10,20 +20,65 @@ import { filter } from "rxjs/operators";
templateUrl: "reports-layout.component.html",
standalone: false,
})
-export class ReportsLayoutComponent {
+export class ReportsLayoutComponent implements AfterViewInit, OnDestroy {
homepage = true;
- constructor(router: Router) {
- const reportsHomeRoute = "/reports";
+ private readonly backButtonTemplate =
+ viewChild.required
>("backButtonTemplate");
- this.homepage = router.url === reportsHomeRoute;
- router.events
+ private overlayRef: OverlayRef | null = null;
+ private overlay = inject(Overlay);
+ private viewContainerRef = inject(ViewContainerRef);
+ private router = inject(Router);
+
+ constructor() {
+ this.router.events
.pipe(
takeUntilDestroyed(),
filter((event) => event instanceof NavigationEnd),
)
- .subscribe((event) => {
- this.homepage = (event as NavigationEnd).url == reportsHomeRoute;
+ .subscribe(() => this.updateOverlay());
+ }
+
+ ngAfterViewInit(): void {
+ this.updateOverlay();
+ }
+
+ ngOnDestroy(): void {
+ this.overlayRef?.dispose();
+ }
+
+ returnFocusToPage(event: Event): void {
+ if ((event as KeyboardEvent).shiftKey) {
+ return; // Allow natural Shift+Tab behavior
+ }
+ event.preventDefault();
+ const firstFocusable = document.querySelector(
+ "[cdktrapfocus] a:not([tabindex='-1'])",
+ ) as HTMLElement;
+ firstFocusable?.focus();
+ }
+
+ focusOverlayButton(event: Event): void {
+ if ((event as KeyboardEvent).shiftKey) {
+ return; // Allow natural Shift+Tab behavior
+ }
+ event.preventDefault();
+ const button = this.overlayRef?.overlayElement?.querySelector("a") as HTMLElement;
+ button?.focus();
+ }
+
+ private updateOverlay(): void {
+ if (this.router.url === "/reports") {
+ this.homepage = true;
+ this.overlayRef?.dispose();
+ this.overlayRef = null;
+ } else if (!this.overlayRef) {
+ this.homepage = false;
+ this.overlayRef = this.overlay.create({
+ positionStrategy: this.overlay.position().global().bottom("20px").right("32px"),
});
+ this.overlayRef.attach(new TemplatePortal(this.backButtonTemplate(), this.viewContainerRef));
+ }
}
}
diff --git a/apps/web/src/app/dirt/reports/reports.module.ts b/apps/web/src/app/dirt/reports/reports.module.ts
index 4fc152917f4..c4bd9fef809 100644
--- a/apps/web/src/app/dirt/reports/reports.module.ts
+++ b/apps/web/src/app/dirt/reports/reports.module.ts
@@ -1,3 +1,4 @@
+import { OverlayModule } from "@angular/cdk/overlay";
import { CommonModule } from "@angular/common";
import { NgModule } from "@angular/core";
@@ -29,6 +30,7 @@ import { ReportsSharedModule } from "./shared";
@NgModule({
imports: [
CommonModule,
+ OverlayModule,
SharedModule,
ReportsSharedModule,
ReportsRoutingModule,