Skip to content

Commit f927e1d

Browse files
committed
fix: gantt calendar error / add time range error (#2220)
* fix: fix gantt * fix: fix header tab split type * fix: fix bar style * fix: fix preview bar box height
1 parent 91bc9ec commit f927e1d

File tree

12 files changed

+72
-47
lines changed

12 files changed

+72
-47
lines changed

shell/app/common/components/menu/index.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface IMenuItem {
2222
key: string;
2323
name: string;
2424
disabled?: boolean;
25+
split?: boolean;
2526
}
2627

2728
interface IMenu {
@@ -112,10 +113,11 @@ const PureMenu = (props: IMenu) => {
112113
<div className={tabClass}>
113114
<ul className="tab-item-wraps">
114115
{finalMenus.map((menu: Merge<IMenuItem, { hrefType: 'back' }>) => {
115-
const { disabled, key, name, hrefType } = menu;
116+
const { disabled, key, name, hrefType, split } = menu;
116117
const menuItemClass = classnames({
117118
'tab-menu-item': true,
118119
'tab-menu-disabled': disabled,
120+
'tab-split-line-before': split,
119121
active: activeKey === key,
120122
});
121123
return (

shell/app/config-page/components/gantt/components/calendar/calendar.tsx

+12-11
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,18 @@ export const Calendar: React.FC<CalendarProps> = React.memo(
162162
}
163163
return [topValues, bottomValues];
164164
};
165+
const reHighlightRange = {
166+
...highlightRange,
167+
...(highlightRange?.id && !highlightRange.start && !highlightRange.end ? { x1: -1, x2: -1 } : {}),
168+
};
165169
const HoverBar = ({ style }: { style: Obj }) =>
166170
highlightRange ? (
167171
<div
168172
className="absolute rounded bg-hover-gray-bg"
169173
style={{
170-
width: Math.abs(highlightRange.x2 - highlightRange.x1),
174+
width: Math.abs(reHighlightRange.x2 - reHighlightRange.x1),
171175
height: 40,
172-
left: min([highlightRange.x1, highlightRange.x2]),
176+
left: min([reHighlightRange.x1, reHighlightRange.x2]),
173177
top: 24,
174178
...style,
175179
}}
@@ -180,6 +184,7 @@ export const Calendar: React.FC<CalendarProps> = React.memo(
180184
const dates = dateSetup.dates.slice(...horizontalRange);
181185
const dateInWeeks = [];
182186
// append date when screen have more space
187+
if (!dates.length) return null;
183188
let appendDateLength = Math.max(0, horizontalRange[1] - horizontalRange[0] - dates.length);
184189
while (appendDateLength-- > 0) {
185190
const lastDayInLastWeek = dates[dates.length - 1];
@@ -205,17 +210,13 @@ export const Calendar: React.FC<CalendarProps> = React.memo(
205210
lastWeek.push(addToDate(lastDayInLastWeek, 1, 'day'));
206211
}
207212
let leftDis = 0;
208-
213+
const offsetX = (firstDayInWeek ? firstDayInWeek - 1 : 6) * columnWidth;
209214
bottomValues = (
210215
<div
211216
className="flex h-full w-full erda-gantt-calendar-header-container"
212-
style={{ transform: `translateX(${-(firstDayInWeek ? firstDayInWeek - 1 : 6) * columnWidth}px)` }}
217+
style={{ transform: `translateX(${-offsetX}px)` }}
213218
>
214-
{
215-
<HoverBar
216-
style={{ transform: `translateX(${(firstDayInWeek ? firstDayInWeek - 1 : 6) * columnWidth}px)` }}
217-
/>
218-
}
219+
{<HoverBar style={{ transform: `translateX(${offsetX}px)` }} />}
219220
{dateInWeeks.map((week, idx) => {
220221
const weekWidth = columnWidth * week.length;
221222
leftDis += weekWidth;
@@ -227,8 +228,8 @@ export const Calendar: React.FC<CalendarProps> = React.memo(
227228
<div className="flex">
228229
{week.map((day, dIdx) => {
229230
const mark =
230-
highlightRange?.x1 === columnWidth * dIdx + leftDis - weekWidth ||
231-
highlightRange?.x2 === columnWidth * (dIdx + 1) + leftDis - weekWidth;
231+
reHighlightRange?.x1 === columnWidth * dIdx + leftDis - weekWidth - offsetX ||
232+
reHighlightRange?.x2 === columnWidth * (dIdx + 1) + leftDis - weekWidth - offsetX;
232233
const cls = `${
233234
mark
234235
? 'calendar-highlight-text'

shell/app/config-page/components/gantt/components/gantt/gantt.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
7272
}) => {
7373
const wrapperRef = useRef<HTMLDivElement>(null);
7474
const taskListRef = useRef<HTMLDivElement>(null);
75+
7576
const [dateSetup, setDateSetup] = useState<DateSetup>(() => {
7677
const [startDate, endDate] = ganttDateRange(tasks, viewMode);
7778
return { viewMode, dates: seedDates(startDate, endDate, viewMode) };
@@ -118,6 +119,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
118119
filteredTasks = tasks;
119120
}
120121
const [startDate, endDate] = ganttDateRange(filteredTasks, viewMode);
122+
121123
const newDates = seedDates(startDate, endDate, viewMode);
122124
// if (rtl) {
123125
// newDates = newDates.reverse();
@@ -126,6 +128,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
126128
// }
127129
// }
128130
setDateSetup({ dates: newDates, viewMode });
131+
129132
setBarTasks(
130133
convertToBarTasks(
131134
filteredTasks,
@@ -358,9 +361,9 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
358361
}
359362
}
360363
if (newSelectedTask?.x1) {
361-
if (scrollX > newSelectedTask.x1) {
364+
if (scrollX > newSelectedTask.x2) {
362365
setScrollX(newSelectedTask.x1 - 40);
363-
} else if (scrollX + horizontalRef.current?.offsetWidth < newSelectedTask.x2) {
366+
} else if (scrollX + horizontalRef.current?.offsetWidth < newSelectedTask.x1) {
364367
setScrollX(newSelectedTask.x2 + 40 - horizontalRef.current.offsetWidth);
365368
}
366369
}

shell/app/config-page/components/gantt/components/grid/grid-body.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const GridBody: React.FC<GridBodyProps> = ({
5151
onDateChange,
5252
ganttEvent,
5353
setRangeAddTime,
54+
horizontalRange,
5455
}) => {
5556
let y = 0;
5657
const gridRows: ReactChild[] = [];
@@ -88,8 +89,8 @@ export const GridBody: React.FC<GridBodyProps> = ({
8889
setEndPos(null);
8990
setChosenTask(null);
9091
};
91-
92-
const addTime = getDateFormX(startPos?.[0], endPos?.[0], dateDelta, columnWidth, dates[0].getTime());
92+
const curDates = dates.slice(...horizontalRange);
93+
const addTime = getDateFormX(startPos?.[0], endPos?.[0], dateDelta, columnWidth, curDates[0]?.getTime());
9394

9495
const onMouseUp = () => {
9596
if (addTime.length && addTime[1] - addTime[0] >= dateDelta * 0.6 && chosenTask) {

shell/app/config-page/components/gantt/components/task-item/bar/bar.scss

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
.erda-gantt-bar-handle-box {
77
.erda-gantt-bar-handle {
88
visibility: hidden;
9+
height: 100%;
10+
display: inline-flex;
11+
align-items: center;
912
}
1013

1114
.left-handle {

shell/app/config-page/components/gantt/components/task-item/bar/bar.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const Bar: React.FC<TaskItemProps> = ({
2929
isSelected,
3030
}) => {
3131
const progressPoint = getProgressPoint(+!rtl * task.progressWidth + task.progressX, task.y, task.height);
32-
const handleHeight = task.height - 2;
32+
const handleHeight = task.height;
3333
const taskWidth = task.x2 - task.x1;
3434

3535
const getBarColor = () => {

shell/app/config-page/components/gantt/components/task-item/task-item.tsx

+20-13
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export type TaskItemProps = {
3232
isSelected: boolean;
3333
rtl: boolean;
3434
ganttEvent: Obj;
35+
isMoving: boolean;
3536
BarContentRender?: React.ReactNode;
3637
onEventStart: (
3738
action: GanttContentMoveAction,
@@ -41,7 +42,18 @@ export type TaskItemProps = {
4142
};
4243

4344
export const TaskItem: React.FC<TaskItemProps> = (props) => {
44-
const { task, arrowIndent, isDelete, taskHeight, isSelected, rtl, onEventStart, BarContentRender, ganttEvent } = {
45+
const {
46+
task,
47+
arrowIndent,
48+
isDelete,
49+
taskHeight,
50+
isSelected,
51+
rtl,
52+
onEventStart,
53+
BarContentRender,
54+
ganttEvent,
55+
isMoving,
56+
} = {
4557
...props,
4658
};
4759
const textRef = useRef<SVGTextElement>(null);
@@ -58,8 +70,9 @@ export const TaskItem: React.FC<TaskItemProps> = (props) => {
5870
});
5971

6072
const { changedTask } = ganttEvent || {};
73+
6174
useUpdateEffect(() => {
62-
if (!changedTask) {
75+
if (!(isSelected && isMoving)) {
6376
setCurPos({
6477
x2: task.x2,
6578
x1: task.x1,
@@ -69,7 +82,7 @@ export const TaskItem: React.FC<TaskItemProps> = (props) => {
6982
end: task.end,
7083
});
7184
}
72-
}, [changedTask, task]);
85+
}, [isSelected, task, isSelected, isMoving]);
7386

7487
useEffect(() => {
7588
switch (task.typeInternal) {
@@ -117,7 +130,7 @@ export const TaskItem: React.FC<TaskItemProps> = (props) => {
117130
// y={curPos.y - 2}
118131
transform={`translate(${curPos.x1 - 4},${curPos.y - 2})`}
119132
width={curPos.x2 - curPos.x1 + 8}
120-
height={curPos.height + 2}
133+
height={curPos.height + 4}
121134
>
122135
<div
123136
className={`text-sm text-desc erda-gantt-task-preview-box bg-white bg-opacity-100 w-full h-full ${
@@ -131,12 +144,6 @@ export const TaskItem: React.FC<TaskItemProps> = (props) => {
131144
) : null}
132145
<g
133146
onKeyDown={(e) => {
134-
switch (e.key) {
135-
case 'Delete': {
136-
if (isDelete) onEventStart('delete', task, e);
137-
break;
138-
}
139-
}
140147
e.stopPropagation();
141148
}}
142149
onMouseEnter={(e) => {
@@ -163,10 +170,10 @@ export const TaskItem: React.FC<TaskItemProps> = (props) => {
163170
onEventStart('select', task);
164171
}}
165172
// style={{ transform: `translate(${task.x1 + 4},${task.y})` }}
166-
transform={`translate(${task.x1 + 4},${task.y})`}
173+
// transform={`translate(${task.x1 + 4},${task.y})`}
167174
// style={{ willChange: 'transform' }}
168-
// x={task.x1 + 4}
169-
// y={task.y}
175+
x={task.x1 + 4}
176+
y={task.y}
170177
width={task.x2 - task.x1 - 8}
171178
height={task.height}
172179
>

shell/app/config-page/components/gantt/gantt.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ const CP_Gantt = (props: CP_GANTT.Props) => {
210210
<Gantt
211211
tasks={list}
212212
rowHeight={40}
213-
barFill={50}
213+
barFill={60}
214214
ganttHeight={ganttHeight}
215215
onDateChange={handleTaskChange}
216216
BarContentRender={BarContentRender}

shell/app/config-page/mock/crud.mock.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,8 @@ export const mockData = {
243243
{
244244
id: '1-5',
245245
name: 'T1-5测试测试测试测试测试测试测试测试测试测试测试',
246-
start: new Date('2019-1-1').getTime(),
247-
end: getDate(10),
246+
start: getDate(1),
247+
end: getDate(30),
248248
isLeaf: true,
249249
extra: {
250250
type: 'task',

shell/app/layout/pages/page-container/components/header.scss

+11
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@
5959
.tab-menu .tab-menu-item {
6060
height: 32px;
6161
line-height: 32px;
62+
&.tab-split-line-before {
63+
&::before {
64+
position: absolute;
65+
content: '';
66+
width: 1px;
67+
height: 12px;
68+
left: -20px;
69+
top: 10px;
70+
background-color: $color-text-desc;
71+
}
72+
}
6273
}
6374
}
6475

shell/app/modules/project/pages/issue/plan/index.tsx

+4-9
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,14 @@
1414
import React from 'react';
1515
import DiceConfigPage, { useMock } from 'app/config-page';
1616
import { ISSUE_TYPE } from 'project/common/components/issue/issue-config';
17-
import { getUrlQuery, statusColorMap } from 'config-page/utils';
17+
import { getUrlQuery } from 'config-page/utils';
1818
import { getAvatarChars, updateSearch, mergeSearch } from 'common/utils';
1919
import { Badge, ErdaIcon } from 'common';
2020
import { useUserMap } from 'core/stores/userMap';
2121
import { useUpdate, useSwitch } from 'common/use-hooks';
2222
import { IssueIcon } from 'project/common/components/issue/issue-icon';
2323
import routeInfoStore from 'core/stores/route';
2424
import { Avatar, Select } from 'antd';
25-
import { groupBy, map } from 'lodash';
2625
import moment from 'moment';
2726
import i18n from 'i18n';
2827
import EditIssueDrawer, { CloseDrawerParam } from 'project/common/components/issue/edit-issue-drawer';
@@ -47,7 +46,7 @@ const BarContentRender = (props: IBarProps) => {
4746
{task.name}
4847
</span>
4948
</div>
50-
<div className={`absolute text-sub text-xs ${isHover ? 'visible' : 'invisible'}`} style={{ right: -150, top: 1 }}>
49+
<div className={`absolute text-sub text-xs ${isHover ? 'visible' : 'invisible'}`} style={{ right: -150, top: 4 }}>
5150
{moment(task.start).format('YYYY-MM-DD')} ~ {moment(task.end).format('YYYY-MM-DD')}
5251
</div>
5352
</div>
@@ -77,16 +76,12 @@ const TaskListHeader = (props: { headerHeight: number; rowWidth: number }) => {
7776

7877
interface ITreeNodeProps {
7978
node: CP_GANTT.IGanttData;
80-
originList: CP_GANTT.IGanttData[];
8179
clickNode?: (params: Obj) => void;
8280
}
8381

8482
const TreeNodeRender = (props: ITreeNodeProps) => {
85-
const { node, originList, clickNode } = props;
86-
const { extra, name, id, isLeaf } = node;
87-
const tasksGroup = groupBy(originList || [], 'project');
88-
const subNodeStatus = tasksGroup[id] || [];
89-
const statusGroup = groupBy(subNodeStatus, 'extra.status.status');
83+
const { node, clickNode } = props;
84+
const { extra, name } = node;
9085
const { status, type, user } = extra || {};
9186
const userMap = useUserMap();
9287
const curUser = userMap[user];

shell/app/modules/project/tabs.tsx

+7-5
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,7 @@ export const PROJECT_TABS = () => {
107107
name: i18n.t('dop:backlog'),
108108
show: projectPerm.backLog.viewBackLog.pass,
109109
},
110-
{
111-
key: 'plan',
112-
name: i18n.t('plan'),
113-
show: projectPerm.requirement.read.pass,
114-
},
110+
115111
{
116112
key: 'iteration',
117113
name: i18n.t('dop:sprint'),
@@ -137,6 +133,12 @@ export const PROJECT_TABS = () => {
137133
name: i18n.t('bug'),
138134
show: projectPerm.bug.read.pass,
139135
},
136+
{
137+
key: 'plan',
138+
name: i18n.t('plan'),
139+
show: projectPerm.requirement.read.pass,
140+
split: true,
141+
},
140142
];
141143
};
142144

0 commit comments

Comments
 (0)