diff --git a/src/frontend/web/von_interface/static/js/components/taskPanel.js b/src/frontend/web/von_interface/static/js/components/taskPanel.js index 4ca9bd7d..c38b7490 100644 --- a/src/frontend/web/von_interface/static/js/components/taskPanel.js +++ b/src/frontend/web/von_interface/static/js/components/taskPanel.js @@ -5,6 +5,8 @@ * Tasks are stored as Vontology concepts and accessed via REST API. */ +import { copyJsonTextWithButtonFeedback } from '../utils/copyJsonButtonState.js'; +import { buildTaskLink, readTaskLink } from '../utils/taskLinks.js'; import { openTaskRunActivity } from './taskRunActivity.js'; import { deleteJson, getJson, patchJson, postJson, getUserContext, ensureUniqueWindowSessionId, WINDOW_SESSION_HEADER } from '../apiService.js'; import { activateTab } from '../tabNavigation.js'; @@ -32,6 +34,7 @@ let _taskDetailState = {}; // taskId -> detail panel state let _selectedTaskId = ''; let _selectionCleared = false; let _pendingTaskNavigation = null; +let _taskLinkConsumed = false; let _referencedGlobalTaskId = ''; let _panelReturnFocus = null; let _panelTaskIds = null; @@ -964,6 +967,22 @@ async function openGlobalTasks() { loadGlobalTasks({ telemetry }), loadTaskQueueActivity(), ]); + const linkedTaskId = !_taskLinkConsumed && readTaskLink(); + if (!_pendingTaskNavigation && linkedTaskId) { + _taskLinkConsumed = true; + const scopeGeneration = _taskQueueActivityGeneration; + const loadGeneration = _globalTaskLoadGeneration; + try { + const task = await getJson(`/api/tasks/${encodeURIComponent(linkedTaskId)}`); + if (scopeGeneration !== _taskQueueActivityGeneration || loadGeneration !== _globalTaskLoadGeneration) return; + if (getTaskId(task) !== linkedTaskId) throw new Error('Task link target mismatch'); + _pendingTaskNavigation = task; + } catch (_) { + if (scopeGeneration !== _taskQueueActivityGeneration || loadGeneration !== _globalTaskLoadGeneration) return; + clearTaskSelection(); + showToast('Could not open linked task', 'error'); + } + } if (_pendingTaskNavigation) { const task = _pendingTaskNavigation; _pendingTaskNavigation = null; @@ -2821,6 +2840,12 @@ async function openTaskWorkProduct(taskId) { } } +function renderTaskCopyLink(taskId) { + return ` + `; +} + function renderTaskDetailsPanel(task, detailState) { const taskId = getTaskId(task); const detailTask = detailState.task || task; @@ -3130,7 +3155,7 @@ function renderTaskInspector(task, detailState) {
${escapeHtml(detailTask.description || 'No description yet.')}