diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..2801aaeac --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,72 @@ +# Contributing to @scharinger/gantt-task-react + +Thank you for your interest in contributing! This guide will help you set up the development environment. + +## Development Setup + +### Prerequisites +- Node.js (v14 or higher) +- npm + +### Getting Started + +```bash +# Clone the repository +git clone https://github.com/yourusername/gantt-task-react.git +cd gantt-task-react + +# Install dependencies +npm install + +# Build the library +npm run build + +# Run tests +npm test +``` + +### Running the Example + +To test your changes with the example application: + +```bash +cd example +npm install +npm start +``` + +The example will be available at `http://localhost:3000`. + +## Development Workflow + +1. **Make your changes** in the `src/` directory +2. **Build the library** with `npm run build` +3. **Test your changes** using the example application +4. **Run tests** with `npm test` +5. **Update documentation** if needed + +## Code Guidelines + +- Follow TypeScript best practices +- Maintain existing code style +- Add JSDoc comments for public APIs +- Include tests for new features +- Update documentation for new features + +## Submitting Changes + +1. Fork the repository +2. Create a feature branch: `git checkout -b feature/your-feature-name` +3. Make your changes +4. Test your changes +5. Commit with descriptive messages +6. Push to your fork +7. Create a Pull Request + +## Publishing + +For maintainers: See [PUBLISHING.md](PUBLISHING.md) for instructions on publishing new versions. + +## Questions? + +If you have questions about contributing, please open an issue on GitHub. diff --git a/PUBLISHING.md b/PUBLISHING.md new file mode 100644 index 000000000..541ffb9c0 --- /dev/null +++ b/PUBLISHING.md @@ -0,0 +1,146 @@ +# Publishing Guide for @scharinger/gantt-task-react + +This guide covers the process of publishing new versions of the package to npm. + +## Version Strategy + +We follow [Semantic Versioning](https://semver.org/): + +- **Patch (0.4.X)**: Bug fixes and small improvements +- **Minor (0.X.0)**: New features, backwards compatible +- **Major (X.0.0)**: Breaking changes +- **Beta (X.Y.Z-beta.N)**: Pre-release versions for testing + +## Prerequisites + +1. **npm account**: Make sure you're logged in to npm + ```bash + npm whoami # Check if logged in + npm login # Login if needed + ``` + +2. **Repository access**: You should have write access to the repository + +3. **Clean working directory**: Commit all changes before publishing + +## Publishing Steps + +### 1. Update Version + +Update the version in `package.json`: + +```json +{ + "version": "0.4.1-beta.0" // For beta releases + // or + "version": "0.4.1" // For stable releases +} +``` + +### 2. Update Documentation + +- Update `README.md` if there are new features or API changes +- Update `CHANGELOG.md` (if it exists) with the changes + +### 3. Build and Test + +```bash +# Build the library +npm run build + +# Run tests +npm test + +# Test with example project +cd example +npm install +npm start +``` + +### 4. Publish to NPM + +**For beta releases:** +```bash +npm publish --tag beta --access public +``` + +**For stable releases:** +```bash +npm publish --access public +``` + +### 5. Create Git Tag (Recommended) + +```bash +git tag v0.4.1-beta.0 +git push origin v0.4.1-beta.0 +``` + +### 6. Update GitHub Release (Optional) + +Create a release on GitHub with: +- Tag version +- Release notes describing changes +- Any breaking changes or migration notes + +## Post-Publishing + +### Verify Publication + +Check that the package is available: + +```bash +npm view @scharinger/gantt-task-react versions --json +``` + +### Test Installation + +Test in a fresh project: + +```bash +mkdir test-install +cd test-install +npm init -y +npm install @scharinger/gantt-task-react@beta # or @latest +``` + +## Installation Commands for Users + +After publishing, users can install with: + +```bash +# Latest stable version +npm install @scharinger/gantt-task-react + +# Beta version +npm install @scharinger/gantt-task-react@beta + +# Specific version +npm install @scharinger/gantt-task-react@0.4.0-beta.0 +``` + +## Troubleshooting + +### Common Issues + +1. **402 Payment Required**: Use `--access public` for scoped packages +2. **403 Forbidden**: Check npm login and package permissions +3. **Version already exists**: Increment version number + +### Rollback + +If you need to unpublish (only for packages published less than 72 hours ago): + +```bash +npm unpublish @scharinger/gantt-task-react@0.4.1-beta.0 +``` + +**Note**: Unpublishing is discouraged and may not be possible for stable releases. + +## Automation (Future) + +Consider setting up GitHub Actions for automated publishing: + +- Automated testing on PR +- Automated beta releases on merge to develop +- Automated stable releases on merge to main diff --git a/README.md b/README.md index 9191d87ba..e1b77fcf8 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ npm install gantt-task-react ## How to use it ```javascript -import { Gantt, Task, EventOption, StylingOption, ViewMode, DisplayOption } from 'gantt-task-react'; +import { Gantt, Task, ExtraColumn, DateFormat, EventOption, StylingOption, ViewMode, DisplayOption } from 'gantt-task-react'; import "gantt-task-react/dist/index.css"; let tasks: Task[] = [ @@ -40,6 +40,7 @@ You may handle actions ( + + {task.extraColumns?.priority} + + ), + }, +]; + +// Add extra data to your tasks +const tasks: Task[] = [ + { + id: "1", + name: "Task 1", + start: new Date(), + end: new Date(), + progress: 50, + type: "task", + extraColumns: { + status: "In Progress", + assignee: "John Doe", + priority: "High", + }, + }, +]; + + +``` + +### ExtraColumn Interface + +| Parameter Name | Type | Description | +| :------------- | :-------------------------------------- | :----------------------------------------------------------------------- | +| key\* | string | Unique key for the column, used to access data in task.extraColumns | +| title\* | string | Column header title | +| width | string | Column width (e.g., "100px", "120px"). Defaults to listCellWidth | +| render | `(task: Task) => React.ReactNode` | Optional custom render function for complex column content | + +### Column Width Configuration + +You can customize the width of the default columns: + +| Parameter Name | Type | Description | +| :---------------- | :----- | :----------------------------------------------- | +| nameColumnWidth | string | Width of the Name column (e.g., "200px") | +| fromColumnWidth | string | Width of the From/Start date column (e.g., "130px") | +| toColumnWidth | string | Width of the To/End date column (e.g., "130px") | + +### Date Format Configuration + +You can choose how dates are displayed in the From and To columns: + +```javascript +import { Gantt, DateFormat } from 'gantt-task-react'; + + +``` + +| Parameter Name | Type | Description | +| :------------- | :--------- | :------------------------------------------------------------------- | +| dateFormat | DateFormat | Date display format. "locale" uses locale formatting (e.g., "Fri, June 15, 2025"), "iso8601" uses ISO 8601 format (YYYY-MM-DD) | + +**DateFormat Options:** +- `"locale"` (default): Displays dates in locale-specific format (e.g., "Fri, June 15, 2025") +- `"iso8601"`: Displays dates in ISO 8601 format (e.g., "2025-06-15") + +\*Required + +## Contributing + +For development setup and contributing guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md). + +For maintainers: Publishing instructions are in [PUBLISHING.md](PUBLISHING.md). + ## License [MIT](https://oss.ninja/mit/jaredpalmer/) diff --git a/example/src/App.tsx b/example/src/App.tsx index c2ab602eb..c132031a8 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -2,6 +2,7 @@ import React from "react"; import { Task, ViewMode, Gantt } from "gantt-task-react"; import { ViewSwitcher } from "./components/view-switcher"; import { getStartEndDateForProject, initTasks } from "./helper"; +import ExtraColumnsApp from "./ExtraColumnsApp"; import "gantt-task-react/dist/index.css"; // Init @@ -103,6 +104,7 @@ const App = () => { ganttHeight={300} columnWidth={columnWidth} /> + ); }; diff --git a/example/src/ExtraColumnsApp.tsx b/example/src/ExtraColumnsApp.tsx new file mode 100644 index 000000000..562ff85b3 --- /dev/null +++ b/example/src/ExtraColumnsApp.tsx @@ -0,0 +1,107 @@ +import React, { useState } from "react"; +import { ViewMode, Gantt, DateFormat } from "gantt-task-react"; +import { ViewSwitcher } from "./components/view-switcher"; +import { initTasksWithExtraColumns, extraColumns } from "./extra-columns-helper"; +import "gantt-task-react/dist/index.css"; + +//Init +const ExtraColumnsApp: React.FC = () => { + const [tasks, setTasks] = useState(initTasksWithExtraColumns()); + const [view, setView] = useState(ViewMode.Day); + const [dateFormat, setDateFormat] = useState("locale"); + + let columnWidth = 65; + if (view === ViewMode.Year) { + columnWidth = 350; + } else if (view === ViewMode.Month) { + columnWidth = 300; + } else if (view === ViewMode.Week) { + columnWidth = 250; + } + + return ( +
+

