diff --git a/src/App.tsx b/src/App.tsx
index c5eb0110..de7ff626 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -3,6 +3,7 @@ import { Layout } from "./components/layout"
import { Login } from "./components/Login"
import { ProjectsView } from "./components/ProjectsView"
import { BacklogView } from "./components/BacklogView"
+import { EpicView } from "./components/EpicView"
import { StoryMapView } from "./components/StoryMapView"
import { StoryMapDashboard } from "./components/StoryMapView/StoryMapDashboard"
@@ -13,6 +14,7 @@ export function App() {
}>
} />
} />
+ } />
} />
} />
diff --git a/src/components/CreateIssue/CreateIssueModal.tsx b/src/components/CreateIssue/CreateIssueModal.tsx
index 00770cca..2103d7cd 100644
--- a/src/components/CreateIssue/CreateIssueModal.tsx
+++ b/src/components/CreateIssue/CreateIssueModal.tsx
@@ -117,6 +117,7 @@ export function CreateIssueModal({
color: "green",
})
queryClient.invalidateQueries({ queryKey: ["issues"] })
+ queryClient.invalidateQueries({ queryKey: ["epics"] })
setOpened(false)
form.reset()
},
diff --git a/src/components/EpicView/EpicCard.tsx b/src/components/EpicView/EpicCard.tsx
new file mode 100644
index 00000000..dc80d299
--- /dev/null
+++ b/src/components/EpicView/EpicCard.tsx
@@ -0,0 +1,194 @@
+import {Issue} from "types";
+import {
+ Avatar,
+ Badge,
+ Box,
+ Center,
+ Grid,
+ Group,
+ Modal,
+ Stack,
+ Text, ThemeIcon,
+ Tooltip,
+ useMantineTheme
+} from "@mantine/core";
+import {useHover} from "@mantine/hooks";
+import {useState} from "react";
+import {useQueryClient} from "@tanstack/react-query";
+import {IconBolt} from "@tabler/icons";
+import {DeleteButton} from "../BacklogView/Issue/DeleteButton";
+
+export function EpicCard ({
+ issueKey,
+ summary,
+ status,
+ storyPointsEstimate,
+ epic,
+ labels,
+ assignee,
+}: Issue) {
+ let storyPointsColor: string
+ const [opened, setOpened] = useState(false)
+ const queryClient = useQueryClient()
+ const {hovered} = useHover()
+ const theme = useMantineTheme()
+ const hoverStyles =
+ theme.colorScheme === "dark"
+ ? {
+ backgroundColor: theme.colors.dark[8],
+ transition: "background-color .1s ease-in",
+ }
+ : {
+ backgroundColor: theme.colors.gray[1],
+ transition: "background-color .1s ease-in",
+ }
+ switch (status) {
+ case "To Do":
+ storyPointsColor = "gray.6"
+ break
+ case "In Progress":
+ storyPointsColor = "blue.8"
+ break
+ case "Done":
+ storyPointsColor = "green.9"
+ break
+ default:
+ storyPointsColor = "gray.6"
+ }
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {issueKey}
+
+ {epic && (
+
+ {epic}
+
+ )}
+ {labels?.length !== 0 &&
+ labels.map((label) => (
+
+ {label}
+
+ ))}
+
+ {summary}
+
+
+
+
+ {assignee?.avatarUrls !== undefined ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ {storyPointsEstimate}
+
+
+
+
+ {
+ setOpened(false)
+ queryClient.invalidateQueries({ queryKey: ["issues"] })
+ }}
+ size="90vw"
+ overflow="outside"
+ overlayOpacity={0.55}
+ overlayBlur={3}
+ withCloseButton={false}
+ >
+ {/* TODO open Epic Detail View */}
+
+ >
+ )
+}
diff --git a/src/components/EpicView/EpicView.tsx b/src/components/EpicView/EpicView.tsx
new file mode 100644
index 00000000..b6651534
--- /dev/null
+++ b/src/components/EpicView/EpicView.tsx
@@ -0,0 +1,122 @@
+import {Group, Stack, Text, Title, ScrollArea, Box, Button, Center, Loader} from "@mantine/core";
+import {useNavigate} from "react-router-dom";
+import {useState} from "react";
+import {useQuery} from "@tanstack/react-query";
+import {useCanvasStore} from "../../lib/Store";
+import {CreateIssueModal} from "../CreateIssue/CreateIssueModal";
+import {Issue} from "../../../types";
+import {EpicWrapper} from "./EpicWrapper";
+import {getEpics} from "./helpers/queryFetchers";
+
+
+export function EpicView() {
+ const navigate = useNavigate()
+ const projectName = useCanvasStore((state) => state.selectedProject?.name)
+ const [createIssueModalOpened, setCreateIssueModalOpened] = useState(false)
+ const projectKey = useCanvasStore((state) => state.selectedProject?.key)
+ const [EpicWrappers, setEpicWrappers] = useState(
+ new Map()
+ )
+
+ const updateEpicWrapper = (
+ key: string,
+ value: { issues: Issue[]}
+ ) => {
+ setEpicWrappers((map) => new Map(map.set(key, value)))
+ }
+
+ const {isLoading: isLoadingEpics} =
+ useQuery({
+ queryKey: ["epics", projectKey],
+ queryFn: () => getEpics(projectKey),
+ enabled: !!projectKey,
+ onSuccess: (epics) => {
+ updateEpicWrapper("EpicView", {
+ issues:
+ epics && epics instanceof Array ? epics : []
+ })
+ },
+ })
+ if (isLoadingEpics)
+ return (
+
+ {projectKey ? (
+
+ ) : (
+
+ No Project has been selected!
+
+ Please go back to the Projects View section and select a project
+
+
+
+ )}
+
+ )
+ return (
+
+
+
+
+ navigate("/projectsview")}
+ sx={{
+ ":hover": {
+ textDecoration: "underline",
+ cursor: "pointer",
+ },
+ }}
+ >
+ Projects
+
+ /
+ {projectName}
+
+
+ Epics
+
+
+ {EpicWrappers.get("EpicView") &&(
+
+
+
+ )}
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/EpicView/EpicWrapper.tsx b/src/components/EpicView/EpicWrapper.tsx
new file mode 100644
index 00000000..91bbda03
--- /dev/null
+++ b/src/components/EpicView/EpicWrapper.tsx
@@ -0,0 +1,18 @@
+import {Stack} from "@mantine/core";
+import {Issue} from "../../../types";
+import {EpicCard} from "./EpicCard";
+
+
+export function EpicWrapper({
+ epics,
+}: {
+ epics: Issue[]
+}){
+ return (
+
+ {epics.map((epic: Issue) => (
+
+ ))}
+
+ )
+}
diff --git a/src/components/EpicView/helpers/queryFetchers.ts b/src/components/EpicView/helpers/queryFetchers.ts
new file mode 100644
index 00000000..c5605f3c
--- /dev/null
+++ b/src/components/EpicView/helpers/queryFetchers.ts
@@ -0,0 +1,6 @@
+import {Issue} from "../../../../types";
+
+export const getEpics = (
+ projectKey: string | undefined
+): Promise =>
+ window.provider.getEpicsByProject(projectKey || "")
diff --git a/src/components/EpicView/index.ts b/src/components/EpicView/index.ts
new file mode 100644
index 00000000..01648816
--- /dev/null
+++ b/src/components/EpicView/index.ts
@@ -0,0 +1 @@
+export * from "./EpicView"
diff --git a/src/components/layout/LayoutHeader.tsx b/src/components/layout/LayoutHeader.tsx
index f03b7c5e..bea190d5 100644
--- a/src/components/layout/LayoutHeader.tsx
+++ b/src/components/layout/LayoutHeader.tsx
@@ -50,6 +50,12 @@ export function LayoutHeader() {
>
Backlog
+ navigate("/epicview")}>
+ Epics
+