From a50a00edefbd5c696c69efb0432c59aa84917ee7 Mon Sep 17 00:00:00 2001 From: gakshita Date: Mon, 14 Oct 2024 18:17:29 +0530 Subject: [PATCH 1/4] fix: Added a common dropdown component --- .../cycles/analytics-sidebar/base.tsx | 24 ++++------ .../cycles/active-cycle/productivity.tsx | 34 ++++--------- .../cycles/dropdowns/estimate-dropdown.tsx | 48 +++++++++++++++++++ 3 files changed, 67 insertions(+), 39 deletions(-) create mode 100644 web/core/components/cycles/dropdowns/estimate-dropdown.tsx diff --git a/web/ce/components/cycles/analytics-sidebar/base.tsx b/web/ce/components/cycles/analytics-sidebar/base.tsx index 34d61efaa5d..54ab90c729b 100644 --- a/web/ce/components/cycles/analytics-sidebar/base.tsx +++ b/web/ce/components/cycles/analytics-sidebar/base.tsx @@ -4,11 +4,12 @@ import { observer } from "mobx-react"; // plane ui import { TCycleEstimateType } from "@plane/types"; import { EEstimateSystem } from "@plane/types/src/enums"; -import { CustomSelect, Loader } from "@plane/ui"; +import { Loader } from "@plane/ui"; // components import ProgressChart from "@/components/core/sidebar/progress-chart"; -import { cycleEstimateOptions, validateCycleSnapshot } from "@/components/cycles"; +import { validateCycleSnapshot } from "@/components/cycles"; // helpers +import { CycleEstimateOptions } from "@/components/cycles/dropdowns/estimate-dropdown"; import { getDate } from "@/helpers/date-time.helper"; // hooks import { useCycle, useProjectEstimates } from "@/hooks/store"; @@ -65,19 +66,12 @@ export const SidebarChart: FC = observer((props) => { <> {isCurrentEstimateTypeIsPoints && (
- {cycleEstimateOptions.find((v) => v.value === estimateType)?.label ?? "None"}} - onChange={onChange} - maxHeight="lg" - buttonClassName="border-none rounded text-sm font-medium capitalize" - > - {cycleEstimateOptions.map((item) => ( - - {item.label} - - ))} - +
)}
diff --git a/web/core/components/cycles/active-cycle/productivity.tsx b/web/core/components/cycles/active-cycle/productivity.tsx index 1e70f326f40..17220d97ff3 100644 --- a/web/core/components/cycles/active-cycle/productivity.tsx +++ b/web/core/components/cycles/active-cycle/productivity.tsx @@ -1,8 +1,8 @@ import { FC, Fragment } from "react"; import { observer } from "mobx-react"; import Link from "next/link"; -import { ICycle, TCycleEstimateType, TCyclePlotType } from "@plane/types"; -import { CustomSelect, Loader } from "@plane/ui"; +import { ICycle, TCycleEstimateType } from "@plane/types"; +import { Loader } from "@plane/ui"; // components import ProgressChart from "@/components/core/sidebar/progress-chart"; import { EmptyState } from "@/components/empty-state"; @@ -11,6 +11,7 @@ import { EmptyStateType } from "@/constants/empty-state"; import { useCycle, useProjectEstimates } from "@/hooks/store"; // plane web constants import { EEstimateSystem } from "@/plane-web/constants/estimates"; +import { CycleEstimateOptions } from "../dropdowns/estimate-dropdown"; export type ActiveCycleProductivityProps = { workspaceSlug: string; @@ -18,11 +19,6 @@ export type ActiveCycleProductivityProps = { cycle: ICycle | null; }; -const cycleBurnDownChartOptions = [ - { value: "issues", label: "Issues" }, - { value: "points", label: "Points" }, -]; - export const ActiveCycleProductivity: FC = observer((props) => { const { workspaceSlug, projectId, cycle } = props; // hooks @@ -40,7 +36,7 @@ export const ActiveCycleProductivity: FC = observe const isCurrentProjectEstimateEnabled = projectId && areEstimateEnabledByProjectId(projectId) ? true : false; const estimateDetails = isCurrentProjectEstimateEnabled && currentActiveEstimateId && estimateById(currentActiveEstimateId); - const isCurrentEstimateTypeIsPoints = estimateDetails && estimateDetails?.type === EEstimateSystem.POINTS; + const isCurrentEstimateTypeIsPoints = Boolean(estimateDetails && estimateDetails?.type === EEstimateSystem.POINTS); const chartDistributionData = cycle && estimateType === "points" ? cycle?.estimate_distribution : cycle?.distribution || undefined; @@ -52,22 +48,12 @@ export const ActiveCycleProductivity: FC = observe

