fix: cycle build issue (#1509)

* fix: cycle build issue

* fix: removed beyond time

* fix: today value + chart stacking
This commit is contained in:
Akshita Goyal
2024-10-15 19:04:33 +05:30
committed by GitHub
parent 64f80ca4d8
commit f5205cd221
6 changed files with 80 additions and 50 deletions

View File

@@ -277,7 +277,7 @@ export class CycleStore implements ICycleStore {
getIsPointsDataAvailable = computedFn((cycleId: string) => {
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);
if (this.cycleMap[cycleId].version === 2) return cycle.progress?.some((p) => p.total_estimate_points > 0);
else if (this.cycleMap[cycleId].version === 1) {
const completionChart = cycle.estimate_distribution?.completion_chart || {};
return !isEmpty(completionChart) && Object.keys(completionChart).some((p) => completionChart[p]! > 0);

View File

@@ -31,10 +31,19 @@ type Props = {
isFullWidth?: boolean;
estimateType?: string;
plotType: string;
showToday?: boolean;
};
export const ActiveCycleChart = observer((props: Props) => {
const { areaToHighlight, data = [], cycle, isFullWidth = false, plotType, estimateType = "ISSUES" } = props;
const {
areaToHighlight,
data = [],
cycle,
isFullWidth = false,
plotType,
estimateType = "ISSUES",
showToday,
} = props;
const { resolvedTheme } = useTheme();
const colors = getColors(resolvedTheme);
@@ -53,7 +62,7 @@ export const ActiveCycleChart = observer((props: Props) => {
data={dataWithRange}
margin={{
top: isFullWidth ? 10 : 30,
right: isFullWidth ? 10 : 0,
right: isFullWidth ? 10 : 20,
bottom: isFullWidth ? 30 : 70,
left: isFullWidth ? -30 : 20,
}}
@@ -126,10 +135,12 @@ export const ActiveCycleChart = observer((props: Props) => {
stroke={colors.axisLines}
text={colors.axisText}
startDate={startDate}
showToday={showToday}
/>
}
tickLine={false}
interval={0}
minTickGap={5}
/>
<YAxis
tickCount={10}
@@ -165,8 +176,9 @@ export const ActiveCycleChart = observer((props: Props) => {
fillOpacity={0.5}
/>
{/* Required when manual cycles are implemented */}
{/* Beyond Time */}
<Area dataKey="beyondTime" stroke="#FF9999" strokeWidth={0} fill={`url(#fillTimeBeyond)`} />
{/* <Area dataKey="beyondTime" stroke="#FF9999" strokeWidth={0} fill={`url(#fillTimeBeyond)`} />
<ReferenceArea
x1={endDate}
x2={dataWithRange[dataWithRange.length - 1]?.date}
@@ -183,7 +195,7 @@ export const ActiveCycleChart = observer((props: Props) => {
position="middle"
/>
)}
</ReferenceArea>
</ReferenceArea> */}
{/* Today */}
{today < endDate && (
@@ -191,8 +203,38 @@ export const ActiveCycleChart = observer((props: Props) => {
)}
{/* Beyond Time */}
<ReferenceLine x={endDate} stroke={colors.beyondTimeStroke} label="" strokeDasharray="3 3" />
{/* Ideal - Actual */}
<Area dataKey="range" strokeWidth={0} fill={`url(#diff)`} isAnimationActive={false} />
{/* Ideal */}
<Line
type="linear"
dataKey="ideal"
strokeWidth={1}
stroke={colors.idealStroke}
dot={false}
strokeDasharray="5 5"
isAnimationActive={false}
/>
{areaToHighlight === "ideal" && (
<Area
dataKey="ideal"
fill="url(#fillIdeal)"
fillOpacity={0.4}
stroke={colors.idealStroke}
strokeWidth={0}
isAnimationActive={false}
/>
)}
{/* Started */}
<Line type="linear" dataKey="started" strokeWidth={1} stroke={colors.startedStroke} dot={false} />
<Line
type="linear"
dataKey="started"
strokeWidth={2}
stroke={colors.startedStroke}
dot={false}
isAnimationActive={false}
/>
{areaToHighlight === "started" && (
<Area
dataKey="started"
@@ -222,26 +264,7 @@ export const ActiveCycleChart = observer((props: Props) => {
isAnimationActive={false}
/>
)}
{/* Ideal */}
<Line
type="linear"
dataKey="ideal"
strokeWidth={1}
stroke={colors.idealStroke}
dot={false}
strokeDasharray="5 5"
isAnimationActive={false}
/>
{areaToHighlight === "ideal" && (
<Area
dataKey="ideal"
fill="url(#fillIdeal)"
fillOpacity={0.4}
stroke={colors.idealStroke}
strokeWidth={0}
isAnimationActive={false}
/>
)}
{/* Scope */}
<Line
type="stepAfter"
@@ -267,8 +290,6 @@ export const ActiveCycleChart = observer((props: Props) => {
isAnimationActive={false}
/>
)}
{/* Ideal - Actual */}
<Area dataKey="range" strokeWidth={0} fill={`url(#diff)`} isAnimationActive={false} />
</ComposedChart>
</ResponsiveContainer>
);

View File

@@ -10,9 +10,10 @@ type TProps = {
endDate?: string;
stroke?: string;
text?: string;
showToday?: boolean;
};
const CustomizedXAxisTicks = (props: TProps) => {
const { x, y, payload, data, endDate, startDate, stroke, text } = props;
const { x, y, payload, data, endDate, startDate, stroke, text, showToday } = props;
if (data === undefined || endDate === undefined) return null;
const [year, month, day] = payload.value.split("-");
const monthName = new Date(payload.value).toLocaleString("default", { month: "short" });
@@ -25,7 +26,7 @@ const CustomizedXAxisTicks = (props: TProps) => {
<>
<line x1={"0"} y1="-8" x2="0" y2="0" stroke={stroke} stroke-width="1" />
<text
x={day === "01" || payload.index === 0 ? "-10" : "-5"}
x={day === "01" || payload.index === 0 ? "-10" : payload.value === endDate ? "5" : "-5"}
y={0}
dy={12}
textAnchor={payload.index === data.length - 1 ? "end" : "start"}
@@ -37,7 +38,7 @@ const CustomizedXAxisTicks = (props: TProps) => {
</text>
{(payload.value === startDate || payload.value === endDate) && (
<text
x={-8}
x={payload.value === endDate ? "10" : "-8"}
y={12}
dy={16}
textAnchor={payload.index === data.length - 1 ? "end" : "start"}
@@ -52,7 +53,7 @@ const CustomizedXAxisTicks = (props: TProps) => {
{payload.value === format(startOfToday(), "yyyy-MM-dd") && payload.value < endDate && (
<>
<line x1="0" y1="-8" x2="0" y2="0" stroke={stroke} stroke-width="1" />
<text x={0} y={0} dy={12} textAnchor={"middle"} fill={text} style={{ fontSize: "10px" }}>
<text x={0} y={0} dy={12} textAnchor={"middle"} fill={text} style={{ fontSize: "10px", fontWeight: 500 }}>
{day}
</text>
{(payload.value === startDate || payload.value === endDate) && (
@@ -67,19 +68,21 @@ const CustomizedXAxisTicks = (props: TProps) => {
{payload.value === startDate ? "Start" : "End"}
</text>
)}
<svg
x={-17}
y={payload.value === startDate || payload.value === endDate ? 30 : 18}
dy={payload.value === startDate || payload.value === endDate ? 30 : 18}
width="34"
height="16px"
xmlns="http://www.w3.org/2000/svg"
>
<rect rx="2" width="100%" height="100%" fill="#667699" />
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="white" font-size="10px">
Today
</text>
</svg>
{showToday && (
<svg
x={-17}
y={payload.value === startDate || payload.value === endDate ? 30 : 18}
dy={payload.value === startDate || payload.value === endDate ? 30 : 18}
width="34"
height="16px"
xmlns="http://www.w3.org/2000/svg"
>
<rect rx="2" width="100%" height="100%" fill="#667699" />
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="white" font-size="10px">
Today
</text>
</svg>
)}
</>
)}
</g>

View File

@@ -87,6 +87,7 @@ const ActiveCycleDetail = observer((props: ActiveCycleDetailProps) => {
isFullWidth={containerWidth < 890}
estimateType={computedEstimateType}
plotType={computedPlotType}
showToday
/>
</div>
) : (

View File

@@ -13,7 +13,9 @@ const ideal = (date: string, scope: number, cycle: ICycle) => {
const formatV1Data = (isTypeIssue: boolean, cycle: ICycle, isBurnDown: boolean, endDate: Date | string) => {
const today = format(startOfToday(), "yyyy-MM-dd");
const data = isTypeIssue ? cycle.distribution : cycle.estimate_distribution;
const extendedArray = generateDateArray(endDate, endDate).map((d) => d.date);
const extendedArray = generateDateArray(endDate, endDate)
.filter((d) => d.date >= cycle.start_date! && d.date <= cycle.end_date!)
.map((d) => d.date);
if (!data?.completion_chart) return null;
if (isEmpty(data?.completion_chart)) return generateDateArray(new Date(cycle.start_date!), endDate);
let progress = [...Object.keys(data.completion_chart), ...extendedArray].map((p) => {
@@ -23,7 +25,7 @@ const formatV1Data = (isTypeIssue: boolean, cycle: ICycle, isBurnDown: boolean,
const idealDone = ideal(p, total, cycle);
return {
date: p,
scope: p! <= format(endDate as Date, "yyyy-MM-dd") ? total : null,
scope: p! <= cycle.end_date! ? total : null,
completed,
backlog: isTypeIssue ? cycle.backlog_issues : cycle.backlog_estimate_points,
started: p === today ? cycle[isTypeIssue ? "started_issues" : "started_estimate_points"] : undefined,
@@ -42,7 +44,11 @@ const formatV1Data = (isTypeIssue: boolean, cycle: ICycle, isBurnDown: boolean,
const formatV2Data = (isTypeIssue: boolean, cycle: ICycle, isBurnDown: boolean, endDate: Date | string) => {
let today: Date | string = startOfToday();
const extendedArray =
endDate > today ? generateDateArray(today as Date, endDate).filter((d) => d.date >= cycle.start_date!) : [];
endDate > today
? generateDateArray(today as Date, endDate).filter(
(d) => d.date >= cycle.start_date! && d.date <= cycle.end_date!
)
: [];
if (!cycle?.progress) return null;
if (isEmpty(cycle.progress)) return generateDateArray(new Date(cycle.start_date!), endDate);
const startDate = cycle.start_date && format(new Date(cycle.start_date), "yyyy-MM-dd");

View File

@@ -1,6 +1,5 @@
"use client";
import { isEmpty } from "lodash";
import { observer } from "mobx-react";
// helpers
import { TCycleEstimateType, TCyclePlotType } from "@plane/types";
@@ -76,8 +75,8 @@ export const SidebarChart = observer((props: TProps) => {
projectId={projectId}
handlePlotChange={handlePlotChange}
handleEstimateChange={handleEstimateChange}
showEstimateSelection={!isEmpty(cycle.estimate_distribution)}
className="!px-0 mt-0"
cycleId={cycle.id}
/>
<div className="flex items-center justify-center gap-2">
<div className="flex items-center gap-1 text-xs">