From 435c09ba01ba8271a038b6923221341df172102b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20R=C3=BCsch?= <78490564+maximilianruesch@users.noreply.github.com> Date: Wed, 6 Dec 2023 12:57:51 +0100 Subject: [PATCH] Add first epic detail view (#80) Co-authored-by: Benedict Teutsch Co-authored-by: Julian Rupprecht --- .../jira-cloud-provider/JiraCloudProvider.ts | 15 +- .../Components/AssigneeMenu/queries.ts | 1 + .../DetailView/Components/Labels.tsx | 17 ++- .../EpicDetailView/Components/IssueSprint.tsx | 106 ++++++++++++++ .../Components/IssueSummary.tsx | 72 ++++++++++ .../Components/SubTask/Subtask.tsx | 62 +++++++++ .../Components/SubTask/index.ts | 1 + .../Components/SubTask/queries.ts | 21 +++ .../Components/SubTask/queryFunctions.ts | 2 + .../EpicDetailView/EpicDetailView.tsx | 130 ++++++++++++++++++ .../EpicDetailView/helpers/queryFunctions.ts | 4 + src/components/EpicView/EpicCard.tsx | 20 ++- src/components/EpicView/EpicView.tsx | 3 +- src/components/EpicView/EpicWrapper.tsx | 2 +- types/index.ts | 11 +- 15 files changed, 442 insertions(+), 25 deletions(-) create mode 100644 src/components/EpicDetailView/Components/IssueSprint.tsx create mode 100644 src/components/EpicDetailView/Components/IssueSummary.tsx create mode 100644 src/components/EpicDetailView/Components/SubTask/Subtask.tsx create mode 100644 src/components/EpicDetailView/Components/SubTask/index.ts create mode 100644 src/components/EpicDetailView/Components/SubTask/queries.ts create mode 100644 src/components/EpicDetailView/Components/SubTask/queryFunctions.ts create mode 100644 src/components/EpicDetailView/EpicDetailView.tsx create mode 100644 src/components/EpicDetailView/helpers/queryFunctions.ts diff --git a/electron/providers/jira-cloud-provider/JiraCloudProvider.ts b/electron/providers/jira-cloud-provider/JiraCloudProvider.ts index 6fae6c6f..e837ec4a 100644 --- a/electron/providers/jira-cloud-provider/JiraCloudProvider.ts +++ b/electron/providers/jira-cloud-provider/JiraCloudProvider.ts @@ -767,11 +767,7 @@ export class JiraCloudProvider implements IProvider { id: projectId, }, }), - ...(reporter && { - reporter: { - id: reporter, - }, - }), + ...(reporter && { reporter }), ...(priority && priority.id && { priority }), ...(assignee && assignee.id && { @@ -862,6 +858,15 @@ export class JiraCloudProvider implements IProvider { displayName: element.fields.assignee?.displayName, avatarUrls: element.fields.assignee?.avatarUrls, }, + subtasks: element.fields.subtasks, + created: element.fields.created, + updated: element.fields.updated, + comment: element.fields.comment ?? { + comments: [], + }, + projectId: element.fields.project.id, + sprint: element.fields.sprint, + attachments: element.fields.attachment, })) ) resolve(epics) diff --git a/src/components/DetailView/Components/AssigneeMenu/queries.ts b/src/components/DetailView/Components/AssigneeMenu/queries.ts index 7a5e2b2d..f59bea01 100644 --- a/src/components/DetailView/Components/AssigneeMenu/queries.ts +++ b/src/components/DetailView/Components/AssigneeMenu/queries.ts @@ -17,6 +17,7 @@ export const editIssueMutation = (queryClient: QueryClient, issueKey: string) => message: `The assignee for issue ${issueKey} has been modified!`, color: "green", }) + queryClient.invalidateQueries({ queryKey: ["epics"] }) queryClient.invalidateQueries({ queryKey: ["issues"] }) }, }) diff --git a/src/components/DetailView/Components/Labels.tsx b/src/components/DetailView/Components/Labels.tsx index c82d43a4..59210046 100644 --- a/src/components/DetailView/Components/Labels.tsx +++ b/src/components/DetailView/Components/Labels.tsx @@ -16,18 +16,20 @@ import { editIssue } from "../helpers/queryFunctions" export function Labels({ labels, issueKey, + onMutate = () => {} }: { labels: string[] issueKey: string + onMutate?: () => void }) { const theme = useMantineTheme() - const [defaultLabels, setdefaultLabels] = useState(labels) - const [showLabelsInput, setshowLabelsInput] = useState(false) + const [defaultLabels, setDefaultLabels] = useState(labels) + const [showLabelsInput, setShowLabelsInput] = useState(false) const { data: allLabels } = useQuery({ queryKey: ["labels"], queryFn: () => getLabels(), }) - const mutationLalbels = useMutation({ + const mutationLabels = useMutation({ mutationFn: (issue: Issue) => editIssue(issue, issueKey), onError: () => { showNotification({ @@ -40,6 +42,7 @@ export function Labels({ message: `Labels for issue ${issueKey} has been modified!`, color: "green", }) + onMutate() }, }) return ( @@ -62,15 +65,15 @@ export function Labels({ defaultValue={defaultLabels} data={allLabels || []} onBlur={() => { - setshowLabelsInput(false) - mutationLalbels.mutate({ + setShowLabelsInput(false) + mutationLabels.mutate({ labels: defaultLabels, } as Issue) }} - onChange={(value) => setdefaultLabels(value)} + onChange={(value) => setDefaultLabels(value)} /> ) : ( - setshowLabelsInput(true)}> + setShowLabelsInput(true)}> {defaultLabels.length !== 0 ? ( {defaultLabels.map((label) => ( diff --git a/src/components/EpicDetailView/Components/IssueSprint.tsx b/src/components/EpicDetailView/Components/IssueSprint.tsx new file mode 100644 index 00000000..eecdebed --- /dev/null +++ b/src/components/EpicDetailView/Components/IssueSprint.tsx @@ -0,0 +1,106 @@ +import { Text, Box, Select, useMantineTheme } from "@mantine/core" +import { showNotification } from "@mantine/notifications" +import { useMutation, useQuery } from "@tanstack/react-query" +import { Issue, Sprint } from "types" +import { useState } from "react" +import { useCanvasStore } from "../../../lib/Store" +import { + getSprints, + moveIssueToBacklog, +} from "../../CreateIssue/queryFunctions" +import { editIssue } from "../helpers/queryFunctions" + +export function IssueSprint(props: { + sprint: Sprint | undefined + issueKey: string +}) { + const theme = useMantineTheme() + const [defaultsprint, setdefaultsprint] = useState(props.sprint || undefined) + const [showSprintInput, setshowSprintInput] = useState(false) + + const boardIds = useCanvasStore((state) => state.selectedProjectBoardIds) + const currentBoardId = boardIds[0] + const { data: sprints } = useQuery({ + queryKey: ["sprints"], + queryFn: () => getSprints(currentBoardId), + enabled: !!currentBoardId, + }) + + const mutationSprint = useMutation({ + mutationFn: (issue: Issue) => editIssue(issue, props.issueKey), + onError: () => { + showNotification({ + message: `An error occured while modifing the sprint 😢`, + color: "red", + }) + }, + onSuccess: () => { + showNotification({ + message: `The sprint for issue ${props.issueKey} has been modified!`, + color: "green", + }) + }, + }) + const mutationBacklog = useMutation({ + mutationFn: () => moveIssueToBacklog(props.issueKey), + onError: () => { + showNotification({ + message: `An error occured while modifing the sprint 😢`, + color: "red", + }) + }, + onSuccess: () => { + showNotification({ + message: `The sprint for issue ${props.issueKey} has been modified!`, + color: "green", + }) + }, + }) + const sprintNames = sprints ? sprints?.map((sprint) => sprint.name) : [] + return ( + + {showSprintInput ? ( +