forked from github/plane
[WEB-1301] chore: handled issues count in project, module, and cycle issues (#4538)
* chore: handled issues count in project, module, and cycle issues * chore: changed the typo from getIssuesCount to issuesCount
This commit is contained in:
parent
e2ac60e259
commit
4feec35773
@ -70,6 +70,7 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
|||||||
// store hooks
|
// store hooks
|
||||||
const {
|
const {
|
||||||
issuesFilter: { issueFilters, updateFilters },
|
issuesFilter: { issueFilters, updateFilters },
|
||||||
|
issues: { issuesCount },
|
||||||
} = useIssues(EIssuesStoreType.CYCLE);
|
} = useIssues(EIssuesStoreType.CYCLE);
|
||||||
const { currentProjectCycleIds, getCycleById } = useCycle();
|
const { currentProjectCycleIds, getCycleById } = useCycle();
|
||||||
const { toggleCreateIssueModal } = useCommandPalette();
|
const { toggleCreateIssueModal } = useCommandPalette();
|
||||||
@ -145,12 +146,6 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
|||||||
const canUserCreateIssue =
|
const canUserCreateIssue =
|
||||||
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
||||||
|
|
||||||
const issueCount = cycleDetails
|
|
||||||
? !issueFilters?.displayFilters?.sub_issue && cycleDetails?.sub_issues
|
|
||||||
? cycleDetails.total_issues - cycleDetails?.sub_issues
|
|
||||||
: cycleDetails.total_issues
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
const isFiltersApplied = calculateTotalFilters(issueFilters?.filters ?? {}) !== 0;
|
const isFiltersApplied = calculateTotalFilters(issueFilters?.filters ?? {}) !== 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -209,16 +204,16 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
|||||||
<ContrastIcon className="h-3 w-3" />
|
<ContrastIcon className="h-3 w-3" />
|
||||||
<div className="flex w-auto max-w-[70px] items-center gap-2 truncate sm:max-w-[200px]">
|
<div className="flex w-auto max-w-[70px] items-center gap-2 truncate sm:max-w-[200px]">
|
||||||
<p className="truncate">{cycleDetails?.name && cycleDetails.name}</p>
|
<p className="truncate">{cycleDetails?.name && cycleDetails.name}</p>
|
||||||
{issueCount && issueCount > 0 ? (
|
{issuesCount && issuesCount > 0 ? (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
isMobile={isMobile}
|
isMobile={isMobile}
|
||||||
tooltipContent={`There are ${issueCount} ${
|
tooltipContent={`There are ${issuesCount} ${
|
||||||
issueCount > 1 ? "issues" : "issue"
|
issuesCount > 1 ? "issues" : "issue"
|
||||||
} in this cycle`}
|
} in this cycle`}
|
||||||
position="bottom"
|
position="bottom"
|
||||||
>
|
>
|
||||||
<span className="flex flex-shrink-0 cursor-default items-center justify-center rounded-xl bg-custom-primary-100/20 px-2 text-center text-xs font-semibold text-custom-primary-100">
|
<span className="flex flex-shrink-0 cursor-default items-center justify-center rounded-xl bg-custom-primary-100/20 px-2 text-center text-xs font-semibold text-custom-primary-100">
|
||||||
{issueCount}
|
{issuesCount}
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -71,6 +71,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
|||||||
// store hooks
|
// store hooks
|
||||||
const {
|
const {
|
||||||
issuesFilter: { issueFilters },
|
issuesFilter: { issueFilters },
|
||||||
|
issues: { issuesCount },
|
||||||
} = useIssues(EIssuesStoreType.MODULE);
|
} = useIssues(EIssuesStoreType.MODULE);
|
||||||
const { updateFilters } = useIssuesActions(EIssuesStoreType.MODULE);
|
const { updateFilters } = useIssuesActions(EIssuesStoreType.MODULE);
|
||||||
const { projectModuleIds, getModuleById } = useModule();
|
const { projectModuleIds, getModuleById } = useModule();
|
||||||
@ -145,12 +146,6 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
|||||||
const canUserCreateIssue =
|
const canUserCreateIssue =
|
||||||
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
||||||
|
|
||||||
const issueCount = moduleDetails
|
|
||||||
? !issueFilters?.displayFilters?.sub_issue && moduleDetails.sub_issues
|
|
||||||
? moduleDetails.total_issues - moduleDetails.sub_issues
|
|
||||||
: moduleDetails.total_issues
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
const isFiltersApplied = calculateTotalFilters(issueFilters?.filters ?? {}) !== 0;
|
const isFiltersApplied = calculateTotalFilters(issueFilters?.filters ?? {}) !== 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -209,16 +204,16 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
|||||||
<DiceIcon className="h-3 w-3" />
|
<DiceIcon className="h-3 w-3" />
|
||||||
<div className="flex w-auto max-w-[70px] items-center gap-2 truncate sm:max-w-[200px]">
|
<div className="flex w-auto max-w-[70px] items-center gap-2 truncate sm:max-w-[200px]">
|
||||||
<p className="truncate">{moduleDetails?.name && moduleDetails.name}</p>
|
<p className="truncate">{moduleDetails?.name && moduleDetails.name}</p>
|
||||||
{issueCount && issueCount > 0 ? (
|
{issuesCount && issuesCount > 0 ? (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
isMobile={isMobile}
|
isMobile={isMobile}
|
||||||
tooltipContent={`There are ${issueCount} ${
|
tooltipContent={`There are ${issuesCount} ${
|
||||||
issueCount > 1 ? "issues" : "issue"
|
issuesCount > 1 ? "issues" : "issue"
|
||||||
} in this module`}
|
} in this module`}
|
||||||
position="bottom"
|
position="bottom"
|
||||||
>
|
>
|
||||||
<span className="flex flex-shrink-0 cursor-default items-center justify-center rounded-xl bg-custom-primary-100/20 px-2 text-center text-xs font-semibold text-custom-primary-100">
|
<span className="flex flex-shrink-0 cursor-default items-center justify-center rounded-xl bg-custom-primary-100/20 px-2 text-center text-xs font-semibold text-custom-primary-100">
|
||||||
{issueCount}
|
{issuesCount}
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -43,6 +43,7 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
|||||||
} = useMember();
|
} = useMember();
|
||||||
const {
|
const {
|
||||||
issuesFilter: { issueFilters, updateFilters },
|
issuesFilter: { issueFilters, updateFilters },
|
||||||
|
issues: { issuesCount },
|
||||||
} = useIssues(EIssuesStoreType.PROJECT);
|
} = useIssues(EIssuesStoreType.PROJECT);
|
||||||
const { toggleCreateIssueModal } = useCommandPalette();
|
const { toggleCreateIssueModal } = useCommandPalette();
|
||||||
const { setTrackElement } = useEventTracker();
|
const { setTrackElement } = useEventTracker();
|
||||||
@ -105,12 +106,6 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
|||||||
const canUserCreateIssue =
|
const canUserCreateIssue =
|
||||||
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
||||||
|
|
||||||
const issueCount = currentProjectDetails
|
|
||||||
? !issueFilters?.displayFilters?.sub_issue && currentProjectDetails?.sub_issues
|
|
||||||
? currentProjectDetails?.total_issues - currentProjectDetails?.sub_issues
|
|
||||||
: currentProjectDetails?.total_issues
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
const isFiltersApplied = calculateTotalFilters(issueFilters?.filters ?? {}) !== 0;
|
const isFiltersApplied = calculateTotalFilters(issueFilters?.filters ?? {}) !== 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -153,14 +148,14 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
|||||||
link={<BreadcrumbLink label="Issues" icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} />}
|
link={<BreadcrumbLink label="Issues" icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} />}
|
||||||
/>
|
/>
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
{issueCount && issueCount > 0 ? (
|
{issuesCount && issuesCount > 0 ? (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
isMobile={isMobile}
|
isMobile={isMobile}
|
||||||
tooltipContent={`There are ${issueCount} ${issueCount > 1 ? "issues" : "issue"} in this project`}
|
tooltipContent={`There are ${issuesCount} ${issuesCount > 1 ? "issues" : "issue"} in this project`}
|
||||||
position="bottom"
|
position="bottom"
|
||||||
>
|
>
|
||||||
<span className="cursor-default flex items-center text-center justify-center px-2.5 py-0.5 flex-shrink-0 bg-custom-primary-100/20 text-custom-primary-100 text-xs font-semibold rounded-xl">
|
<span className="cursor-default flex items-center text-center justify-center px-2.5 py-0.5 flex-shrink-0 bg-custom-primary-100/20 text-custom-primary-100 text-xs font-semibold rounded-xl">
|
||||||
{issueCount}
|
{issuesCount}
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -2,12 +2,15 @@ import differenceInCalendarDays from "date-fns/differenceInCalendarDays";
|
|||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
// types
|
// types
|
||||||
import {
|
import {
|
||||||
|
TGroupedIssues,
|
||||||
TIssue,
|
TIssue,
|
||||||
TIssueGroupByOptions,
|
TIssueGroupByOptions,
|
||||||
TIssueLayouts,
|
TIssueLayouts,
|
||||||
TIssueOrderByOptions,
|
TIssueOrderByOptions,
|
||||||
TIssueParams,
|
TIssueParams,
|
||||||
TStateGroups,
|
TStateGroups,
|
||||||
|
TSubGroupedIssues,
|
||||||
|
TUnGroupedIssues,
|
||||||
} from "@plane/types";
|
} from "@plane/types";
|
||||||
import { IGanttBlock } from "@/components/gantt-chart";
|
import { IGanttBlock } from "@/components/gantt-chart";
|
||||||
// constants
|
// constants
|
||||||
@ -211,3 +214,43 @@ export const getDescriptionPlaceholder = (isFocused: boolean, description: strin
|
|||||||
if (!isDescriptionEmpty || isFocused) return "Press '/' for commands...";
|
if (!isDescriptionEmpty || isFocused) return "Press '/' for commands...";
|
||||||
else return "Click to add description";
|
else return "Click to add description";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const issueCountBasedOnFilters = (
|
||||||
|
issueIds: TUnGroupedIssues | TGroupedIssues | TSubGroupedIssues,
|
||||||
|
layout: TIssueLayouts,
|
||||||
|
groupBy: string | undefined,
|
||||||
|
subGroupBy: string | undefined
|
||||||
|
): number => {
|
||||||
|
let issuesCount = 0;
|
||||||
|
if (!layout) return issuesCount;
|
||||||
|
|
||||||
|
if (["spreadsheet", "gantt_chart"].includes(layout)) {
|
||||||
|
issuesCount = (issueIds as TUnGroupedIssues)?.length;
|
||||||
|
} else if (layout === "calendar") {
|
||||||
|
Object.keys(issueIds || {}).map((groupId) => {
|
||||||
|
issuesCount += (issueIds as TGroupedIssues)?.[groupId]?.length;
|
||||||
|
});
|
||||||
|
} else if (layout === "list") {
|
||||||
|
if (groupBy) {
|
||||||
|
Object.keys(issueIds || {}).map((groupId) => {
|
||||||
|
issuesCount += (issueIds as TGroupedIssues)?.[groupId]?.length;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
issuesCount = (issueIds as TUnGroupedIssues)?.length;
|
||||||
|
}
|
||||||
|
} else if (layout === "kanban") {
|
||||||
|
if (groupBy && subGroupBy) {
|
||||||
|
Object.keys(issueIds || {}).map((groupId) => {
|
||||||
|
Object.keys((issueIds as TSubGroupedIssues)?.[groupId] || {}).map((subGroupId) => {
|
||||||
|
issuesCount += (issueIds as TSubGroupedIssues)?.[groupId]?.[subGroupId]?.length || 0;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (groupBy) {
|
||||||
|
Object.keys(issueIds || {}).map((groupId) => {
|
||||||
|
issuesCount += (issueIds as TGroupedIssues)?.[groupId]?.length;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return issuesCount;
|
||||||
|
};
|
||||||
|
@ -6,6 +6,8 @@ import update from "lodash/update";
|
|||||||
import { action, observable, makeObservable, computed, runInAction } from "mobx";
|
import { action, observable, makeObservable, computed, runInAction } from "mobx";
|
||||||
// types
|
// types
|
||||||
import { TIssue, TSubGroupedIssues, TGroupedIssues, TLoader, TUnGroupedIssues, ViewFlags } from "@plane/types";
|
import { TIssue, TSubGroupedIssues, TGroupedIssues, TLoader, TUnGroupedIssues, ViewFlags } from "@plane/types";
|
||||||
|
// helpers
|
||||||
|
import { issueCountBasedOnFilters } from "@/helpers/issue.helper";
|
||||||
// services
|
// services
|
||||||
import { CycleService } from "@/services/cycle.service";
|
import { CycleService } from "@/services/cycle.service";
|
||||||
import { IssueService } from "@/services/issue";
|
import { IssueService } from "@/services/issue";
|
||||||
@ -21,6 +23,7 @@ export interface ICycleIssues {
|
|||||||
issues: { [cycle_id: string]: string[] };
|
issues: { [cycle_id: string]: string[] };
|
||||||
viewFlags: ViewFlags;
|
viewFlags: ViewFlags;
|
||||||
// computed
|
// computed
|
||||||
|
issuesCount: number;
|
||||||
groupedIssueIds: TGroupedIssues | TSubGroupedIssues | TUnGroupedIssues | undefined;
|
groupedIssueIds: TGroupedIssues | TSubGroupedIssues | TUnGroupedIssues | undefined;
|
||||||
// actions
|
// actions
|
||||||
getIssueIds: (groupId?: string, subGroupId?: string) => string[] | undefined;
|
getIssueIds: (groupId?: string, subGroupId?: string) => string[] | undefined;
|
||||||
@ -60,7 +63,7 @@ export interface ICycleIssues {
|
|||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
removeIssueFromCycle: (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) => Promise<void>;
|
removeIssueFromCycle: (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) => Promise<void>;
|
||||||
addCycleToIssue: (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) => Promise<void>;
|
addCycleToIssue: (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) => Promise<void>;
|
||||||
removeCycleFromIssue: (workspaceSlug: string, projectId: string, issueId: string) => Promise<void>
|
removeCycleFromIssue: (workspaceSlug: string, projectId: string, issueId: string) => Promise<void>;
|
||||||
transferIssuesFromCycle: (
|
transferIssuesFromCycle: (
|
||||||
workspaceSlug: string,
|
workspaceSlug: string,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
@ -93,6 +96,7 @@ export class CycleIssues extends IssueHelperStore implements ICycleIssues {
|
|||||||
loader: observable.ref,
|
loader: observable.ref,
|
||||||
issues: observable,
|
issues: observable,
|
||||||
// computed
|
// computed
|
||||||
|
issuesCount: computed,
|
||||||
groupedIssueIds: computed,
|
groupedIssueIds: computed,
|
||||||
// action
|
// action
|
||||||
fetchIssues: action,
|
fetchIssues: action,
|
||||||
@ -113,6 +117,22 @@ export class CycleIssues extends IssueHelperStore implements ICycleIssues {
|
|||||||
this.cycleService = new CycleService();
|
this.cycleService = new CycleService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get issuesCount() {
|
||||||
|
let issuesCount = 0;
|
||||||
|
|
||||||
|
const displayFilters = this.rootStore?.cycleIssuesFilter?.issueFilters?.displayFilters;
|
||||||
|
const groupedIssueIds = this.groupedIssueIds;
|
||||||
|
if (!displayFilters || !groupedIssueIds) return issuesCount;
|
||||||
|
|
||||||
|
const layout = displayFilters?.layout || undefined;
|
||||||
|
const groupBy = displayFilters?.group_by || undefined;
|
||||||
|
const subGroupBy = displayFilters?.sub_group_by || undefined;
|
||||||
|
|
||||||
|
if (!layout) return issuesCount;
|
||||||
|
issuesCount = issueCountBasedOnFilters(groupedIssueIds, layout, groupBy, subGroupBy);
|
||||||
|
return issuesCount;
|
||||||
|
}
|
||||||
|
|
||||||
get groupedIssueIds() {
|
get groupedIssueIds() {
|
||||||
const cycleId = this.rootIssueStore?.cycleId;
|
const cycleId = this.rootIssueStore?.cycleId;
|
||||||
if (!cycleId) return undefined;
|
if (!cycleId) return undefined;
|
||||||
@ -343,7 +363,7 @@ export class CycleIssues extends IssueHelperStore implements ICycleIssues {
|
|||||||
*/
|
*/
|
||||||
removeCycleFromIssue = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
removeCycleFromIssue = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
||||||
const issueCycleId = this.rootIssueStore.issues.getIssueById(issueId)?.cycle_id;
|
const issueCycleId = this.rootIssueStore.issues.getIssueById(issueId)?.cycle_id;
|
||||||
if(!issueCycleId) return;
|
if (!issueCycleId) return;
|
||||||
try {
|
try {
|
||||||
// perform optimistic update, update store
|
// perform optimistic update, update store
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
|
@ -7,6 +7,8 @@ import update from "lodash/update";
|
|||||||
import { action, observable, makeObservable, computed, runInAction } from "mobx";
|
import { action, observable, makeObservable, computed, runInAction } from "mobx";
|
||||||
// types
|
// types
|
||||||
import { TIssue, TLoader, TGroupedIssues, TSubGroupedIssues, TUnGroupedIssues, ViewFlags } from "@plane/types";
|
import { TIssue, TLoader, TGroupedIssues, TSubGroupedIssues, TUnGroupedIssues, ViewFlags } from "@plane/types";
|
||||||
|
// helpers
|
||||||
|
import { issueCountBasedOnFilters } from "@/helpers/issue.helper";
|
||||||
// services
|
// services
|
||||||
import { IssueService } from "@/services/issue";
|
import { IssueService } from "@/services/issue";
|
||||||
import { ModuleService } from "@/services/module.service";
|
import { ModuleService } from "@/services/module.service";
|
||||||
@ -21,6 +23,7 @@ export interface IModuleIssues {
|
|||||||
issues: { [module_id: string]: string[] };
|
issues: { [module_id: string]: string[] };
|
||||||
viewFlags: ViewFlags;
|
viewFlags: ViewFlags;
|
||||||
// computed
|
// computed
|
||||||
|
issuesCount: number;
|
||||||
groupedIssueIds: TGroupedIssues | TSubGroupedIssues | TUnGroupedIssues | undefined;
|
groupedIssueIds: TGroupedIssues | TSubGroupedIssues | TUnGroupedIssues | undefined;
|
||||||
// actions
|
// actions
|
||||||
getIssueIds: (groupId?: string, subGroupId?: string) => string[] | undefined;
|
getIssueIds: (groupId?: string, subGroupId?: string) => string[] | undefined;
|
||||||
@ -95,6 +98,7 @@ export class ModuleIssues extends IssueHelperStore implements IModuleIssues {
|
|||||||
loader: observable.ref,
|
loader: observable.ref,
|
||||||
issues: observable,
|
issues: observable,
|
||||||
// computed
|
// computed
|
||||||
|
issuesCount: computed,
|
||||||
groupedIssueIds: computed,
|
groupedIssueIds: computed,
|
||||||
// action
|
// action
|
||||||
fetchIssues: action,
|
fetchIssues: action,
|
||||||
@ -113,6 +117,22 @@ export class ModuleIssues extends IssueHelperStore implements IModuleIssues {
|
|||||||
this.moduleService = new ModuleService();
|
this.moduleService = new ModuleService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get issuesCount() {
|
||||||
|
let issuesCount = 0;
|
||||||
|
|
||||||
|
const displayFilters = this.rootIssueStore?.moduleIssuesFilter?.issueFilters?.displayFilters;
|
||||||
|
const groupedIssueIds = this.groupedIssueIds;
|
||||||
|
if (!displayFilters || !groupedIssueIds) return issuesCount;
|
||||||
|
|
||||||
|
const layout = displayFilters?.layout || undefined;
|
||||||
|
const groupBy = displayFilters?.group_by || undefined;
|
||||||
|
const subGroupBy = displayFilters?.sub_group_by || undefined;
|
||||||
|
|
||||||
|
if (!layout) return issuesCount;
|
||||||
|
issuesCount = issueCountBasedOnFilters(groupedIssueIds, layout, groupBy, subGroupBy);
|
||||||
|
return issuesCount;
|
||||||
|
}
|
||||||
|
|
||||||
get groupedIssueIds() {
|
get groupedIssueIds() {
|
||||||
const moduleId = this.rootIssueStore?.moduleId;
|
const moduleId = this.rootIssueStore?.moduleId;
|
||||||
if (!moduleId) return undefined;
|
if (!moduleId) return undefined;
|
||||||
@ -404,7 +424,7 @@ export class ModuleIssues extends IssueHelperStore implements IModuleIssues {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if(originalModuleIds){
|
if (originalModuleIds) {
|
||||||
// update the root issue map with the new module ids
|
// update the root issue map with the new module ids
|
||||||
let currentModuleIds = concat([...originalModuleIds], addModuleIds);
|
let currentModuleIds = concat([...originalModuleIds], addModuleIds);
|
||||||
currentModuleIds = pull(currentModuleIds, ...removeModuleIds);
|
currentModuleIds = pull(currentModuleIds, ...removeModuleIds);
|
||||||
@ -420,7 +440,6 @@ export class ModuleIssues extends IssueHelperStore implements IModuleIssues {
|
|||||||
if (!isEmpty(removeModuleIds)) {
|
if (!isEmpty(removeModuleIds)) {
|
||||||
await this.moduleService.removeModulesFromIssueBulk(workspaceSlug, projectId, issueId, removeModuleIds);
|
await this.moduleService.removeModulesFromIssueBulk(workspaceSlug, projectId, issueId, removeModuleIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// revert the issue back to its original module ids
|
// revert the issue back to its original module ids
|
||||||
set(this.rootStore.issues.issuesMap, [issueId, "module_ids"], originalModuleIds);
|
set(this.rootStore.issues.issuesMap, [issueId, "module_ids"], originalModuleIds);
|
||||||
|
@ -5,6 +5,8 @@ import update from "lodash/update";
|
|||||||
import { action, makeObservable, observable, runInAction, computed } from "mobx";
|
import { action, makeObservable, observable, runInAction, computed } from "mobx";
|
||||||
// types
|
// types
|
||||||
import { TIssue, TGroupedIssues, TSubGroupedIssues, TLoader, TUnGroupedIssues, ViewFlags } from "@plane/types";
|
import { TIssue, TGroupedIssues, TSubGroupedIssues, TLoader, TUnGroupedIssues, ViewFlags } from "@plane/types";
|
||||||
|
// helpers
|
||||||
|
import { issueCountBasedOnFilters } from "@/helpers/issue.helper";
|
||||||
// base class
|
// base class
|
||||||
import { IssueService, IssueArchiveService } from "@/services/issue";
|
import { IssueService, IssueArchiveService } from "@/services/issue";
|
||||||
import { IssueHelperStore } from "../helpers/issue-helper.store";
|
import { IssueHelperStore } from "../helpers/issue-helper.store";
|
||||||
@ -17,6 +19,7 @@ export interface IProjectIssues {
|
|||||||
issues: Record<string, string[]>; // Record of project_id as key and issue_ids as value
|
issues: Record<string, string[]>; // Record of project_id as key and issue_ids as value
|
||||||
viewFlags: ViewFlags;
|
viewFlags: ViewFlags;
|
||||||
// computed
|
// computed
|
||||||
|
issuesCount: number;
|
||||||
groupedIssueIds: TGroupedIssues | TSubGroupedIssues | TUnGroupedIssues | undefined;
|
groupedIssueIds: TGroupedIssues | TSubGroupedIssues | TUnGroupedIssues | undefined;
|
||||||
getIssueIds: (groupId?: string, subGroupId?: string) => string[] | undefined;
|
getIssueIds: (groupId?: string, subGroupId?: string) => string[] | undefined;
|
||||||
// action
|
// action
|
||||||
@ -51,6 +54,7 @@ export class ProjectIssues extends IssueHelperStore implements IProjectIssues {
|
|||||||
loader: observable.ref,
|
loader: observable.ref,
|
||||||
issues: observable,
|
issues: observable,
|
||||||
// computed
|
// computed
|
||||||
|
issuesCount: computed,
|
||||||
groupedIssueIds: computed,
|
groupedIssueIds: computed,
|
||||||
// action
|
// action
|
||||||
fetchIssues: action,
|
fetchIssues: action,
|
||||||
@ -68,6 +72,22 @@ export class ProjectIssues extends IssueHelperStore implements IProjectIssues {
|
|||||||
this.issueArchiveService = new IssueArchiveService();
|
this.issueArchiveService = new IssueArchiveService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get issuesCount() {
|
||||||
|
let issuesCount = 0;
|
||||||
|
|
||||||
|
const displayFilters = this.rootStore?.projectIssuesFilter?.issueFilters?.displayFilters;
|
||||||
|
const groupedIssueIds = this.groupedIssueIds;
|
||||||
|
if (!displayFilters || !groupedIssueIds) return issuesCount;
|
||||||
|
|
||||||
|
const layout = displayFilters?.layout || undefined;
|
||||||
|
const groupBy = displayFilters?.group_by || undefined;
|
||||||
|
const subGroupBy = displayFilters?.sub_group_by || undefined;
|
||||||
|
|
||||||
|
if (!layout) return issuesCount;
|
||||||
|
issuesCount = issueCountBasedOnFilters(groupedIssueIds, layout, groupBy, subGroupBy);
|
||||||
|
return issuesCount;
|
||||||
|
}
|
||||||
|
|
||||||
get groupedIssueIds() {
|
get groupedIssueIds() {
|
||||||
const projectId = this.rootStore?.projectId;
|
const projectId = this.rootStore?.projectId;
|
||||||
if (!projectId) return undefined;
|
if (!projectId) return undefined;
|
||||||
|
Loading…
Reference in New Issue
Block a user