[WEB-3826] fix: estimate dropdown formatting (#6906)

* * fix: time conversion for estimate dropdown in browse
* chore: updated puncutations for estimates.

* chore: estimate activiy formatting

* chore: estimate activity refactor
This commit is contained in:
Vamsi Krishna 2025-04-11 01:41:43 +05:30 committed by GitHub
parent 33a1b916cb
commit b4fc715aba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 18 additions and 54 deletions

View file

@ -0,0 +1,3 @@
import { TIssueActivity } from "@plane/types";
export const renderEstimate = (activity: TIssueActivity, value: string) => value;

View file

@ -1 +1,2 @@
export * from "./root"; export * from "./root";
export * from "./helper";

View file

@ -90,13 +90,15 @@ export const EstimateDropdown: React.FC<Props> = observer((props) => {
// router // router
const { workspaceSlug } = useParams(); const { workspaceSlug } = useParams();
// store hooks // store hooks
const { currentActiveEstimateIdByProjectId, getProjectEstimates, currentActiveEstimate } = useProjectEstimates(); const { currentActiveEstimateIdByProjectId, getProjectEstimates, getEstimateById } = useProjectEstimates();
const { estimatePointIds, estimatePointById } = useEstimate( const { estimatePointIds, estimatePointById } = useEstimate(
projectId ? currentActiveEstimateIdByProjectId(projectId) : undefined projectId ? currentActiveEstimateIdByProjectId(projectId) : undefined
); );
const currentActiveEstimateId = projectId ? currentActiveEstimateIdByProjectId(projectId) : undefined; const currentActiveEstimateId = projectId ? currentActiveEstimateIdByProjectId(projectId) : undefined;
const currentActiveEstimate = currentActiveEstimateId ? getEstimateById(currentActiveEstimateId) : undefined;
const options: DropdownOptions = (estimatePointIds ?? []) const options: DropdownOptions = (estimatePointIds ?? [])
?.map((estimatePoint) => { ?.map((estimatePoint) => {
const currentEstimatePoint = estimatePointById(estimatePoint); const currentEstimatePoint = estimatePointById(estimatePoint);

View file

@ -78,7 +78,7 @@ export const EstimateCreateStageOne: FC<TEstimateCreateStageOne> = (props) => {
<p className="text-base font-medium">{t("project_settings.estimates.create.custom")}</p> <p className="text-base font-medium">{t("project_settings.estimates.create.custom")}</p>
<p className="text-xs text-custom-text-300"> <p className="text-xs text-custom-text-300">
{/* TODO: Translate here */} {/* TODO: Translate here */}
Add your own <span className="lowercase">{currentEstimateSystem.name}</span> from scratch Add your own <span className="lowercase">{currentEstimateSystem.name}</span> from scratch.
</p> </p>
</button> </button>
</div> </div>
@ -100,7 +100,7 @@ export const EstimateCreateStageOne: FC<TEstimateCreateStageOne> = (props) => {
{currentEstimateSystem.templates[name]?.values {currentEstimateSystem.templates[name]?.values
?.map((template) => ?.map((template) =>
estimateSystem === EEstimateSystem.TIME estimateSystem === EEstimateSystem.TIME
? convertMinutesToHoursMinutesString(Number(template.value)) ? convertMinutesToHoursMinutesString(Number(template.value)).trim()
: template.value : template.value
) )
?.join(", ")} ?.join(", ")}

View file

@ -2,10 +2,9 @@ import { FC } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { Triangle } from "lucide-react"; import { Triangle } from "lucide-react";
// hooks // hooks
import { EEstimateSystem } from "@plane/types/src/enums"; import { useIssueDetail } from "@/hooks/store";
import { convertMinutesToHoursMinutesString } from "@/helpers/date-time.helper";
import { useIssueDetail, useProjectEstimates } from "@/hooks/store";
// components // components
import { renderEstimate } from "@/plane-web/components/issues/issue-details";
import { IssueActivityBlockComponent, IssueLink } from "./"; import { IssueActivityBlockComponent, IssueLink } from "./";
type TIssueEstimateActivity = { activityId: string; showIssue?: boolean; ends: "top" | "bottom" | undefined }; type TIssueEstimateActivity = { activityId: string; showIssue?: boolean; ends: "top" | "bottom" | undefined };
@ -16,18 +15,9 @@ export const IssueEstimateActivity: FC<TIssueEstimateActivity> = observer((props
const { const {
activity: { getActivityById }, activity: { getActivityById },
} = useIssueDetail(); } = useIssueDetail();
const { currentActiveEstimate } = useProjectEstimates();
const activity = getActivityById(activityId); const activity = getActivityById(activityId);
const renderValue = (value: string) => {
const isTinmeEstimate = currentActiveEstimate?.type === EEstimateSystem.TIME;
if (isTinmeEstimate) {
return convertMinutesToHoursMinutesString(Number(value));
}
return value;
};
if (!activity) return <></>; if (!activity) return <></>;
return ( return (
@ -38,7 +28,9 @@ export const IssueEstimateActivity: FC<TIssueEstimateActivity> = observer((props
> >
<> <>
{activity.new_value ? `set the estimate to ` : `removed the estimate `} {activity.new_value ? `set the estimate to ` : `removed the estimate `}
{activity.new_value ? renderValue(activity.new_value) : renderValue(activity?.old_value || "")} {activity.new_value
? renderEstimate(activity, activity.new_value)
: renderEstimate(activity, activity?.old_value || "")}
{showIssue && (activity.new_value ? ` to ` : ` from `)} {showIssue && (activity.new_value ? ` to ` : ` from `)}
{showIssue && <IssueLink activityId={activityId} />}. {showIssue && <IssueLink activityId={activityId} />}.
</> </>

View file

@ -1,6 +1,6 @@
import { useMemo } from "react"; import { useMemo } from "react";
import { useTranslation } from "@plane/i18n"; import { useTranslation } from "@plane/i18n";
import { TCommentsOperations, TIssueComment } from "@plane/types"; import { TCommentsOperations, TIssueActivity, TIssueComment } from "@plane/types";
import { EFileAssetType } from "@plane/types/src/enums"; import { EFileAssetType } from "@plane/types/src/enums";
import { setToast, TOAST_TYPE } from "@plane/ui"; import { setToast, TOAST_TYPE } from "@plane/ui";
import { formatTextList } from "@/helpers/issue.helper"; import { formatTextList } from "@/helpers/issue.helper";

View file

@ -1,7 +1,6 @@
import orderBy from "lodash/orderBy"; import orderBy from "lodash/orderBy";
import set from "lodash/set"; import set from "lodash/set";
import unset from "lodash/unset"; import unset from "lodash/unset";
import update from "lodash/update";
import { action, computed, makeObservable, observable, runInAction } from "mobx"; import { action, computed, makeObservable, observable, runInAction } from "mobx";
import { computedFn } from "mobx-utils"; import { computedFn } from "mobx-utils";
// types // types
@ -39,7 +38,7 @@ export interface IProjectEstimateStore {
projectId: string, projectId: string,
loader?: TEstimateLoader loader?: TEstimateLoader
) => Promise<IEstimateType[] | undefined>; ) => Promise<IEstimateType[] | undefined>;
getEstimateById: (workspaceSlug: string, projectId: string, estimateId: string) => Promise<IEstimateType | undefined>; getEstimateById: (estimateId: string) => IEstimate | undefined;
createEstimate: ( createEstimate: (
workspaceSlug: string, workspaceSlug: string,
projectId: string, projectId: string,
@ -241,44 +240,10 @@ export class ProjectEstimateStore implements IProjectEstimateStore {
}; };
/** /**
* @description update an estimate for a project
* @param { string } workspaceSlug
* @param { string } projectId
* @param { string } estimateId * @param { string } estimateId
* @returns IEstimateType | undefined * @returns IEstimateType | undefined
*/ */
getEstimateById = async ( getEstimateById = (estimateId: string): IEstimate | undefined => this.estimates[estimateId];
workspaceSlug: string,
projectId: string,
estimateId: string
): Promise<IEstimateType | undefined> => {
try {
this.error = undefined;
const estimate = await estimateService.fetchEstimateById(workspaceSlug, projectId, estimateId);
if (estimate) {
runInAction(() => {
if (estimate.id)
update(this.estimates, [estimate.id], (estimateStore) => {
if (estimateStore) estimateStore.updateEstimate(estimate);
else
return new Estimate(this.store, {
...estimate,
type: estimate.type?.toLowerCase() as TEstimateSystemKeys,
});
});
});
}
return estimate;
} catch (error) {
this.error = {
status: "error",
message: "Error fetching estimate by id",
};
throw error;
}
};
/** /**
* @description create an estimate for a project * @description create an estimate for a project

View file

@ -0,0 +1 @@
export * from "ce/components/issues/issue-details/issue-properties-activity";