Issue burndown

- {isCurrentEstimateTypeIsPoints && ( -
- {cycleBurnDownChartOptions.find((v) => v.value === estimateType)?.label ?? "None"}} - onChange={onChange} - maxHeight="lg" - > - {cycleBurnDownChartOptions.map((item) => ( - - {item.label} - - ))} - -
- )} +
diff --git a/web/core/components/cycles/dropdowns/estimate-dropdown.tsx b/web/core/components/cycles/dropdowns/estimate-dropdown.tsx new file mode 100644 index 00000000000..f9d4f0b3739 --- /dev/null +++ b/web/core/components/cycles/dropdowns/estimate-dropdown.tsx @@ -0,0 +1,48 @@ +import React from "react"; +import { TCycleEstimateType } from "@plane/types"; +import { CustomSelect } from "@plane/ui"; +import { useProjectEstimates } from "@/hooks/store"; +import { cycleEstimateOptions } from "../analytics-sidebar"; + +export type TDropdownProps = { + value: string; + onChange: (value: TCycleEstimateType) => Promise; + options: any[]; +}; + +type TProps = { + showEstimateSelection: boolean | undefined; + estimateType: TCycleEstimateType; + handleEstimateChange: (value: TCycleEstimateType) => Promise; + projectId: string; + defaultValue?: string | React.ReactNode; +}; + +const Dropdown = ({ value, onChange, options }: TDropdownProps) => ( +
+ {options.find((v) => v.value === value)?.label ?? "None"}} + onChange={onChange} + maxHeight="lg" + buttonClassName="bg-custom-background-90 border-none rounded text-sm font-medium " + > + {options.map((item) => ( + + {item.label} + + ))} + +
+); +export const CycleEstimateOptions = (props: TProps) => { + const { showEstimateSelection, estimateType, handleEstimateChange, projectId, defaultValue = null } = props; + + const { areEstimateEnabledByProjectId } = useProjectEstimates(); + const isCurrentProjectEstimateEnabled = projectId && areEstimateEnabledByProjectId(projectId) ? true : false; + return showEstimateSelection && isCurrentProjectEstimateEnabled ? ( + + ) : ( + defaultValue + ); +}; From b56b83585c5abccc291a3a972a954b8345e63b65 Mon Sep 17 00:00:00 2001 From: gakshita Date: Mon, 14 Oct 2024 19:37:06 +0530 Subject: [PATCH 2/4] fix: dropdown --- .../cycles/analytics-sidebar/base.tsx | 10 +--- .../cycles/active-cycle/productivity.tsx | 8 ++-- .../cycles/dropdowns/estimate-dropdown.tsx | 48 ------------------- .../dropdowns/estimate-type-dropdown.tsx | 39 +++++++++++++++ web/core/components/cycles/dropdowns/index.ts | 1 + 5 files changed, 46 insertions(+), 60 deletions(-) delete mode 100644 web/core/components/cycles/dropdowns/estimate-dropdown.tsx create mode 100644 web/core/components/cycles/dropdowns/estimate-type-dropdown.tsx diff --git a/web/ce/components/cycles/analytics-sidebar/base.tsx b/web/ce/components/cycles/analytics-sidebar/base.tsx index 54ab90c729b..68f039fa066 100644 --- a/web/ce/components/cycles/analytics-sidebar/base.tsx +++ b/web/ce/components/cycles/analytics-sidebar/base.tsx @@ -7,9 +7,8 @@ import { EEstimateSystem } from "@plane/types/src/enums"; import { Loader } from "@plane/ui"; // components import ProgressChart from "@/components/core/sidebar/progress-chart"; -import { validateCycleSnapshot } from "@/components/cycles"; +import { EstimateTypeDropdown, validateCycleSnapshot } from "@/components/cycles"; // helpers -import { CycleEstimateOptions } from "@/components/cycles/dropdowns/estimate-dropdown"; import { getDate } from "@/helpers/date-time.helper"; // hooks import { useCycle, useProjectEstimates } from "@/hooks/store"; @@ -66,12 +65,7 @@ export const SidebarChart: FC = observer((props) => { <> {isCurrentEstimateTypeIsPoints && (
- +
)}
diff --git a/web/core/components/cycles/active-cycle/productivity.tsx b/web/core/components/cycles/active-cycle/productivity.tsx index 17220d97ff3..2b73f77576f 100644 --- a/web/core/components/cycles/active-cycle/productivity.tsx +++ b/web/core/components/cycles/active-cycle/productivity.tsx @@ -11,7 +11,7 @@ import { EmptyStateType } from "@/constants/empty-state"; import { useCycle, useProjectEstimates } from "@/hooks/store"; // plane web constants import { EEstimateSystem } from "@/plane-web/constants/estimates"; -import { CycleEstimateOptions } from "../dropdowns/estimate-dropdown"; +import { EstimateTypeDropdown } from "../dropdowns/estimate-type-dropdown"; export type ActiveCycleProductivityProps = { workspaceSlug: string; @@ -48,10 +48,10 @@ export const ActiveCycleProductivity: FC = observe

