Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions examples/collapsible-tasks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Collapsible Dependent Tasks Feature

## Overview
This implementation adds the ability to collapse and expand dependent tasks in the Frappe Gantt chart. Tasks that have dependencies can be collapsed to hide all their dependent tasks, making it easier to focus on high-level tasks and manage complex project hierarchies.

## Features Implemented

### 1. Collapse/Expand Toggle Button
- Tasks that have dependents display a collapse/expand button (−/+) on the left side of the task bar
- Click the button to toggle between collapsed and expanded states
- Visual feedback with appropriate icons (− for expanded, + for collapsed)

### 2. Dependency Tracking
- Automatically detects which tasks have dependents
- Recursively identifies all dependent tasks (including nested dependencies)
- Maintains collapsed state across re-renders

### 3. Smart Visibility Management
- When a task is collapsed, all its dependent tasks are hidden
- Arrows (dependencies) are also hidden for invisible tasks
- The chart layout automatically adjusts to remove gaps from hidden tasks

### 4. Dynamic Layout Adjustment
- Grid height automatically recalculates based on visible tasks
- Task positions are updated to maintain proper spacing
- No visual gaps when tasks are hidden

## Implementation Details

### Modified Files

1. **src/index.js**
- Added `collapsed_tasks` Set to track collapsed state
- Added `tasks_with_dependents` Set to identify collapsible tasks
- Implemented `get_all_dependent_tasks()` for recursive dependency tracking
- Implemented `toggle_task_collapse()` for state management
- Implemented `is_task_visible()` to check task visibility
- Modified `make_bars()` to handle visible/hidden tasks
- Modified `make_arrows()` to only show arrows for visible tasks
- Added `bind_collapse_buttons()` for event handling
- Updated grid calculations to use visible task count

2. **src/bar.js**
- Modified `draw_label()` to add collapse/expand button for tasks with dependents
- Button includes visual styling and click target

## Usage

### Basic Usage
```javascript
const tasks = [
{
id: 'task1',
name: 'Main Task',
start: '2025-10-01',
end: '2025-10-05',
dependencies: []
},
{
id: 'task2',
name: 'Dependent Task',
start: '2025-10-06',
end: '2025-10-10',
dependencies: ['task1']
}
];

const gantt = new Gantt('#gantt', tasks);
```

### Programmatic Control
```javascript
// Toggle collapse state of a task
gantt.toggle_task_collapse('task1');

// Check if a task is visible
const isVisible = gantt.is_task_visible('task2');

// Get all dependent tasks
const dependents = gantt.get_all_dependent_tasks('task1');

// Check which tasks have dependents
const collapsibleTasks = Array.from(gantt.tasks_with_dependents);
```

## Demo
Open `collapsible-tasks-demo.html` in a browser to see the feature in action. The demo includes:
- A project with multiple tasks and dependencies
- Tasks with nested dependencies
- Visual demonstration of collapse/expand functionality

To run the demo:
1. Install dependencies: `npm install`
2. Start the dev server: `npm run dev`
3. Open http://localhost:5173/collapsible-tasks-demo.html

## Browser Compatibility
This feature uses standard JavaScript and SVG, so it should work in all modern browsers that support the base Frappe Gantt library.

## Future Enhancements
Potential improvements that could be added:
1. Collapse/expand all buttons
2. Keyboard shortcuts for collapse/expand
3. Animation transitions when collapsing/expanding
4. Persistence of collapsed state (localStorage)
5. Indentation to show task hierarchy visually
6. Option to collapse by task groups or categories
171 changes: 171 additions & 0 deletions examples/collapsible-tasks/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Collapsible Dependent Tasks - Frappe Gantt Demo</title>
<style>
body {
font-family: Arial, sans-serif;
padding: 20px;
background: #f4f4f4;
}
h1 {
color: #333;
margin-bottom: 10px;
}
p {
color: #666;
margin-bottom: 20px;
}
#gantt {
background: white;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
padding: 20px;
overflow: auto;
}
.info-box {
background: #e8f4fd;
border: 1px solid #bee5ff;
border-radius: 4px;
padding: 15px;
margin-bottom: 20px;
}
.info-box h3 {
margin-top: 0;
color: #0066cc;
}
.info-box ul {
margin: 10px 0;
padding-left: 20px;
}
.info-box li {
margin: 5px 0;
color: #444;
}
</style>
</head>
<body>
<h1>Collapsible Dependent Tasks Demo</h1>
<p>This demo shows the new collapsible dependent tasks feature for the Frappe Gantt library.</p>

<div class="info-box">
<h3>How to use:</h3>
<ul>
<li>Tasks with dependencies show a collapse/expand button (−/+) on the left side</li>
<li>Click the button to collapse/expand all dependent tasks</li>
<li>When collapsed, dependent tasks and their arrows are hidden</li>
<li>The Gantt chart automatically adjusts the layout</li>
</ul>
</div>

<div id="gantt"></div>

<script type="module">
import Gantt from '../../src/index.js';

// Sample tasks with dependencies to demonstrate the feature
const tasks = [
{
id: 'project-planning',
name: 'Plan',
start: '2025-10-01',
end: '2025-10-05',
progress: 100,
dependencies: []
},
{
id: 'requirements',
name: 'Req',
start: '2025-10-06',
end: '2025-10-10',
progress: 80,
dependencies: ['project-planning']
},
{
id: 'design',
name: 'System Design',
start: '2025-10-11',
end: '2025-10-15',
progress: 60,
dependencies: ['requirements']
},
{
id: 'ui-design',
name: 'UI/UX Design',
start: '2025-10-11',
end: '2025-10-14',
progress: 70,
dependencies: ['requirements']
},
{
id: 'backend-dev',
name: 'Backend Development',
start: '2025-10-16',
end: '2025-10-25',
progress: 40,
dependencies: ['design']
},
{
id: 'frontend-dev',
name: 'Frontend Development',
start: '2025-10-16',
end: '2025-10-28',
progress: 30,
dependencies: ['ui-design']
},
{
id: 'api-dev',
name: 'API Development',
start: '2025-10-20',
end: '2025-10-25',
progress: 20,
dependencies: ['backend-dev']
},
{
id: 'integration',
name: 'Integration',
start: '2025-10-26',
end: '2025-10-30',
progress: 0,
dependencies: ['backend-dev', 'frontend-dev']
},
{
id: 'testing',
name: 'Testing',
start: '2025-10-31',
end: '2025-11-05',
progress: 0,
dependencies: ['integration']
},
{
id: 'deployment',
name: 'Deployment',
start: '2025-11-06',
end: '2025-11-08',
progress: 0,
dependencies: ['testing']
}
];

// Initialize the Gantt chart
const gantt = new Gantt('#gantt', tasks, {
view_mode: 'Day',
date_format: 'YYYY-MM-DD',
custom_popup_html: null,
bar_height: 30,
padding: 18,
column_width: 30,
arrow_curve: 5
});

// Make gantt instance available globally for debugging
window.gantt = gantt;

console.log('Gantt chart initialized with collapsible tasks feature');
console.log('Tasks with dependents:', Array.from(gantt.tasks_with_dependents));
console.log('Click on the −/+ buttons to collapse/expand dependent tasks');
</script>
</body>
</html>
Loading