From 099bce87b5c02a6e2e0773ca677da06e12a4d38b Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Fri, 1 Sep 2023 00:08:40 +0530 Subject: [PATCH 1/6] chore: public board endpoints (#2030) --- apiserver/plane/api/serializers/issue.py | 5 ++-- apiserver/plane/api/views/issue.py | 37 +++++++++++++++--------- apiserver/plane/db/models/issue.py | 2 +- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/apiserver/plane/api/serializers/issue.py b/apiserver/plane/api/serializers/issue.py index 1f4d814a429..6cd06a767ef 100644 --- a/apiserver/plane/api/serializers/issue.py +++ b/apiserver/plane/api/serializers/issue.py @@ -680,7 +680,7 @@ class Meta: class IssuePublicSerializer(BaseSerializer): project_detail = ProjectLiteSerializer(read_only=True, source="project") state_detail = StateLiteSerializer(read_only=True, source="state") - issue_reactions = IssueReactionLiteSerializer(read_only=True, many=True) + reactions = IssueReactionLiteSerializer(read_only=True, many=True, source="issue_reactions") votes = IssueVoteSerializer(read_only=True, many=True) class Meta: @@ -697,12 +697,13 @@ class Meta: "workspace", "priority", "target_date", - "issue_reactions", + "reactions", "votes", ] read_only_fields = fields + class IssueSubscriberSerializer(BaseSerializer): class Meta: model = IssueSubscriber diff --git a/apiserver/plane/api/views/issue.py b/apiserver/plane/api/views/issue.py index cbcd40f0416..74b5744233d 100644 --- a/apiserver/plane/api/views/issue.py +++ b/apiserver/plane/api/views/issue.py @@ -28,7 +28,7 @@ from rest_framework.response import Response from rest_framework import status from rest_framework.parsers import MultiPartParser, FormParser -from rest_framework.permissions import AllowAny +from rest_framework.permissions import AllowAny, IsAuthenticated from sentry_sdk import capture_exception # Module imports @@ -1504,7 +1504,7 @@ def destroy(self, request, slug, project_id, comment_id, reaction_code): { "reaction": str(reaction_code), "identifier": str(comment_reaction.id), - "comment_id": str(comment_id) + "comment_id": str(comment_id), } ), ) @@ -1532,6 +1532,18 @@ class IssueCommentPublicViewSet(BaseViewSet): "workspace__id", ] + def get_permissions(self): + if self.action in ["list", "retrieve"]: + self.permission_classes = [ + AllowAny, + ] + else: + self.permission_classes = [ + IsAuthenticated, + ] + + return super(IssueCommentPublicViewSet, self).get_permissions() + def get_queryset(self): project_deploy_board = ProjectDeployBoard.objects.get( workspace__slug=self.kwargs.get("slug"), @@ -1741,7 +1753,7 @@ def create(self, request, slug, project_id, issue_id): issue_id=str(self.kwargs.get("issue_id", None)), project_id=str(self.kwargs.get("project_id", None)), current_instance=None, - ) + ) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) except ProjectDeployBoard.DoesNotExist: @@ -1855,7 +1867,7 @@ def create(self, request, slug, project_id, comment_id): issue_id=None, project_id=str(self.kwargs.get("project_id", None)), current_instance=None, - ) + ) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) except IssueComment.DoesNotExist: @@ -1903,7 +1915,7 @@ def destroy(self, request, slug, project_id, comment_id, reaction_code): { "reaction": str(reaction_code), "identifier": str(comment_reaction.id), - "comment_id": str(comment_id) + "comment_id": str(comment_id), } ), ) @@ -1953,13 +1965,13 @@ def create(self, request, slug, project_id, issue_id): issue_vote.vote = request.data.get("vote", 1) issue_vote.save() issue_activity.delay( - type="issue_vote.activity.created", - requested_data=json.dumps(self.request.data, cls=DjangoJSONEncoder), - actor_id=str(self.request.user.id), - issue_id=str(self.kwargs.get("issue_id", None)), - project_id=str(self.kwargs.get("project_id", None)), - current_instance=None, - ) + type="issue_vote.activity.created", + requested_data=json.dumps(self.request.data, cls=DjangoJSONEncoder), + actor_id=str(self.request.user.id), + issue_id=str(self.kwargs.get("issue_id", None)), + project_id=str(self.kwargs.get("project_id", None)), + current_instance=None, + ) serializer = IssueVoteSerializer(issue_vote) return Response(serializer.data, status=status.HTTP_201_CREATED) except Exception as e: @@ -2170,4 +2182,3 @@ def get(self, request, slug, project_id): {"error": "Something went wrong please try again later"}, status=status.HTTP_400_BAD_REQUEST, ) - diff --git a/apiserver/plane/db/models/issue.py b/apiserver/plane/db/models/issue.py index 1633cbaf917..8f085b2a275 100644 --- a/apiserver/plane/db/models/issue.py +++ b/apiserver/plane/db/models/issue.py @@ -293,7 +293,7 @@ class IssueComment(ProjectBaseModel): comment_json = models.JSONField(blank=True, default=dict) comment_html = models.TextField(blank=True, default="

") attachments = ArrayField(models.URLField(), size=10, blank=True, default=list) - issue = models.ForeignKey(Issue, on_delete=models.CASCADE) + issue = models.ForeignKey(Issue, on_delete=models.CASCADE, related_name="issue_comments") # System can also create comment actor = models.ForeignKey( settings.AUTH_USER_MODEL, From eab1d9329bb0aa0e44c677c8513ce12da82f9661 Mon Sep 17 00:00:00 2001 From: Lakhan Baheti <94619783+1akhanBaheti@users.noreply.github.com> Date: Fri, 1 Sep 2023 10:59:17 +0530 Subject: [PATCH 2/6] feat: editor for issue description (#2038) --- apps/app/pages/[workspaceSlug]/editor.tsx | 192 ++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 apps/app/pages/[workspaceSlug]/editor.tsx diff --git a/apps/app/pages/[workspaceSlug]/editor.tsx b/apps/app/pages/[workspaceSlug]/editor.tsx new file mode 100644 index 00000000000..73f0932eaad --- /dev/null +++ b/apps/app/pages/[workspaceSlug]/editor.tsx @@ -0,0 +1,192 @@ +import { TipTapEditor } from "components/tiptap"; +import type { NextPage } from "next"; +import { useCallback, useEffect, useState } from "react"; +import { Controller, useForm } from "react-hook-form"; +import issuesService from "services/issues.service"; +import { ICurrentUserResponse, IIssue } from "types"; +import useReloadConfirmations from "hooks/use-reload-confirmation"; +import { Spinner } from "components/ui"; +import Image404 from "public/404.svg"; +import DefaultLayout from "layouts/default-layout"; +import Image from "next/image"; +import userService from "services/user.service"; +import { useRouter } from "next/router"; + +const Editor: NextPage = () => { + const [user, setUser] = useState(); + const [isSubmitting, setIsSubmitting] = useState<"submitting" | "submitted" | "saved">("saved"); + const [isLoading, setIsLoading] = useState("false"); + const { setShowAlert } = useReloadConfirmations(); + const [cookies, setCookies] = useState({}); + const [issueDetail, setIssueDetail] = useState(null); + const router = useRouter(); + const { editable } = router.query; + const { + handleSubmit, + watch, + setValue, + control, + formState: { errors }, + } = useForm({ + defaultValues: { + name: "", + description: "", + description_html: "", + }, + }); + + const getCookies = () => { + const cookies = document.cookie.split(";"); + const cookieObj: any = {}; + cookies.forEach((cookie) => { + const cookieArr = cookie.split("="); + cookieObj[cookieArr[0].trim()] = cookieArr[1]; + }); + + setCookies(cookieObj); + return cookieObj; + }; + + const getIssueDetail = async (cookiesData: any) => { + try { + setIsLoading("true"); + const userData = await userService.currentUser(); + setUser(userData); + const issueDetail = await issuesService.retrieve( + cookiesData.MOBILE_slug, + cookiesData.MOBILE_project_id, + cookiesData.MOBILE_issue_id + ); + setIssueDetail(issueDetail); + setIsLoading("false"); + setValue("description_html", issueDetail.description_html); + setValue("description", issueDetail.description); + } catch (e) { + setIsLoading("error"); + console.log(e); + } + }; + useEffect(() => { + const cookiesData = getCookies(); + + getIssueDetail(cookiesData); + }, []); + + useEffect(() => { + if (isSubmitting === "submitted") { + setShowAlert(false); + setTimeout(async () => { + setIsSubmitting("saved"); + }, 2000); + } else if (isSubmitting === "submitting") { + setShowAlert(true); + } + }, [isSubmitting, setShowAlert]); + + const submitChanges = async ( + formData: Partial, + workspaceSlug: string, + projectId: string, + issueId: string + ) => { + if (!workspaceSlug || !projectId || !issueId) return; + + const payload: Partial = { + ...formData, + }; + + delete payload.blocker_issues; + delete payload.blocked_issues; + await issuesService + .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user) + .catch((e) => { + console.log(e); + }); + }; + + const handleDescriptionFormSubmit = useCallback( + async (formData: Partial) => { + if (!formData) return; + + await submitChanges( + { + name: issueDetail?.name ?? "", + description: formData.description ?? "", + description_html: formData.description_html ?? "

", + }, + cookies.MOBILE_slug, + cookies.MOBILE_project_id, + cookies.MOBILE_issue_id + ); + }, + [submitChanges] + ); + + return isLoading === "error" ? ( + + ) : isLoading === "true" ? ( +
+ +
+ ) : ( +
+ ( + { + setShowAlert(true); + setIsSubmitting("submitting"); + onChange(description_html); + setValue("description", description); + handleSubmit(handleDescriptionFormSubmit)().finally(() => { + setIsSubmitting("submitted"); + }); + }} + /> + )} + /> +
+ {isSubmitting === "submitting" ? "Saving..." : "Saved"} +
+
+ ); +}; + +const ErrorEncountered: NextPage = () => ( + +
+
+
+ 404- Page not found +
+
+

Oops! Something went wrong.

+
+
+
+
+); + +export default Editor; From 3a0d96a48d9756817d168b6774faea3fb6dbab6f Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Fri, 1 Sep 2023 11:21:34 +0530 Subject: [PATCH 3/6] chore: cycle endpoint to return display name as well in the assignee distribution (#2041) * chore: cycle endpoint to return display name as well in the assignee distribution * fix: value error --- apiserver/plane/api/views/cycle.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apiserver/plane/api/views/cycle.py b/apiserver/plane/api/views/cycle.py index a3d89fa8182..3dca6c3126e 100644 --- a/apiserver/plane/api/views/cycle.py +++ b/apiserver/plane/api/views/cycle.py @@ -191,11 +191,10 @@ def list(self, request, slug, project_id): workspace__slug=slug, project_id=project_id, ) - .annotate(first_name=F("assignees__first_name")) - .annotate(last_name=F("assignees__last_name")) + .annotate(display_name=F("assignees__display_name")) .annotate(assignee_id=F("assignees__id")) .annotate(avatar=F("assignees__avatar")) - .values("first_name", "last_name", "assignee_id", "avatar") + .values("display_name", "assignee_id", "avatar") .annotate(total_issues=Count("assignee_id")) .annotate( completed_issues=Count( @@ -209,7 +208,7 @@ def list(self, request, slug, project_id): filter=Q(completed_at__isnull=True), ) ) - .order_by("first_name", "last_name") + .order_by("display_name") ) label_distribution = ( From 0d4bcd2758671f2b68508a8ec1cafa5158311342 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Fri, 1 Sep 2023 11:23:43 +0530 Subject: [PATCH 4/6] fix: Gantt chart bugs (#2024) * fix: only left mouse button should trigger all the events * fix: extra block shadow --- .../app/components/gantt-chart/helpers/draggable.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/app/components/gantt-chart/helpers/draggable.tsx b/apps/app/components/gantt-chart/helpers/draggable.tsx index 20423ff5905..b665bf5d3ca 100644 --- a/apps/app/components/gantt-chart/helpers/draggable.tsx +++ b/apps/app/components/gantt-chart/helpers/draggable.tsx @@ -73,9 +73,11 @@ export const ChartDraggable: React.FC = ({ }; // handle block resize from the left end - const handleBlockLeftResize = () => { + const handleBlockLeftResize = (e: React.MouseEvent) => { if (!currentViewData || !resizableRef.current || !block.position) return; + if (e.button !== 0) return; + const resizableDiv = resizableRef.current; const columnWidth = currentViewData.data.width; @@ -126,9 +128,11 @@ export const ChartDraggable: React.FC = ({ }; // handle block resize from the right end - const handleBlockRightResize = () => { + const handleBlockRightResize = (e: React.MouseEvent) => { if (!currentViewData || !resizableRef.current || !block.position) return; + if (e.button !== 0) return; + const resizableDiv = resizableRef.current; const columnWidth = currentViewData.data.width; @@ -173,6 +177,8 @@ export const ChartDraggable: React.FC = ({ const handleBlockMove = (e: React.MouseEvent) => { if (!enableBlockMove || !currentViewData || !resizableRef.current || !block.position) return; + if (e.button !== 0) return; + e.preventDefault(); e.stopPropagation(); @@ -266,7 +272,7 @@ export const ChartDraggable: React.FC = ({
Date: Fri, 1 Sep 2023 15:29:50 +0530 Subject: [PATCH 5/6] chore: minor updates on the peek overview --- .../issues/peek-overview/header.tsx | 88 ++++++++----- .../issues/peek-overview/issue-details.tsx | 29 +++-- .../peek-overview/issue-emoji-reactions.tsx | 78 +++++++----- .../peek-overview/issue-vote-reactions.tsx | 119 ++++++++++++------ .../issues/peek-overview/layout.tsx | 76 ++++++----- apps/space/components/ui/index.ts | 2 + apps/space/components/ui/tooltip.tsx | 71 +++++++++++ apps/space/types/issue.ts | 9 +- 8 files changed, 316 insertions(+), 156 deletions(-) create mode 100644 apps/space/components/ui/tooltip.tsx diff --git a/apps/space/components/issues/peek-overview/header.tsx b/apps/space/components/issues/peek-overview/header.tsx index 0f13e97c329..7d2e76668eb 100644 --- a/apps/space/components/issues/peek-overview/header.tsx +++ b/apps/space/components/issues/peek-overview/header.tsx @@ -1,9 +1,15 @@ +import React from "react"; + import { useRouter } from "next/router"; -import { ArrowRightAlt, CloseFullscreen, East, OpenInFull } from "@mui/icons-material"; + +// headless ui +import { Listbox, Transition } from "@headlessui/react"; // hooks import useToast from "hooks/use-toast"; // ui import { Icon } from "components/ui"; +// icons +import { East } from "@mui/icons-material"; // helpers import { copyTextToClipboard } from "helpers/string.helper"; // store @@ -72,37 +78,59 @@ export const PeekOverviewHeader: React.FC = (props) => { /> )} - {/* - - - - */} - {/* setMode(val)} - customButton={ - - } - position="left" + issueDetailStore.setPeekMode(val)} + className="relative flex-shrink-0 text-left" > - {peekModes.map((mode) => ( - -
- - {mode.label} + + m.key === issueDetailStore.peekMode)?.icon ?? ""} /> + + + + +
+ {peekModes.map((mode) => ( + + `cursor-pointer select-none truncate rounded px-1 py-1.5 ${ + active || selected ? "bg-custom-background-80" : "" + } ${selected ? "text-custom-text-100" : "text-custom-text-200"}` + } + > + {({ selected }) => ( +
+
+
+ + {mode.label} +
+
+ {selected && } +
+ )} +
+ ))}
- - ))} - */} +
+
+
{(issueDetailStore.peekMode === "side" || issueDetailStore.peekMode === "modal") && (
diff --git a/apps/space/components/issues/peek-overview/issue-details.tsx b/apps/space/components/issues/peek-overview/issue-details.tsx index 22bc14c7e7e..0b329568c78 100644 --- a/apps/space/components/issues/peek-overview/issue-details.tsx +++ b/apps/space/components/issues/peek-overview/issue-details.tsx @@ -18,19 +18,22 @@ export const PeekOverviewIssueDetails: React.FC = ({ issueDetails }) => { {issueDetails.project_detail.identifier}-{issueDetails.sequence_id}

{issueDetails.name}

-

" - : issueDetails.description_html - } - customClassName="p-3 min-h-[50px] shadow-sm" - debouncedUpdatesEnabled={false} - editable={false} - /> + {issueDetails.description_html !== "" && issueDetails.description_html !== "

" && ( +

" + : issueDetails.description_html + } + customClassName="p-3 min-h-[50px] shadow-sm" + debouncedUpdatesEnabled={false} + editable={false} + /> + )}
); diff --git a/apps/space/components/issues/peek-overview/issue-emoji-reactions.tsx b/apps/space/components/issues/peek-overview/issue-emoji-reactions.tsx index b56d4649d0e..b39c3bae37b 100644 --- a/apps/space/components/issues/peek-overview/issue-emoji-reactions.tsx +++ b/apps/space/components/issues/peek-overview/issue-emoji-reactions.tsx @@ -7,7 +7,7 @@ import { useMobxStore } from "lib/mobx/store-provider"; // helpers import { groupReactions, renderEmoji } from "helpers/emoji.helper"; // components -import { ReactionSelector } from "components/ui"; +import { ReactionSelector, Tooltip } from "components/ui"; import { useEffect } from "react"; export const IssueEmojiReactions: React.FC = observer(() => { @@ -22,6 +22,8 @@ export const IssueEmojiReactions: React.FC = observer(() => { const reactions = issueId ? issueDetailsStore.details[issueId]?.reactions || [] : []; const groupedReactions = groupReactions(reactions, "reaction"); + console.log("groupedReactions", groupedReactions); + const handleReactionClick = (reactionHex: string) => { if (!workspace_slug || !project_slug || !issueId) return; @@ -54,39 +56,55 @@ export const IssueEmojiReactions: React.FC = observer(() => { handleReactionClick(value); }); }} + size="md" /> +
+ {Object.keys(groupedReactions || {}).map((reaction) => { + const reactions = groupedReactions?.[reaction] ?? []; + const REACTIONS_LIMIT = 1000; - {Object.keys(groupedReactions || {}).map( - (reaction) => - groupedReactions?.[reaction]?.length && - groupedReactions[reaction].length > 0 && ( -
} > - {groupedReactions?.[reaction].length}{" "} - - - ) - )} + + + ); + })} +
); }); diff --git a/apps/space/components/issues/peek-overview/issue-vote-reactions.tsx b/apps/space/components/issues/peek-overview/issue-vote-reactions.tsx index dace360d4db..ac20565ea3d 100644 --- a/apps/space/components/issues/peek-overview/issue-vote-reactions.tsx +++ b/apps/space/components/issues/peek-overview/issue-vote-reactions.tsx @@ -1,15 +1,19 @@ -import { useState, useEffect, useRef } from "react"; -import { observer } from "mobx-react-lite"; +import { useState, useEffect } from "react"; + import { useRouter } from "next/router"; + +// mobx +import { observer } from "mobx-react-lite"; // lib import { useMobxStore } from "lib/mobx/store-provider"; +import { Tooltip } from "components/ui"; export const IssueVotes: React.FC = observer(() => { const [isSubmitting, setIsSubmitting] = useState(false); const router = useRouter(); - const { workspace_slug, project_slug } = router.query as { workspace_slug: string; project_slug: string }; + const { workspace_slug, project_slug } = router.query; const { user: userStore, issueDetails: issueDetailsStore } = useMobxStore(); @@ -18,11 +22,11 @@ export const IssueVotes: React.FC = observer(() => { const votes = issueId ? issueDetailsStore.details[issueId]?.votes : []; - const upVoteCount = votes?.filter((vote) => vote.vote === 1).length || 0; - const downVoteCount = votes?.filter((vote) => vote.vote === -1).length || 0; + const allUpVotes = votes?.filter((vote) => vote.vote === 1); + const allDownVotes = votes?.filter((vote) => vote.vote === -1); - const isUpVotedByUser = votes?.some((vote) => vote.actor === user?.id && vote.vote === 1); - const isDownVotedByUser = votes?.some((vote) => vote.actor === user?.id && vote.vote === -1); + const isUpVotedByUser = allUpVotes?.some((vote) => vote.actor === user?.id); + const isDownVotedByUser = allDownVotes?.some((vote) => vote.actor === user?.id); const handleVote = async (e: any, voteValue: 1 | -1) => { if (!workspace_slug || !project_slug || !issueId) return; @@ -31,9 +35,10 @@ export const IssueVotes: React.FC = observer(() => { const actionPerformed = votes?.find((vote) => vote.actor === user?.id && vote.vote === voteValue); - if (actionPerformed) await issueDetailsStore.removeIssueVote(workspace_slug, project_slug, issueId); + if (actionPerformed) + await issueDetailsStore.removeIssueVote(workspace_slug.toString(), project_slug.toString(), issueId); else - await issueDetailsStore.addIssueVote(workspace_slug, project_slug, issueId, { + await issueDetailsStore.addIssueVote(workspace_slug.toString(), project_slug.toString(), issueId, { vote: voteValue, }); @@ -46,43 +51,79 @@ export const IssueVotes: React.FC = observer(() => { userStore.fetchCurrentUser(); }, [user, userStore]); + const VOTES_LIMIT = 1000; + return (
{/* upvote button 👇 */} -
+ } > - arrow_upward_alt - {upVoteCount} - + + {/* downvote button 👇 */} - + + ); }); diff --git a/apps/space/components/issues/peek-overview/layout.tsx b/apps/space/components/issues/peek-overview/layout.tsx index 57de2e55f1c..abb76db481c 100644 --- a/apps/space/components/issues/peek-overview/layout.tsx +++ b/apps/space/components/issues/peek-overview/layout.tsx @@ -66,22 +66,20 @@ export const IssuePeekOverview: React.FC = observer((props) => { <> -
-
- - - - - -
+
+ + + + +
@@ -98,31 +96,29 @@ export const IssuePeekOverview: React.FC = observer((props) => { >
-
-
- + + - - {issueDetailStore.peekMode === "modal" && ( - - )} - {issueDetailStore.peekMode === "full" && ( - - )} - - -
+ {issueDetailStore.peekMode === "modal" && ( + + )} + {issueDetailStore.peekMode === "full" && ( + + )} + +
diff --git a/apps/space/components/ui/index.ts b/apps/space/components/ui/index.ts index ab077407375..e4409690965 100644 --- a/apps/space/components/ui/index.ts +++ b/apps/space/components/ui/index.ts @@ -1,6 +1,8 @@ export * from "./dropdown"; export * from "./input"; +export * from "./loader"; export * from "./primary-button"; export * from "./secondary-button"; export * from "./icon"; export * from "./reaction-selector"; +export * from "./tooltip"; diff --git a/apps/space/components/ui/tooltip.tsx b/apps/space/components/ui/tooltip.tsx new file mode 100644 index 00000000000..994c0f32a86 --- /dev/null +++ b/apps/space/components/ui/tooltip.tsx @@ -0,0 +1,71 @@ +import React from "react"; + +// next-themes +import { useTheme } from "next-themes"; +// tooltip2 +import { Tooltip2 } from "@blueprintjs/popover2"; + +type Props = { + tooltipHeading?: string; + tooltipContent: string | React.ReactNode; + position?: + | "top" + | "right" + | "bottom" + | "left" + | "auto" + | "auto-end" + | "auto-start" + | "bottom-left" + | "bottom-right" + | "left-bottom" + | "left-top" + | "right-bottom" + | "right-top" + | "top-left" + | "top-right"; + children: JSX.Element; + disabled?: boolean; + className?: string; + openDelay?: number; + closeDelay?: number; +}; + +export const Tooltip: React.FC = ({ + tooltipHeading, + tooltipContent, + position = "top", + children, + disabled = false, + className = "", + openDelay = 200, + closeDelay, +}) => { + const { theme } = useTheme(); + + return ( + + {tooltipHeading && ( +
+ {tooltipHeading} +
+ )} + {tooltipContent} +
+ } + position={position} + renderTarget={({ isOpen: isTooltipOpen, ref: eleReference, ...tooltipProps }) => + React.cloneElement(children, { ref: eleReference, ...tooltipProps, ...children.props }) + } + /> + ); +}; diff --git a/apps/space/types/issue.ts b/apps/space/types/issue.ts index 2d9ac0b7f53..323df995ce7 100644 --- a/apps/space/types/issue.ts +++ b/apps/space/types/issue.ts @@ -48,6 +48,7 @@ export interface IIssue { workspace: string; project: string; actor: string; + actor_detail: ActorDetail; }[]; } @@ -94,12 +95,12 @@ export interface IIssueReaction { } export interface ActorDetail { - id: string; - first_name: string; - last_name: string; avatar: string; - is_bot: boolean; display_name: string; + first_name: string; + id: string; + is_bot: boolean; + last_name: string; } export interface IssueDetail { From bb1b4cb9ba512978cd831128a187036a3bef2f2a Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Fri, 1 Sep 2023 15:39:09 +0530 Subject: [PATCH 6/6] chore: remove filters button from the navbar --- apps/space/components/issues/navbar/index.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/apps/space/components/issues/navbar/index.tsx b/apps/space/components/issues/navbar/index.tsx index 90c82b9d56b..83d79f349e1 100644 --- a/apps/space/components/issues/navbar/index.tsx +++ b/apps/space/components/issues/navbar/index.tsx @@ -68,11 +68,6 @@ const IssueNavbar = observer(() => { - {/* issue filters */} -
- -
- {/* issue views */}