Issue burndown

-
diff --git a/web/core/components/cycles/dropdowns/estimate-dropdown.tsx b/web/core/components/cycles/dropdowns/estimate-dropdown.tsx deleted file mode 100644 index f9d4f0b3739..00000000000 --- a/web/core/components/cycles/dropdowns/estimate-dropdown.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from "react"; -import { TCycleEstimateType } from "@plane/types"; -import { CustomSelect } from "@plane/ui"; -import { useProjectEstimates } from "@/hooks/store"; -import { cycleEstimateOptions } from "../analytics-sidebar"; - -export type TDropdownProps = { - value: string; - onChange: (value: TCycleEstimateType) => Promise; - options: any[]; -}; - -type TProps = { - showEstimateSelection: boolean | undefined; - estimateType: TCycleEstimateType; - handleEstimateChange: (value: TCycleEstimateType) => Promise; - projectId: string; - defaultValue?: string | React.ReactNode; -}; - -const Dropdown = ({ value, onChange, options }: TDropdownProps) => ( -
- {options.find((v) => v.value === value)?.label ?? "None"}} - onChange={onChange} - maxHeight="lg" - buttonClassName="bg-custom-background-90 border-none rounded text-sm font-medium " - > - {options.map((item) => ( - - {item.label} - - ))} - -
-); -export const CycleEstimateOptions = (props: TProps) => { - const { showEstimateSelection, estimateType, handleEstimateChange, projectId, defaultValue = null } = props; - - const { areEstimateEnabledByProjectId } = useProjectEstimates(); - const isCurrentProjectEstimateEnabled = projectId && areEstimateEnabledByProjectId(projectId) ? true : false; - return showEstimateSelection && isCurrentProjectEstimateEnabled ? ( - - ) : ( - defaultValue - ); -}; diff --git a/web/core/components/cycles/dropdowns/estimate-type-dropdown.tsx b/web/core/components/cycles/dropdowns/estimate-type-dropdown.tsx new file mode 100644 index 00000000000..3f9800744d0 --- /dev/null +++ b/web/core/components/cycles/dropdowns/estimate-type-dropdown.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import { TCycleEstimateType } from "@plane/types"; +import { CustomSelect } from "@plane/ui"; +import { useProjectEstimates } from "@/hooks/store"; +import { cycleEstimateOptions } from "../analytics-sidebar"; + +type TProps = { + showEstimateSelection: boolean | undefined; + value: TCycleEstimateType; + onChange: (value: TCycleEstimateType) => Promise; + projectId: string; + showDefault?: boolean; +}; + +export const EstimateTypeDropdown = (props: TProps) => { + const { showEstimateSelection, value, onChange, projectId, showDefault = false } = props; + + const { areEstimateEnabledByProjectId } = useProjectEstimates(); + const isCurrentProjectEstimateEnabled = projectId && areEstimateEnabledByProjectId(projectId) ? true : false; + return showEstimateSelection && isCurrentProjectEstimateEnabled ? ( +
+ {cycleEstimateOptions.find((v) => v.value === value)?.label ?? "None"}} + onChange={onChange} + maxHeight="lg" + buttonClassName="bg-custom-background-90 border-none rounded text-sm font-medium " + > + {cycleEstimateOptions.map((item) => ( + + {item.label} + + ))} + +
+ ) : showDefault ? ( + {value} + ) : null; +}; diff --git a/web/core/components/cycles/dropdowns/index.ts b/web/core/components/cycles/dropdowns/index.ts index 302e3a1a6ed..2d1f1155417 100644 --- a/web/core/components/cycles/dropdowns/index.ts +++ b/web/core/components/cycles/dropdowns/index.ts @@ -1 +1,2 @@ export * from "./filters"; +export * from "./estimate-type-dropdown"; From 9893319407a5229deb95a03ef3edc5c2ea35b2d0 Mon Sep 17 00:00:00 2001 From: gakshita Date: Tue, 15 Oct 2024 14:31:32 +0530 Subject: [PATCH 3/4] fix: estimate dropdown --- .../cycles/analytics-sidebar/base.tsx | 17 +++++------------ .../cycles/active-cycle/productivity.tsx | 13 +------------ .../cycles/dropdowns/estimate-type-dropdown.tsx | 12 ++++++------ web/core/store/cycle.store.ts | 15 +++++++++++++++ 4 files changed, 27 insertions(+), 30 deletions(-) diff --git a/web/ce/components/cycles/analytics-sidebar/base.tsx b/web/ce/components/cycles/analytics-sidebar/base.tsx index 68f039fa066..87f07e387c0 100644 --- a/web/ce/components/cycles/analytics-sidebar/base.tsx +++ b/web/ce/components/cycles/analytics-sidebar/base.tsx @@ -3,7 +3,6 @@ import { FC, Fragment } from "react"; import { observer } from "mobx-react"; // plane ui import { TCycleEstimateType } from "@plane/types"; -import { EEstimateSystem } from "@plane/types/src/enums"; import { Loader } from "@plane/ui"; // components import ProgressChart from "@/components/core/sidebar/progress-chart"; @@ -11,7 +10,7 @@ import { EstimateTypeDropdown, validateCycleSnapshot } from "@/components/cycles // helpers import { getDate } from "@/helpers/date-time.helper"; // hooks -import { useCycle, useProjectEstimates } from "@/hooks/store"; +import { useCycle } from "@/hooks/store"; type ProgressChartProps = { workspaceSlug: string; @@ -24,7 +23,6 @@ export const SidebarChart: FC = observer((props) => { // hooks const { getEstimateTypeByCycleId, getCycleById, fetchCycleDetails, fetchArchivedCycleDetails, setEstimateType } = useCycle(); - const { currentActiveEstimateId, areEstimateEnabledByProjectId, estimateById } = useProjectEstimates(); // derived data const cycleDetails = validateCycleSnapshot(getCycleById(cycleId)); @@ -33,10 +31,7 @@ export const SidebarChart: FC = observer((props) => { const totalEstimatePoints = cycleDetails?.total_estimate_points || 0; const totalIssues = cycleDetails?.total_issues || 0; const estimateType = getEstimateTypeByCycleId(cycleId); - const isCurrentProjectEstimateEnabled = Boolean(projectId && areEstimateEnabledByProjectId(projectId)); - const estimateDetails = - isCurrentProjectEstimateEnabled && currentActiveEstimateId && estimateById(currentActiveEstimateId); - const isCurrentEstimateTypeIsPoints = estimateDetails && estimateDetails?.type === EEstimateSystem.POINTS; + const chartDistributionData = estimateType === "points" ? cycleDetails?.estimate_distribution : cycleDetails?.distribution || undefined; @@ -63,11 +58,9 @@ export const SidebarChart: FC = observer((props) => { }; return ( <> - {isCurrentEstimateTypeIsPoints && ( -
- -
- )} +
+ +
diff --git a/web/core/components/cycles/active-cycle/productivity.tsx b/web/core/components/cycles/active-cycle/productivity.tsx index 2b73f77576f..74957af03c7 100644 --- a/web/core/components/cycles/active-cycle/productivity.tsx +++ b/web/core/components/cycles/active-cycle/productivity.tsx @@ -23,7 +23,6 @@ export const ActiveCycleProductivity: FC = observe const { workspaceSlug, projectId, cycle } = props; // hooks const { getEstimateTypeByCycleId, setEstimateType } = useCycle(); - const { currentActiveEstimateId, areEstimateEnabledByProjectId, estimateById } = useProjectEstimates(); // derived values const estimateType: TCycleEstimateType = (cycle && getEstimateTypeByCycleId(cycle.id)) || "issues"; @@ -33,11 +32,6 @@ export const ActiveCycleProductivity: FC = observe setEstimateType(cycle.id, value); }; - const isCurrentProjectEstimateEnabled = projectId && areEstimateEnabledByProjectId(projectId) ? true : false; - const estimateDetails = - isCurrentProjectEstimateEnabled && currentActiveEstimateId && estimateById(currentActiveEstimateId); - const isCurrentEstimateTypeIsPoints = Boolean(estimateDetails && estimateDetails?.type === EEstimateSystem.POINTS); - const chartDistributionData = cycle && estimateType === "points" ? cycle?.estimate_distribution : cycle?.distribution || undefined; const completionChartDistributionData = chartDistributionData?.completion_chart || undefined; @@ -48,12 +42,7 @@ export const ActiveCycleProductivity: FC = observe

