mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-02 03:02:19 +08:00
feat: style module -> emotion css
This commit is contained in:
parent
5f8cb58d7e
commit
24cf984191
@ -1,4 +1,6 @@
|
|||||||
import React, { ReactChild } from 'react';
|
import React, { ReactChild } from 'react';
|
||||||
|
import { cx } from '@emotion/css';
|
||||||
|
import { DateSetup } from '../../types/date-setup';
|
||||||
import { ViewMode } from '../../types/public-types';
|
import { ViewMode } from '../../types/public-types';
|
||||||
import { TopPartOfCalendar } from './top-part-of-calendar';
|
import { TopPartOfCalendar } from './top-part-of-calendar';
|
||||||
import {
|
import {
|
||||||
@ -8,8 +10,7 @@ import {
|
|||||||
getLocaleMonth,
|
getLocaleMonth,
|
||||||
getWeekNumberISO8601,
|
getWeekNumberISO8601,
|
||||||
} from '../../helpers/date-helper';
|
} from '../../helpers/date-helper';
|
||||||
import { DateSetup } from '../../types/date-setup';
|
import { calendarBottomText, calendarHeader } from './style';
|
||||||
import styles from './calendar.css';
|
|
||||||
|
|
||||||
export type CalendarProps = {
|
export type CalendarProps = {
|
||||||
dateSetup: DateSetup;
|
dateSetup: DateSetup;
|
||||||
@ -44,7 +45,7 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|||||||
key={date.getTime()}
|
key={date.getTime()}
|
||||||
y={headerHeight * 0.8}
|
y={headerHeight * 0.8}
|
||||||
x={columnWidth * i + columnWidth * 0.5}
|
x={columnWidth * i + columnWidth * 0.5}
|
||||||
className={styles.calendarBottomText}
|
className={cx(calendarBottomText)}
|
||||||
>
|
>
|
||||||
{bottomValue}
|
{bottomValue}
|
||||||
</text>,
|
</text>,
|
||||||
@ -86,7 +87,7 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|||||||
key={date.getTime()}
|
key={date.getTime()}
|
||||||
y={headerHeight * 0.8}
|
y={headerHeight * 0.8}
|
||||||
x={columnWidth * i + columnWidth * 0.5}
|
x={columnWidth * i + columnWidth * 0.5}
|
||||||
className={styles.calendarBottomText}
|
className={cx(calendarBottomText)}
|
||||||
>
|
>
|
||||||
{quarter}
|
{quarter}
|
||||||
</text>,
|
</text>,
|
||||||
@ -127,7 +128,7 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|||||||
key={bottomValue + date.getFullYear()}
|
key={bottomValue + date.getFullYear()}
|
||||||
y={headerHeight * 0.8}
|
y={headerHeight * 0.8}
|
||||||
x={columnWidth * i + columnWidth * 0.5}
|
x={columnWidth * i + columnWidth * 0.5}
|
||||||
className={styles.calendarBottomText}
|
className={cx(calendarBottomText)}
|
||||||
>
|
>
|
||||||
{bottomValue}
|
{bottomValue}
|
||||||
</text>,
|
</text>,
|
||||||
@ -177,7 +178,7 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|||||||
key={date.getTime()}
|
key={date.getTime()}
|
||||||
y={headerHeight * 0.8}
|
y={headerHeight * 0.8}
|
||||||
x={columnWidth * (i + +rtl)}
|
x={columnWidth * (i + +rtl)}
|
||||||
className={styles.calendarBottomText}
|
className={cx(calendarBottomText)}
|
||||||
>
|
>
|
||||||
{bottomValue}
|
{bottomValue}
|
||||||
</text>,
|
</text>,
|
||||||
@ -219,7 +220,7 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|||||||
key={date.getTime()}
|
key={date.getTime()}
|
||||||
y={headerHeight * 0.8}
|
y={headerHeight * 0.8}
|
||||||
x={columnWidth * i + columnWidth * 0.5}
|
x={columnWidth * i + columnWidth * 0.5}
|
||||||
className={styles.calendarBottomText}
|
className={cx(calendarBottomText)}
|
||||||
>
|
>
|
||||||
{bottomValue}
|
{bottomValue}
|
||||||
</text>,
|
</text>,
|
||||||
@ -261,7 +262,7 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|||||||
key={date.getTime()}
|
key={date.getTime()}
|
||||||
y={headerHeight * 0.8}
|
y={headerHeight * 0.8}
|
||||||
x={columnWidth * (i + +rtl)}
|
x={columnWidth * (i + +rtl)}
|
||||||
className={styles.calendarBottomText}
|
className={cx(calendarBottomText)}
|
||||||
fontFamily={fontFamily}
|
fontFamily={fontFamily}
|
||||||
>
|
>
|
||||||
{bottomValue}
|
{bottomValue}
|
||||||
@ -306,7 +307,7 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|||||||
key={date.getTime()}
|
key={date.getTime()}
|
||||||
y={headerHeight * 0.8}
|
y={headerHeight * 0.8}
|
||||||
x={columnWidth * (i + +rtl)}
|
x={columnWidth * (i + +rtl)}
|
||||||
className={styles.calendarBottomText}
|
className={cx(calendarBottomText)}
|
||||||
fontFamily={fontFamily}
|
fontFamily={fontFamily}
|
||||||
>
|
>
|
||||||
{bottomValue}
|
{bottomValue}
|
||||||
@ -368,7 +369,7 @@ export const Calendar: React.FC<CalendarProps> = ({
|
|||||||
y={0}
|
y={0}
|
||||||
width={columnWidth * dateSetup.dates.length}
|
width={columnWidth * dateSetup.dates.length}
|
||||||
height={headerHeight}
|
height={headerHeight}
|
||||||
className={styles.calendarHeader}
|
className={cx(calendarHeader)}
|
||||||
/>
|
/>
|
||||||
{bottomValues} {topValues}
|
{bottomValues} {topValues}
|
||||||
</g>
|
</g>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
.calendarBottomText {
|
import { css } from '@emotion/css';
|
||||||
|
|
||||||
|
export const calendarBottomText = css`
|
||||||
text-anchor: middle;
|
text-anchor: middle;
|
||||||
fill: #333;
|
fill: #333;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
@ -7,13 +9,13 @@
|
|||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
`;
|
||||||
|
|
||||||
.calendarTopTick {
|
export const calendarTopTick = css`
|
||||||
stroke: #e6e4e4;
|
stroke: #e6e4e4;
|
||||||
}
|
`;
|
||||||
|
|
||||||
.calendarTopText {
|
export const calendarTopText = css`
|
||||||
text-anchor: middle;
|
text-anchor: middle;
|
||||||
fill: #555;
|
fill: #555;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
@ -22,10 +24,10 @@
|
|||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
`;
|
||||||
|
|
||||||
.calendarHeader {
|
export const calendarHeader = css`
|
||||||
fill: #ffffff;
|
fill: #ffffff;
|
||||||
stroke: #e0e0e0;
|
stroke: #e0e0e0;
|
||||||
stroke-width: 1.4;
|
stroke-width: 1.4;
|
||||||
}
|
`;
|
@ -1,5 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import styles from "./calendar.css";
|
import { cx } from '@emotion/css';
|
||||||
|
import { calendarTopTick, calendarTopText } from './style';
|
||||||
|
|
||||||
|
|
||||||
type TopPartOfCalendarProps = {
|
type TopPartOfCalendarProps = {
|
||||||
value: string;
|
value: string;
|
||||||
@ -25,14 +27,14 @@ export const TopPartOfCalendar: React.FC<TopPartOfCalendarProps> = ({
|
|||||||
y1={y1Line}
|
y1={y1Line}
|
||||||
x2={x1Line}
|
x2={x1Line}
|
||||||
y2={y2Line}
|
y2={y2Line}
|
||||||
className={styles.calendarTopTick}
|
className={cx(calendarTopTick)}
|
||||||
key={value + "line"}
|
key={value + "line"}
|
||||||
/>
|
/>
|
||||||
<text
|
<text
|
||||||
key={value + "text"}
|
key={value + "text"}
|
||||||
y={yText}
|
y={yText}
|
||||||
x={xText}
|
x={xText}
|
||||||
className={styles.calendarTopText}
|
className={cx(calendarTopText)}
|
||||||
>
|
>
|
||||||
{value}
|
{value}
|
||||||
</text>
|
</text>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useState, SyntheticEvent, useRef, useEffect, useMemo } from 'react';
|
import React, { useState, SyntheticEvent, useRef, useEffect, useMemo } from 'react';
|
||||||
import { useFieldSchema, Schema, RecursionField } from '@formily/react';
|
import { useFieldSchema, Schema, RecursionField } from '@formily/react';
|
||||||
|
import { cx } from '@emotion/css';
|
||||||
import { Task } from '../../types/public-types';
|
import { Task } from '../../types/public-types';
|
||||||
import { GridProps } from '../grid/grid';
|
import { GridProps } from '../grid/grid';
|
||||||
import { ganttDateRange, seedDates } from '../../helpers/date-helper';
|
import { ganttDateRange, seedDates } from '../../helpers/date-helper';
|
||||||
@ -14,16 +15,16 @@ import { GanttEvent } from '../../types/gantt-task-actions';
|
|||||||
import { DateSetup } from '../../types/date-setup';
|
import { DateSetup } from '../../types/date-setup';
|
||||||
import { HorizontalScroll } from '../other/horizontal-scroll';
|
import { HorizontalScroll } from '../other/horizontal-scroll';
|
||||||
import { removeHiddenTasks, sortTasks } from '../../helpers/other-helper';
|
import { removeHiddenTasks, sortTasks } from '../../helpers/other-helper';
|
||||||
import styles from './gantt.css';
|
import { wrapper } from './style';
|
||||||
import { GanttToolbarContext } from '../../context';
|
import { GanttToolbarContext } from '../../context';
|
||||||
import { useDesignable } from '../../../../../schema-component';
|
import { useDesignable } from '../../../../../schema-component';
|
||||||
import { TableBlockProvider, useGanttBlockContext, useBlockRequestContext } from '../../../../../block-provider';
|
import { TableBlockProvider, useGanttBlockContext, useBlockRequestContext } from '../../../../../block-provider';
|
||||||
|
|
||||||
function Toolbar(props) {
|
function Toolbar(props:any) {
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const toolBarSchema: Schema = useMemo(
|
const toolBarSchema: Schema = useMemo(
|
||||||
() =>
|
() =>
|
||||||
fieldSchema.reduceProperties((buf, current) => {
|
fieldSchema.reduceProperties((buf:any, current:any) => {
|
||||||
if (current['x-component'].endsWith('.ActionBar')) {
|
if (current['x-component'].endsWith('.ActionBar')) {
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
@ -38,12 +39,12 @@ function Toolbar(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getColumnWidth = (dataSetLength, clientWidth) => {
|
const getColumnWidth = (dataSetLength:any, clientWidth:any) => {
|
||||||
const columnWidth = clientWidth / dataSetLength > 50 ? Math.floor(clientWidth / dataSetLength) + 20 : 50;
|
const columnWidth = clientWidth / dataSetLength > 50 ? Math.floor(clientWidth / dataSetLength) + 20 : 50;
|
||||||
return columnWidth;
|
return columnWidth;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Gantt: any = (props) => {
|
export const Gantt: any = (props:any) => {
|
||||||
const { designable } = useDesignable();
|
const { designable } = useDesignable();
|
||||||
const {
|
const {
|
||||||
headerHeight = designable ? 65 : 55,
|
headerHeight = designable ? 65 : 55,
|
||||||
@ -363,12 +364,12 @@ export const Gantt: any = (props) => {
|
|||||||
setSelectedTask(newSelectedTask);
|
setSelectedTask(newSelectedTask);
|
||||||
};
|
};
|
||||||
const handleTableExpanderClick = (expanded: boolean, record: any) => {
|
const handleTableExpanderClick = (expanded: boolean, record: any) => {
|
||||||
const task = tasks.find((v) => v.id === record.id + '');
|
const task = tasks.find((v:any) => v.id === record.id + '');
|
||||||
if (onExpanderClick && record.children.length) {
|
if (onExpanderClick && record.children.length) {
|
||||||
onExpanderClick({ ...task, hideChildren: !expanded });
|
onExpanderClick({ ...task, hideChildren: !expanded });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleProgressChange = async (task) => {
|
const handleProgressChange = async (task:Task) => {
|
||||||
await resource.update({
|
await resource.update({
|
||||||
filterByTk: task.id,
|
filterByTk: task.id,
|
||||||
values: {
|
values: {
|
||||||
@ -377,7 +378,7 @@ export const Gantt: any = (props) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const handleTaskChange = async (task) => {
|
const handleTaskChange = async (task:Task) => {
|
||||||
await resource.update({
|
await resource.update({
|
||||||
filterByTk: task.id,
|
filterByTk: task.id,
|
||||||
values: {
|
values: {
|
||||||
@ -448,7 +449,7 @@ export const Gantt: any = (props) => {
|
|||||||
<RecursionField name={'table'} schema={fieldSchema.properties.table} />
|
<RecursionField name={'table'} schema={fieldSchema.properties.table} />
|
||||||
</TableBlockProvider>
|
</TableBlockProvider>
|
||||||
|
|
||||||
<div className={styles.wrapper} onKeyDown={handleKeyDown} tabIndex={0} ref={wrapperRef}>
|
<div className={cx(wrapper)} onKeyDown={handleKeyDown} tabIndex={0} ref={wrapperRef}>
|
||||||
<TaskGantt
|
<TaskGantt
|
||||||
gridProps={gridProps}
|
gridProps={gridProps}
|
||||||
calendarProps={calendarProps}
|
calendarProps={calendarProps}
|
||||||
|
@ -1,22 +1,25 @@
|
|||||||
.ganttVerticalContainer {
|
|
||||||
|
import { css } from '@emotion/css';
|
||||||
|
|
||||||
|
export const ganttVerticalContainer=css `
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width:100%
|
width:100%
|
||||||
}
|
`
|
||||||
|
|
||||||
.horizontalContainer {
|
export const horizontalContainer=css `
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
`
|
||||||
|
|
||||||
.wrapper {
|
export const wrapper =css`
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
`
|
@ -1,8 +1,10 @@
|
|||||||
import React, { useRef, useEffect, forwardRef } from 'react';
|
import React, { useRef, useEffect, forwardRef } from 'react';
|
||||||
|
import { cx } from '@emotion/css';
|
||||||
import { GridProps, Grid } from '../grid/grid';
|
import { GridProps, Grid } from '../grid/grid';
|
||||||
import { CalendarProps, Calendar } from '../calendar/calendar';
|
import { CalendarProps, Calendar } from '../calendar/calendar';
|
||||||
import { TaskGanttContentProps, TaskGanttContent } from './task-gantt-content';
|
import { TaskGanttContentProps, TaskGanttContent } from './task-gantt-content';
|
||||||
import styles from './gantt.css';
|
import { ganttVerticalContainer,horizontalContainer } from './style';
|
||||||
|
|
||||||
|
|
||||||
export type TaskGanttProps = {
|
export type TaskGanttProps = {
|
||||||
gridProps: GridProps;
|
gridProps: GridProps;
|
||||||
@ -32,7 +34,7 @@ export const TaskGantt: React.FC<TaskGanttProps> = forwardRef(
|
|||||||
}, [scrollX]);
|
}, [scrollX]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.ganttVerticalContainer} ref={ref} dir="ltr">
|
<div className={cx(ganttVerticalContainer)} ref={ref} dir="ltr">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width={gridProps.svgWidth}
|
width={gridProps.svgWidth}
|
||||||
@ -43,7 +45,7 @@ export const TaskGantt: React.FC<TaskGanttProps> = forwardRef(
|
|||||||
</svg>
|
</svg>
|
||||||
<div
|
<div
|
||||||
ref={horizontalContainerRef}
|
ref={horizontalContainerRef}
|
||||||
className={styles.horizontalContainer}
|
className={cx(horizontalContainer)}
|
||||||
style={ganttHeight ? { height: ganttHeight, width: gridProps.svgWidth } : { width: gridProps.svgWidth }}
|
style={ganttHeight ? { height: ganttHeight, width: gridProps.svgWidth } : { width: gridProps.svgWidth }}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import React, { ReactChild } from "react";
|
import React, { ReactChild } from "react";
|
||||||
|
import { cx } from '@emotion/css';
|
||||||
import { Task } from "../../types/public-types";
|
import { Task } from "../../types/public-types";
|
||||||
import { addToDate } from "../../helpers/date-helper";
|
import { addToDate } from "../../helpers/date-helper";
|
||||||
import styles from "./grid.css";
|
import { gridRowLine, gridRow,gridTick } from './style';
|
||||||
|
|
||||||
export type GridBodyProps = {
|
export type GridBodyProps = {
|
||||||
tasks: Task[];
|
tasks: Task[];
|
||||||
@ -30,7 +31,7 @@ export const GridBody: React.FC<GridBodyProps> = ({
|
|||||||
y1={0}
|
y1={0}
|
||||||
x2={svgWidth}
|
x2={svgWidth}
|
||||||
y2={0}
|
y2={0}
|
||||||
className={styles.gridRowLine}
|
className={cx(gridRowLine)}
|
||||||
/>,
|
/>,
|
||||||
];
|
];
|
||||||
for (const task of tasks) {
|
for (const task of tasks) {
|
||||||
@ -41,7 +42,7 @@ export const GridBody: React.FC<GridBodyProps> = ({
|
|||||||
y={y}
|
y={y}
|
||||||
width={svgWidth}
|
width={svgWidth}
|
||||||
height={rowHeight}
|
height={rowHeight}
|
||||||
className={styles.gridRow}
|
className={cx(gridRow)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
rowLines.push(
|
rowLines.push(
|
||||||
@ -51,7 +52,7 @@ export const GridBody: React.FC<GridBodyProps> = ({
|
|||||||
y1={y + rowHeight}
|
y1={y + rowHeight}
|
||||||
x2={svgWidth}
|
x2={svgWidth}
|
||||||
y2={y + rowHeight}
|
y2={y + rowHeight}
|
||||||
className={styles.gridRowLine}
|
className={cx(gridRowLine)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
y += rowHeight;
|
y += rowHeight;
|
||||||
@ -70,7 +71,7 @@ export const GridBody: React.FC<GridBodyProps> = ({
|
|||||||
y1={0}
|
y1={0}
|
||||||
x2={tickX}
|
x2={tickX}
|
||||||
y2={y}
|
y2={y}
|
||||||
className={styles.gridTick}
|
className={cx(gridTick)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
if (
|
if (
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
.gridRow {
|
|
||||||
fill: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gridRow:nth-child(even) {
|
|
||||||
fill: #f5f5f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gridRowLine {
|
|
||||||
stroke: #ebeff2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gridTick {
|
|
||||||
stroke: #e6e4e4;
|
|
||||||
}
|
|
@ -0,0 +1,15 @@
|
|||||||
|
import { css } from '@emotion/css';
|
||||||
|
export const gridRow = css`
|
||||||
|
fill: #fff;
|
||||||
|
&:nth-child(even) {
|
||||||
|
fill: #f5f5f5;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const gridRowLine = css`
|
||||||
|
stroke: #ebeff2;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const gridTick = css`
|
||||||
|
stroke: #e6e4e4;
|
||||||
|
`;
|
@ -1,33 +0,0 @@
|
|||||||
.scrollWrapper {
|
|
||||||
overflow: auto;
|
|
||||||
max-width: 100%;
|
|
||||||
/*firefox*/
|
|
||||||
scrollbar-width: thin;
|
|
||||||
/*iPad*/
|
|
||||||
height: 1.2rem;
|
|
||||||
}
|
|
||||||
.scrollWrapper::-webkit-scrollbar {
|
|
||||||
width: 1.1rem;
|
|
||||||
height: 1.1rem;
|
|
||||||
}
|
|
||||||
.scrollWrapper::-webkit-scrollbar-corner {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
.scrollWrapper::-webkit-scrollbar-thumb {
|
|
||||||
border: 6px solid transparent;
|
|
||||||
background: rgba(0, 0, 0, 0.2);
|
|
||||||
background: var(--palette-black-alpha-20, rgba(0, 0, 0, 0.2));
|
|
||||||
border-radius: 10px;
|
|
||||||
background-clip: padding-box;
|
|
||||||
}
|
|
||||||
.scrollWrapper::-webkit-scrollbar-thumb:hover {
|
|
||||||
border: 4px solid transparent;
|
|
||||||
background: rgba(0, 0, 0, 0.3);
|
|
||||||
background: var(--palette-black-alpha-30, rgba(0, 0, 0, 0.3));
|
|
||||||
background-clip: padding-box;
|
|
||||||
}
|
|
||||||
@media only screen and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) {
|
|
||||||
}
|
|
||||||
.scroll {
|
|
||||||
height: 1px;
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
import React, { SyntheticEvent, useRef, useEffect } from "react";
|
import React, { SyntheticEvent, useRef, useEffect } from "react";
|
||||||
import styles from "./horizontal-scroll.css";
|
import { cx } from '@emotion/css';
|
||||||
|
import {scrollWrapper,horizontalScroll} from './style'
|
||||||
|
|
||||||
export const HorizontalScroll: React.FC<{
|
export const HorizontalScroll: React.FC<{
|
||||||
scroll: number;
|
scroll: number;
|
||||||
@ -24,11 +25,11 @@ export const HorizontalScroll: React.FC<{
|
|||||||
? `0px ${taskListWidth}px 0px 0px`
|
? `0px ${taskListWidth}px 0px 0px`
|
||||||
: `0px 0px 0px ${taskListWidth}px`,
|
: `0px 0px 0px ${taskListWidth}px`,
|
||||||
}}
|
}}
|
||||||
className={styles.scrollWrapper}
|
className={cx(scrollWrapper)}
|
||||||
onScroll={onScroll}
|
onScroll={onScroll}
|
||||||
ref={scrollRef}
|
ref={scrollRef}
|
||||||
>
|
>
|
||||||
<div style={{ width: svgWidth }} className={styles.scroll} />
|
<div style={{ width: svgWidth }} className={cx(horizontalScroll)} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
import { css } from '@emotion/css';
|
||||||
|
|
||||||
|
export const scrollWrapper =css`
|
||||||
|
overflow: auto;
|
||||||
|
max-width: 100%;
|
||||||
|
/*firefox*/
|
||||||
|
scrollbar-width: thin;
|
||||||
|
/*iPad*/
|
||||||
|
height: 1.2rem;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 1.1rem;
|
||||||
|
height: 1.1rem;
|
||||||
|
};
|
||||||
|
&::-webkit-scrollbar-corner {
|
||||||
|
background: transparent;
|
||||||
|
};
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
border: 6px solid transparent;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
background: var(--palette-black-alpha-20, rgba(0, 0, 0, 0.2));
|
||||||
|
border-radius: 10px;
|
||||||
|
background-clip: padding-box;
|
||||||
|
};
|
||||||
|
&::-webkit-scrollbar-thumb:hover {
|
||||||
|
border: 4px solid transparent;
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
background: var(--palette-black-alpha-30, rgba(0, 0, 0, 0.3));
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const horizontalScroll =css`
|
||||||
|
height: 1px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const tooltipDefaultContainer =css`
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px;
|
||||||
|
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
|
||||||
|
`
|
||||||
|
|
||||||
|
export const tooltipDefaultContainerParagraph =css`
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
color: #666;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const tooltipDetailsContainer =css`
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const tooltipDetailsContainerHidden= css`
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
pointer-events: none;
|
||||||
|
`
|
||||||
|
|
||||||
|
|
||||||
|
export const verticalScroll =css`
|
||||||
|
overflow: hidden auto;
|
||||||
|
width: 1rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
/*firefox*/
|
||||||
|
scrollbar-width: thin;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 1.1rem;
|
||||||
|
height: 1.1rem;
|
||||||
|
};
|
||||||
|
&::-webkit-scrollbar-corner {
|
||||||
|
background: transparent;
|
||||||
|
};
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
border: 6px solid transparent;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
background: var(--palette-black-alpha-20, rgba(0, 0, 0, 0.2));
|
||||||
|
border-radius: 10px;
|
||||||
|
background-clip: padding-box;
|
||||||
|
};
|
||||||
|
&::-webkit-scrollbar-thumb:hover {
|
||||||
|
border: 4px solid transparent;
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
background: var(--palette-black-alpha-30, rgba(0, 0, 0, 0.3));
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
.tooltipDefaultContainer {
|
|
||||||
background: #fff;
|
|
||||||
padding: 12px;
|
|
||||||
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltipDefaultContainerParagraph {
|
|
||||||
font-size: 12px;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltipDetailsContainer {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltipDetailsContainerHidden {
|
|
||||||
visibility: hidden;
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
@ -1,7 +1,13 @@
|
|||||||
import React, { useRef, useEffect, useState } from "react";
|
import React, { useRef, useEffect, useState } from 'react';
|
||||||
import { Task } from "../../types/public-types";
|
import { cx } from '@emotion/css';
|
||||||
import { BarTask } from "../../types/bar-task";
|
import { Task } from '../../types/public-types';
|
||||||
import styles from "./tooltip.css";
|
import { BarTask } from '../../types/bar-task';
|
||||||
|
import {
|
||||||
|
tooltipDefaultContainer,
|
||||||
|
tooltipDetailsContainer,
|
||||||
|
tooltipDetailsContainerHidden,
|
||||||
|
tooltipDefaultContainerParagraph,
|
||||||
|
} from './style';
|
||||||
|
|
||||||
export type TooltipProps = {
|
export type TooltipProps = {
|
||||||
task: BarTask;
|
task: BarTask;
|
||||||
@ -63,12 +69,7 @@ export const Tooltip: React.FC<TooltipProps> = ({
|
|||||||
const tooltipLeftmostPoint = tooltipWidth + newRelatedX;
|
const tooltipLeftmostPoint = tooltipWidth + newRelatedX;
|
||||||
const fullChartWidth = taskListWidth + svgContainerWidth;
|
const fullChartWidth = taskListWidth + svgContainerWidth;
|
||||||
if (tooltipLeftmostPoint > fullChartWidth) {
|
if (tooltipLeftmostPoint > fullChartWidth) {
|
||||||
newRelatedX =
|
newRelatedX = task.x1 + taskListWidth - arrowIndent * 1.5 - scrollX - tooltipWidth;
|
||||||
task.x1 +
|
|
||||||
taskListWidth -
|
|
||||||
arrowIndent * 1.5 -
|
|
||||||
scrollX -
|
|
||||||
tooltipWidth;
|
|
||||||
}
|
}
|
||||||
if (newRelatedX < taskListWidth) {
|
if (newRelatedX < taskListWidth) {
|
||||||
newRelatedX = svgContainerWidth + taskListWidth - tooltipWidth;
|
newRelatedX = svgContainerWidth + taskListWidth - tooltipWidth;
|
||||||
@ -100,11 +101,7 @@ export const Tooltip: React.FC<TooltipProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={tooltipRef}
|
ref={tooltipRef}
|
||||||
className={
|
className={relatedX ? cx(tooltipDetailsContainer) : cx(tooltipDetailsContainerHidden)}
|
||||||
relatedX
|
|
||||||
? styles.tooltipDetailsContainer
|
|
||||||
: styles.tooltipDetailsContainerHidden
|
|
||||||
}
|
|
||||||
style={{ left: relatedX, top: relatedY }}
|
style={{ left: relatedX, top: relatedY }}
|
||||||
>
|
>
|
||||||
<TooltipContent task={task} fontSize={fontSize} fontFamily={fontFamily} />
|
<TooltipContent task={task} fontSize={fontSize} fontFamily={fontFamily} />
|
||||||
@ -122,24 +119,18 @@ export const StandardTooltipContent: React.FC<{
|
|||||||
fontFamily,
|
fontFamily,
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className={styles.tooltipDefaultContainer} style={style}>
|
<div className={cx(tooltipDefaultContainer)} style={style}>
|
||||||
<b style={{ fontSize: fontSize + 6 }}>{`${
|
<b style={{ fontSize: fontSize + 6 }}>{`${task.name}: ${task.start.getDate()}-${
|
||||||
task.name
|
|
||||||
}: ${task.start.getDate()}-${
|
|
||||||
task.start.getMonth() + 1
|
task.start.getMonth() + 1
|
||||||
}-${task.start.getFullYear()} - ${task.end.getDate()}-${
|
}-${task.start.getFullYear()} - ${task.end.getDate()}-${task.end.getMonth() + 1}-${task.end.getFullYear()}`}</b>
|
||||||
task.end.getMonth() + 1
|
|
||||||
}-${task.end.getFullYear()}`}</b>
|
|
||||||
{task.end.getTime() - task.start.getTime() !== 0 && (
|
{task.end.getTime() - task.start.getTime() !== 0 && (
|
||||||
<p className={styles.tooltipDefaultContainerParagraph}>{`Duration: ${~~(
|
<p className={cx(tooltipDefaultContainerParagraph)}>{`Duration: ${~~(
|
||||||
(task.end.getTime() - task.start.getTime()) /
|
(task.end.getTime() - task.start.getTime()) /
|
||||||
(1000 * 60 * 60 * 24)
|
(1000 * 60 * 60 * 24)
|
||||||
)} day(s)`}</p>
|
)} day(s)`}</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<p className={styles.tooltipDefaultContainerParagraph}>
|
<p className={cx(tooltipDefaultContainerParagraph)}>{!!task.progress && `Progress: ${task.progress} %`}</p>
|
||||||
{!!task.progress && `Progress: ${task.progress} %`}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
.scroll {
|
|
||||||
overflow: hidden auto;
|
|
||||||
width: 1rem;
|
|
||||||
flex-shrink: 0;
|
|
||||||
/*firefox*/
|
|
||||||
scrollbar-width: thin;
|
|
||||||
}
|
|
||||||
.scroll::-webkit-scrollbar {
|
|
||||||
width: 1.1rem;
|
|
||||||
height: 1.1rem;
|
|
||||||
}
|
|
||||||
.scroll::-webkit-scrollbar-corner {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
.scroll::-webkit-scrollbar-thumb {
|
|
||||||
border: 6px solid transparent;
|
|
||||||
background: rgba(0, 0, 0, 0.2);
|
|
||||||
background: var(--palette-black-alpha-20, rgba(0, 0, 0, 0.2));
|
|
||||||
border-radius: 10px;
|
|
||||||
background-clip: padding-box;
|
|
||||||
}
|
|
||||||
.scroll::-webkit-scrollbar-thumb:hover {
|
|
||||||
border: 4px solid transparent;
|
|
||||||
background: rgba(0, 0, 0, 0.3);
|
|
||||||
background: var(--palette-black-alpha-30, rgba(0, 0, 0, 0.3));
|
|
||||||
background-clip: padding-box;
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
import React, { SyntheticEvent, useRef, useEffect } from "react";
|
import React, { SyntheticEvent, useRef, useEffect } from 'react';
|
||||||
import styles from "./vertical-scroll.css";
|
import { cx } from '@emotion/css';
|
||||||
|
import { verticalScroll } from './style';
|
||||||
|
|
||||||
export const VerticalScroll: React.FC<{
|
export const VerticalScroll: React.FC<{
|
||||||
scroll: number;
|
scroll: number;
|
||||||
@ -8,14 +9,7 @@ export const VerticalScroll: React.FC<{
|
|||||||
headerHeight: number;
|
headerHeight: number;
|
||||||
rtl: boolean;
|
rtl: boolean;
|
||||||
onScroll: (event: SyntheticEvent<HTMLDivElement>) => void;
|
onScroll: (event: SyntheticEvent<HTMLDivElement>) => void;
|
||||||
}> = ({
|
}> = ({ scroll, ganttHeight, ganttFullHeight, headerHeight, rtl, onScroll }) => {
|
||||||
scroll,
|
|
||||||
ganttHeight,
|
|
||||||
ganttFullHeight,
|
|
||||||
headerHeight,
|
|
||||||
rtl,
|
|
||||||
onScroll,
|
|
||||||
}) => {
|
|
||||||
const scrollRef = useRef<HTMLDivElement>(null);
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -29,9 +23,9 @@ export const VerticalScroll: React.FC<{
|
|||||||
style={{
|
style={{
|
||||||
height: ganttHeight,
|
height: ganttHeight,
|
||||||
marginTop: headerHeight,
|
marginTop: headerHeight,
|
||||||
marginLeft: rtl ? "" : "-1rem",
|
marginLeft: rtl ? '' : '-1rem',
|
||||||
}}
|
}}
|
||||||
className={styles.scroll}
|
className={cx(verticalScroll)}
|
||||||
onScroll={onScroll}
|
onScroll={onScroll}
|
||||||
ref={scrollRef}
|
ref={scrollRef}
|
||||||
>
|
>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import styles from "./bar.css";
|
import { cx } from '@emotion/css';
|
||||||
|
import { barHandle } from './style';
|
||||||
|
|
||||||
type BarDateHandleProps = {
|
type BarDateHandleProps = {
|
||||||
x: number;
|
x: number;
|
||||||
@ -9,21 +10,14 @@ type BarDateHandleProps = {
|
|||||||
barCornerRadius: number;
|
barCornerRadius: number;
|
||||||
onMouseDown: (event: React.MouseEvent<SVGRectElement, MouseEvent>) => void;
|
onMouseDown: (event: React.MouseEvent<SVGRectElement, MouseEvent>) => void;
|
||||||
};
|
};
|
||||||
export const BarDateHandle: React.FC<BarDateHandleProps> = ({
|
export const BarDateHandle: React.FC<BarDateHandleProps> = ({ x, y, width, height, barCornerRadius, onMouseDown }) => {
|
||||||
x,
|
|
||||||
y,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
barCornerRadius,
|
|
||||||
onMouseDown,
|
|
||||||
}) => {
|
|
||||||
return (
|
return (
|
||||||
<rect
|
<rect
|
||||||
x={x}
|
x={x}
|
||||||
y={y}
|
y={y}
|
||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
className={styles.barHandle}
|
className={cx(barHandle)}
|
||||||
ry={barCornerRadius}
|
ry={barCornerRadius}
|
||||||
rx={barCornerRadius}
|
rx={barCornerRadius}
|
||||||
onMouseDown={onMouseDown}
|
onMouseDown={onMouseDown}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import style from "./bar.css";
|
import { cx } from '@emotion/css';
|
||||||
|
import { barBackground } from './style';
|
||||||
|
|
||||||
type BarDisplayProps = {
|
type BarDisplayProps = {
|
||||||
x: number;
|
x: number;
|
||||||
@ -49,7 +50,7 @@ export const BarDisplay: React.FC<BarDisplayProps> = ({
|
|||||||
ry={barCornerRadius}
|
ry={barCornerRadius}
|
||||||
rx={barCornerRadius}
|
rx={barCornerRadius}
|
||||||
fill={getBarColor()}
|
fill={getBarColor()}
|
||||||
className={style.barBackground}
|
className={cx(barBackground)}
|
||||||
/>
|
/>
|
||||||
<rect
|
<rect
|
||||||
x={progressX}
|
x={progressX}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import styles from "./bar.css";
|
import { cx } from '@emotion/css';
|
||||||
|
import { barHandle } from './style';
|
||||||
|
|
||||||
type BarProgressHandleProps = {
|
type BarProgressHandleProps = {
|
||||||
progressPoint: string;
|
progressPoint: string;
|
||||||
@ -11,7 +12,7 @@ export const BarProgressHandle: React.FC<BarProgressHandleProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<polygon
|
<polygon
|
||||||
className={styles.barHandle}
|
className={cx(barHandle)}
|
||||||
points={progressPoint}
|
points={progressPoint}
|
||||||
onMouseDown={onMouseDown}
|
onMouseDown={onMouseDown}
|
||||||
/>
|
/>
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { cx } from '@emotion/css';
|
||||||
import { getProgressPoint } from "../../../helpers/bar-helper";
|
import { getProgressPoint } from "../../../helpers/bar-helper";
|
||||||
import { BarDisplay } from "./bar-display";
|
import { BarDisplay } from "./bar-display";
|
||||||
import { BarProgressHandle } from "./bar-progress-handle";
|
import { BarProgressHandle } from "./bar-progress-handle";
|
||||||
import { TaskItemProps } from "../task-item";
|
import { TaskItemProps } from "../task-item";
|
||||||
import styles from "./bar.css";
|
import { barWrapper } from './style';
|
||||||
|
|
||||||
|
|
||||||
export const BarSmall: React.FC<TaskItemProps> = ({
|
export const BarSmall: React.FC<TaskItemProps> = ({
|
||||||
task,
|
task,
|
||||||
@ -18,7 +20,7 @@ export const BarSmall: React.FC<TaskItemProps> = ({
|
|||||||
task.height
|
task.height
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<g className={styles.barWrapper} tabIndex={0}>
|
<g className={cx(barWrapper)} tabIndex={0}>
|
||||||
<BarDisplay
|
<BarDisplay
|
||||||
x={task.x1}
|
x={task.x1}
|
||||||
y={task.y}
|
y={task.y}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
.barWrapper {
|
|
||||||
cursor: pointer;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.barWrapper:hover .barHandle {
|
|
||||||
visibility: visible;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.barHandle {
|
|
||||||
fill: #ddd;
|
|
||||||
cursor: ew-resize;
|
|
||||||
opacity: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.barBackground {
|
|
||||||
user-select: none;
|
|
||||||
stroke-width: 0;
|
|
||||||
}
|
|
@ -1,10 +1,12 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { cx } from '@emotion/css';
|
||||||
import { getProgressPoint } from "../../../helpers/bar-helper";
|
import { getProgressPoint } from "../../../helpers/bar-helper";
|
||||||
import { BarDisplay } from "./bar-display";
|
import { BarDisplay } from "./bar-display";
|
||||||
import { BarDateHandle } from "./bar-date-handle";
|
import { BarDateHandle } from "./bar-date-handle";
|
||||||
import { BarProgressHandle } from "./bar-progress-handle";
|
import { BarProgressHandle } from "./bar-progress-handle";
|
||||||
import { TaskItemProps } from "../task-item";
|
import { TaskItemProps } from "../task-item";
|
||||||
import styles from "./bar.css";
|
import { barWrapper } from './style';
|
||||||
|
|
||||||
|
|
||||||
export const Bar: React.FC<TaskItemProps> = ({
|
export const Bar: React.FC<TaskItemProps> = ({
|
||||||
task,
|
task,
|
||||||
@ -21,7 +23,7 @@ export const Bar: React.FC<TaskItemProps> = ({
|
|||||||
);
|
);
|
||||||
const handleHeight = task.height - 2;
|
const handleHeight = task.height - 2;
|
||||||
return (
|
return (
|
||||||
<g className={styles.barWrapper} tabIndex={0}>
|
<g className={cx(barWrapper)} tabIndex={0}>
|
||||||
<BarDisplay
|
<BarDisplay
|
||||||
x={task.x1}
|
x={task.x1}
|
||||||
y={task.y}
|
y={task.y}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
import { css } from '@emotion/css';
|
||||||
|
|
||||||
|
export const barWrapper = css`
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
&:hover .barHandle {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const barHandle = css`
|
||||||
|
fill: #ddd;
|
||||||
|
cursor: ew-resize;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const barBackground = css`
|
||||||
|
user-select: none;
|
||||||
|
stroke-width: 0;
|
||||||
|
`;
|
@ -1,8 +0,0 @@
|
|||||||
.milestoneWrapper {
|
|
||||||
cursor: pointer;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.milestoneBackground {
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { cx } from '@emotion/css';
|
||||||
import { TaskItemProps } from "../task-item";
|
import { TaskItemProps } from "../task-item";
|
||||||
import styles from "./milestone.css";
|
import { milestoneWrapper,milestoneBackground } from './style';
|
||||||
|
|
||||||
export const Milestone: React.FC<TaskItemProps> = ({
|
export const Milestone: React.FC<TaskItemProps> = ({
|
||||||
task,
|
task,
|
||||||
@ -17,7 +18,7 @@ export const Milestone: React.FC<TaskItemProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g tabIndex={0} className={styles.milestoneWrapper}>
|
<g tabIndex={0} className={cx(milestoneWrapper)}>
|
||||||
<rect
|
<rect
|
||||||
fill={getBarColor()}
|
fill={getBarColor()}
|
||||||
x={task.x1}
|
x={task.x1}
|
||||||
@ -27,7 +28,7 @@ export const Milestone: React.FC<TaskItemProps> = ({
|
|||||||
rx={task.barCornerRadius}
|
rx={task.barCornerRadius}
|
||||||
ry={task.barCornerRadius}
|
ry={task.barCornerRadius}
|
||||||
transform={transform}
|
transform={transform}
|
||||||
className={styles.milestoneBackground}
|
className={cx(milestoneBackground)}
|
||||||
onMouseDown={e => {
|
onMouseDown={e => {
|
||||||
isDateChangeable && onEventStart("move", task, e);
|
isDateChangeable && onEventStart("move", task, e);
|
||||||
}}
|
}}
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
import { css } from '@emotion/css';
|
||||||
|
|
||||||
|
export const milestoneWrapper =css`
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const milestoneBackground =css`
|
||||||
|
user-select: none;
|
||||||
|
`
|
@ -1,13 +0,0 @@
|
|||||||
.projectWrapper {
|
|
||||||
cursor: pointer;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.projectBackground {
|
|
||||||
user-select: none;
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.projectTop {
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
@ -1,6 +1,8 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { cx } from '@emotion/css';
|
||||||
import { TaskItemProps } from "../task-item";
|
import { TaskItemProps } from "../task-item";
|
||||||
import styles from "./project.css";
|
import { projectWrapper,projectBackground,projectTop } from './style';
|
||||||
|
|
||||||
|
|
||||||
export const Project: React.FC<TaskItemProps> = ({ task, isSelected }) => {
|
export const Project: React.FC<TaskItemProps> = ({ task, isSelected }) => {
|
||||||
const barColor = isSelected
|
const barColor = isSelected
|
||||||
@ -29,7 +31,7 @@ export const Project: React.FC<TaskItemProps> = ({ task, isSelected }) => {
|
|||||||
].join(",");
|
].join(",");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g tabIndex={0} className={styles.projectWrapper}>
|
<g tabIndex={0} className={cx(projectWrapper)}>
|
||||||
<rect
|
<rect
|
||||||
fill={barColor}
|
fill={barColor}
|
||||||
x={task.x1}
|
x={task.x1}
|
||||||
@ -38,7 +40,7 @@ export const Project: React.FC<TaskItemProps> = ({ task, isSelected }) => {
|
|||||||
height={task.height}
|
height={task.height}
|
||||||
rx={task.barCornerRadius}
|
rx={task.barCornerRadius}
|
||||||
ry={task.barCornerRadius}
|
ry={task.barCornerRadius}
|
||||||
className={styles.projectBackground}
|
className={cx(projectBackground)}
|
||||||
/>
|
/>
|
||||||
<rect
|
<rect
|
||||||
x={task.progressX}
|
x={task.progressX}
|
||||||
@ -57,15 +59,15 @@ export const Project: React.FC<TaskItemProps> = ({ task, isSelected }) => {
|
|||||||
height={task.height / 2}
|
height={task.height / 2}
|
||||||
rx={task.barCornerRadius}
|
rx={task.barCornerRadius}
|
||||||
ry={task.barCornerRadius}
|
ry={task.barCornerRadius}
|
||||||
className={styles.projectTop}
|
className={cx(projectTop)}
|
||||||
/>
|
/>
|
||||||
<polygon
|
<polygon
|
||||||
className={styles.projectTop}
|
className={cx(projectTop)}
|
||||||
points={projectLeftTriangle}
|
points={projectLeftTriangle}
|
||||||
fill={barColor}
|
fill={barColor}
|
||||||
/>
|
/>
|
||||||
<polygon
|
<polygon
|
||||||
className={styles.projectTop}
|
className={cx(projectTop)}
|
||||||
points={projectRightTriangle}
|
points={projectRightTriangle}
|
||||||
fill={barColor}
|
fill={barColor}
|
||||||
/>
|
/>
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
import { css } from '@emotion/css';
|
||||||
|
|
||||||
|
export const projectWrapper =css `
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const projectBackground =css`
|
||||||
|
user-select: none;
|
||||||
|
opacity: 0.6;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const projectTop =css`
|
||||||
|
user-select: none;
|
||||||
|
`
|
@ -1,4 +1,7 @@
|
|||||||
.barLabel {
|
|
||||||
|
import { css } from '@emotion/css';
|
||||||
|
|
||||||
|
export const barLabel =css`
|
||||||
fill: #fff;
|
fill: #fff;
|
||||||
text-anchor: middle;
|
text-anchor: middle;
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
@ -9,9 +12,9 @@
|
|||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
`
|
||||||
|
|
||||||
.barLabelOutside {
|
export const barLabelOutside =css`
|
||||||
fill: #555;
|
fill: #555;
|
||||||
text-anchor: start;
|
text-anchor: start;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
@ -20,4 +23,4 @@
|
|||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
`
|
@ -1,11 +1,12 @@
|
|||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
|
import { cx } from '@emotion/css';
|
||||||
import { BarTask } from "../../types/bar-task";
|
import { BarTask } from "../../types/bar-task";
|
||||||
import { GanttContentMoveAction } from "../../types/gantt-task-actions";
|
import { GanttContentMoveAction } from "../../types/gantt-task-actions";
|
||||||
import { Bar } from "./bar/bar";
|
import { Bar } from "./bar/bar";
|
||||||
import { BarSmall } from "./bar/bar-small";
|
import { BarSmall } from "./bar/bar-small";
|
||||||
import { Milestone } from "./milestone/milestone";
|
import { Milestone } from "./milestone/milestone";
|
||||||
import { Project } from "./project/project";
|
import { Project } from "./project/project";
|
||||||
import style from "./task-list.css";
|
import { barLabel,barLabelOutside } from './style';
|
||||||
|
|
||||||
export type TaskItemProps = {
|
export type TaskItemProps = {
|
||||||
task: BarTask;
|
task: BarTask;
|
||||||
@ -113,8 +114,8 @@ export const TaskItem: React.FC<TaskItemProps> = props => {
|
|||||||
y={task.y + taskHeight * 0.5}
|
y={task.y + taskHeight * 0.5}
|
||||||
className={
|
className={
|
||||||
isTextInside
|
isTextInside
|
||||||
? style.barLabel
|
? cx(barLabel)
|
||||||
: style.barLabel && style.barLabelOutside
|
: cx(barLabel) && cx(barLabelOutside)
|
||||||
}
|
}
|
||||||
ref={textRef}
|
ref={textRef}
|
||||||
>
|
>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user