@aicupa/plugin-todo-dependency 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/service.js +7 -2
- package/view/index.html +42 -7
package/package.json
CHANGED
package/service.js
CHANGED
|
@@ -54,11 +54,16 @@ module.exports = (api) => {
|
|
|
54
54
|
const data = JSON.parse(content)
|
|
55
55
|
const todotree = data.todotree
|
|
56
56
|
|
|
57
|
+
const allTodos = []
|
|
58
|
+
flattenTodos(todotree.tree, allTodos)
|
|
59
|
+
const existingIds = new Set(allTodos.map(t => t.id))
|
|
60
|
+
const validDepIds = depIds.filter(id => existingIds.has(id))
|
|
61
|
+
|
|
57
62
|
function findAndUpdate(nodes) {
|
|
58
63
|
for (const node of nodes) {
|
|
59
64
|
if (node.todo && node.todo.id === todoId) {
|
|
60
|
-
if (
|
|
61
|
-
node.todo.depIds =
|
|
65
|
+
if (validDepIds.length > 0) {
|
|
66
|
+
node.todo.depIds = validDepIds
|
|
62
67
|
} else {
|
|
63
68
|
delete node.todo.depIds
|
|
64
69
|
}
|
package/view/index.html
CHANGED
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
|
|
44
44
|
#graphArea { flex: 1; overflow: auto; position: relative; background: #f7f8fa; }
|
|
45
45
|
.dark #graphArea { background: #1e1e1e; }
|
|
46
|
-
#graphContainer {
|
|
46
|
+
#graphContainer { min-width: 100%; min-height: 100%; display: flex; align-items: center; justify-content: center; }
|
|
47
|
+
#graphInner { position: relative; flex-shrink: 0; }
|
|
47
48
|
|
|
48
49
|
.node {
|
|
49
50
|
position: absolute; width: 200px; background: #fff;
|
|
@@ -241,8 +242,39 @@
|
|
|
241
242
|
} catch { return }
|
|
242
243
|
if (!data) return
|
|
243
244
|
|
|
244
|
-
const { todos, edges } = data
|
|
245
|
-
|
|
245
|
+
const { todos, edges: allEdges } = data
|
|
246
|
+
|
|
247
|
+
// Build adjacency (both directions) to find connected components
|
|
248
|
+
const allIds = new Set()
|
|
249
|
+
const neighbors = {}
|
|
250
|
+
for (const [from, to] of allEdges) {
|
|
251
|
+
allIds.add(from); allIds.add(to)
|
|
252
|
+
if (!neighbors[from]) neighbors[from] = []
|
|
253
|
+
if (!neighbors[to]) neighbors[to] = []
|
|
254
|
+
neighbors[from].push(to)
|
|
255
|
+
neighbors[to].push(from)
|
|
256
|
+
}
|
|
257
|
+
// BFS to find connected components, keep components that have any undone node
|
|
258
|
+
const visited = new Set()
|
|
259
|
+
const visibleIds = new Set()
|
|
260
|
+
for (const start of allIds) {
|
|
261
|
+
if (visited.has(start)) continue
|
|
262
|
+
const comp = []
|
|
263
|
+
const queue = [start]
|
|
264
|
+
visited.add(start)
|
|
265
|
+
while (queue.length) {
|
|
266
|
+
const cur = queue.shift()
|
|
267
|
+
comp.push(cur)
|
|
268
|
+
for (const nb of (neighbors[cur] || [])) {
|
|
269
|
+
if (!visited.has(nb)) { visited.add(nb); queue.push(nb) }
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (comp.some(id => !todos[id]?.done)) {
|
|
273
|
+
for (const id of comp) visibleIds.add(id)
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const edges = allEdges.filter(([from, to]) => visibleIds.has(from) && visibleIds.has(to))
|
|
277
|
+
const nodeIds = [...visibleIds]
|
|
246
278
|
if (!nodeIds.length) { showEmpty(); return }
|
|
247
279
|
|
|
248
280
|
const { layers, hasCycle } = assignLayers(nodeIds, edges)
|
|
@@ -323,8 +355,11 @@
|
|
|
323
355
|
function renderGraph(nodeIds, edges, positions, todoData, layout) {
|
|
324
356
|
const container = document.getElementById('graphContainer')
|
|
325
357
|
container.innerHTML = ''
|
|
326
|
-
|
|
327
|
-
|
|
358
|
+
const inner = document.createElement('div')
|
|
359
|
+
inner.id = 'graphInner'
|
|
360
|
+
inner.style.width = layout.width + 'px'
|
|
361
|
+
inner.style.height = layout.height + 'px'
|
|
362
|
+
container.appendChild(inner)
|
|
328
363
|
|
|
329
364
|
// Build dependency map: nodeId -> [depIds]
|
|
330
365
|
const depsOf = {}
|
|
@@ -382,7 +417,7 @@
|
|
|
382
417
|
'marker-end': isBlockingEdge ? 'url(#arrow-blocked)' : 'url(#arrow)',
|
|
383
418
|
}))
|
|
384
419
|
}
|
|
385
|
-
|
|
420
|
+
inner.appendChild(svg)
|
|
386
421
|
|
|
387
422
|
for (const id of nodeIds) {
|
|
388
423
|
const pos = positions[id]; if (!pos) continue
|
|
@@ -431,7 +466,7 @@
|
|
|
431
466
|
body.appendChild(sb)
|
|
432
467
|
}
|
|
433
468
|
|
|
434
|
-
el.appendChild(body);
|
|
469
|
+
el.appendChild(body); inner.appendChild(el)
|
|
435
470
|
}
|
|
436
471
|
}
|
|
437
472
|
|