Issue burndown

- +
diff --git a/web/core/components/cycles/dropdowns/estimate-type-dropdown.tsx b/web/core/components/cycles/dropdowns/estimate-type-dropdown.tsx index 3f9800744d0..7eba6418d90 100644 --- a/web/core/components/cycles/dropdowns/estimate-type-dropdown.tsx +++ b/web/core/components/cycles/dropdowns/estimate-type-dropdown.tsx @@ -1,23 +1,23 @@ import React from "react"; import { TCycleEstimateType } from "@plane/types"; import { CustomSelect } from "@plane/ui"; -import { useProjectEstimates } from "@/hooks/store"; +import { useCycle, useProjectEstimates } from "@/hooks/store"; import { cycleEstimateOptions } from "../analytics-sidebar"; type TProps = { - showEstimateSelection: boolean | undefined; value: TCycleEstimateType; onChange: (value: TCycleEstimateType) => Promise; - projectId: string; showDefault?: boolean; + projectId: string; + cycleId: string; }; export const EstimateTypeDropdown = (props: TProps) => { - const { showEstimateSelection, value, onChange, projectId, showDefault = false } = props; - + const { value, onChange, projectId, cycleId, showDefault = false } = props; + const { getIsPointsDataAvailable } = useCycle(); const { areEstimateEnabledByProjectId } = useProjectEstimates(); const isCurrentProjectEstimateEnabled = projectId && areEstimateEnabledByProjectId(projectId) ? true : false; - return showEstimateSelection && isCurrentProjectEstimateEnabled ? ( + return getIsPointsDataAvailable(cycleId) || isCurrentProjectEstimateEnabled ? (
string[] | null; getPlotTypeByCycleId: (cycleId: string) => TCyclePlotType; getEstimateTypeByCycleId: (cycleId: string) => TCycleEstimateType; + getIsPointsDataAvailable: (cycleId: string) => boolean; + // actions updateCycleDistribution: (distributionUpdates: DistributionUpdates, cycleId: string) => void; validateDate: (workspaceSlug: string, projectId: string, payload: CycleDateCheckData) => Promise; @@ -271,6 +274,18 @@ export class CycleStore implements ICycleStore { return this.cycleMap?.[this.currentProjectActiveCycleId!] ?? null; } + getIsPointsDataAvailable = computedFn((cycleId: string) => { + console.log(this.cycleMap[cycleId]?.version); + const cycle = this.cycleMap[cycleId]; + if (!cycle) return false; + if (this.cycleMap[cycleId].version === 2) return cycle.progress.some((p) => p.total_estimate_points > 0); + else if (this.cycleMap[cycleId].version === 1) { + console.log({ ...cycle.estimate_distribution?.completion_chart }); + const completionChart = cycle.estimate_distribution?.completion_chart || {}; + return !isEmpty(completionChart) && Object.keys(completionChart).some((p) => completionChart[p]! > 0); + } else return false; + }); + /** * returns active cycle progress for a project */ From f0e13558e0448dfe5cd4a305d5c781a2829bdfc2 Mon Sep 17 00:00:00 2001 From: gakshita Date: Tue, 15 Oct 2024 15:08:42 +0530 Subject: [PATCH 4/4] fix: removed consoles --- web/core/store/cycle.store.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/web/core/store/cycle.store.ts b/web/core/store/cycle.store.ts index 4b79038efa1..d4408d80554 100644 --- a/web/core/store/cycle.store.ts +++ b/web/core/store/cycle.store.ts @@ -275,12 +275,10 @@ export class CycleStore implements ICycleStore { } getIsPointsDataAvailable = computedFn((cycleId: string) => { - console.log(this.cycleMap[cycleId]?.version); const cycle = this.cycleMap[cycleId]; if (!cycle) return false; if (this.cycleMap[cycleId].version === 2) return cycle.progress.some((p) => p.total_estimate_points > 0); else if (this.cycleMap[cycleId].version === 1) { - console.log({ ...cycle.estimate_distribution?.completion_chart }); const completionChart = cycle.estimate_distribution?.completion_chart || {}; return !isEmpty(completionChart) && Object.keys(completionChart).some((p) => completionChart[p]! > 0); } else return false;