mirror of
https://github.com/makeplane/plane.git
synced 2026-07-13 14:01:45 +02:00
[WEB-4554]fix: initiative epics stats (#3730)
This commit is contained in:
@@ -401,6 +401,25 @@ class InitiativeAnalyticsEndpoint(BaseAPIView):
|
||||
"cancelled",
|
||||
]
|
||||
},
|
||||
# Total issue count
|
||||
**{
|
||||
f"total_{state}_issues": Count(
|
||||
"id",
|
||||
filter=Q(
|
||||
Q(project_id__in=project_ids)
|
||||
| Q(id__in=initiative_epics)
|
||||
| Q(id__in=related_issues_ids),
|
||||
)
|
||||
& Q(state__group=state),
|
||||
)
|
||||
for state in [
|
||||
"backlog",
|
||||
"unstarted",
|
||||
"started",
|
||||
"completed",
|
||||
"cancelled",
|
||||
]
|
||||
},
|
||||
)
|
||||
return issues_counts
|
||||
|
||||
@@ -506,6 +525,13 @@ class InitiativeAnalyticsEndpoint(BaseAPIView):
|
||||
"completed_issues": issues_counts.get("completed_issues", 0),
|
||||
"cancelled_issues": issues_counts.get("cancelled_issues", 0),
|
||||
},
|
||||
"total_count": {
|
||||
"backlog_issues": issues_counts.get("total_backlog_issues", 0),
|
||||
"unstarted_issues": issues_counts.get("total_unstarted_issues", 0),
|
||||
"started_issues": issues_counts.get("total_started_issues", 0),
|
||||
"completed_issues": issues_counts.get("total_completed_issues", 0),
|
||||
"cancelled_issues": issues_counts.get("total_cancelled_issues", 0),
|
||||
},
|
||||
}
|
||||
|
||||
return Response(
|
||||
|
||||
@@ -22,13 +22,11 @@ export const InitiativeProgressSection: FC<Props> = observer((props) => {
|
||||
|
||||
// derived values
|
||||
const initiative = getInitiativeById(initiativeId);
|
||||
const initiativeProjectAnalytics = getInitiativeAnalyticsById(initiativeId)?.project;
|
||||
const cumulatedAnalytics = getInitiativeAnalyticsById(initiativeId)?.total_count;
|
||||
|
||||
const projectsIds = initiative?.project_ids ?? [];
|
||||
const initiativeEpics = initiative?.epic_ids ?? [];
|
||||
const totalIssues = initiativeProjectAnalytics
|
||||
? Object.values(omit(initiativeProjectAnalytics, "overdue_issues")).reduce((acc, val) => acc + val, 0)
|
||||
: 0;
|
||||
const totalIssues = Object.values(cumulatedAnalytics ?? {}).reduce((acc, val) => acc + val, 0);
|
||||
|
||||
const shouldRenderProgressSection = (projectsIds.length ?? 0) > 0 || initiativeEpics.length > 0 || totalIssues > 0;
|
||||
|
||||
@@ -36,7 +34,7 @@ export const InitiativeProgressSection: FC<Props> = observer((props) => {
|
||||
|
||||
return (
|
||||
<ProgressSection
|
||||
data={initiativeProjectAnalytics as TStateAnalytics}
|
||||
data={cumulatedAnalytics as TStateAnalytics}
|
||||
indicatorElement={
|
||||
<>
|
||||
<Tooltip
|
||||
|
||||
@@ -87,14 +87,19 @@ type Props = {
|
||||
export const ScopeBreakdown = observer((props: Props) => {
|
||||
const { workspaceSlug, initiativeId, toggleProjectModal, toggleEpicModal, disabled } = props;
|
||||
const {
|
||||
initiative: { getInitiativeAnalyticsById, getInitiativeById },
|
||||
initiative: {
|
||||
getInitiativeAnalyticsById,
|
||||
getInitiativeById,
|
||||
epics: { getInitiativeEpicsById },
|
||||
},
|
||||
} = useInitiatives();
|
||||
|
||||
// derived values
|
||||
const initiativeAnalytics = getInitiativeAnalyticsById(initiativeId);
|
||||
const initiative = getInitiativeById(initiativeId);
|
||||
const initiativeEpics = getInitiativeEpicsById(initiativeId);
|
||||
|
||||
const epicsCount = initiative?.epic_ids?.length ?? 0;
|
||||
const epicsCount = initiativeEpics?.length ?? 0;
|
||||
const projectsCount = initiative?.project_ids?.length ?? 0;
|
||||
|
||||
return (
|
||||
@@ -119,7 +124,7 @@ export const ScopeBreakdown = observer((props: Props) => {
|
||||
</div>
|
||||
</div>
|
||||
{/* content */}
|
||||
{!projectsCount && !epicsCount ? (
|
||||
{projectsCount === 0 && epicsCount === 0 ? (
|
||||
<SectionEmptyState
|
||||
heading="No scope added to this initiative yet"
|
||||
subHeading="Link projects and epics and track that work in this space."
|
||||
|
||||
10
apps/web/ee/types/initiative/initiative.d.ts
vendored
10
apps/web/ee/types/initiative/initiative.d.ts
vendored
@@ -169,21 +169,29 @@ export type TInitiativeAnalyticsGroup =
|
||||
| "cancelled_issues"
|
||||
| "overdue_issues";
|
||||
|
||||
export type TInitiativeAnalyticData = {
|
||||
export type TInitiativeIssueAnalytics = {
|
||||
backlog_issues: number;
|
||||
unstarted_issues: number;
|
||||
started_issues: number;
|
||||
completed_issues: number;
|
||||
cancelled_issues: number;
|
||||
overdue_issues: number;
|
||||
};
|
||||
|
||||
export type TInitiativeUpdateAnalytics = {
|
||||
on_track_updates: number;
|
||||
at_risk_updates: number;
|
||||
off_track_updates: number;
|
||||
};
|
||||
|
||||
export type TInitiativeAnalyticData = TInitiativeIssueAnalytics & TInitiativeUpdateAnalytics;
|
||||
|
||||
export type TInitiativeAnalyticDataWithCumulated = TInitiativeIssueAnalytics;
|
||||
|
||||
export type TInitiativeAnalytics = TInitiativeAnalyticData & {
|
||||
project: TInitiativeAnalyticData;
|
||||
epic: TInitiativeAnalyticData;
|
||||
total_count: TInitiativeAnalyticDataWithCumulated;
|
||||
};
|
||||
|
||||
export type TInitiativeStats = {
|
||||
|
||||
Reference in New Issue
Block a user