Gantt Chart with Extra Columns Example

+

This example demonstrates how to add custom columns to the Gantt chart task list.

+ +
+ setView(viewMode)} + onViewListChange={() => {}} + isChecked={true} + /> + +
+ + +
+
+ +
+ { + console.log("On date change Id:" + task.id); + setTasks(tasks); + }} + onDelete={(task) => { + const conf = window.confirm("Are you sure about " + task.name + " ?"); + if (conf) { + setTasks(tasks.filter((t) => t.id !== task.id)); + } + return conf; + }} + onProgressChange={(task, _children) => { + console.log("On progress change Id:" + task.id); + setTasks(tasks); + }} + onDoubleClick={(task) => { + console.log("On Double Click event Id:" + task.id); + }} + onClick={(task) => { + console.log("On Click event Id:" + task.id); + }} + columnWidth={columnWidth} + listCellWidth="180px" + /> +
+ +
+

Features Demonstrated:

+
    +
  • Status Column: Shows task status with colored badges
  • +
  • Assignee Column: Displays who is responsible for each task
  • +
  • Priority Column: Shows task priority with colored indicators
  • +
  • Budget Column: Displays formatted budget amounts
  • +
  • Custom Column Widths: Name, From, and To columns have custom widths
  • +
  • Date Format Options: Toggle between locale and ISO (YYYY-MM-DD) date formats
  • +
