Skip to content

Commit c7abe5f

Browse files
hangtime79claude
andcommitted
feat(v0.9.7): Add Reset Zoom button (#60)
Adds a Reset button to the zoom controls that returns zoom to 100% (or viewport floor if larger). Button placed left of Zoom Out. Changes: - body.html: Add reset button with circular arrow icon - app.js: Add resetZoom() function and event listener - plugin.json: Version bump to 0.9.7 Fixes #60 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 842feaf commit c7abe5f

5 files changed

Lines changed: 217 additions & 2 deletions

File tree

plan/specs/feature-v0.9.7-spec.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Feature v0.9.7 Specification - Reset Zoom
2+
3+
## Branch
4+
`feature/v0.9.7-reset-zoom`
5+
6+
## Linked Issues
7+
- Fixes #60
8+
9+
## Overview
10+
Add a "Reset Zoom" button to the control bar that resets the zoom level to 100% (or viewport floor if larger).
11+
12+
---
13+
14+
## Feature: Reset Zoom Button
15+
16+
### User Story
17+
As a user, I want to quickly reset the zoom to a standard view after zooming in/out, so I don't have to click multiple times to return to baseline.
18+
19+
### Current Behavior
20+
- Zoom In/Out buttons adjust by ZOOM_STEP (5px) per click
21+
- No way to quickly return to baseline without multiple clicks
22+
- Each view mode maintains its own zoom level in `columnWidthByViewMode`
23+
24+
### New Behavior
25+
- New "Reset" button appears left of "Zoom Out"
26+
- Clicking resets to `max(COLUMN_WIDTH_BASELINE, minColumnWidthByViewMode[currentViewMode])`
27+
- Zoom indicator updates immediately
28+
29+
---
30+
31+
## Fix Plan
32+
33+
### Step 1: Add Reset Button HTML
34+
**File:** `webapps/gantt-chart/body.html`
35+
36+
Add reset button before zoom-out button inside `.btn-group`:
37+
38+
```html
39+
<button id="btn-zoom-reset" class="btn btn-icon" title="Reset Zoom to 100%" aria-label="Reset Zoom">
40+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
41+
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/>
42+
<path d="M3 3v5h5"/>
43+
</svg>
44+
</button>
45+
```
46+
47+
### Step 2: Add Reset Button Event Handler
48+
**File:** `webapps/gantt-chart/app.js`
49+
50+
In `setupControls()` function (around line 2290), add:
51+
52+
```javascript
53+
const zoomResetBtn = document.getElementById('btn-zoom-reset');
54+
if (zoomResetBtn) {
55+
zoomResetBtn.addEventListener('click', resetZoom);
56+
}
57+
```
58+
59+
### Step 3: Create resetZoom() Function
60+
**File:** `webapps/gantt-chart/app.js`
61+
62+
Add new function after `adjustZoom()`:
63+
64+
```javascript
65+
/**
66+
* Reset zoom to 100% or viewport floor (whichever is larger).
67+
* Uses the greater of COLUMN_WIDTH_BASELINE (75px) or the
68+
* calculated minimum for the current view mode.
69+
*/
70+
function resetZoom() {
71+
const viewFloor = minColumnWidthByViewMode[currentViewMode] || ABSOLUTE_FLOOR;
72+
const targetWidth = Math.max(COLUMN_WIDTH_BASELINE, viewFloor);
73+
const currentWidth = columnWidthByViewMode[currentViewMode] || COLUMN_WIDTH_BASELINE;
74+
75+
if (targetWidth === currentWidth) {
76+
console.log('Zoom already at reset level:', targetWidth);
77+
return;
78+
}
79+
80+
columnWidthByViewMode[currentViewMode] = targetWidth;
81+
ganttInstance.options.column_width = targetWidth;
82+
ganttInstance.change_view_mode(currentViewMode);
83+
updateZoomIndicator();
84+
console.log('Zoom reset to:', targetWidth, '(' + Math.round((targetWidth / COLUMN_WIDTH_BASELINE) * 100) + '%) for', currentViewMode);
85+
}
86+
```
87+
88+
### Step 4: Version Bump
89+
**File:** `plugin.json`
90+
91+
Change version from `"0.9.5"` to `"0.9.7"`
92+
93+
---
94+
95+
## Files to Modify
96+
97+
| File | Action | Description |
98+
|------|--------|-------------|
99+
| `webapps/gantt-chart/body.html` | Modify | Add reset button before zoom-out |
100+
| `webapps/gantt-chart/app.js` | Modify | Add resetZoom() function and event listener |
101+
| `plugin.json` | Modify | Version bump to 0.9.7 |
102+
103+
---
104+
105+
## Testing Checklist
106+
- [ ] Reset button appears left of Zoom Out button
107+
- [ ] Reset button has correct icon (circular arrow)
108+
- [ ] Reset button has tooltip "Reset Zoom to 100%"
109+
- [ ] Clicking reset at 150% zoom returns to 100%
110+
- [ ] Clicking reset at 50% zoom returns to 100%
111+
- [ ] If viewport floor > 100%, reset goes to floor instead
112+
- [ ] Zoom indicator shows correct percentage after reset
113+
- [ ] Reset works independently per view mode (Week, Month, etc.)
114+
- [ ] Dark mode styling works correctly
115+
- [ ] Button hover states work
116+
117+
---
118+
119+
## User QA Gate
120+
121+
**CRITICAL: Code must be committed BEFORE User QA.**
122+
123+
**Pre-QA Commit Process:**
124+
1. After implementing the fix, commit with message:
125+
```
126+
feat(v0.9.7): Add Reset Zoom button (#60)
127+
128+
Adds a Reset button to the zoom controls that returns zoom to 100%
129+
(or viewport floor if larger). Button placed left of Zoom Out.
130+
131+
Changes:
132+
- body.html: Add reset button with circular arrow icon
133+
- app.js: Add resetZoom() function and event listener
134+
- plugin.json: Version bump to 0.9.7
135+
136+
Fixes #60
137+
```
138+
139+
2. Verify commit: `git log --oneline -1`
140+
3. Notify user that code is ready for QA
141+
142+
**QA Script for User:**
143+
```
144+
1. Reload plugin in Dataiku (Actions menu → Reload)
145+
2. Open a Gantt chart with tasks
146+
3. Verify Reset button appears left of "−" (Zoom Out) button
147+
4. Hover over Reset button - confirm tooltip shows "Reset Zoom to 100%"
148+
5. Click Zoom In several times to reach 150%+
149+
6. Click Reset - confirm zoom returns to 100%
150+
7. Click Zoom Out several times to reach 50%
151+
8. Click Reset - confirm zoom returns to 100%
152+
9. Switch to Month view, zoom to 200%
153+
10. Switch back to Week view - confirm Week's zoom was independent
154+
11. In Week view, click Reset - confirm it resets Week view
155+
12. Switch to Month view - confirm it still shows 200%
156+
13. (If dark mode) Toggle dark mode and verify button styling
157+
```
158+
159+
**Do not proceed to PR/merge until user confirms the fix works.**
160+
161+
---
162+
163+
## Rollback Plan
164+
Revert the commit: `git revert HEAD`
165+
166+
---
167+
168+
## Watch Out For
169+
- Button order: Reset must be BEFORE Zoom Out in HTML for correct visual order
170+
- SVG icon: Use inline SVG (FontAwesome classes don't work in Dataiku webapp context)
171+
- Per-view zoom: Each view mode has independent zoom - reset only affects current view

plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"id": "gantt-chart",
44

55
// It is highly recommended to use Semantic Versioning
6-
"version": "0.9.5",
6+
"version": "0.9.7",
77

88
// Meta data for display purposes:
99
"meta": {

resource/webapp/style.css

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@
7373
--text-inverted: #1a1a2e;
7474

7575
--chart-grid-line: #2c3e50;
76-
--chart-today-line: #e74c3c;
76+
--chart-today-line: #C7C7C7;
77+
--g-today-highlight: #C7C7C7;
7778

7879
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
7980
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);
@@ -1009,6 +1010,12 @@ body {
10091010
fill: #ffffff !important;
10101011
}
10111012

1013+
/* Dark mode: light highlight needs dark text */
1014+
.dark-theme .gantt-container .lower-text.current-date-highlight {
1015+
color: #1a1a2e !important;
1016+
fill: #1a1a2e !important;
1017+
}
1018+
10121019
/* Smaller font for narrow views */
10131020
.gantt-container[data-narrow-view="true"] .lower-text {
10141021
font-size: 10px;

webapps/gantt-chart/app.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,6 +2303,11 @@
23032303
zoomOutBtn.addEventListener('click', () => adjustZoom(-ZOOM_STEP));
23042304
}
23052305

2306+
const zoomResetBtn = document.getElementById('btn-zoom-reset');
2307+
if (zoomResetBtn) {
2308+
zoomResetBtn.addEventListener('click', resetZoom);
2309+
}
2310+
23062311
// Init indicator
23072312
updateZoomIndicator();
23082313

@@ -2369,6 +2374,30 @@
23692374
console.log('Zoom to:', newWidth, '(' + Math.round((newWidth / COLUMN_WIDTH_BASELINE) * 100) + '%) for', currentViewMode);
23702375
}
23712376

2377+
/**
2378+
* Reset zoom to 100% or viewport floor (whichever is larger).
2379+
* Uses the greater of COLUMN_WIDTH_BASELINE (75px) or the
2380+
* calculated minimum for the current view mode.
2381+
*/
2382+
function resetZoom() {
2383+
if (!ganttInstance) return;
2384+
2385+
const viewFloor = minColumnWidthByViewMode[currentViewMode] || ABSOLUTE_FLOOR;
2386+
const targetWidth = Math.max(COLUMN_WIDTH_BASELINE, viewFloor);
2387+
const currentWidth = columnWidthByViewMode[currentViewMode] || COLUMN_WIDTH_BASELINE;
2388+
2389+
if (targetWidth === currentWidth) {
2390+
console.log('Zoom already at reset level:', targetWidth);
2391+
return;
2392+
}
2393+
2394+
columnWidthByViewMode[currentViewMode] = targetWidth;
2395+
ganttInstance.options.column_width = targetWidth;
2396+
ganttInstance.change_view_mode(currentViewMode);
2397+
updateZoomIndicator();
2398+
console.log('Zoom reset to:', targetWidth, '(' + Math.round((targetWidth / COLUMN_WIDTH_BASELINE) * 100) + '%) for', currentViewMode);
2399+
}
2400+
23722401
function updateZoomIndicator() {
23732402
const indicator = document.getElementById('zoom-level-indicator');
23742403
if (indicator) {

webapps/gantt-chart/body.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,15 @@
4545
Today
4646
</button>
4747

48+
<div class="control-spacer"></div>
49+
4850
<div class="btn-group">
51+
<button id="btn-zoom-reset" class="btn btn-icon" title="Reset Zoom to 100%" aria-label="Reset Zoom">
52+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
53+
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/>
54+
<path d="M3 3v5h5"/>
55+
</svg>
56+
</button>
4957
<button id="btn-zoom-out" class="btn btn-icon" title="Zoom Out" aria-label="Zoom Out">
5058
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
5159
<line x1="5" y1="12" x2="19" y2="12"></line>

0 commit comments

Comments
 (0)