Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion apiserver/plane/app/views/issue/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,44 @@ def retrieve(self, request, slug, project_id, pk=None):
project = Project.objects.get(pk=project_id, workspace__slug=slug)

issue = (
self.get_queryset()
Issue.objects.filter(
project_id=self.kwargs.get("project_id")
)
.filter(workspace__slug=self.kwargs.get("slug"))
.select_related("workspace", "project", "state", "parent")
.prefetch_related("assignees", "labels", "issue_module__module")
.annotate(
cycle_id=Case(
When(
issue_cycle__cycle__deleted_at__isnull=True,
then=F("issue_cycle__cycle_id"),
),
default=None,
)
)
.annotate(
link_count=IssueLink.objects.filter(issue=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
attachment_count=FileAsset.objects.filter(
issue_id=OuterRef("id"),
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
)
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
sub_issues_count=Issue.issue_objects.filter(
parent=OuterRef("id")
)
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
Comment on lines +485 to +522
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor repeated queryset logic into a helper method

The queryset annotations and prefetches in the retrieve method are similar to those in partial_update. To reduce code duplication and enhance maintainability, consider refactoring this logic into a shared helper method or modifying get_queryset() to include the necessary annotations.


⚠️ Potential issue

Use self.get_queryset() to ensure consistent querying

In the retrieve method, you're directly querying Issue.objects instead of using self.get_queryset(). This may bypass filters, annotations, or prefetches defined in get_queryset(), potentially leading to inconsistencies. It's recommended to use self.get_queryset().filter(pk=pk) to maintain consistency across the viewset methods.

Apply this diff to fix the issue:

-def retrieve(self, request, slug, project_id, pk=None):
-    project = Project.objects.get(pk=project_id, workspace__slug=slug)
-
-    issue = (
-        Issue.objects.filter(
-            project_id=self.kwargs.get("project_id")
-        )
-        .filter(workspace__slug=self.kwargs.get("slug"))
-        .select_related("workspace", "project", "state", "parent")
-        .prefetch_related("assignees", "labels", "issue_module__module")
-        .annotate(
-            cycle_id=Case(
-                When(
-                    issue_cycle__cycle__deleted_at__isnull=True,
-                    then=F("issue_cycle__cycle_id"),
-                ),
-                default=None,
-            )
-        )
-        .annotate(
-            link_count=IssueLink.objects.filter(issue=OuterRef("id"))
-            .order_by()
-            .annotate(count=Func(F("id"), function="Count"))
-            .values("count")
-        )
-        .annotate(
-            attachment_count=FileAsset.objects.filter(
-                issue_id=OuterRef("id"),
-                entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
-            )
-            .order_by()
-            .annotate(count=Func(F("id"), function="Count"))
-            .values("count")
-        )
-        .annotate(
-            sub_issues_count=Issue.issue_objects.filter(
-                parent=OuterRef("id")
-            )
-            .order_by()
-            .annotate(count=Func(F("id"), function="Count"))
-            .values("count")
-        )
-        .filter(pk=pk)
-        .annotate(
-            # Annotations...
-        )
-        .prefetch_related(
-            # Prefetches...
-        )
-    ).first()
+    issue = (
+        self.get_queryset()
+        .filter(pk=pk)
+        .annotate(
+            label_ids=Coalesce(
+                ArrayAgg(
+                    "labels__id",
+                    distinct=True,
+                    filter=(
+                        ~Q(labels__id__isnull=True)
+                        & Q(labels__deleted_at__isnull=True)
+                    ),
+                ),
+                Value([], output_field=ArrayField(UUIDField())),
+            ),
+            assignee_ids=Coalesce(
+                ArrayAgg(
+                    "assignees__id",
+                    distinct=True,
+                    filter=~Q(assignees__id__isnull=True)
+                    & Q(assignees__member_project__is_active=True),
+                ),
+                Value([], output_field=ArrayField(UUIDField())),
+            ),
+            module_ids=Coalesce(
+                ArrayAgg(
+                    "issue_module__module_id",
+                    distinct=True,
+                    filter=~Q(issue_module__module_id__isnull=True)
+                    & Q(issue_module__module__archived_at__isnull=True)
+                    & Q(issue_module__module__deleted_at__isnull=True),
+                ),
+                Value([], output_field=ArrayField(UUIDField())),
+            ),
+        )
+        .prefetch_related(
+            Prefetch(
+                "issue_reactions",
+                queryset=IssueReaction.objects.select_related(
+                    "issue", "actor"
+                ),
+            )
+        )
+        .prefetch_related(
+            Prefetch(
+                "issue_link",
+                queryset=IssueLink.objects.select_related("created_by"),
+            )
+        )
+        .annotate(
+            is_subscribed=Exists(
+                IssueSubscriber.objects.filter(
+                    workspace__slug=slug,
+                    project_id=project_id,
+                    issue_id=OuterRef("pk"),
+                    subscriber=request.user,
+                )
+            )
+        )
+        .first()
+    )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Issue.objects.filter(
project_id=self.kwargs.get("project_id")
)
.filter(workspace__slug=self.kwargs.get("slug"))
.select_related("workspace", "project", "state", "parent")
.prefetch_related("assignees", "labels", "issue_module__module")
.annotate(
cycle_id=Case(
When(
issue_cycle__cycle__deleted_at__isnull=True,
then=F("issue_cycle__cycle_id"),
),
default=None,
)
)
.annotate(
link_count=IssueLink.objects.filter(issue=OuterRef("id"))
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
attachment_count=FileAsset.objects.filter(
issue_id=OuterRef("id"),
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
)
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
sub_issues_count=Issue.issue_objects.filter(
parent=OuterRef("id")
)
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
issue = (
self.get_queryset()
.filter(pk=pk)
.annotate(
label_ids=Coalesce(
ArrayAgg(
"labels__id",
distinct=True,
filter=(
~Q(labels__id__isnull=True)
& Q(labels__deleted_at__isnull=True)
),
),
Value([], output_field=ArrayField(UUIDField())),
),
assignee_ids=Coalesce(
ArrayAgg(
"assignees__id",
distinct=True,
filter=~Q(assignees__id__isnull=True)
& Q(assignees__member_project__is_active=True),
),
Value([], output_field=ArrayField(UUIDField())),
),
module_ids=Coalesce(
ArrayAgg(
"issue_module__module_id",
distinct=True,
filter=~Q(issue_module__module_id__isnull=True)
& Q(issue_module__module__archived_at__isnull=True)
& Q(issue_module__module__deleted_at__isnull=True),
),
Value([], output_field=ArrayField(UUIDField())),
),
)
.prefetch_related(
Prefetch(
"issue_reactions",
queryset=IssueReaction.objects.select_related(
"issue", "actor"
),
)
)
.prefetch_related(
Prefetch(
"issue_link",
queryset=IssueLink.objects.select_related("created_by"),
)
)
.annotate(
is_subscribed=Exists(
IssueSubscriber.objects.filter(
workspace__slug=slug,
project_id=project_id,
issue_id=OuterRef("pk"),
subscriber=request.user,
)
)
)
.first()
)

.filter(pk=pk)
.annotate(
label_ids=Coalesce(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const ArchivedIssueDetailsPage = observer(() => {
? `ARCHIVED_ISSUE_DETAIL_${workspaceSlug}_${projectId}_${archivedIssueId}`
: null,
workspaceSlug && projectId && archivedIssueId
? () => fetchIssue(workspaceSlug.toString(), projectId.toString(), archivedIssueId.toString(), "ARCHIVED")
? () => fetchIssue(workspaceSlug.toString(), projectId.toString(), archivedIssueId.toString())
: null
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import { ISSUE_DETAILS } from "@/constants/fetch-keys";
// hooks
import { useProject } from "@/hooks/store";
// services
import { IssueArchiveService } from "@/services/issue";
import { IssueService } from "@/services/issue";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Unresolved references to IssueArchiveService found.

The following files still reference IssueArchiveService:

  • web/core/services/issue/issue_archive.service.ts
  • web/core/store/issue/issue-details/issue.store.ts
  • web/core/store/issue/helpers/base-issues.store.ts

Please update these to use IssueService as per the refactoring.

🔗 Analysis chain

LGTM! Verify impact on other components.

The change from IssueArchiveService to IssueService aligns with the PR objective of merging default and archived issue endpoints. This refactoring improves code consistency and maintainability.

To ensure this change doesn't introduce unintended side effects, please run the following script to check for any remaining references to IssueArchiveService:

Also applies to: 18-18

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining references to IssueArchiveService

# Test: Search for IssueArchiveService usage
rg 'IssueArchiveService'

Length of output: 621


const issueArchiveService = new IssueArchiveService();
const issueService = new IssueService();

export const ProjectArchivedIssueDetailsHeader = observer(() => {
// router
Expand All @@ -24,14 +24,9 @@ export const ProjectArchivedIssueDetailsHeader = observer(() => {
const { currentProjectDetails, loader } = useProject();

const { data: issueDetails } = useSWR(
workspaceSlug && projectId && archivedIssueId ? ISSUE_DETAILS(archivedIssueId as string) : null,
workspaceSlug && projectId && archivedIssueId ? ISSUE_DETAILS(archivedIssueId.toString()) : null,
workspaceSlug && projectId && archivedIssueId
? () =>
issueArchiveService.retrieveArchivedIssue(
workspaceSlug as string,
projectId as string,
archivedIssueId as string
)
? () => issueService.retrieve(workspaceSlug.toString(), projectId.toString(), archivedIssueId.toString())
: null
);

Expand Down
7 changes: 6 additions & 1 deletion web/core/components/cycles/active-cycle/cycle-stats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,12 @@ export const ActiveCycleStats: FC<ActiveCycleStatsProps> = observer((props) => {
className="group flex cursor-pointer items-center justify-between gap-2 rounded-md hover:bg-custom-background-90 p-1"
onClick={() => {
if (issue.id) {
setPeekIssue({ workspaceSlug, projectId, issueId: issue.id });
setPeekIssue({
workspaceSlug,
projectId,
issueId: issue.id,
isArchived: !!issue.archived_at,
});
handleFiltersUpdate("priority", ["urgent", "high"], true);
}
}}
Expand Down
8 changes: 7 additions & 1 deletion web/core/components/issues/issue-layouts/list/block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,13 @@ export const IssueBlock = observer((props: IssueBlockProps) => {
issue.project_id &&
issue.id &&
!getIsIssuePeeked(issue.id) &&
setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id, nestingLevel: nestingLevel });
setPeekIssue({
workspaceSlug,
projectId: issue.project_id,
issueId: issue.id,
nestingLevel: nestingLevel,
isArchived: !!issue.archived_at,
});

const issue = issuesMap[issueId];
const subIssuesCount = issue?.sub_issues_count ?? 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const ArchivedIssueLayoutRoot: React.FC = observer(() => {
<div className="relative h-full w-full overflow-auto">
<ArchivedIssueListLayout />
</div>
<IssuePeekOverview is_archived />
<IssuePeekOverview />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Remaining usage of is_archived prop detected in the following files:

  • web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/archives/issues/(detail)/[archivedIssueId]/page.tsx
  • web/core/components/issues/issue-detail/root.tsx
  • web/core/components/issues/peek-overview/view.tsx
🔗 Analysis chain

Verify the removal of is_archived prop from IssuePeekOverview

The is_archived prop has been removed from the IssuePeekOverview component. This change aligns with the PR objective of merging the default and archived issue detail endpoints and removing the archived status check.

However, to ensure this change doesn't introduce any unintended side effects:

  1. Confirm that the IssuePeekOverview component can now handle both archived and non-archived issues correctly without this prop.
  2. Verify that this change is consistent with updates in the IssuePeekOverview component implementation.

To verify this change, please run the following script:

This script will help us confirm that the is_archived prop has been consistently removed from the IssuePeekOverview component and its usage across the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining uses of 'is_archived' prop in IssuePeekOverview

# Search for IssuePeekOverview component definition
echo "IssuePeekOverview component definition:"
ast-grep --pattern 'const IssuePeekOverview = $_' -A 10

# Search for uses of IssuePeekOverview component
echo "\nUses of IssuePeekOverview component:"
rg '<IssuePeekOverview' -A 3 -g '!archived-issue-layout-root.tsx'

# Check if 'is_archived' is still used in the component
echo "\nChecking for 'is_archived' usage in IssuePeekOverview:"
rg 'is_archived' $(rg -l 'const IssuePeekOverview = $_')

Length of output: 8618

</Fragment>
</IssuesStoreContext.Provider>
);
Expand Down
40 changes: 17 additions & 23 deletions web/core/components/issues/peek-overview/root.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { FC, useEffect, useState, useMemo } from "react";
import { FC, useEffect, useState, useMemo, useCallback } from "react";
import { observer } from "mobx-react";
import { usePathname } from "next/navigation";
// plane types
Expand All @@ -21,12 +21,11 @@ import { EUserPermissions, EUserPermissionsLevel } from "@/plane-web/constants/u
interface IIssuePeekOverview {
embedIssue?: boolean;
embedRemoveCurrentNotification?: () => void;
is_archived?: boolean;
is_draft?: boolean;
}

export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
const { embedIssue = false, embedRemoveCurrentNotification, is_archived = false, is_draft = false } = props;
const { embedIssue = false, embedRemoveCurrentNotification, is_draft = false } = props;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

is_archived Prop Still in Use

The is_archived prop is still being referenced in multiple files, indicating incomplete removal. Please review and update all usages accordingly to prevent potential issues.

  • web/core/components/issues/peek-overview/root.tsx
  • web/core/components/issues/peek-overview/view.tsx
  • web/core/components/issues/issue-detail/root.tsx
  • web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/archives/issues/(detail)/[archivedIssueId]/page.tsx
🔗 Analysis chain

Verify the removal of is_archived prop

The removal of the is_archived prop aligns with the changes mentioned in the summary. This simplification is good, but please ensure that all uses of this prop throughout the codebase have been updated accordingly to prevent any potential bugs.

To verify this change, run the following command to check for any remaining uses of is_archived:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

rg "is_archived" --type tsx --type ts

Length of output: 65


Script:

#!/bin/bash
# Searching for 'is_archived' in .ts and .tsx files
rg "is_archived" --glob "*.ts" --glob "*.tsx"

Length of output: 2428

// router
const pathname = usePathname();
// store hook
Expand All @@ -47,26 +46,20 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
// state
const [error, setError] = useState(false);

const removeRoutePeekId = () => {
const removeRoutePeekId = useCallback(() => {
setPeekIssue(undefined);
if (embedIssue) embedRemoveCurrentNotification?.();
};
}, [embedIssue, embedRemoveCurrentNotification, setPeekIssue]);

const issueOperations: TIssueOperations = useMemo(
() => ({
fetch: async (workspaceSlug: string, projectId: string, issueId: string) => {
try {
setError(false);
await fetchIssue(
workspaceSlug,
projectId,
issueId,
is_archived ? "ARCHIVED" : is_draft ? "DRAFT" : "DEFAULT"
);
setError(false);
await fetchIssue(workspaceSlug, projectId, issueId, is_draft ? "DRAFT" : "DEFAULT");
} catch (error) {
setError(true);
console.error("Error fetching the parent issue");
console.error("Error fetching the parent issue", error);
}
},
update: async (workspaceSlug: string, projectId: string, issueId: string, data: Partial<TIssue>) => {
Expand Down Expand Up @@ -109,7 +102,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
});
removeRoutePeekId();
});
} catch (error) {
} catch {
setToast({
title: "Error!",
type: TOAST_TYPE.ERROR,
Expand All @@ -124,13 +117,14 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
},
archive: async (workspaceSlug: string, projectId: string, issueId: string) => {
try {
issues?.archiveIssue && (await issues.archiveIssue(workspaceSlug, projectId, issueId));
if (!issues?.archiveIssue) return;
await issues.archiveIssue(workspaceSlug, projectId, issueId);
captureIssueEvent({
eventName: ISSUE_ARCHIVED,
payload: { id: issueId, state: "SUCCESS", element: "Issue peek-overview" },
path: pathname,
});
} catch (error) {
} catch {
captureIssueEvent({
eventName: ISSUE_ARCHIVED,
payload: { id: issueId, state: "FAILED", element: "Issue peek-overview" },
Expand All @@ -151,7 +145,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
payload: { id: issueId, state: "SUCCESS", element: "Issue peek-overview" },
path: pathname,
});
} catch (error) {
} catch {
setToast({
type: TOAST_TYPE.ERROR,
title: "Error!",
Expand All @@ -177,7 +171,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
},
path: pathname,
});
} catch (error) {
} catch {
setToast({
type: TOAST_TYPE.ERROR,
title: "Error!",
Expand Down Expand Up @@ -206,7 +200,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
},
path: pathname,
});
} catch (error) {
} catch {
setToast({
type: TOAST_TYPE.ERROR,
title: "Error!",
Expand Down Expand Up @@ -248,7 +242,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
},
path: pathname,
});
} catch (error) {
} catch {
captureIssueEvent({
eventName: ISSUE_UPDATED,
payload: { state: "FAILED", element: "Issue peek-overview" },
Expand Down Expand Up @@ -311,7 +305,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
},
path: pathname,
});
} catch (error) {
} catch {
captureIssueEvent({
eventName: ISSUE_UPDATED,
payload: { id: issueId, state: "FAILED", element: "Issue peek-overview" },
Expand All @@ -324,7 +318,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
}
},
}),
[is_archived, is_draft, fetchIssue, issues, restoreIssue, captureIssueEvent, pathname]
[fetchIssue, is_draft, issues, fetchActivities, captureIssueEvent, pathname, removeRoutePeekId, restoreIssue]
);

useEffect(() => {
Expand All @@ -350,7 +344,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
issueId={peekIssue.issueId}
isLoading={getIsFetchingIssueDetails(peekIssue.issueId)}
isError={error}
is_archived={is_archived}
is_archived={!!peekIssue.isArchived}
disabled={!isEditable}
embedIssue={embedIssue}
embedRemoveCurrentNotification={embedRemoveCurrentNotification}
Expand Down
2 changes: 1 addition & 1 deletion web/core/components/issues/peek-overview/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const IssueView: FC<IIssueView> = observer((props) => {
// remove peek id
const removeRoutePeekId = () => {
setPeekIssue(undefined);
if (embedIssue) embedRemoveCurrentNotification && embedRemoveCurrentNotification();
if (embedIssue && embedRemoveCurrentNotification) embedRemoveCurrentNotification();
};

const isLocalDBIssueDescription = getIsLocalDBIssueDescription(issueId);
Expand Down
8 changes: 5 additions & 3 deletions web/core/hooks/use-issue-peek-overview-redirection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ const useIssuePeekOverviewRedirection = () => {
if (workspaceSlug && project_id && id && !getIsIssuePeeked(id) && !tempId) {
const issuePath = `/${workspaceSlug}/projects/${project_id}/${archived_at ? "archives/" : ""}issues/${id}`;

isMobile
? router.push(issuePath)
: setPeekIssue({ workspaceSlug, projectId: project_id, issueId: id, nestingLevel });
if (isMobile) {
router.push(issuePath);
} else {
setPeekIssue({ workspaceSlug, projectId: project_id, issueId: id, nestingLevel, isArchived: !!archived_at });
}
}
};

Expand Down
8 changes: 3 additions & 5 deletions web/core/store/issue/issue-details/issue.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface IIssueStoreActions {
workspaceSlug: string,
projectId: string,
issueId: string,
issueType?: "DEFAULT" | "DRAFT" | "ARCHIVED"
issueStatus?: "DEFAULT" | "DRAFT",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Unresolved references to "ARCHIVED" found.

  • web/core/constants/issue.ts: ARCHIVED = "ARCHIVED",
🔗 Analysis chain

LGTM! Verify impact on codebase.

The simplification of the issueStatus parameter aligns with the PR objective. This change removes the distinction between default and archived issues at the interface level, which should simplify issue handling.

Please run the following script to ensure that there are no remaining references to the "ARCHIVED" status in the codebase:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to "ARCHIVED" status
rg '"ARCHIVED"' --type ts

Length of output: 4764


Script:

#!/bin/bash
# Search for any remaining references to "ARCHIVED" status
rg '"ARCHIVED"' --type ts

Length of output: 80

) => Promise<TIssue>;
updateIssue: (workspaceSlug: string, projectId: string, issueId: string, data: Partial<TIssue>) => Promise<void>;
removeIssue: (workspaceSlug: string, projectId: string, issueId: string) => Promise<void>;
Expand Down Expand Up @@ -82,7 +82,7 @@ export class IssueStore implements IIssueStore {
});

// actions
fetchIssue = async (workspaceSlug: string, projectId: string, issueId: string, issueType = "DEFAULT") => {
fetchIssue = async (workspaceSlug: string, projectId: string, issueId: string, issueStatus = "DEFAULT") => {
const query = {
expand: "issue_reactions,issue_attachments,issue_link,parent",
};
Expand All @@ -99,9 +99,7 @@ export class IssueStore implements IIssueStore {
this.localDBIssueDescription = issueId;
}

if (issueType === "ARCHIVED")
issue = await this.issueArchiveService.retrieveArchivedIssue(workspaceSlug, projectId, issueId, query);
else if (issueType === "DRAFT")
if (issueStatus === "DRAFT")
issue = await this.issueDraftService.getDraftIssueById(workspaceSlug, projectId, issueId, query);
else issue = await this.issueService.retrieve(workspaceSlug, projectId, issueId, query);

Expand Down
5 changes: 3 additions & 2 deletions web/core/store/issue/issue-details/root.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export type TPeekIssue = {
projectId: string;
issueId: string;
nestingLevel?: number;
isArchived?: boolean;
};

export type TIssueRelationModal = {
Expand Down Expand Up @@ -251,8 +252,8 @@ export class IssueDetail implements IIssueDetail {
workspaceSlug: string,
projectId: string,
issueId: string,
issueType: "DEFAULT" | "ARCHIVED" | "DRAFT" = "DEFAULT"
) => this.issue.fetchIssue(workspaceSlug, projectId, issueId, issueType);
issueStatus: "DEFAULT" | "DRAFT" = "DEFAULT"
) => this.issue.fetchIssue(workspaceSlug, projectId, issueId, issueStatus);
Comment on lines +255 to +256
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Potential Issues: Incomplete fetchIssue Calls Identified

The following calls to fetchIssue are missing the issueStatus parameter:

  • web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/archives/issues/(detail)/[archivedIssueId])/page.tsx:32
  • web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/issues/(detail)/[issueId])/page.tsx:38
  • web/core/components/issues/issue-detail/root.tsx:86

Please update these calls to include the issueStatus argument as per the new method signature.

🔗 Analysis chain

LGTM: Updated fetchIssue method signature

The update to the fetchIssue method signature is a good change. Renaming issueType to issueStatus improves clarity, and removing "ARCHIVED" as a possible value aligns with the PR objective of merging default and archived issue details endpoints.

To ensure this change doesn't break existing code, please verify all calls to fetchIssue across the codebase. Run the following script to find all occurrences:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all calls to fetchIssue method
# Expected result: All calls should use "DEFAULT" or "DRAFT" as the last argument, or omit it entirely

rg -p 'fetchIssue\s*\([^)]*\)' --type ts

Length of output: 857

updateIssue = async (workspaceSlug: string, projectId: string, issueId: string, data: Partial<TIssue>) =>
this.issue.updateIssue(workspaceSlug, projectId, issueId, data);
removeIssue = async (workspaceSlug: string, projectId: string, issueId: string) =>
Expand Down