+ +

How to Use:

+
    +
  1. Define your extra columns configuration with ExtraColumn[]
  2. +
  3. Add extraColumns data to your task objects
  4. +
  5. Pass the columns configuration to the Gantt component
  6. +
  7. Optionally use custom render functions for complex column content
  8. +
  9. Set custom widths using nameColumnWidth, fromColumnWidth, toColumnWidth
  10. +
  11. Choose date format with dateFormat prop: "locale" or "iso"
  12. +
+
+
+ ); +}; + +export default ExtraColumnsApp; diff --git a/example/src/extra-columns-helper.tsx b/example/src/extra-columns-helper.tsx new file mode 100644 index 000000000..c0ae6fac3 --- /dev/null +++ b/example/src/extra-columns-helper.tsx @@ -0,0 +1,172 @@ +import React from "react"; +import { Task, ExtraColumn } from "../../dist/types/public-types"; + +export function initTasksWithExtraColumns() { + const currentDate = new Date(); + const tasks: Task[] = [ + { + start: new Date(currentDate.getFullYear(), currentDate.getMonth(), 1), + end: new Date(currentDate.getFullYear(), currentDate.getMonth(), 15), + name: "Website Redesign", + id: "ProjectSample", + progress: 25, + type: "project", + hideChildren: false, + displayOrder: 1, + extraColumns: { + status: "In Progress", + assignee: "Project Team", + priority: "High", + budget: 50000, + }, + }, + { + start: new Date(currentDate.getFullYear(), currentDate.getMonth(), 1), + end: new Date( + currentDate.getFullYear(), + currentDate.getMonth(), + 2, + 12, + 28 + ), + name: "Initial Planning", + id: "Task 0", + progress: 45, + type: "task", + project: "ProjectSample", + displayOrder: 2, + extraColumns: { + status: "Completed", + assignee: "John Doe", + priority: "High", + budget: 5000, + }, + }, + { + start: new Date(currentDate.getFullYear(), currentDate.getMonth(), 2), + end: new Date(currentDate.getFullYear(), currentDate.getMonth(), 4, 0, 0), + name: "Market Research", + id: "Task 1", + progress: 25, + dependencies: ["Task 0"], + type: "task", + project: "ProjectSample", + displayOrder: 3, + extraColumns: { + status: "In Progress", + assignee: "Jane Smith", + priority: "Medium", + budget: 8000, + }, + }, + { + start: new Date(currentDate.getFullYear(), currentDate.getMonth(), 4), + end: new Date(currentDate.getFullYear(), currentDate.getMonth(), 8, 0, 0), + name: "Design Mockups", + id: "Task 2", + progress: 10, + dependencies: ["Task 1"], + type: "task", + project: "ProjectSample", + displayOrder: 4, + extraColumns: { + status: "Not Started", + assignee: "Bob Wilson", + priority: "High", + budget: 12000, + }, + }, + { + start: new Date(currentDate.getFullYear(), currentDate.getMonth(), 8), + end: new Date(currentDate.getFullYear(), currentDate.getMonth(), 9, 0, 0), + name: "Client Review", + id: "Task 3", + progress: 0, + dependencies: ["Task 2"], + type: "milestone", + project: "ProjectSample", + displayOrder: 5, + extraColumns: { + status: "Pending", + assignee: "Client", + priority: "Critical", + budget: 0, + }, + }, + { + start: new Date(currentDate.getFullYear(), currentDate.getMonth(), 10), + end: new Date(currentDate.getFullYear(), currentDate.getMonth(), 15), + name: "Development", + id: "Task 4", + progress: 0, + dependencies: ["Task 3"], + type: "task", + project: "ProjectSample", + displayOrder: 6, + extraColumns: { + status: "Not Started", + assignee: "Dev Team", + priority: "High", + budget: 25000, + }, + }, + ]; + return tasks; +} + +export const extraColumns: ExtraColumn[] = [ + { + key: "status", + title: "Status", + width: "120px", + render: (task) => { + const status = task.extraColumns?.status as string; + const statusClass = { + "Completed": "status-completed", + "In Progress": "status-in-progress", + "Not Started": "status-not-started", + "Pending": "status-pending" + }[status] || ""; + + return ( + + {status} + + ); + }, + }, + { + key: "assignee", + title: "Assignee", + width: "140px", + }, + { + key: "priority", + title: "Priority", + width: "100px", + render: (task) => { + const priority = task.extraColumns?.priority as string; + const priorityClass = { + "Critical": "priority-critical", + "High": "priority-high", + "Medium": "priority-medium", + "Low": "priority-low" + }[priority] || ""; + + return ( + + {priority} + + ); + }, + }, + { + key: "budget", + title: "Budget", + width: "100px", + render: (task) => { + const budget = task.extraColumns?.budget as number; + return budget > 0 ? `$${budget.toLocaleString()}` : "-"; + }, + }, +]; diff --git a/example/src/index.css b/example/src/index.css index 9fd1ea03d..8ddef1d31 100644 --- a/example/src/index.css +++ b/example/src/index.css @@ -80,3 +80,51 @@ input:checked + .Slider:before { -ms-transform: translateX(26px); transform: translateX(26px); } + +/* Extra columns styles */ +.status-badge, .priority-badge { + padding: 4px 8px; + border-radius: 4px; + font-size: 12px; + font-weight: 500; + color: white; + text-align: center; + display: inline-block; + min-width: 60px; +} + +/* Status badge styles */ +.status-completed { + background-color: #28a745; +} + +.status-in-progress { + background-color: #007bff; +} + +.status-not-started { + background-color: #6c757d; +} + +.status-pending { + background-color: #ffc107; + color: #212529; +} + +/* Priority badge styles */ +.priority-critical { + background-color: #dc3545; +} + +.priority-high { + background-color: #fd7e14; +} + +.priority-medium { + background-color: #ffc107; + color: #212529; +} + +.priority-low { + background-color: #28a745; +} diff --git a/package-lock.json b/package-lock.json index aeca7dc81..46dbdfe5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gantt-task-react", - "version": "0.3.8", + "version": "0.3.9", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "gantt-task-react", - "version": "0.3.8", + "version": "0.3.9", "license": "MIT", "devDependencies": { "@testing-library/jest-dom": "^5.16.4", diff --git a/package.json b/package.json index a0097baa7..0d13e3504 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,23 @@ { - "name": "gantt-task-react", - "version": "0.3.9", - "description": "Interactive Gantt Chart for React with TypeScript.", - "author": "MaTeMaTuK ", - "homepage": "https://github.com/MaTeMaTuK/gantt-task-react", + "name": "@scharinger/gantt-task-react", + "version": "0.4.0-beta.2", + "description": "Interactive Gantt Chart for React with TypeScript and Extra Columns Support. Based on gantt-task-react by MaTeMaTuK.", + "author": "scharinger ", + "homepage": "https://github.com/scharinger/gantt-task-react", "license": "MIT", - "repository": "MaTeMaTuK/gantt-task-react", + "repository": { + "type": "git", + "url": "git+https://github.com/scharinger/gantt-task-react.git" + }, "main": "dist/index.js", "module": "dist/index.modern.js", "source": "src/index.tsx", "engines": { "node": ">=10" }, + "contributors": [ + "MaTeMaTuK (original author)" + ], "keywords": [ "react", "gantt", @@ -21,7 +27,8 @@ "gantt-chart", "gantt chart", "react-gantt", - "task" + "task", + "configurable-columns" ], "scripts": { "build": "microbundle-crl --no-compress --format modern,cjs", diff --git a/src/components/gantt/gantt.tsx b/src/components/gantt/gantt.tsx index b90483f3d..d5f2ce816 100644 --- a/src/components/gantt/gantt.tsx +++ b/src/components/gantt/gantt.tsx @@ -58,6 +58,11 @@ export const Gantt: React.FunctionComponent = ({ TooltipContent = StandardTooltipContent, TaskListHeader = TaskListHeaderDefault, TaskListTable = TaskListTableDefault, + extraColumns, + nameColumnWidth, + fromColumnWidth, + toColumnWidth, + dateFormat = "locale", onDateChange, onProgressChange, onDoubleClick, @@ -446,6 +451,11 @@ export const Gantt: React.FunctionComponent = ({ taskListRef, setSelectedTask: handleSelectedTask, onExpanderClick: handleExpanderClick, + extraColumns, + nameColumnWidth, + fromColumnWidth, + toColumnWidth, + dateFormat, TaskListHeader, TaskListTable, }; diff --git a/src/components/task-list/task-list-header.tsx b/src/components/task-list/task-list-header.tsx index 4e8cdb66b..f655d679e 100644 --- a/src/components/task-list/task-list-header.tsx +++ b/src/components/task-list/task-list-header.tsx @@ -1,12 +1,26 @@ import React from "react"; import styles from "./task-list-header.module.css"; +import { ExtraColumn } from "../../types/public-types"; export const TaskListHeaderDefault: React.FC<{ headerHeight: number; rowWidth: string; fontFamily: string; fontSize: string; -}> = ({ headerHeight, fontFamily, fontSize, rowWidth }) => { + extraColumns?: ExtraColumn[]; + nameColumnWidth?: string; + fromColumnWidth?: string; + toColumnWidth?: string; +}> = ({ + headerHeight, + fontFamily, + fontSize, + rowWidth, + extraColumns = [], + nameColumnWidth, + fromColumnWidth, + toColumnWidth +}) => { return (
 Name @@ -39,7 +53,7 @@ export const TaskListHeaderDefault: React.FC<{
 From @@ -54,11 +68,31 @@ export const TaskListHeaderDefault: React.FC<{
 To
+ {/* Render extra column headers */} + {extraColumns.map((column) => ( + +
+
+  {column.title} +
+ + ))}
); diff --git a/src/components/task-list/task-list-table.tsx b/src/components/task-list/task-list-table.tsx index b165f6002..f3328c61b 100644 --- a/src/components/task-list/task-list-table.tsx +++ b/src/components/task-list/task-list-table.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from "react"; import styles from "./task-list-table.module.css"; -import { Task } from "../../types/public-types"; +import { Task, ExtraColumn, DateFormat } from "../../types/public-types"; const localeDateStringCache = {}; const toLocaleDateStringFactory = @@ -14,6 +14,11 @@ const toLocaleDateStringFactory = } return lds; }; + +const toISODateString = (date: Date): string => { + return date.toISOString().split("T")[0]; // Returns yyyy-MM-dd format +}; + const dateTimeOptions: Intl.DateTimeFormatOptions = { weekday: "short", year: "numeric", @@ -31,6 +36,11 @@ export const TaskListTableDefault: React.FC<{ selectedTaskId: string; setSelectedTask: (taskId: string) => void; onExpanderClick: (task: Task) => void; + extraColumns?: ExtraColumn[]; + nameColumnWidth?: string; + fromColumnWidth?: string; + toColumnWidth?: string; + dateFormat?: DateFormat; }> = ({ rowHeight, rowWidth, @@ -39,12 +49,24 @@ export const TaskListTableDefault: React.FC<{ fontSize, locale, onExpanderClick, + extraColumns = [], + nameColumnWidth, + fromColumnWidth, + toColumnWidth, + dateFormat = "locale", }) => { const toLocaleDateString = useMemo( () => toLocaleDateStringFactory(locale), [locale] ); + const formatDate = useMemo(() => { + if (dateFormat === "iso8601") { + return toISODateString; + } + return (date: Date) => toLocaleDateString(date, dateTimeOptions); + }, [dateFormat, toLocaleDateString]); + return (
@@ -92,21 +114,38 @@ export const TaskListTableDefault: React.FC<{
-  {toLocaleDateString(t.start, dateTimeOptions)} +  {formatDate(t.start)}
-  {toLocaleDateString(t.end, dateTimeOptions)} +  {formatDate(t.end)}
+ {/* Render extra column values */} + {extraColumns.map((column) => ( +
+ {column.render + ? column.render(t) + : t.extraColumns?.[column.key] || "" + } +
+ ))}
); })} diff --git a/src/components/task-list/task-list.tsx b/src/components/task-list/task-list.tsx index bbfed4365..5c78d65d2 100644 --- a/src/components/task-list/task-list.tsx +++ b/src/components/task-list/task-list.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useRef } from "react"; import { BarTask } from "../../types/bar-task"; -import { Task } from "../../types/public-types"; +import { Task, ExtraColumn, DateFormat } from "../../types/public-types"; export type TaskListProps = { headerHeight: number; @@ -17,11 +17,20 @@ export type TaskListProps = { selectedTask: BarTask | undefined; setSelectedTask: (task: string) => void; onExpanderClick: (task: Task) => void; + extraColumns?: ExtraColumn[]; + nameColumnWidth?: string; + fromColumnWidth?: string; + toColumnWidth?: string; + dateFormat?: DateFormat; TaskListHeader: React.FC<{ headerHeight: number; rowWidth: string; fontFamily: string; fontSize: string; + extraColumns?: ExtraColumn[]; + nameColumnWidth?: string; + fromColumnWidth?: string; + toColumnWidth?: string; }>; TaskListTable: React.FC<{ rowHeight: number; @@ -33,6 +42,11 @@ export type TaskListProps = { selectedTaskId: string; setSelectedTask: (taskId: string) => void; onExpanderClick: (task: Task) => void; + extraColumns?: ExtraColumn[]; + nameColumnWidth?: string; + fromColumnWidth?: string; + toColumnWidth?: string; + dateFormat?: DateFormat; }>; }; @@ -51,6 +65,11 @@ export const TaskList: React.FC = ({ ganttHeight, taskListRef, horizontalContainerClass, + extraColumns, + nameColumnWidth, + fromColumnWidth, + toColumnWidth, + dateFormat, TaskListHeader, TaskListTable, }) => { @@ -66,6 +85,10 @@ export const TaskList: React.FC = ({ fontFamily, fontSize, rowWidth, + extraColumns, + nameColumnWidth, + fromColumnWidth, + toColumnWidth, }; const selectedTaskId = selectedTask ? selectedTask.id : ""; const tableProps = { @@ -78,6 +101,11 @@ export const TaskList: React.FC = ({ selectedTaskId: selectedTaskId, setSelectedTask, onExpanderClick, + extraColumns, + nameColumnWidth, + fromColumnWidth, + toColumnWidth, + dateFormat, }; return ( diff --git a/src/index.tsx b/src/index.tsx index 47e8b63a4..3899ab394 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -3,6 +3,8 @@ export { ViewMode } from "./types/public-types"; export type { GanttProps, Task, + ExtraColumn, + DateFormat, StylingOption, DisplayOption, EventOption, diff --git a/src/types/public-types.ts b/src/types/public-types.ts index cc44ff17c..883a888b5 100644 --- a/src/types/public-types.ts +++ b/src/types/public-types.ts @@ -10,6 +10,16 @@ export enum ViewMode { Year = "Year", } export type TaskType = "task" | "milestone" | "project"; + +export type DateFormat = "locale" | "iso8601"; + +export interface ExtraColumn { + key: string; + title: string; + width?: string; + render?: (task: Task) => React.ReactNode; +} + export interface Task { id: string; type: TaskType; @@ -31,6 +41,10 @@ export interface Task { dependencies?: string[]; hideChildren?: boolean; displayOrder?: number; + /** + * Extra column data - key-value pairs for additional columns + */ + extraColumns?: { [key: string]: string | number }; } export interface EventOption { @@ -123,6 +137,10 @@ export interface StylingOption { rowWidth: string; fontFamily: string; fontSize: string; + extraColumns?: ExtraColumn[]; + nameColumnWidth?: string; + fromColumnWidth?: string; + toColumnWidth?: string; }>; TaskListTable?: React.FC<{ rowHeight: number; @@ -137,9 +155,34 @@ export interface StylingOption { */ setSelectedTask: (taskId: string) => void; onExpanderClick: (task: Task) => void; + extraColumns?: ExtraColumn[]; + nameColumnWidth?: string; + fromColumnWidth?: string; + toColumnWidth?: string; + dateFormat?: DateFormat; }>; } export interface GanttProps extends EventOption, DisplayOption, StylingOption { tasks: Task[]; + /** + * Extra columns to display in the task list + */ + extraColumns?: ExtraColumn[]; + /** + * Width of the Name column + */ + nameColumnWidth?: string; + /** + * Width of the From column + */ + fromColumnWidth?: string; + /** + * Width of the To column + */ + toColumnWidth?: string; + /** + * Date format for start and end dates. "locale" uses locale formatting, "iso8601" uses yyyy-MM-dd format + */ + dateFormat?: DateFormat; }