Skip to content

Commit 1a039b3

Browse files
authored
Merge pull request #394 from mariohmol/fix/376-original-id-removal
feat(#376): GetTaskByOriginalID + RemoveTaskItem accepts original IDs
2 parents eeca70c + 29b2625 commit 1a039b3

9 files changed

Lines changed: 1179 additions & 12 deletions

File tree

.mocharc.cjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module.exports = {
22
require: ['ts-node/register'],
3-
spec: 'test/**/*.ts',
3+
spec: 'test/unit/**/*.ts',
44
timeout: 10000
55
};

dist/draw.js

Lines changed: 845 additions & 0 deletions
Large diffs are not rendered by default.

dist/jsgantt.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ var GanttChart = function (pDiv, pFormat) {
154154
this.AddTaskItem = task_1.AddTaskItem;
155155
this.AddTaskItemObject = task_1.AddTaskItemObject;
156156
this.RemoveTaskItem = task_1.RemoveTaskItem;
157+
this.GetTaskByOriginalID = task_1.GetTaskByOriginalID;
157158
this.ClearTasks = task_1.ClearTasks;
158159
this.getXMLProject = xml_1.getXMLProject;
159160
this.getXMLTask = xml_1.getXMLTask;
@@ -3681,7 +3682,7 @@ var __assign = (this && this.__assign) || function () {
36813682
return __assign.apply(this, arguments);
36823683
};
36833684
Object.defineProperty(exports, "__esModule", { value: true });
3684-
exports.processRows = exports.ClearTasks = exports.RemoveTaskItem = exports.AddTaskItemObject = exports.AddTaskItem = exports.createTaskInfo = exports.TaskItem = exports.TaskItemObject = exports.sortTasks = exports.taskLink = void 0;
3685+
exports.processRows = exports.ClearTasks = exports.RemoveTaskItem = exports.GetTaskByOriginalID = exports.AddTaskItemObject = exports.AddTaskItem = exports.createTaskInfo = exports.TaskItem = exports.TaskItemObject = exports.sortTasks = exports.taskLink = void 0;
36853686
var general_utils_1 = require("./utils/general_utils");
36863687
var draw_utils_1 = require("./utils/draw_utils");
36873688
var date_utils_1 = require("./utils/date_utils");
@@ -4262,6 +4263,7 @@ var AddTaskItem = function (value) {
42624263
this.vTaskList.push(value);
42634264
this.vProcessNeeded = true;
42644265
}
4266+
return value.getID();
42654267
};
42664268
exports.AddTaskItem = AddTaskItem;
42674269
var AddTaskItemObject = function (object) {
@@ -4271,12 +4273,31 @@ var AddTaskItemObject = function (object) {
42714273
return this.AddTaskItem((0, exports.TaskItemObject)(object));
42724274
};
42734275
exports.AddTaskItemObject = AddTaskItemObject;
4276+
var GetTaskByOriginalID = function (pOriginalID) {
4277+
var id = String(pOriginalID);
4278+
for (var i = 0; i < this.vTaskList.length; i++) {
4279+
if (this.vTaskList[i].getOriginalID() === id)
4280+
return this.vTaskList[i];
4281+
}
4282+
return null;
4283+
};
4284+
exports.GetTaskByOriginalID = GetTaskByOriginalID;
42744285
var RemoveTaskItem = function (pID) {
4286+
// Accept either the internal vID or the original string ID.
4287+
// Resolve an original ID to its vID so the recursive child-removal still works.
4288+
var vID = pID;
4289+
var asString = String(pID);
4290+
for (var i = 0; i < this.vTaskList.length; i++) {
4291+
if (this.vTaskList[i].getOriginalID() === asString) {
4292+
vID = this.vTaskList[i].getID();
4293+
break;
4294+
}
4295+
}
42754296
// simply mark the task for removal at this point - actually remove it next time we re-draw the chart
42764297
for (var i = 0; i < this.vTaskList.length; i++) {
4277-
if (this.vTaskList[i].getID() == pID)
4298+
if (this.vTaskList[i].getID() == vID)
42784299
this.vTaskList[i].setToDelete(true);
4279-
else if (this.vTaskList[i].getParent() == pID)
4300+
else if (this.vTaskList[i].getParent() == vID)
42804301
this.RemoveTaskItem(this.vTaskList[i].getID());
42814302
}
42824303
this.vProcessNeeded = true;

dist/task.js

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ var __assign = (this && this.__assign) || function () {
1010
};
1111
return __assign.apply(this, arguments);
1212
};
13-
exports.__esModule = true;
14-
exports.processRows = exports.ClearTasks = exports.RemoveTaskItem = exports.AddTaskItemObject = exports.AddTaskItem = exports.createTaskInfo = exports.TaskItem = exports.TaskItemObject = exports.sortTasks = exports.taskLink = void 0;
13+
Object.defineProperty(exports, "__esModule", { value: true });
14+
exports.processRows = exports.ClearTasks = exports.RemoveTaskItem = exports.GetTaskByOriginalID = exports.AddTaskItemObject = exports.AddTaskItem = exports.createTaskInfo = exports.TaskItem = exports.TaskItemObject = exports.sortTasks = exports.taskLink = void 0;
1515
var general_utils_1 = require("./utils/general_utils");
1616
var draw_utils_1 = require("./utils/draw_utils");
1717
var date_utils_1 = require("./utils/date_utils");
@@ -151,7 +151,7 @@ var TaskItem = function (pID, pName, pStart, pEnd, pClass, pLink, pMile, pRes, p
151151
function parseDepend(pDep) {
152152
vDepend = [];
153153
vDependType = [];
154-
if (pDep == null)
154+
if (!pDep)
155155
return;
156156
var vDepList = (pDep + '').split(',');
157157
for (var k = 0; k < vDepList.length; k++) {
@@ -592,6 +592,7 @@ var AddTaskItem = function (value) {
592592
this.vTaskList.push(value);
593593
this.vProcessNeeded = true;
594594
}
595+
return value.getID();
595596
};
596597
exports.AddTaskItem = AddTaskItem;
597598
var AddTaskItemObject = function (object) {
@@ -601,12 +602,31 @@ var AddTaskItemObject = function (object) {
601602
return this.AddTaskItem((0, exports.TaskItemObject)(object));
602603
};
603604
exports.AddTaskItemObject = AddTaskItemObject;
605+
var GetTaskByOriginalID = function (pOriginalID) {
606+
var id = String(pOriginalID);
607+
for (var i = 0; i < this.vTaskList.length; i++) {
608+
if (this.vTaskList[i].getOriginalID() === id)
609+
return this.vTaskList[i];
610+
}
611+
return null;
612+
};
613+
exports.GetTaskByOriginalID = GetTaskByOriginalID;
604614
var RemoveTaskItem = function (pID) {
615+
// Accept either the internal vID or the original string ID.
616+
// Resolve an original ID to its vID so the recursive child-removal still works.
617+
var vID = pID;
618+
var asString = String(pID);
619+
for (var i = 0; i < this.vTaskList.length; i++) {
620+
if (this.vTaskList[i].getOriginalID() === asString) {
621+
vID = this.vTaskList[i].getID();
622+
break;
623+
}
624+
}
605625
// simply mark the task for removal at this point - actually remove it next time we re-draw the chart
606626
for (var i = 0; i < this.vTaskList.length; i++) {
607-
if (this.vTaskList[i].getID() == pID)
627+
if (this.vTaskList[i].getID() == vID)
608628
this.vTaskList[i].setToDelete(true);
609-
else if (this.vTaskList[i].getParent() == pID)
629+
else if (this.vTaskList[i].getParent() == vID)
610630
this.RemoveTaskItem(this.vTaskList[i].getID());
611631
}
612632
this.vProcessNeeded = true;

docs/demo.html

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,31 @@ <h3 class="row">Hide and Show Properties</h3>
345345
</div>
346346
</td>
347347
</tr>
348+
<tr style="border-top:1px solid #ffe082">
349+
<td style="padding:6px 8px;vertical-align:top">
350+
<a href="https://github.com/jsGanttImproved/jsgantt-improved/issues/376" target="_blank" style="color:#0066cc">#376</a>
351+
</td>
352+
<td style="padding:6px 8px;vertical-align:top" colspan="2">
353+
<strong>RemoveTaskItem / GetTaskByOriginalID accept original (pre-hash) IDs.</strong><br>
354+
After tasks are loaded via <code>parseXMLString</code>, each task's public ID (e.g. <code>TASK-1</code>)
355+
differs from its internal hashed vID. Previously <code>RemoveTaskItem</code> only accepted the hashed vID.
356+
PR #394 lets you pass the original string ID directly — and adds <code>GetTaskByOriginalID</code> for lookups.
357+
<br><br>
358+
<button onclick="load376Demo()" style="padding:4px 10px;margin-right:8px">Load #376 scenario</button>
359+
<span style="font-family:sans-serif;font-size:12px;color:#888">Loads 3 XML tasks: TASK-1 (group), TASK-2 (child), TASK-3 (standalone)</span>
360+
<br><br>
361+
<div id="demo376-controls" style="display:none">
362+
<label style="font-family:sans-serif;font-size:12px">Original ID:&nbsp;</label>
363+
<input id="demo376-id" type="text" value="TASK-1" style="width:100px;padding:2px 4px;font-family:monospace">
364+
&nbsp;
365+
<button onclick="demo376Search()" style="padding:4px 10px;margin-right:6px">Search (GetTaskByOriginalID)</button>
366+
<button onclick="demo376Remove()" style="padding:4px 10px">Remove (RemoveTaskItem)</button>
367+
<br><br>
368+
<span style="font-family:sans-serif;font-size:12px">Result: </span>
369+
<span id="demo376-status" style="color:#0066cc;font-family:monospace"></span>
370+
</div>
371+
</td>
372+
</tr>
348373
</tbody>
349374
</table>
350375

docs/index.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,4 +298,75 @@ function generateTooltip(task) {
298298
});
299299
}
300300

301+
// ─── Issue #376 demo ─────────────────────────────────────────────────────────
302+
// Demonstrates GetTaskByOriginalID and RemoveTaskItem with original string IDs.
303+
// Tasks are loaded via parseXMLString so their internal vIDs differ from the
304+
// human-readable IDs in the source XML.
305+
306+
const DEMO_376_XML = `<?xml version="1.0" encoding="UTF-8"?>
307+
<project>
308+
<task>
309+
<pID>TASK-1</pID><pName>Alpha (group)</pName>
310+
<pStart>2026-04-01</pStart><pEnd>2026-04-30</pEnd>
311+
<pClass>gtaskblue</pClass><pGroup>1</pGroup><pParent>0</pParent><pOpen>1</pOpen>
312+
</task>
313+
<task>
314+
<pID>TASK-2</pID><pName>Beta (child of TASK-1)</pName>
315+
<pStart>2026-04-01</pStart><pEnd>2026-04-15</pEnd>
316+
<pClass>gtaskgreen</pClass><pGroup>0</pGroup><pParent>TASK-1</pParent><pOpen>1</pOpen>
317+
</task>
318+
<task>
319+
<pID>TASK-3</pID><pName>Gamma (standalone)</pName>
320+
<pStart>2026-04-16</pStart><pEnd>2026-04-30</pEnd>
321+
<pClass>gtaskred</pClass><pGroup>0</pGroup><pParent>0</pParent><pOpen>1</pOpen>
322+
</task>
323+
</project>`;
324+
325+
function load376Demo() {
326+
g = new JSGantt.GanttChart(document.getElementById("embedded-Gantt"), "month");
327+
g.setOptions({
328+
vCaptionType: "Caption",
329+
vLang: "en",
330+
vFormat: "month",
331+
vFormatArr: ["Week", "Month"],
332+
vShowRes: 0, vShowCost: 0, vShowComp: 0, vShowDur: 0,
333+
vShowStartDate: 1, vShowEndDate: 1,
334+
vEditable: false,
335+
});
336+
JSGantt.parseXMLString(DEMO_376_XML, g);
337+
g.Draw();
338+
document.getElementById("demo376-controls").style.display = "block";
339+
document.getElementById("demo376-status").textContent = "Chart loaded with TASK-1, TASK-2, TASK-3";
340+
}
341+
342+
function demo376Search() {
343+
const id = document.getElementById("demo376-id").value.trim();
344+
const task = g.GetTaskByOriginalID(id);
345+
const status = document.getElementById("demo376-status");
346+
if (task) {
347+
status.style.color = "#007700";
348+
status.textContent = 'Found: "' + task.getName() + '" (internal vID: ' + task.getID() + ')';
349+
} else {
350+
status.style.color = "#cc0000";
351+
status.textContent = 'No task with original ID "' + id + '"';
352+
}
353+
}
354+
355+
function demo376Remove() {
356+
const id = document.getElementById("demo376-id").value.trim();
357+
const before = g.vTaskList.filter(t => !t.getToDelete()).length;
358+
g.RemoveTaskItem(id);
359+
g.Draw();
360+
const after = g.vTaskList.filter(t => !t.getToDelete()).length;
361+
const removed = before - after;
362+
const status = document.getElementById("demo376-status");
363+
if (removed > 0) {
364+
status.style.color = "#007700";
365+
status.textContent = 'Removed ' + removed + ' task(s) with original ID "' + id + '" (including children)';
366+
} else {
367+
status.style.color = "#cc0000";
368+
status.textContent = 'No task found with original ID "' + id + '"';
369+
}
370+
}
371+
301372
start("pt");

src/draw.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
removeListener,
1616
} from "./events";
1717
import { calculateCurrentDateOffset, getOffset, getScrollbarWidth, printChart } from "./utils/general_utils";
18-
import { createTaskInfo, AddTaskItem, AddTaskItemObject, RemoveTaskItem, processRows, ClearTasks } from "./task";
18+
import { createTaskInfo, AddTaskItem, AddTaskItemObject, RemoveTaskItem, GetTaskByOriginalID, processRows, ClearTasks } from "./task";
1919

2020
import { getXMLProject, getXMLTask } from "./xml";
2121
import { COLUMN_ORDER, draw_header, draw_bottom, draw_task_headings } from "./draw_columns";
@@ -162,6 +162,7 @@ export const GanttChart = function (pDiv, pFormat) {
162162
this.AddTaskItem = AddTaskItem;
163163
this.AddTaskItemObject = AddTaskItemObject;
164164
this.RemoveTaskItem = RemoveTaskItem;
165+
this.GetTaskByOriginalID = GetTaskByOriginalID;
165166
this.ClearTasks = ClearTasks;
166167

167168
this.getXMLProject = getXMLProject;

src/task.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ export const AddTaskItem = function (value) {
517517
this.vTaskList.push(value);
518518
this.vProcessNeeded = true;
519519
}
520+
return value.getID();
520521
};
521522

522523
export const AddTaskItemObject = function (object) {
@@ -526,11 +527,29 @@ export const AddTaskItemObject = function (object) {
526527
return this.AddTaskItem(TaskItemObject(object));
527528
}
528529

530+
export const GetTaskByOriginalID = function (pOriginalID) {
531+
const id = String(pOriginalID);
532+
for (let i = 0; i < this.vTaskList.length; i++) {
533+
if (this.vTaskList[i].getOriginalID() === id) return this.vTaskList[i];
534+
}
535+
return null;
536+
};
537+
529538
export const RemoveTaskItem = function (pID) {
539+
// Accept either the internal vID or the original string ID.
540+
// Resolve an original ID to its vID so the recursive child-removal still works.
541+
let vID = pID;
542+
const asString = String(pID);
543+
for (let i = 0; i < this.vTaskList.length; i++) {
544+
if (this.vTaskList[i].getOriginalID() === asString) {
545+
vID = this.vTaskList[i].getID();
546+
break;
547+
}
548+
}
530549
// simply mark the task for removal at this point - actually remove it next time we re-draw the chart
531550
for (let i = 0; i < this.vTaskList.length; i++) {
532-
if (this.vTaskList[i].getID() == pID) this.vTaskList[i].setToDelete(true);
533-
else if (this.vTaskList[i].getParent() == pID) this.RemoveTaskItem(this.vTaskList[i].getID());
551+
if (this.vTaskList[i].getID() == vID) this.vTaskList[i].setToDelete(true);
552+
else if (this.vTaskList[i].getParent() == vID) this.RemoveTaskItem(this.vTaskList[i].getID());
534553
}
535554
this.vProcessNeeded = true;
536555
};

0 commit comments

Comments
 (0)