Skip to content

fix: fix gant style #2211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
getLocaleMonth,
getWeekNumberISO8601,
} from '../../helpers/date-helper';
import { min } from 'lodash';
import { min, max } from 'lodash';
import { DateSetup } from '../../types/date-setup';
import i18n from 'i18n';
import './calendar.scss';
Expand Down Expand Up @@ -162,27 +162,35 @@ export const Calendar: React.FC<CalendarProps> = React.memo(
}
return [topValues, bottomValues];
};

const HoverBar = highlightRange ? (
<div
className="absolute rounded bg-hover-gray-bg"
style={{
width: Math.abs(highlightRange.x2 - highlightRange.x1),
height: 40,
left: min([highlightRange.x1, highlightRange.x2]),
top: 24,
}}
/>
) : null;
const HoverBar = ({ style }: { style: Obj }) =>
highlightRange ? (
<div
className="absolute rounded bg-hover-gray-bg"
style={{
width: Math.abs(highlightRange.x2 - highlightRange.x1),
height: 40,
left: min([highlightRange.x1, highlightRange.x2]),
top: 24,
...style,
}}
/>
) : null;
const getCalendarValuesForDay = () => {
let bottomValues: React.ReactNode = null;
const dates = dateSetup.dates.slice(...horizontalRange);
const dateInWeeks = [];

// append date when screen have more space
let appendDateLength = Math.max(0, horizontalRange[1] - horizontalRange[0] - dates.length);
while (appendDateLength-- > 0) {
const lastDayInLastWeek = dates[dates.length - 1];
dates.push(addToDate(lastDayInLastWeek, 1, 'day'));
}
const firstDay = dates[0];

const firstDayInWeek = firstDay.getDay();
// use Monday as first day of week
const firstWeek = dates.splice(0, firstDayInWeek === 0 ? 7 : 7 - firstDayInWeek + 1);

const firstWeek = dates.splice(0, firstDayInWeek === 0 ? 1 : 7 - firstDayInWeek + 1);
while (firstWeek.length < 7) {
const firstDayInFirstWeek = firstWeek[0];
firstWeek.unshift(addToDate(firstDayInFirstWeek, -1, 'day'));
Expand All @@ -197,12 +205,17 @@ export const Calendar: React.FC<CalendarProps> = React.memo(
lastWeek.push(addToDate(lastDayInLastWeek, 1, 'day'));
}
let leftDis = 0;

bottomValues = (
<div
className="flex h-full w-full erda-gantt-calendar-header-container"
style={{ transform: `translateX(${-(firstDayInWeek + 1) * columnWidth}px)` }}
style={{ transform: `translateX(${-(firstDayInWeek ? firstDayInWeek - 1 : 6) * columnWidth}px)` }}
>
{HoverBar}
{
<HoverBar
style={{ transform: `translateX(${(firstDayInWeek ? firstDayInWeek - 1 : 6) * columnWidth}px)` }}
/>
}
{dateInWeeks.map((week, idx) => {
const weekWidth = columnWidth * week.length;
leftDis += weekWidth;
Expand Down Expand Up @@ -304,23 +317,12 @@ export const Calendar: React.FC<CalendarProps> = React.memo(
// [topValues, bottomValues] = getCalendarValuesForOther();
// break;
// }
const finalWidth = max([columnWidth * dateSetup.dates.length, width]);
return (
<svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} fontFamily={fontFamily}>
<g className="erda-gantt-calendar" fontSize={fontSize}>
<rect
x={0}
y={0}
width={columnWidth * dateSetup.dates.length}
height={height}
className={'erda-gantt-calendar-header'}
/>
<foreignObject
x={0}
y={0}
width={columnWidth * dateSetup.dates.length}
height={height}
className={'erda-gantt-calendar-header'}
>
<rect x={0} y={0} width={finalWidth} height={height} className={'erda-gantt-calendar-header'} />
<foreignObject x={0} y={0} width={finalWidth} height={height} className={'erda-gantt-calendar-header'}>
{getCalendarValuesForDay()}
</foreignObject>
{/* {topValues} */}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
const h_start = Math.abs(Math.ceil(scrollX / columnWidth));
const h_number = Math.floor((horizontalRef.current?.clientWidth || 0) / columnWidth) + 2;
const horizontalRange = [h_start, h_start + h_number];
// console.log('横', horizontalRef.current?.clientWidth, scrollX, horizontalRange, h_number)
// console.log('横', horizontalRef.current?.clientWidth, scrollX, horizontalRange, h_number);

const v_start = Math.abs(Math.ceil(scrollY / rowHeight));
const v_number = Math.floor((ganttHeight || 0) / rowHeight) + 1;
Expand Down Expand Up @@ -407,6 +407,10 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
// position data will update after convert
const newSelectedTask = newTasks.find((item) => item.id === selectedTask?.id);

const reGanttEvent = {
...ganttEvent,
changedTask: ganttEvent?.changedTask ? newTasks.find((item) => item.id === ganttEvent.changedTask.id) : undefined,
};
const gridProps: GridProps = {
columnWidth,
svgWidth,
Expand All @@ -421,7 +425,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
setRangeAddTime,
setSelectedTask: handleSelectedTask,
onDateChange,
ganttEvent,
ganttEvent: reGanttEvent,
verticalRange,
horizontalRange,
};
Expand All @@ -437,12 +441,12 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
fontSize,
rtl,
horizontalRange,
highlightRange: rangeAddTime || ganttEvent.changedTask || newSelectedTask,
highlightRange: rangeAddTime || reGanttEvent.changedTask || newSelectedTask,
};
const barProps: TaskGanttContentProps = {
tasks: newTasks,
dates: dateSetup.dates,
ganttEvent,
ganttEvent: reGanttEvent,
selectedTask: newSelectedTask,
rowHeight,
taskHeight,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import React, { useRef, useEffect } from 'react';
import { GridProps, Grid } from '../grid/grid';
import { CalendarProps, Calendar } from '../calendar/calendar';
import { max } from 'lodash';
import { TaskGanttContentProps, TaskGanttContent } from './task-gantt-content';
import './gantt.scss';

Expand All @@ -27,19 +28,20 @@ export interface TaskGanttProps {
export const TaskGantt: React.FC<TaskGanttProps> = ({ gridProps, calendarProps, barProps, BarContentRender }) => {
const ganttSVGRef = useRef<SVGSVGElement>(null);
const newBarProps = { ...barProps, svg: ganttSVGRef };

const verticalGanttContainerRef = useRef<HTMLDivElement>(null);
const offsetWidth = verticalGanttContainerRef?.current?.offsetWidth;
return (
<div className={'erda-gantt-vertical-container'} dir="ltr">
<Calendar {...calendarProps} />
<div className={'erda-gantt-vertical-container'} dir="ltr" ref={verticalGanttContainerRef}>
<Calendar {...calendarProps} width={max([calendarProps.width, offsetWidth])} />
<svg
xmlns="http://www.w3.org/2000/svg"
width={gridProps.svgWidth}
width={max([gridProps.svgWidth, offsetWidth])}
height={barProps.rowHeight * barProps.tasks.length}
fontFamily={barProps.fontFamily}
style={{ overflow: 'visible' }}
ref={ganttSVGRef}
>
<Grid {...gridProps} />
<Grid {...gridProps} svgWidth={max([gridProps.svgWidth, offsetWidth])} />
<TaskGanttContent {...newBarProps} BarContentRender={BarContentRender} />
</svg>
</div>
Expand Down
24 changes: 20 additions & 4 deletions shell/app/config-page/components/gantt/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import { groupBy, set, findIndex } from 'lodash';
import moment from 'moment';

export const convertDataForGantt = (
data: { expandList: CP_GANTT.IData[]; updateList: CP_GANTT.IData[] },
Expand All @@ -20,21 +21,36 @@ export const convertDataForGantt = (
let ganttData: CP_GANTT.IGanttData[] = [...prevList];

const { expandList, updateList } = data;
const timeConvert = (start: number, end: number) => {
let _start = start && moment(start).startOf('day');
let _end = end && moment(end).endOf('day');
if (!start && end) {
// no start time
_start = moment(_end).startOf('day');
} else if (!end && start) {
_end = moment(_start).endOf('day');
}
return {
start: _start && new Date(_start.valueOf()),
end: _end && new Date(_end.valueOf()),
};
};

const timeLimit = (t) => (t && new Date(t).getTime() > new Date('2019-1-1').getTime() ? t : 0);

const prevDataGroup = { ...groupBy(prevList, 'pId'), ...expandList };

const convert = (dataTemp: CP_GANTT.IData[], level = 0, pId?: string) => {
dataTemp.forEach((item) => {
const { key, title, start, end, isLeaf = true, hideChildren, ...rest } = item;
const validTime = timeLimit(start) && timeLimit(end);
const validTime = timeConvert(start, end);

const curData = {
type: !isLeaf ? 'project' : 'task',
type: !isLeaf ? 'project' : ('task' as CP_GANTT.TaskType),
id: key,
name: title,
start: validTime ? new Date(start) : undefined,
end: validTime ? new Date(end) : undefined,
start: validTime.start,
end: validTime.end,
progress: 0,
isLeaf,
hideChildren: hideChildren === undefined ? (!isLeaf ? !prevDataGroup[key]?.length : undefined) : hideChildren,
Expand Down
40 changes: 10 additions & 30 deletions shell/app/modules/project/pages/issue/plan/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,37 +101,17 @@ const TreeNodeRender = (props: ITreeNodeProps) => {
}}
>
{<IssueIcon type={type} size={'16px'} />}
{!isLeaf ? (
<>
<div className="flex-1 ml-1 w-0" style={{ marginRight: 86 }}>
<div className="truncate">{name}</div>
<div className="flex relative issue-plan-status-total">
{map(statusGroup, (subItem, idx) => (
<div
key={`${idx}`}
className="h-1 issue-plan-status-total-item"
style={{
width: `${(subItem.length / subNodeStatus.length) * 100}%`,
backgroundColor: statusColorMap[subItem?.[0]?.extra?.status?.status],
}}
/>
))}
</div>
<div className="truncate flex-1 ml-1">{name}</div>
<div className="flex items-center ml-2">
<Avatar src={curUser.avatar || undefined} size={16}>
{getAvatarChars(curUserName || '')}
</Avatar>
{status ? (
<div className="ml-1">
<Badge showDot={false} text={status.text} status={status?.status || 'default'} />
</div>
</>
) : (
<>
<div className="truncate flex-1 ml-1">{name}</div>
<div className="flex items-center ml-2">
<Avatar size={16}>{getAvatarChars(curUserName || '')}</Avatar>
{status ? (
<div className="ml-1">
<Badge showDot={false} text={status.text} status={status?.status || 'default'} />
</div>
) : null}
</div>
</>
)}
) : null}
</div>
</div>
);
};
Expand Down