From 1b66c45ddcc81f15b6794f1f43e2ee6c0c8a50ed Mon Sep 17 00:00:00 2001 From: nikitita Date: Tue, 20 Oct 2026 10:26:05 +0200 Subject: [PATCH] feat: add dynamic back navigation across detail pages --- frontend/src/components/Example.tsx | 1 - .../src/components/navigation/BackButton.css | 27 ++++++++++++ .../src/components/navigation/BackButton.tsx | 43 ++++++++++++++++++ .../TacticDetailedHeader.tsx | 9 +--- .../TechniqueDetailedHeader.tsx | 11 ++--- .../ThreatActorAssociatedList.css | 15 +++++++ .../ThreatActorAssociatedList.tsx | 44 +++++++++++-------- .../ThreatActorDetailedHeader.tsx | 5 +-- .../src/pages/Software/SoftwareDetail.tsx | 5 +-- 9 files changed, 119 insertions(+), 41 deletions(-) delete mode 100644 frontend/src/components/Example.tsx create mode 100644 frontend/src/components/navigation/BackButton.css create mode 100644 frontend/src/components/navigation/BackButton.tsx diff --git a/frontend/src/components/Example.tsx b/frontend/src/components/Example.tsx deleted file mode 100644 index 5943cdc..0000000 --- a/frontend/src/components/Example.tsx +++ /dev/null @@ -1 +0,0 @@ -// Just a file to make the folder appear in git. \ No newline at end of file diff --git a/frontend/src/components/navigation/BackButton.css b/frontend/src/components/navigation/BackButton.css new file mode 100644 index 0000000..1d8a4c4 --- /dev/null +++ b/frontend/src/components/navigation/BackButton.css @@ -0,0 +1,27 @@ + +.back-navigation { + display: inline-flex; + align-items: center; + gap: 6px; + width: fit-content; + + padding: 0; + border: none; + background: none; + + color: var(--accent); + font: inherit; + font-size: 14px; + font-weight: 600; + + cursor: pointer; +} + +.back-navigation:hover { + text-decoration: underline; +} + +.back-navigation:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 4px; +} diff --git a/frontend/src/components/navigation/BackButton.tsx b/frontend/src/components/navigation/BackButton.tsx new file mode 100644 index 0000000..bd93832 --- /dev/null +++ b/frontend/src/components/navigation/BackButton.tsx @@ -0,0 +1,43 @@ + +import { ArrowLeft } from "lucide-react"; +import { useNavigate } from "react-router-dom"; +import "./BackButton.css"; + +type BackButtonProps = { + fallbackTo: string; +}; + +/** + * Gjenbrukbar tilbakeknapp for detaljsider. + * Navigerer til forrige side, eller til fallbackTo dersom + * det ikke finnes en tidligere side i React Routers historikk. + * + * @param fallbackTo - Standardsiden brukeren sendes til. + */ +function BackButton({ fallbackTo }: BackButtonProps) { + /** Innebygd React-Hook som lar oss navigere mellom sider + * Den "husker" den browse-historikken og dermed + * kan man bruke navigate(-1) for å gå tilbake. + */ + const navigate = useNavigate(); + + /** Håndterer trykking av tilbake knappen */ + const handleBack = () => { + /** Hvis de er noe å gå tilbake til */ + if (window.history.state?.idx > 0) { + /** Gå tilbkae */ + navigate(-1); + return; + } + /** Hvis de er ikk noe å gå tilbake til: gå til startpage */ + navigate(fallbackTo, { replace: true }); + }; + + return ( + + ); +} + +export default BackButton; diff --git a/frontend/src/components/tactic/TacticDetailed/TacticDetailedHeader/TacticDetailedHeader.tsx b/frontend/src/components/tactic/TacticDetailed/TacticDetailedHeader/TacticDetailedHeader.tsx index 8092e42..3f0335d 100644 --- a/frontend/src/components/tactic/TacticDetailed/TacticDetailedHeader/TacticDetailedHeader.tsx +++ b/frontend/src/components/tactic/TacticDetailed/TacticDetailedHeader/TacticDetailedHeader.tsx @@ -2,6 +2,7 @@ import { ArrowLeft, Star } from "lucide-react"; import { Link } from "react-router-dom"; import "./TacticDetailedHeader.css"; +import BackButton from "../../../navigation/BackButton"; type TacticDetailedHeaderProps = { mitreId: string; @@ -14,13 +15,7 @@ function TacticDetailedHeader({ }: TacticDetailedHeaderProps) { return (
- - - Back to Tactics - + TACTIC diff --git a/frontend/src/components/techniques/specificTechnique/TechniqueDetailedHeader/TechniqueDetailedHeader.tsx b/frontend/src/components/techniques/specificTechnique/TechniqueDetailedHeader/TechniqueDetailedHeader.tsx index ee24631..65fbb41 100644 --- a/frontend/src/components/techniques/specificTechnique/TechniqueDetailedHeader/TechniqueDetailedHeader.tsx +++ b/frontend/src/components/techniques/specificTechnique/TechniqueDetailedHeader/TechniqueDetailedHeader.tsx @@ -2,6 +2,7 @@ import { ArrowLeft, Star } from "lucide-react"; import { Link } from "react-router-dom"; import "./TechniqueDetailedHeader.css"; +import BackButton from "../../../navigation/BackButton"; type TechniqueDetailedHeaderProps = { mitreId: string; @@ -18,14 +19,8 @@ function TechniqueDetailedHeader({ }: TechniqueDetailedHeaderProps) { return (
- - - Back to Techniques - - + + TECHNIQUE diff --git a/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorAssociated/ThreatActorAssociatedList.css b/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorAssociated/ThreatActorAssociatedList.css index 13a42e7..97941b5 100644 --- a/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorAssociated/ThreatActorAssociatedList.css +++ b/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorAssociated/ThreatActorAssociatedList.css @@ -275,3 +275,18 @@ gap: 12px; } } +.associated-row, +.associated-row:visited { + text-decoration: none; + color: inherit; +} + +.associated-row:hover { + border-color: var(--accent); + cursor: pointer; +} + +.associated-row:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; +} \ No newline at end of file diff --git a/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorAssociated/ThreatActorAssociatedList.tsx b/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorAssociated/ThreatActorAssociatedList.tsx index b8e97c5..635edff 100644 --- a/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorAssociated/ThreatActorAssociatedList.tsx +++ b/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorAssociated/ThreatActorAssociatedList.tsx @@ -6,7 +6,11 @@ import { } from "lucide-react"; import type { AssociatedItem } from "../../../../types/ThreatActorTypes"; import "./ThreatActorAssociatedList.css"; +<<<<<<< HEAD import FeedbackCard from "../../../feedback/FeedbackCard"; +======= +import { Link } from "react-router-dom"; +>>>>>>> e54f807 (feat: add dynamic back navigation across detail pages) type ThreatActorAssociatedListProps = { type: "techniques" | "software"; @@ -44,28 +48,30 @@ function ThreatActorAssociatedList({type,items,totalCount,page,pageSize,onPageCh /> )} -
- {items.map((item) => ( -
( + - - {isTechnique ? : } - - - {item.mitreId} + + {isTechnique ? : } + - {item.name} + {item.mitreId} + {item.name} - -
- ))} -
+ + + ))} {totalPages > 1 && (
diff --git a/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorDetailedHeader/ThreatActorDetailedHeader.tsx b/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorDetailedHeader/ThreatActorDetailedHeader.tsx index 63c36a7..e97ca98 100644 --- a/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorDetailedHeader/ThreatActorDetailedHeader.tsx +++ b/frontend/src/components/threatactor/ThreatActorDetailed/ThreatActorDetailedHeader/ThreatActorDetailedHeader.tsx @@ -1,6 +1,7 @@ import { Star } from "lucide-react"; import { Link } from "react-router-dom"; import "./ThreatActorDetailedHeader.css"; +import BackButton from "../../../navigation/BackButton"; type ThreatActorDetailsHeaderProps = { name: string; @@ -17,9 +18,7 @@ function ThreatActorDetailedHeader({ }: ThreatActorDetailsHeaderProps){ return (
- - ← Back to Threat Actors - +

{name}

diff --git a/frontend/src/pages/Software/SoftwareDetail.tsx b/frontend/src/pages/Software/SoftwareDetail.tsx index 791c1b2..17552a4 100644 --- a/frontend/src/pages/Software/SoftwareDetail.tsx +++ b/frontend/src/pages/Software/SoftwareDetail.tsx @@ -4,6 +4,7 @@ import { Link, useParams } from "react-router-dom"; import { getSoftwareByMitreId } from "../../data/softwareData"; import type { SoftwareEntry } from "../../data/softwareData"; import "./SoftwareDetail.css"; +import BackButton from "../../components/navigation/BackButton"; function cleanDescription(description: string): string { return description @@ -84,9 +85,7 @@ function SoftwareDetail() { return (
- -