[WEB-5871] chore: added intake count for projects (#8497)
* chore: add intake_count in project list endpoint * chore: sidebar project navigation intake count added * fix: filter out closed intake issues in the count * chore: code refactor * chore: code refactor * fix: filter out deleted intake issues --------- Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia@plane.so>
This commit is contained in:
parent
ef5d481a19
commit
3a99ecf8f3
5 changed files with 76 additions and 7 deletions
|
|
@ -181,12 +181,19 @@ export const ProjectNavigation = observer(function ProjectNavigation(props: TPro
|
|||
const hasAccess = allowPermissions(item.access, EUserPermissionsLevel.PROJECT, workspaceSlug, project.id);
|
||||
if (!hasAccess) return null;
|
||||
|
||||
const shouldShowCount = item.key === "intake" && (project.intake_count ?? 0) > 0;
|
||||
|
||||
return (
|
||||
<Link key={item.key} href={item.href} onClick={handleProjectClick}>
|
||||
<SidebarNavItem isActive={!!isActive(item)}>
|
||||
<div className="flex items-center gap-1.5 py-[1px]">
|
||||
<item.icon className={`flex-shrink-0 size-4 ${item.name === "Intake" ? "stroke-1" : "stroke-[1.5]"}`} />
|
||||
<span className="text-11 font-medium">{t(item.i18n_key)}</span>
|
||||
<div className="flex items-center justify-between gap-1.5 py-[1px] w-full">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<item.icon
|
||||
className={`flex-shrink-0 size-4 ${item.name === "Intake" ? "stroke-1" : "stroke-[1.5]"}`}
|
||||
/>
|
||||
<span className="text-11 font-medium">{t(item.i18n_key)}</span>
|
||||
</div>
|
||||
{shouldShowCount && <span className="text-11 font-medium text-tertiary">{project.intake_count}</span>}
|
||||
</div>
|
||||
</SidebarNavItem>
|
||||
</Link>
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ export class InboxIssueStore implements IInboxIssueStore {
|
|||
const previousData: Partial<TInboxIssue> = {
|
||||
status: this.status,
|
||||
};
|
||||
const previousStatus = this.status;
|
||||
|
||||
try {
|
||||
if (!this.issue.id) return;
|
||||
|
|
@ -107,7 +108,24 @@ export class InboxIssueStore implements IInboxIssueStore {
|
|||
const inboxIssue = await this.inboxIssueService.update(this.workspaceSlug, this.projectId, this.issue.id, {
|
||||
status: status,
|
||||
});
|
||||
runInAction(() => set(this, "status", inboxIssue?.status));
|
||||
runInAction(() => {
|
||||
set(this, "status", inboxIssue?.status);
|
||||
|
||||
// Handle intake_count transitions
|
||||
if (previousStatus === EInboxIssueStatus.PENDING && inboxIssue.status !== EInboxIssueStatus.PENDING) {
|
||||
// Changed from PENDING to something else: decrement
|
||||
const currentCount = this.store.projectRoot.project.projectMap[this.projectId]?.intake_count ?? 0;
|
||||
set(
|
||||
this.store.projectRoot.project.projectMap,
|
||||
[this.projectId, "intake_count"],
|
||||
Math.max(0, currentCount - 1)
|
||||
);
|
||||
} else if (previousStatus !== EInboxIssueStatus.PENDING && inboxIssue.status === EInboxIssueStatus.PENDING) {
|
||||
// Changed from something else to PENDING: increment
|
||||
const currentCount = this.store.projectRoot.project.projectMap[this.projectId]?.intake_count ?? 0;
|
||||
set(this.store.projectRoot.project.projectMap, [this.projectId, "intake_count"], currentCount + 1);
|
||||
}
|
||||
});
|
||||
|
||||
// If issue accepted sync issue to local db
|
||||
if (status === EInboxIssueStatus.ACCEPTED) {
|
||||
|
|
@ -126,6 +144,7 @@ export class InboxIssueStore implements IInboxIssueStore {
|
|||
duplicate_to: this.duplicate_to,
|
||||
duplicate_issue_detail: this.duplicate_issue_detail,
|
||||
};
|
||||
const wasPending = this.status === EInboxIssueStatus.PENDING;
|
||||
try {
|
||||
if (!this.issue.id) return;
|
||||
const inboxIssue = await this.inboxIssueService.update(this.workspaceSlug, this.projectId, this.issue.id, {
|
||||
|
|
@ -136,6 +155,15 @@ export class InboxIssueStore implements IInboxIssueStore {
|
|||
set(this, "status", inboxIssue?.status);
|
||||
set(this, "duplicate_to", inboxIssue?.duplicate_to);
|
||||
set(this, "duplicate_issue_detail", inboxIssue?.duplicate_issue_detail);
|
||||
// Decrement intake_count if the issue was PENDING
|
||||
if (wasPending) {
|
||||
const currentCount = this.store.projectRoot.project.projectMap[this.projectId]?.intake_count ?? 0;
|
||||
set(
|
||||
this.store.projectRoot.project.projectMap,
|
||||
[this.projectId, "intake_count"],
|
||||
Math.max(0, currentCount - 1)
|
||||
);
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
runInAction(() => {
|
||||
|
|
@ -152,6 +180,7 @@ export class InboxIssueStore implements IInboxIssueStore {
|
|||
status: this.status,
|
||||
snoozed_till: this.snoozed_till,
|
||||
};
|
||||
const previousStatus = this.status;
|
||||
try {
|
||||
if (!this.issue.id) return;
|
||||
const inboxIssue = await this.inboxIssueService.update(this.workspaceSlug, this.projectId, this.issue.id, {
|
||||
|
|
@ -161,6 +190,18 @@ export class InboxIssueStore implements IInboxIssueStore {
|
|||
runInAction(() => {
|
||||
set(this, "status", inboxIssue?.status);
|
||||
set(this, "snoozed_till", inboxIssue?.snoozed_till);
|
||||
// Handle intake_count transitions
|
||||
if (previousStatus === EInboxIssueStatus.PENDING && inboxIssue.status === EInboxIssueStatus.SNOOZED) {
|
||||
const currentCount = this.store.projectRoot.project.projectMap[this.projectId]?.intake_count ?? 0;
|
||||
set(
|
||||
this.store.projectRoot.project.projectMap,
|
||||
[this.projectId, "intake_count"],
|
||||
Math.max(0, currentCount - 1)
|
||||
);
|
||||
} else if (previousStatus !== EInboxIssueStatus.PENDING && inboxIssue.status === EInboxIssueStatus.PENDING) {
|
||||
const currentCount = this.store.projectRoot.project.projectMap[this.projectId]?.intake_count ?? 0;
|
||||
set(this.store.projectRoot.project.projectMap, [this.projectId, "intake_count"], currentCount + 1);
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
runInAction(() => {
|
||||
|
|
|
|||
|
|
@ -473,6 +473,11 @@ export class ProjectInboxStore implements IProjectInboxStore {
|
|||
["inboxIssuePaginationInfo", "total_results"],
|
||||
(this.inboxIssuePaginationInfo?.total_results || 0) + 1
|
||||
);
|
||||
// Increment intake_count if the new issue is PENDING
|
||||
if (inboxIssueResponse.status === EInboxIssueStatus.PENDING) {
|
||||
const currentCount = this.store.projectRoot.project.projectMap[projectId]?.intake_count ?? 0;
|
||||
set(this.store.projectRoot.project.projectMap, [projectId, "intake_count"], currentCount + 1);
|
||||
}
|
||||
});
|
||||
return inboxIssueResponse;
|
||||
} catch (error) {
|
||||
|
|
@ -489,6 +494,7 @@ export class ProjectInboxStore implements IProjectInboxStore {
|
|||
*/
|
||||
deleteInboxIssue = async (workspaceSlug: string, projectId: string, inboxIssueId: string) => {
|
||||
const currentIssue = this.inboxIssues?.[inboxIssueId];
|
||||
const wasPending = currentIssue?.status === EInboxIssueStatus.PENDING;
|
||||
try {
|
||||
if (!currentIssue) return;
|
||||
await this.inboxIssueService.destroy(workspaceSlug, projectId, inboxIssueId).then(() => {
|
||||
|
|
@ -504,6 +510,11 @@ export class ProjectInboxStore implements IProjectInboxStore {
|
|||
["inboxIssueIds"],
|
||||
this.inboxIssueIds.filter((id) => id !== inboxIssueId)
|
||||
);
|
||||
// Decrement intake_count if the deleted issue was PENDING
|
||||
if (wasPending) {
|
||||
const currentCount = this.store.projectRoot.project.projectMap[projectId]?.intake_count ?? 0;
|
||||
set(this.store.projectRoot.project.projectMap, [projectId, "intake_count"], Math.max(0, currentCount - 1));
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue