diff --git a/apiserver/plane/app/views/inbox/base.py b/apiserver/plane/app/views/inbox/base.py index 304e7dce5..e08434a6d 100644 --- a/apiserver/plane/app/views/inbox/base.py +++ b/apiserver/plane/app/views/inbox/base.py @@ -429,9 +429,13 @@ class InboxIssueViewSet(BaseViewSet): if state is not None: issue.state = state issue.save() - inbox_issue = ( - InboxIssue.objects.select_related("issue") + InboxIssue.objects.filter( + inbox_id=inbox_id.id, + issue_id=serializer.data["id"], + project_id=project_id, + ) + .select_related("issue") .prefetch_related( "issue__labels", "issue__assignees", @@ -459,12 +463,7 @@ class InboxIssueViewSet(BaseViewSet): output_field=ArrayField(UUIDField()), ), ), - ) - .get( - inbox_id=inbox_id.id, - issue_id=serializer.data["id"], - project_id=project_id, - ) + ).first() ) serializer = InboxIssueDetailSerializer(inbox_issue).data return Response(serializer, status=status.HTTP_200_OK) diff --git a/web/components/inbox/content/inbox-issue-header.tsx b/web/components/inbox/content/inbox-issue-header.tsx index 41a56ef83..2e4c1afdd 100644 --- a/web/components/inbox/content/inbox-issue-header.tsx +++ b/web/components/inbox/content/inbox-issue-header.tsx @@ -60,11 +60,11 @@ export const InboxIssueActionsHeader: FC = observer((p const issue = inboxIssue?.issue; // derived values const isAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER; - const canMarkAsDuplicate = isAllowed && inboxIssue?.status === -2; + const canMarkAsDuplicate = isAllowed && (inboxIssue?.status === 0 || inboxIssue?.status === -2); const canMarkAsAccepted = isAllowed && (inboxIssue?.status === 0 || inboxIssue?.status === -2); - const canMarkAsDeclined = isAllowed && inboxIssue?.status === -2; + const canMarkAsDeclined = isAllowed && (inboxIssue?.status === 0 || inboxIssue?.status === -2); const canDelete = isAllowed || inboxIssue?.created_by === currentUser?.id; - const isAcceptedOrDeclined = inboxIssue?.status ? [-1, 1].includes(inboxIssue.status) : undefined; + const isAcceptedOrDeclined = inboxIssue?.status ? [-1, 1, 2].includes(inboxIssue.status) : undefined; const currentInboxIssueId = inboxIssue?.issue?.id; diff --git a/web/components/inbox/modals/create-edit-modal/create-root.tsx b/web/components/inbox/modals/create-edit-modal/create-root.tsx index 32c192f40..d2a0d1a2f 100644 --- a/web/components/inbox/modals/create-edit-modal/create-root.tsx +++ b/web/components/inbox/modals/create-edit-modal/create-root.tsx @@ -1,4 +1,4 @@ -import { FC, useCallback, useRef, useState } from "react"; +import { FC, FormEvent, useCallback, useRef, useState } from "react"; import { observer } from "mobx-react"; import { useRouter } from "next/router"; import { EditorRefApi } from "@plane/rich-text-editor"; @@ -59,7 +59,8 @@ export const InboxIssueCreateRoot: FC = observer((props) [formData] ); - const handleFormSubmit = async () => { + const handleFormSubmit = async (event: FormEvent) => { + event.preventDefault(); const payload: Partial = { name: formData.name || "", description_html: formData.description_html || "

", @@ -117,7 +118,7 @@ export const InboxIssueCreateRoot: FC = observer((props) if (!workspaceSlug || !projectId || !workspaceId) return <>; return ( -
+
= observer((props) -
- + ); }); diff --git a/web/components/inbox/modals/create-edit-modal/issue-title.tsx b/web/components/inbox/modals/create-edit-modal/issue-title.tsx index 8b1df70c6..27361b1f4 100644 --- a/web/components/inbox/modals/create-edit-modal/issue-title.tsx +++ b/web/components/inbox/modals/create-edit-modal/issue-title.tsx @@ -21,6 +21,8 @@ export const InboxIssueTitle: FC = observer((props) => { onChange={(e) => handleData("name", e.target.value)} placeholder="Title" className="w-full resize-none text-xl" + maxLength={255} + required /> ); diff --git a/web/components/issues/description-input.tsx b/web/components/issues/description-input.tsx index 80cd9a34a..0b9af36fa 100644 --- a/web/components/issues/description-input.tsx +++ b/web/components/issues/description-input.tsx @@ -107,7 +107,7 @@ export const IssueDescriptionInput: FC = observer((p ) : ( ) } diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/inbox/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/inbox/index.tsx index 350f51f33..f32adaf5d 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/inbox/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/inbox/index.tsx @@ -25,6 +25,11 @@ const ProjectInboxPage: NextPageWithLayout = observer(() => { const { currentProjectDetails } = useProject(); const { currentTab, handleCurrentTab } = useProjectInbox(); + useEffect(() => { + if (navigationTab && currentTab != navigationTab) + handleCurrentTab(navigationTab === "open" ? EInboxIssueCurrentTab.OPEN : EInboxIssueCurrentTab.CLOSED); + }, [currentTab, navigationTab, handleCurrentTab]); + // No access to inbox if (currentProjectDetails?.inbox_view === false) return ( @@ -39,11 +44,6 @@ const ProjectInboxPage: NextPageWithLayout = observer(() => { // derived values const pageTitle = currentProjectDetails?.name ? `${currentProjectDetails?.name} - Inbox` : "Plane - Inbox"; - useEffect(() => { - if (navigationTab && currentTab != navigationTab) - handleCurrentTab(navigationTab === "open" ? EInboxIssueCurrentTab.OPEN : EInboxIssueCurrentTab.CLOSED); - }, [currentTab, navigationTab, handleCurrentTab]); - if (!workspaceSlug || !projectId) return <>; return ( diff --git a/web/store/inbox/inbox-issue.store.ts b/web/store/inbox/inbox-issue.store.ts index 4afa25bbd..a76e58ab6 100644 --- a/web/store/inbox/inbox-issue.store.ts +++ b/web/store/inbox/inbox-issue.store.ts @@ -97,23 +97,24 @@ export class InboxIssueStore implements IInboxIssueStore { const previousData: Partial = { status: this.status, duplicate_to: this.duplicate_to, + duplicate_issue_detail: this.duplicate_issue_detail, }; - try { if (!this.issue.id) return; - const issueResponse = await this.inboxIssueService.update(this.workspaceSlug, this.projectId, this.issue.id, { + const inboxIssue = await this.inboxIssueService.update(this.workspaceSlug, this.projectId, this.issue.id, { status: inboxStatus, duplicate_to: issueId, }); runInAction(() => { - this.status = issueResponse.status; - this.duplicate_to = issueResponse.duplicate_to; - this.duplicate_issue_detail = issueResponse.duplicate_issue_detail; + set(this, "status", inboxIssue?.status); + set(this, "duplicate_to", inboxIssue?.duplicate_to); + set(this, "duplicate_issue_detail", inboxIssue?.duplicate_issue_detail); }); } catch { runInAction(() => { set(this, "status", previousData.status); set(this, "duplicate_to", previousData.duplicate_to); + set(this, "duplicate_issue_detail", previousData.duplicate_issue_detail); }); } }; @@ -124,16 +125,15 @@ export class InboxIssueStore implements IInboxIssueStore { status: this.status, snoozed_till: this.snoozed_till, }; - try { if (!this.issue.id) return; - const issueResponse = await this.inboxIssueService.update(this.workspaceSlug, this.projectId, this.issue.id, { + const inboxIssue = await this.inboxIssueService.update(this.workspaceSlug, this.projectId, this.issue.id, { status: inboxStatus, snoozed_till: new Date(date), }); runInAction(() => { - this.status = issueResponse?.status; - this.snoozed_till = issueResponse?.snoozed_till ? new Date(issueResponse.snoozed_till) : undefined; + set(this, "status", inboxIssue?.status); + set(this, "snoozed_till", inboxIssue?.snoozed_till); }); } catch { runInAction(() => { diff --git a/web/store/inbox/project-inbox.store.ts b/web/store/inbox/project-inbox.store.ts index 59ba84ef4..1ecf9a033 100644 --- a/web/store/inbox/project-inbox.store.ts +++ b/web/store/inbox/project-inbox.store.ts @@ -355,6 +355,7 @@ export class ProjectInboxStore implements IProjectInboxStore { if (inboxIssue && issueId) { runInAction(() => { set(this.inboxIssues, [issueId], new InboxIssueStore(workspaceSlug, projectId, inboxIssue, this.store)); + set(this, "loader", undefined); }); // fetching reactions await this.store.issue.issueDetail.fetchReactions(workspaceSlug, projectId, issueId); @@ -362,7 +363,6 @@ export class ProjectInboxStore implements IProjectInboxStore { await this.store.issue.issueDetail.fetchActivities(workspaceSlug, projectId, issueId); // fetching comments await this.store.issue.issueDetail.fetchComments(workspaceSlug, projectId, issueId); - this.loader = undefined; } return inboxIssue; } catch (error) {