From 880200665976680785d20f2868e97677c1e5c461 Mon Sep 17 00:00:00 2001 From: librelad Date: Wed, 27 May 2026 14:48:39 +0100 Subject: [PATCH] ui(tasks): delete-task modal shows friendly title + app icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Delete Task confirmation modal was rendering the raw command ("libreportal app install ipinfo") as its title with no app icon, while the rest of the WebUI (task notifications, task rows) shows "Install Ipinfo" and the ipinfo logo. Inconsistent and slightly intimidating for a confirmation step. Now mirrors the completion-notification flow: - Title: `${formatActionTitle(task.type)} ${getAppDisplayName(task.app)}` → "Install Ipinfo", "Backup Nextcloud", etc. - Icon: /icons/apps/.svg (or libreportal.svg for system tasks) - Tool tasks borrow the same tool-catalog-lookup the completion toast uses so a tool deletion reads as "Manage Shortcuts" rather than the raw tool id. Reuses the existing TasksManager.formatActionTitle() helper so any future task type added to that map flows through here automatically. Signed-off-by: librelad --- .../js/components/tasks/tasks-manager.js | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/containers/libreportal/frontend/js/components/tasks/tasks-manager.js b/containers/libreportal/frontend/js/components/tasks/tasks-manager.js index bb8f00f..bf145c0 100755 --- a/containers/libreportal/frontend/js/components/tasks/tasks-manager.js +++ b/containers/libreportal/frontend/js/components/tasks/tasks-manager.js @@ -2219,7 +2219,36 @@ class TasksManager { const escHtml = (s) => String(s == null ? '' : s) .replace(/&/g, '&').replace(//g, '>'); - const taskLabel = (task && (task.command || task.id)) || 'Unknown task'; + // Build a friendly title + app icon so the modal reads "Install Ipinfo" + // with the app's logo, not the raw "libreportal app install ipinfo" + // command. Mirrors the completion-notification flow above so the + // visual identity of a task is consistent across surfaces. + const appName = (task && task.app) || null; + const action = (task && task.type) || ''; + const isSystemTask = action.startsWith('setup-') || appName === 'system'; + let actionTitle = this.formatActionTitle(action); + // Tool tasks: prefer the tool's curated label. + const toolCmdMatch = (task && task.command || '').match(/libreportal app tool (\S+) (\S+)/); + if (toolCmdMatch) { + const toolId = toolCmdMatch[2]; + let toolLabel = null; + const cat = window.toolsCatalog; + if (cat && cat.apps && cat.apps[toolCmdMatch[1]] && Array.isArray(cat.apps[toolCmdMatch[1]].tools)) { + const t = cat.apps[toolCmdMatch[1]].tools.find(x => x.id === toolId); + if (t && t.label) toolLabel = t.label; + } + if (!toolLabel) toolLabel = toolId.split(/[_-]/).map(w => w ? w.charAt(0).toUpperCase() + w.slice(1) : '').join(' '); + actionTitle = toolLabel; + } + const displayName = isSystemTask + ? '' + : ((appName && window.getAppDisplayName) ? window.getAppDisplayName(appName) : (appName || '')); + const taskLabel = displayName + ? `${actionTitle} ${displayName}` + : (actionTitle || (task && task.id) || 'Unknown task'); + const taskIcon = isSystemTask + ? '/icons/libreportal.svg' + : (appName ? `/icons/apps/${encodeURIComponent(appName)}.svg` : null); const taskStatus = (task && task.status) || 'unknown'; const warningTitle = isActive ? 'Active task' : 'This cannot be undone'; @@ -2257,6 +2286,8 @@ class TasksManager { window.openEoModal({ id: 'delete-task-modal', size: 'sm', + icon: taskIcon || undefined, + iconAlt: displayName || 'Task', eyebrow: 'Delete Task', title: taskLabel, desc: 'Confirm to delete this task.',