[WEB-2681] fix: module progress indicator (#5842)
* fix: module progress indicator * fix: module progress indicator
This commit is contained in:
parent
b833e3b10c
commit
6f8df3279c
2 changed files with 32 additions and 56 deletions
|
|
@ -7,12 +7,21 @@ import { useParams, usePathname, useSearchParams } from "next/navigation";
|
|||
import { Info, SquareUser } from "lucide-react";
|
||||
// ui
|
||||
import { IModule } from "@plane/types";
|
||||
import { Card, FavoriteStar, LayersIcon, LinearProgressIndicator, TOAST_TYPE, Tooltip, setPromiseToast, setToast } from "@plane/ui";
|
||||
import {
|
||||
Card,
|
||||
FavoriteStar,
|
||||
LayersIcon,
|
||||
LinearProgressIndicator,
|
||||
TOAST_TYPE,
|
||||
Tooltip,
|
||||
setPromiseToast,
|
||||
setToast,
|
||||
} from "@plane/ui";
|
||||
// components
|
||||
import { DateRangeDropdown } from "@/components/dropdowns";
|
||||
import { ButtonAvatars } from "@/components/dropdowns/member/avatar";
|
||||
import { ModuleQuickActions } from "@/components/modules";
|
||||
import { ModuleStatusDropdown } from "@/components/modules/module-status-dropdown";
|
||||
import { ModuleStatusDropdown } from "@/components/modules/module-status-dropdown";
|
||||
// constants
|
||||
import { PROGRESS_STATE_GROUPS_DETAILS } from "@/constants/common";
|
||||
import { MODULE_FAVORITED, MODULE_UNFAVORITED } from "@/constants/event-tracker";
|
||||
|
|
@ -21,11 +30,10 @@ import { MODULE_STATUS } from "@/constants/module";
|
|||
import { getDate, renderFormattedPayloadDate } from "@/helpers/date-time.helper";
|
||||
import { generateQueryParams } from "@/helpers/router.helper";
|
||||
// hooks
|
||||
import { useEventTracker, useMember, useModule, useProjectEstimates, useUserPermissions } from "@/hooks/store";
|
||||
import { useEventTracker, useMember, useModule, useUserPermissions } from "@/hooks/store";
|
||||
import { useAppRouter } from "@/hooks/use-app-router";
|
||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||
// plane web constants
|
||||
import { EEstimateSystem } from "@/plane-web/constants/estimates";
|
||||
import { EUserPermissions, EUserPermissionsLevel } from "@/plane-web/constants/user-permissions";
|
||||
|
||||
type Props = {
|
||||
|
|
@ -46,7 +54,6 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
const { getModuleById, addModuleToFavorites, removeModuleFromFavorites, updateModuleDetails } = useModule();
|
||||
const { getUserDetails } = useMember();
|
||||
const { captureEvent } = useEventTracker();
|
||||
const { currentActiveEstimateId, areEstimateEnabledByProjectId, estimateById } = useProjectEstimates();
|
||||
|
||||
// derived values
|
||||
const moduleDetails = getModuleById(moduleId);
|
||||
|
|
@ -57,7 +64,6 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
const isDisabled = !isEditingAllowed || !!moduleDetails?.archived_at;
|
||||
const renderIcon = Boolean(moduleDetails?.start_date) || Boolean(moduleDetails?.target_date);
|
||||
|
||||
|
||||
const { isMobile } = usePlatformOS();
|
||||
const handleAddToFavorites = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.stopPropagation();
|
||||
|
|
@ -156,29 +162,14 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
|
||||
if (!moduleDetails) return null;
|
||||
|
||||
/**
|
||||
* NOTE: This completion percentage calculation is based on the total issues count.
|
||||
* when estimates are available and estimate type is points, we should consider the estimate point count
|
||||
* when estimates are available and estimate type is not points, then by default we consider the issue count
|
||||
*/
|
||||
const isEstimateEnabled =
|
||||
projectId &&
|
||||
currentActiveEstimateId &&
|
||||
areEstimateEnabledByProjectId(projectId.toString()) &&
|
||||
estimateById(currentActiveEstimateId)?.type === EEstimateSystem.POINTS;
|
||||
|
||||
const moduleTotalIssues = isEstimateEnabled
|
||||
? moduleDetails?.total_estimate_points || 0
|
||||
: moduleDetails.backlog_issues +
|
||||
moduleDetails.unstarted_issues +
|
||||
moduleDetails.started_issues +
|
||||
moduleDetails.completed_issues +
|
||||
moduleDetails.cancelled_issues;
|
||||
|
||||
const moduleCompletedIssues = isEstimateEnabled
|
||||
? moduleDetails?.completed_estimate_points || 0
|
||||
: moduleDetails.completed_issues;
|
||||
const moduleTotalIssues =
|
||||
moduleDetails.backlog_issues +
|
||||
moduleDetails.unstarted_issues +
|
||||
moduleDetails.started_issues +
|
||||
moduleDetails.completed_issues +
|
||||
moduleDetails.cancelled_issues;
|
||||
|
||||
const moduleCompletedIssues = moduleDetails.completed_issues;
|
||||
|
||||
// const areYearsEqual = startDate.getFullYear() === endDate.getFullYear();
|
||||
|
||||
|
|
@ -186,11 +177,11 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
|
||||
const issueCount = module
|
||||
? !moduleTotalIssues || moduleTotalIssues === 0
|
||||
? `0 ${isEstimateEnabled ? `Point` : `Issue`}`
|
||||
? `0 Issue`
|
||||
: moduleTotalIssues === moduleCompletedIssues
|
||||
? `${moduleTotalIssues} Issue${moduleTotalIssues > 1 ? `s` : ``}`
|
||||
: `${moduleCompletedIssues}/${moduleTotalIssues} ${isEstimateEnabled ? `Points` : `Issues`}`
|
||||
: `0 ${isEstimateEnabled ? `Point` : `Issue`}`;
|
||||
: `${moduleCompletedIssues}/${moduleTotalIssues} Issues`
|
||||
: `0 Issue`;
|
||||
|
||||
const moduleLeadDetails = moduleDetails.lead_id ? getUserDetails(moduleDetails.lead_id) : undefined;
|
||||
|
||||
|
|
@ -213,9 +204,9 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
<div className="flex items-center gap-2" onClick={handleEventPropagation}>
|
||||
{moduleStatus && (
|
||||
<ModuleStatusDropdown
|
||||
isDisabled={isDisabled}
|
||||
moduleDetails={moduleDetails}
|
||||
handleModuleDetailsChange={handleModuleDetailsChange}
|
||||
isDisabled={isDisabled}
|
||||
moduleDetails={moduleDetails}
|
||||
handleModuleDetailsChange={handleModuleDetailsChange}
|
||||
/>
|
||||
)}
|
||||
<button onClick={openModuleOverview}>
|
||||
|
|
@ -252,9 +243,9 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
}}
|
||||
onSelect={(val) => {
|
||||
handleModuleDetailsChange({
|
||||
start_date: (val?.from ? renderFormattedPayloadDate(val.from) : null),
|
||||
target_date: (val?.to ? renderFormattedPayloadDate(val.to) : null)
|
||||
})
|
||||
start_date: val?.from ? renderFormattedPayloadDate(val.from) : null,
|
||||
target_date: val?.to ? renderFormattedPayloadDate(val.to) : null,
|
||||
});
|
||||
}}
|
||||
placeholder={{
|
||||
from: "Start date",
|
||||
|
|
@ -288,4 +279,4 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,11 +13,9 @@ import { ModuleListItemAction, ModuleQuickActions } from "@/components/modules";
|
|||
// helpers
|
||||
import { generateQueryParams } from "@/helpers/router.helper";
|
||||
// hooks
|
||||
import { useModule, useProjectEstimates } from "@/hooks/store";
|
||||
import { useModule } from "@/hooks/store";
|
||||
import { useAppRouter } from "@/hooks/use-app-router";
|
||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||
// plane web constants
|
||||
import { EEstimateSystem } from "@/plane-web/constants/estimates";
|
||||
|
||||
type Props = {
|
||||
moduleId: string;
|
||||
|
|
@ -35,27 +33,14 @@ export const ModuleListItem: React.FC<Props> = observer((props) => {
|
|||
// store hooks
|
||||
const { getModuleById } = useModule();
|
||||
const { isMobile } = usePlatformOS();
|
||||
const { currentActiveEstimateId, areEstimateEnabledByProjectId, estimateById } = useProjectEstimates();
|
||||
|
||||
// derived values
|
||||
const moduleDetails = getModuleById(moduleId);
|
||||
|
||||
if (!moduleDetails) return null;
|
||||
|
||||
/**
|
||||
* NOTE: This completion percentage calculation is based on the total issues count.
|
||||
* when estimates are available and estimate type is points, we should consider the estimate point count
|
||||
* when estimates are available and estimate type is not points, then by default we consider the issue count
|
||||
*/
|
||||
const isEstimateEnabled =
|
||||
projectId &&
|
||||
currentActiveEstimateId &&
|
||||
areEstimateEnabledByProjectId(projectId?.toString()) &&
|
||||
estimateById(currentActiveEstimateId)?.type === EEstimateSystem.POINTS;
|
||||
|
||||
const completionPercentage = isEstimateEnabled
|
||||
? ((moduleDetails?.completed_estimate_points || 0) / (moduleDetails?.total_estimate_points || 0)) * 100
|
||||
: ((moduleDetails.completed_issues + moduleDetails.cancelled_issues) / moduleDetails.total_issues) * 100;
|
||||
const completionPercentage =
|
||||
((moduleDetails.completed_issues + moduleDetails.cancelled_issues) / moduleDetails.total_issues) * 100;
|
||||
|
||||
const progress = isNaN(completionPercentage) ? 0 : Math.floor(completionPercentage);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue