diff --git a/src/components/BackgroundLayer.js b/src/components/BackgroundLayer.js index 0613d720..75879270 100644 --- a/src/components/BackgroundLayer.js +++ b/src/components/BackgroundLayer.js @@ -252,7 +252,7 @@ export class BackgroundLayer extends React.Component { renderHighlightedWeekends() { return ( - + <> {this.props.highlightWeekends && this.state.weekends.map((weekend, index) => { return ( @@ -269,13 +269,13 @@ export class BackgroundLayer extends React.Component { /> ); })} - + ); } renderCustomComponents(components) { return ( - + <> {components.map((component, index) => { return React.cloneElement(component, { key: index, @@ -285,14 +285,14 @@ export class BackgroundLayer extends React.Component { calculateHorizontalPosition: this.calculateHorizontalPosition }); })} - + ); } renderVerticalGrid() { const {verticalGrid, topOffset, height, leftOffset, width, verticalGridLines, verticalGridClassName} = this.props; return ( - + <> {verticalGrid && verticalGridLines && (
)} - + ); } @@ -318,7 +318,7 @@ export class BackgroundLayer extends React.Component { const overlappsDisplayedInterval = this.props.startDateTimeline.isSameOrBefore(currentDate) && this.props.endDateTimeline.isSameOrAfter(currentDate); return ( - + <> {nowMarker && overlappsDisplayedInterval && ( )} - + ); } render() { return ( - + <> {this.renderHighlightedWeekends()} {this.renderCustomComponents(this.props.highlightedIntervals)} {this.renderNowMarker()} {this.renderCustomComponents(this.props.markers)} {this.renderVerticalGrid()} - + ); } } diff --git a/src/components/GanttDataCell.tsx b/src/components/GanttDataCell.tsx new file mode 100644 index 00000000..0488bf62 --- /dev/null +++ b/src/components/GanttDataCell.tsx @@ -0,0 +1,18 @@ +import { DataCell } from 'fixed-data-table-2'; +import React from 'react'; +import { GanttContext } from '../utils/GanttContext'; + +export interface GanttDataCellProperties { + rowIndex: number, + content: () => string | React.ReactNode +} + +export class GanttDataCell extends React.Component { + static contextType = GanttContext; + context!: React.ContextType; + + render(): React.ReactNode { + const {rows} = this.context; + return this.props.rowIndex < rows.length ? {this.props.content()} : ; + } +} \ No newline at end of file diff --git a/src/components/SimpleGanttTable.tsx b/src/components/SimpleGanttTable.tsx new file mode 100644 index 00000000..5245dcf2 --- /dev/null +++ b/src/components/SimpleGanttTable.tsx @@ -0,0 +1,38 @@ +import React from "react"; +import { Table, Column, DataCell } from 'fixed-data-table-2'; +import { GanttDataCell } from "./GanttDataCell"; +import { GanttContext } from "../utils/GanttContext"; + +export interface SimpleGanttTableProperties { + field: string, + header?: string | React.ReactNode + width?: number +} + +/** + * @author Daniela Buzatu + */ +export class SimpleGanttTable extends React.Component { + static contextType = GanttContext; + static defaultProps = { + width: 130, + header: undefined + } + context!: React.ContextType; + + render(): React.ReactNode { + const { rows, configureTable } = this.context; + return ( + configureTable( + + {this.props.header ? this.props.header : ""}} + cell={({ rowIndex }) => rows[rowIndex][this.props.field]} />} /> +
+ ) + ); + } +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index f89b5018..41208cb5 100644 --- a/src/index.js +++ b/src/index.js @@ -19,6 +19,8 @@ export {Marker} from './components/Marker'; export {default as Selectbox} from './components/selector'; export {BackgroundLayer} from './components/BackgroundLayer'; export {HighlightedInterval} from './components/HighlightedInterval'; +export {SimpleGanttTable} from './components/SimpleGanttTable'; +export {GanttDataCell} from './components/GanttDataCell'; // consts export {timebarFormat} from './consts/timebarConsts'; diff --git a/src/stories/backgroundLayer/BackgroundLayer.stories.tsx b/src/stories/backgroundLayer/BackgroundLayer.stories.tsx index bc0b0dd4..9be474f5 100644 --- a/src/stories/backgroundLayer/BackgroundLayer.stories.tsx +++ b/src/stories/backgroundLayer/BackgroundLayer.stories.tsx @@ -1,12 +1,11 @@ -import React from 'react'; -import Timeline from '../../timeline'; import { BackgroundLayer } from '../../components/BackgroundLayer'; import { HighlightedInterval } from '../../components/HighlightedInterval'; import { Marker } from '../../components/Marker'; -import { someHumanResources, startOfCurrentMonth, endOfCurrentMonth, dateAndHourOfCurrentMonth } from '../sampleData'; -import { backgroundLayerScenarios } from './BackgroundLayerScenarios'; +import { SimpleGanttTable } from '../../components/SimpleGanttTable'; +import Timeline from '../../timeline'; import { Item } from '../../types'; -import { Table, Column, DataCell} from 'fixed-data-table-2'; +import { dateAndHourOfCurrentMonth, endOfCurrentMonth, someHumanResources, startOfCurrentMonth } from '../sampleData'; +import { backgroundLayerScenarios } from './BackgroundLayerScenarios'; export default { title: 'Features/Background Layer' }; @@ -21,13 +20,7 @@ export const Main = () => { return ( - Title} - cell={({rowIndex}) => {rowIndex < someHumanResources.length ? someHumanResources[rowIndex].title : ""}}/> - } + table={} backgroundLayer={ { return ( - Title} - cell={({rowIndex}) => {rowIndex < someHumanResources.length ? someHumanResources[rowIndex].title : ""}}/> - } + table={} backgroundLayer={ { CustomClassNamesAndStyles.parameters = { scenarios: [ backgroundLayerScenarios.verticalGridClassName, - backgroundLayerScenarios.nowMaSrkerClassName, + backgroundLayerScenarios.nowMarkerClassName, backgroundLayerScenarios.highlightWeekendsClassName, backgroundLayerScenarios.classNameForMarker, backgroundLayerScenarios.highlightedIntervalClassName diff --git a/src/stories/basic/Basic.stories.mdx b/src/stories/basic/Basic.stories.mdx index 0aba0e29..7aac4ff0 100644 --- a/src/stories/basic/Basic.stories.mdx +++ b/src/stories/basic/Basic.stories.mdx @@ -71,6 +71,6 @@ const start = this.getStartFromItem(item); **IMPORTANT**: By default the gantt diagram displayes without any table associated. -If you want to display a table (like in the majority of our examples) you should set the table property: +If you want to display a table (like in the majority of our examples) you should set the `table` property: \ No newline at end of file diff --git a/src/stories/basic/Basic.stories.tsx b/src/stories/basic/Basic.stories.tsx index 17e95da3..fab52ae3 100644 --- a/src/stories/basic/Basic.stories.tsx +++ b/src/stories/basic/Basic.stories.tsx @@ -1,10 +1,9 @@ -import React from 'react'; +import { ComponentStory } from '@storybook/react'; +import { SimpleGanttTable } from '../../components/SimpleGanttTable'; +import { Group, Item } from '../../index'; import Timeline from '../../timeline'; import { timelineScenarios } from '../TimelineScenarios'; import { d, someHumanResources, someTasks } from '../sampleData'; -import { ComponentStory } from '@storybook/react'; -import { Group, Item } from '../../index'; -import { Table, Column, DataCell } from 'fixed-data-table-2'; export default { title: 'Features/Basic' @@ -34,13 +33,7 @@ export const Main = () => { {/* 2/ You'll probably have a better flex-box layout, i.e. not hardcoded. 3/ Use CSS classes and not styles. */}
- Title} - cell={({rowIndex}) => {rowIndex < humanResources.length ? humanResources[rowIndex].title : ""}}/> - } + table={} />
@@ -80,13 +73,7 @@ export const AlternativeRowColoring: ComponentStory = () => {
- Title} - cell={({rowIndex}) => {rowIndex < someHumanResources.length ? someHumanResources[rowIndex].title : ""}}/> - }/> + table={}/>
); @@ -118,14 +105,7 @@ const tasks: Item[] = [ {/* 2/ You'll probably have a better flex-box layout, i.e. not hardcoded. 3/ Use CSS classes and not styles. */}
- Title} - cell={({rowIndex}) => {rowIndex < someHumanResources.length ? someHumanResources[rowIndex].title : ""}}/> - } - /> + table={}/>
); diff --git a/src/stories/contextMenuAndSelection/ContextMenuAndSelection.stories.tsx b/src/stories/contextMenuAndSelection/ContextMenuAndSelection.stories.tsx index b92fa821..15442dca 100644 --- a/src/stories/contextMenuAndSelection/ContextMenuAndSelection.stories.tsx +++ b/src/stories/contextMenuAndSelection/ContextMenuAndSelection.stories.tsx @@ -3,11 +3,11 @@ import { Alert } from 'antd'; import moment from 'moment'; import { useState } from 'react'; import { Button, Icon, Menu } from 'semantic-ui-react'; +import { SimpleGanttTable } from '../../components/SimpleGanttTable'; import Timeline from '../../timeline'; import { IGanttAction, IGanttOnContextMenuShowParam, Item } from '../../types'; import { d, someHumanResources, someTasks } from '../sampleData'; import { contextMenuScenarios, selectionScenarios } from './ContextMenuAndSelectionScenarios'; -import { Table, Column, DataCell } from 'fixed-data-table-2'; export default { title: 'Features/Context Menu And Selection', @@ -84,14 +84,8 @@ export const ContextMenu = () => { return actions; }} - table={ - Title} - cell={({rowIndex}) => {rowIndex < someHumanResources.length ? someHumanResources[rowIndex].title : ""}}/> -
} - /> + table={} + />
); }; @@ -124,13 +118,8 @@ export const Selection = () => {
setSelectedItems(selectedItems)} - table={ - Title} - cell={({rowIndex}) => {rowIndex < someHumanResources.length ? someHumanResources[rowIndex].title : ""}}/> -
}/> + table={} + />
); diff --git a/src/stories/custom/Custom.stories.tsx b/src/stories/custom/Custom.stories.tsx index 5f4fe3b1..e5b2f687 100644 --- a/src/stories/custom/Custom.stories.tsx +++ b/src/stories/custom/Custom.stories.tsx @@ -1,10 +1,10 @@ import { useEffect, useRef, useState } from "react"; import { Segment } from "semantic-ui-react"; +import { ItemRenderer } from "../.."; +import { SimpleGanttTable } from "../../components/SimpleGanttTable"; import { d, someHumanResources, someTasks } from "../sampleData"; import { CustomTimeline } from "./CustomTimeline"; import { customTimelineScenarios } from "./CustomTimelineScenarios"; -import { ItemRenderer } from "../.."; -import { Table, Column, DataCell} from 'fixed-data-table-2'; export default { title: 'Features/Custom' @@ -22,13 +22,7 @@ export const CustomMenuButtonRenderer = () => {
- Title} - cell={({rowIndex}) => {rowIndex < someHumanResources.length ? someHumanResources[rowIndex].title : ""}}/> - } + table={} toolbarDomElement={divRef.current} itemRenderer={ItemRenderer}/> ); diff --git a/src/stories/dragToCreate/DragToCreate.stories.tsx b/src/stories/dragToCreate/DragToCreate.stories.tsx index 5dd24fe9..e4c6a0b8 100644 --- a/src/stories/dragToCreate/DragToCreate.stories.tsx +++ b/src/stories/dragToCreate/DragToCreate.stories.tsx @@ -1,11 +1,11 @@ -import React, { useState } from 'react'; +import { createTestids } from '@famiprog-foundation/tests-are-demo'; +import { useState } from 'react'; +import { Form, Radio } from 'semantic-ui-react'; +import { SimpleGanttTable } from '../../components/SimpleGanttTable'; import Timeline from '../../timeline'; +import { DragToCreateParam, Item } from '../../types'; import { d, someHumanResources, someTasks } from '../sampleData'; import { dragToCreateScenarios } from './DragToCreateScenarios'; -import { DragToCreateParam, Item } from '../../types'; -import { Form, Radio } from 'semantic-ui-react'; -import { createTestids } from '@famiprog-foundation/tests-are-demo'; -import { Table, Column, DataCell} from 'fixed-data-table-2'; export default { title: 'Features/Drag to create', @@ -46,13 +46,7 @@ export const Main = () => { - Title} - cell={({rowIndex}) => {rowIndex < someHumanResources.length ? someHumanResources[rowIndex].title : ""}}/> - } + table={} onDragToCreateEnded={(param: DragToCreateParam) => { if (groups[param.groupIndex]) { const task = { diff --git a/src/stories/itemRenderer/ItemRenderer.stories.tsx b/src/stories/itemRenderer/ItemRenderer.stories.tsx index 65b960bf..bb0556c4 100644 --- a/src/stories/itemRenderer/ItemRenderer.stories.tsx +++ b/src/stories/itemRenderer/ItemRenderer.stories.tsx @@ -1,13 +1,11 @@ -import {Alert} from 'antd'; -import React from 'react'; +import { Alert } from 'antd'; import ItemRenderer from '../../components/ItemRenderer'; +import { SimpleGanttTable } from '../../components/SimpleGanttTable'; import Timeline from '../../timeline'; -import {d, someHumanResources, someTasks} from '../sampleData'; -import {itemRendererScenarios} from './ItemRendererScenarios'; -import {timelineScenarios} from '../TimelineScenarios'; -import { ComponentStory } from '@storybook/react'; import { Item } from '../../types'; -import { Table, Column, DataCell} from 'fixed-data-table-2'; +import { timelineScenarios } from '../TimelineScenarios'; +import { d, someHumanResources, someTasks } from '../sampleData'; +import { itemRendererScenarios } from './ItemRendererScenarios'; export default { title: 'Features/Item Renderer' @@ -68,13 +66,8 @@ export const Main = () => { } /> - Title} - cell={({rowIndex}) => {rowIndex < someHumanResources.length ? someHumanResources[rowIndex].title : ""}}/> - }/> + table={} + /> ); }; @@ -108,13 +101,7 @@ export const DefaultPropsForItemRenderer = () => { endDate={d('2018-09-21')} groups={someHumanResources} items={someTasks} - table={ - Title} - cell={({rowIndex}) => {rowIndex < someHumanResources.length ? someHumanResources[rowIndex].title : ""}}/> -
} + table={} itemRendererDefaultProps={{ className: 'story-custom-item-class', color: 'red' @@ -224,13 +211,7 @@ export const CustomItemRenderer = () => { endDate={d('2018-09-21')} groups={someHumanResources} items={someTasks} - table={ - Title} - cell={({rowIndex}) => {rowIndex < someHumanResources.length ? someHumanResources[rowIndex].title : ""}}/> -
} + table={} itemRenderer={CustomItemRenderer} /> diff --git a/src/stories/sampleData.ts b/src/stories/sampleData.ts index 91fdd9b5..b0616d8f 100644 --- a/src/stories/sampleData.ts +++ b/src/stories/sampleData.ts @@ -16,6 +16,7 @@ export const dateAndHourOfCurrentMonth = (day, hour = 0) => d(moment().startOf(' // sample data //////////////////////////////////////////////////////// export type Employee = Group & { + title?: string, job?: string, team?: string } diff --git a/src/stories/table/Table.stories.tsx b/src/stories/table/Table.stories.tsx index d3af26ad..c5592c2c 100644 --- a/src/stories/table/Table.stories.tsx +++ b/src/stories/table/Table.stories.tsx @@ -1,10 +1,11 @@ import { ComponentStory } from "@storybook/react"; -import { Fragment, useState } from "react"; +import { useState } from "react"; import { Checkbox, Icon } from "semantic-ui-react"; import { Timeline } from "../.."; import { d, manyHumanResources, someTasks } from "../sampleData"; import { Column, DataCell, Table } from "fixed-data-table-2"; +import { GanttDataCell } from "../../components/GanttDataCell"; import { DEMO_TABLE_WIDTH, tableScenarios, tableTestIds } from "./TableScenarios"; import { Alert } from "antd"; export default { @@ -15,9 +16,9 @@ export default { export const GanttWithoutTable: ComponentStory = () => { return ( - + <> - + ); } @@ -38,7 +39,7 @@ const headerStyle = { export const ProvidingCustomTable: ComponentStory = () => { const [tableWidth, setTableWidth] = useState(DEMO_TABLE_WIDTH); return ( - + <> Table width: {tableWidth} }/> {setTableWidth(size); console.log("!!!!! " + size)}} @@ -53,31 +54,26 @@ export const ProvidingCustomTable: ComponentStory = () => { columnKey={0} width={100} header={Title} - cell={({rowIndex}) => - {rowIndex < manyHumanResources.length ? manyHumanResources[rowIndex].title : ""} - } + cell={({rowIndex}) => manyHumanResources[rowIndex].title}/>} /> Custom check} - cell={({rowIndex}) => - {rowIndex < manyHumanResources.length ? : ""} - } + cell={({rowIndex}) => }/>} /> Job} - cell={({rowIndex}) => - {rowIndex < manyHumanResources.length ? manyHumanResources[rowIndex].job : ""} - } + cell={({rowIndex}) => manyHumanResources[rowIndex].job}/>} /> } /> - + ); } diff --git a/src/stories/table/TableScenarios.ts b/src/stories/table/TableScenarios.ts index 2cfc1006..c609bddf 100644 --- a/src/stories/table/TableScenarios.ts +++ b/src/stories/table/TableScenarios.ts @@ -10,4 +10,4 @@ export const tableScenarios = { // And could not be exported directly from table.storie.tsx because // everything exported there gets in the storybook tree as a story entry export const tableTestIds = createTestids("Table", {row:""}); -export const DEMO_TABLE_WIDTH = 260; \ No newline at end of file +export const DEMO_TABLE_WIDTH = 280; \ No newline at end of file diff --git a/src/testsAreDemo/TableTestsAreDemo.tsx b/src/testsAreDemo/TableTestsAreDemo.tsx index 02aca056..4863f643 100644 --- a/src/testsAreDemo/TableTestsAreDemo.tsx +++ b/src/testsAreDemo/TableTestsAreDemo.tsx @@ -3,7 +3,7 @@ import { assert } from "chai"; import { Table } from "fixed-data-table-2"; import { ProvidingCustomTable } from "../stories/table/Table.stories"; import { DEMO_TABLE_WIDTH, tableTestIds } from "../stories/table/TableScenarios"; -import { TABLE_OFFSET, timelineTestids as testids } from "../timeline"; +import { timelineTestids as testids } from "../timeline"; export class TableTestsAreDemo { async before() { @@ -61,6 +61,6 @@ export class TableTestsAreDemo { async whenDragTheSplitPaneTheTableIsResizedAccordingly() { tad.cc("Split pane resizer is dragged"); await tad.drag(tad.screenCapturing.getByTestId(testids.splitPaneResizer), { delta: { x: 150, y: 0 }}); - assert.equal((tad.getObjectViaCheat(Table) as Table).props.width, DEMO_TABLE_WIDTH + TABLE_OFFSET + 150); + assert.equal((tad.getObjectViaCheat(Table) as Table).props.width, DEMO_TABLE_WIDTH + 150); } } \ No newline at end of file diff --git a/src/timeline.js b/src/timeline.js index 2d656bcf..95d2c20d 100644 --- a/src/timeline.js +++ b/src/timeline.js @@ -45,6 +45,8 @@ import ItemRenderer from './components/ItemRenderer'; import {SelectionHolder} from './utils/SelectionHolder'; import {IGanttAction} from './types'; import {ContextMenu} from './components/ContextMenu/ContextMenu'; +import {GanttContext} from './utils/GanttContext'; +import {SimpleGanttTable} from './components/SimpleGanttTable'; import moment from 'moment'; import {SCROLLBAR_SIZE, Scrollbar} from './components/Scrollbar'; @@ -64,9 +66,6 @@ const testids = createTestids('Timeline', { export const timelineTestids = testids; const EMPTY_GROUP_KEY = 'empty-group'; -// This was added by bogdan. From my understanding it reprezents the table vertical scrollbar width -// If we don't take in consideration this, a horizontal scrollbar appears -export const TABLE_OFFSET = 15; export const DEFAULT_ITEM_HEIGHT = 40; export const DEFAULT_ROW_CLASS = 'rct9k-row'; export const DEFAULT_ROW_EVEN_CLASS = 'rct9k-row-even'; @@ -87,7 +86,12 @@ const TableWithStyle = ({table}) => { `; return ( -
+ /** `overflowY: hidden` was added because we set the prop `height` of the Table(fixed-data-table) + * to this.state.screenHeight (computed by ) that has floating pecision. + * But if we look in browser inspector the table's main div gets with height rounded to an integer + * (overflowing with some decimals the height of the parent) causing to appear both vertical and horizontal unnecessary scrollbars + */ +
{React.cloneElement(table)}
@@ -540,7 +544,7 @@ export default class Timeline extends React.Component { getInitialTableWidth(props) { props = props ? props : this.props; - return (props.table ? props.table.props.width : 0) + TABLE_OFFSET; + return props.table ? props.table.props.width : 0; } constructor(props) { @@ -612,6 +616,7 @@ export default class Timeline extends React.Component { this.handleScrollGantt = this.handleScrollGantt.bind(this); this.handleDrag = this.handleDrag.bind(this); this.selectionChangedHandler = this.selectionChangedHandler.bind(this); + this.configureTable = this.configureTable.bind(this); const canSelect = Timeline.isBitSet(Timeline.TIMELINE_MODES.SELECT, this.props.timelineMode); const canDrag = Timeline.isBitSet(Timeline.TIMELINE_MODES.DRAG, this.props.timelineMode); @@ -2122,43 +2127,59 @@ export default class Timeline extends React.Component { ); } - render() { - const {componentId} = this.props; - /** - * @returns { number } height of the timebar - */ - function getTimebarHeight() { - if (typeof window === 'undefined') { - return 0; - } - // when this function is called for the first time, the timebar is not yet rendered - let timebar = document.querySelector(`.rct9k-id-${componentId} .rct9k-timebar`); - if (!timebar) { - return 0; - } - // substract timebar height from total height - return timebar.getBoundingClientRect().height; + /** + * @param { number } height (total height of the timeline) + * @returns { number } height of the timeline w/o timebar + */ + calculateHeight(height) { + if (typeof window === 'undefined' || height === undefined) { + return 0; } - /** - * @param { number } height (total height of the timeline) - * @returns { number } height of the timeline w/o timebar - */ - function calculateHeight(height) { - if (typeof window === 'undefined' || height === undefined) { - return 0; - } + return Math.max(height - this.getTimebarHeight(), 0); + } - return Math.max(height - getTimebarHeight(), 0); + /** + * @returns { number } height of the timebar + */ + getTimebarHeight() { + if (typeof window === 'undefined') { + return 0; } + // when this function is called for the first time, the timebar is not yet rendered + let timebar = document.querySelector(`.rct9k-id-${this.props.componentId} .rct9k-timebar`); + if (!timebar) { + return 0; + } + // substract timebar height from total height + return timebar.getBoundingClientRect().height; + } + + configureTable(table) { + return React.cloneElement(table, { + rowsCount: this.state.groups.length, + rowHeightGetter: this.tableRowHeight, + rowHeight: this.props.itemHeight, + ref: this.table_ref_callback, + touchScrollEnabled: true, + onVerticalScroll: this.handleScrollTable, + scrollTop: this.state.scrollTop, + headerHeight: this.getTimebarHeight(), + height: this.state.screenHeight, + width: this.state.tableWidth, + rowClassNameGetter: rowIndex => + this.props.rowClassName + ' ' + (rowIndex % 2 == 0 ? this.props.rowOddClassName : this.props.rowEvenClassName) + }); + } + render() { { /* Instead of , in the past was used. However it would round with/height, which generated and endless scrollbar appear/disappear, depending on the parent, depending on the resolution. */ } return ( // Can not use empty <> instead of because it fails the documentation generation - + <> {({measureRef}) => { - const bodyHeight = calculateHeight(this.state.screenHeight); - const timebarHeight = getTimebarHeight(); + const bodyHeight = this.calculateHeight(this.state.screenHeight); + const timebarHeight = this.getTimebarHeight(); return (
{this.props.table ? ( @@ -2192,24 +2213,15 @@ export default class Timeline extends React.Component { size={this.state.tableWidth} onChange={this.handleDrag} ref={this.splitPane_ref_callback}> - - this.props.rowClassName + - ' ' + - (rowIndex % 2 == 0 ? this.props.rowOddClassName : this.props.rowEvenClassName) - })} - /> + + + {this.renderGanttPart({bodyHeight, timebarHeight})} ) : ( @@ -2219,7 +2231,7 @@ export default class Timeline extends React.Component { ); }} - + ); } diff --git a/src/types.d.ts b/src/types.d.ts index 30abef82..39092d5f 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -1,8 +1,7 @@ import { IAction, IActionParam, IActionParamForRun, IOnContextMenuShowParam } from "./components/ContextMenu/IAction" export type Group = { - id: number, - title?: string + id: number } export type InteractOption = { diff --git a/src/utils/GanttContext.tsx b/src/utils/GanttContext.tsx new file mode 100644 index 00000000..325cf86e --- /dev/null +++ b/src/utils/GanttContext.tsx @@ -0,0 +1,4 @@ +import React, { createContext } from "react"; +import { Group } from "../types"; + +export const GanttContext = createContext<{rows: Group[], configureTable: (table: React.ReactNode) => React.ReactNode}>({rows: undefined, configureTable: undefined}); \ No newline at end of file