[WEB-1177] fix: sub-issues count mutation. (#4516)

* [WEB-1177] fix: sub-issues count mutation.

* chore: refactor sub_issues_count mutation logic.

* fix: build errors.
This commit is contained in:
Prateek Shourya 2024-05-21 17:14:41 +05:30 committed by GitHub
parent 8a960e269f
commit 709cd9dd6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 44 additions and 25 deletions

View File

@ -67,8 +67,9 @@ export const IssueBlock = observer((props: IssueBlockProps) => {
!getIsIssuePeeked(issue.id) &&
setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id, nestingLevel: nestingLevel });
const issue = issuesMap[issueId];
const subIssues = subIssuesStore.subIssuesByIssueId(issueId);
const issue = issuesMap[issueId];
const subIssuesCount = issue.sub_issues_count;
const { isMobile } = usePlatformOS();
useEffect(() => {
@ -97,8 +98,6 @@ export const IssueBlock = observer((props: IssueBlockProps) => {
const canEditIssueProperties = canEditProperties(issue.project_id);
const projectIdentifier = getProjectIdentifierById(issue.project_id);
// if sub issues have been fetched for the issue, use that for count or use issue's sub_issues_count
const subIssuesCount = subIssues ? subIssues.length : issue.sub_issues_count;
const paddingLeft = `${spacingLeft}px`;

View File

@ -2,10 +2,13 @@ import { useCallback, useMemo } from "react";
import xor from "lodash/xor";
import { observer } from "mobx-react";
import { useRouter } from "next/router";
// icons
import { CalendarCheck2, CalendarClock, Layers, Link, Paperclip } from "lucide-react";
// types
import { TIssue, IIssueDisplayProperties, TIssuePriorities } from "@plane/types";
// hooks
// ui
import { Tooltip } from "@plane/ui";
// components
import {
DateDropdown,
EstimateDropdown,
@ -15,23 +18,19 @@ import {
CycleDropdown,
StateDropdown,
} from "@/components/dropdowns";
// helpers
// types
// constants
import { ISSUE_UPDATED } from "@/constants/event-tracker";
import { EIssuesStoreType } from "@/constants/issue";
// helpers
import { cn } from "@/helpers/common.helper";
import { getDate, renderFormattedPayloadDate } from "@/helpers/date-time.helper";
import { shouldHighlightIssueDueDate } from "@/helpers/issue.helper";
// hooks
import { useEventTracker, useEstimate, useLabel, useIssues, useProjectState, useProject } from "@/hooks/store";
import { usePlatformOS } from "@/hooks/use-platform-os";
// components
// local components
import { IssuePropertyLabels } from "../properties/labels";
import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC";
// helpers
// types
// constants
export interface IIssueProperties {
issue: TIssue;
@ -64,6 +63,7 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
const currentLayout = `${activeLayout} layout`;
// derived values
const stateDetails = getStateById(issue.state_id);
const subIssueCount = issue.sub_issues_count;
const issueOperations = useMemo(
() => ({
@ -414,24 +414,24 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
<WithDisplayPropertiesHOC
displayProperties={displayProperties}
displayPropertyKey="sub_issue_count"
shouldRenderProperty={(properties) => !!properties.sub_issue_count && !!issue.sub_issues_count}
shouldRenderProperty={(properties) => !!properties.sub_issue_count && !!subIssueCount}
>
<Tooltip tooltipHeading="Sub-issues" tooltipContent={`${issue.sub_issues_count}`} isMobile={isMobile}>
<Tooltip tooltipHeading="Sub-issues" tooltipContent={`${subIssueCount}`} isMobile={isMobile}>
<div
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
if (issue.sub_issues_count) redirectToIssueDetail();
if (subIssueCount) redirectToIssueDetail();
}}
className={cn(
"flex h-5 flex-shrink-0 items-center justify-center gap-2 overflow-hidden rounded border-[0.5px] border-custom-border-300 px-2.5 py-1",
{
"hover:bg-custom-background-80 cursor-pointer": issue.sub_issues_count,
"hover:bg-custom-background-80 cursor-pointer": subIssueCount,
}
)}
>
<Layers className="h-3 w-3 flex-shrink-0" strokeWidth={2} />
<div className="text-xs">{issue.sub_issues_count}</div>
<div className="text-xs">{subIssueCount}</div>
</div>
</Tooltip>
</WithDisplayPropertiesHOC>

View File

@ -18,6 +18,8 @@ export const SpreadsheetSubIssueColumn: React.FC<Props> = observer((props: Props
const router = useRouter();
// hooks
const { workspaceSlug } = useAppRouter();
// derived values
const subIssueCount = issue.sub_issues_count;
const redirectToIssueDetail = () => {
router.push({
@ -30,15 +32,15 @@ export const SpreadsheetSubIssueColumn: React.FC<Props> = observer((props: Props
return (
<div
onClick={issue?.sub_issues_count ? redirectToIssueDetail : () => {}}
onClick={subIssueCount ? redirectToIssueDetail : () => {}}
className={cn(
"flex h-11 w-full items-center border-b-[0.5px] border-custom-border-200 px-2.5 py-1 text-xs hover:bg-custom-background-80",
{
"cursor-pointer": issue?.sub_issues_count,
"cursor-pointer": subIssueCount,
}
)}
>
{issue?.sub_issues_count} {issue?.sub_issues_count === 1 ? "sub-issue" : "sub-issues"}
{subIssueCount} {subIssueCount === 1 ? "sub-issue" : "sub-issues"}
</div>
);
});

View File

@ -170,7 +170,6 @@ const IssueRowDetails = observer((props: IssueRowDetailsProps) => {
const { subIssues: subIssuesStore, issue } = useIssueDetail();
const issueDetail = issue.getIssueById(issueId);
const subIssues = subIssuesStore.subIssuesByIssueId(issueId);
const paddingLeft = `${spacingLeft}px`;
@ -204,8 +203,7 @@ const IssueRowDetails = observer((props: IssueRowDetailsProps) => {
};
const disableUserActions = !canEditProperties(issueDetail.project_id);
// if sub issues have been fetched for the issue, use that for count or use issue's sub_issues_count
const subIssuesCount = subIssues ? subIssues.length : issueDetail.sub_issues_count;
const subIssuesCount = issueDetail.sub_issues_count;
return (
<>

View File

@ -59,6 +59,7 @@ export const IssueListItem: React.FC<ISubIssues> = observer((props) => {
undefined;
const subIssueHelpers = subIssueHelpersByIssueId(parentIssueId);
const subIssueCount = issue?.sub_issues_count || 0;
const handleIssuePeekOverview = (issue: TIssue) =>
workspaceSlug &&
@ -77,7 +78,7 @@ export const IssueListItem: React.FC<ISubIssues> = observer((props) => {
style={{ paddingLeft: `${spacingLeft}px` }}
>
<div className="h-[22px] w-[22px] flex-shrink-0">
{issue?.sub_issues_count > 0 && (
{subIssueCount > 0 && (
<>
{subIssueHelpers.preview_loader.includes(issue.id) ? (
<div className="flex h-full w-full cursor-not-allowed items-center justify-center rounded-sm bg-custom-background-80 transition-all">
@ -205,7 +206,7 @@ export const IssueListItem: React.FC<ISubIssues> = observer((props) => {
</div>
)}
{subIssueHelpers.issue_visibility.includes(issueId) && issue.sub_issues_count && issue.sub_issues_count > 0 && (
{subIssueHelpers.issue_visibility.includes(issueId) && subIssueCount > 0 && (
<IssueList
workspaceSlug={workspaceSlug}
projectId={issue.project_id}

View File

@ -174,6 +174,13 @@ export class IssueSubIssuesStore implements IIssueSubIssuesStore {
this.rootIssueDetailStore.rootIssueStore.issues.addIssue(subIssues);
// update sub-issues_count of the parent issue
set(
this.rootIssueDetailStore.rootIssueStore.issues.issuesMap,
[parentIssueId, "sub_issues_count"],
this.subIssues[parentIssueId].length
);
return;
} catch (error) {
throw error;
@ -270,6 +277,12 @@ export class IssueSubIssuesStore implements IIssueSubIssuesStore {
runInAction(() => {
pull(this.subIssues[parentIssueId], issueId);
// update sub-issues_count of the parent issue
set(
this.rootIssueDetailStore.rootIssueStore.issues.issuesMap,
[parentIssueId, "sub_issues_count"],
this.subIssues[parentIssueId].length
);
});
return;
@ -301,6 +314,12 @@ export class IssueSubIssuesStore implements IIssueSubIssuesStore {
runInAction(() => {
pull(this.subIssues[parentIssueId], issueId);
// update sub-issues_count of the parent issue
set(
this.rootIssueDetailStore.rootIssueStore.issues.issuesMap,
[parentIssueId, "sub_issues_count"],
this.subIssues[parentIssueId].length
);
});
return;