ui(tasks+devmode): friendly task titles + restyle dev-mode strip
Two unrelated UI polish items.
1. Task notification titles. The "Config_update task completed!" toast
was leaking the literal task-type id because the friendly-name map
in the taskCompleted listener didn't list `config_update`,
`update_config`, or `system_update`, and the fallback only
capitalized the first letter. Same fallback was duplicated in
task-actions.js's started-toast path.
Extracted into `TasksManager.formatActionTitle(action)`:
- Adds the missing entries (`config_update`/`update_config` → "Update
Config", `system_update` → "Update System").
- Smarter fallback: snake/kebab → Title Case, so an unmapped future
type renders as e.g. "Foo Bar" instead of "Foo_bar".
- Both the started (task-actions.js) and completed/failed/cancelled
(tasks-manager.js) notification paths now route through it, so the
started/done pair always reads the same.
2. Dev-mode strip styling. Earlier amber-on-amber recipe read as a
warning state; the strip is just informational. Switched to a
neutral glass surface (rgba(text,0.04) + rgba(text,0.12) border),
text-primary copy, and the icon alone in var(--accent). Label is
now centered with the close button absolute-positioned on the
right (24px / 56px right padding so the centered text never sits
under the X).
Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
parent
b754794789
commit
f5fc659c96
@ -3,10 +3,10 @@
|
|||||||
/* Topbar layout, nav pills, donate/logout buttons. Extracted from style.css. Theme via var(--*) tokens. */
|
/* Topbar layout, nav pills, donate/logout buttons. Extracted from style.css. Theme via var(--*) tokens. */
|
||||||
|
|
||||||
/* Developer-mode strip — sits flush under the fixed topbar when CFG_DEV_MODE
|
/* Developer-mode strip — sits flush under the fixed topbar when CFG_DEV_MODE
|
||||||
is on. Amber-tinted glass so it reads as "non-default state" without
|
is on. Neutral glass so it reads as "system bar" not "warning"; only the
|
||||||
shouting. Body gets .has-dev-banner to bump padding-top by the strip's
|
icon picks up the theme accent. Body gets .has-dev-banner to bump
|
||||||
height; dismissal is local and remembered in localStorage until dev
|
padding-top by the strip's height; dismissal is local and remembered in
|
||||||
mode is toggled off + on again. */
|
localStorage until dev mode is toggled off + on again. */
|
||||||
.dev-banner {
|
.dev-banner {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 60px;
|
top: 60px;
|
||||||
@ -16,13 +16,13 @@
|
|||||||
height: 36px;
|
height: 36px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: center;
|
||||||
padding: 0 24px;
|
padding: 0 56px 0 24px;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
background: rgba(var(--status-warning-rgb), 0.14);
|
background: rgba(var(--text-rgb), 0.04);
|
||||||
border-bottom: 1px solid rgba(var(--status-warning-rgb), 0.35);
|
border-bottom: 1px solid rgba(var(--text-rgb), 0.12);
|
||||||
backdrop-filter: blur(12px) saturate(140%);
|
backdrop-filter: blur(12px) saturate(140%);
|
||||||
-webkit-backdrop-filter: blur(12px) saturate(140%);
|
-webkit-backdrop-filter: blur(12px) saturate(140%);
|
||||||
}
|
}
|
||||||
@ -33,10 +33,15 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
color: var(--status-warning);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dev-banner-label svg { color: var(--accent); }
|
||||||
|
|
||||||
.dev-banner-close {
|
.dev-banner-close {
|
||||||
|
position: absolute;
|
||||||
|
right: 12px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -47,7 +52,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
opacity: 0.7;
|
opacity: 0.65;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: opacity 0.15s ease, background 0.15s ease;
|
transition: opacity 0.15s ease, background 0.15s ease;
|
||||||
}
|
}
|
||||||
@ -60,7 +65,7 @@
|
|||||||
body.has-dev-banner { padding-top: 96px; }
|
body.has-dev-banner { padding-top: 96px; }
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.dev-banner { padding: 0 12px; font-size: 0.8rem; }
|
.dev-banner { padding: 0 48px 0 12px; font-size: 0.8rem; }
|
||||||
body.has-dev-banner .mobile-drawer { top: 96px; height: calc(100vh - 96px); }
|
body.has-dev-banner .mobile-drawer { top: 96px; height: calc(100vh - 96px); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -315,9 +315,12 @@ async configUpdate(changes) {
|
|||||||
? window.tasksManager.getTaskTypeIcon({ type: action })
|
? window.tasksManager.getTaskTypeIcon({ type: action })
|
||||||
: null)?.icon || '';
|
: null)?.icon || '';
|
||||||
const customIcon = typeIcon ? `<span style="font-size:18px;line-height:1;">${typeIcon}</span>` : null;
|
const customIcon = typeIcon ? `<span style="font-size:18px;line-height:1;">${typeIcon}</span>` : null;
|
||||||
|
const friendly = (this.tasksManager && typeof this.tasksManager.formatActionTitle === 'function')
|
||||||
|
? this.tasksManager.formatActionTitle(action)
|
||||||
|
: (action.charAt(0).toUpperCase() + action.slice(1));
|
||||||
const headline = displayLabel
|
const headline = displayLabel
|
||||||
? `${displayLabel} task started!`
|
? `${displayLabel} task started!`
|
||||||
: `${action.charAt(0).toUpperCase() + action.slice(1)} task started!`;
|
: `${friendly} task started!`;
|
||||||
window.notificationSystem.show(
|
window.notificationSystem.show(
|
||||||
`<strong>${displayName}</strong><br>${headline}`,
|
`<strong>${displayName}</strong><br>${headline}`,
|
||||||
'success',
|
'success',
|
||||||
|
|||||||
@ -51,10 +51,33 @@ class TasksManager {
|
|||||||
|
|
||||||
// Setup mobile menu
|
// Setup mobile menu
|
||||||
this.setupMobileMenu();
|
this.setupMobileMenu();
|
||||||
|
|
||||||
//// // console.log('✅ TasksManager initialized with modular architecture');
|
//// // console.log('✅ TasksManager initialized with modular architecture');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User-facing label for a task action. Explicit map first (so
|
||||||
|
// 'config_update' reads as 'Update Config', not 'Config Update');
|
||||||
|
// anything not listed falls back to snake/kebab → Title Case so a
|
||||||
|
// future task type still renders cleanly instead of leaking the
|
||||||
|
// literal id like "Config_update".
|
||||||
|
formatActionTitle(action) {
|
||||||
|
if (!action) return 'Task';
|
||||||
|
const map = {
|
||||||
|
'install': 'Install', 'app-install': 'Install',
|
||||||
|
'uninstall': 'Uninstall', 'restart': 'Restart',
|
||||||
|
'start': 'Start', 'stop': 'Stop',
|
||||||
|
'update': 'Update', 'rebuild': 'Rebuild',
|
||||||
|
'backup': 'Backup', 'restore': 'Restore',
|
||||||
|
'delete': 'Delete Backup', 'delete_all': 'Delete All Backups',
|
||||||
|
'config_update': 'Update Config', 'update_config': 'Update Config',
|
||||||
|
'system_update': 'Update System',
|
||||||
|
'setup-config': 'Apply Configuration',
|
||||||
|
'setup-finalize': 'Finalize Setup'
|
||||||
|
};
|
||||||
|
if (map[action]) return map[action];
|
||||||
|
return action.split(/[_-]/).map(w => w ? w.charAt(0).toUpperCase() + w.slice(1) : '').join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize task system after scripts are loaded
|
// Initialize task system after scripts are loaded
|
||||||
initializeTaskSystem() {
|
initializeTaskSystem() {
|
||||||
try {
|
try {
|
||||||
@ -1381,17 +1404,7 @@ class TasksManager {
|
|||||||
if (window.notificationSystem && task) {
|
if (window.notificationSystem && task) {
|
||||||
const appName = task.app || null;
|
const appName = task.app || null;
|
||||||
const action = task.type || 'task';
|
const action = task.type || 'task';
|
||||||
const friendlyActionMap = {
|
let actionTitle = this.formatActionTitle(action);
|
||||||
'install': 'Install', 'app-install': 'Install',
|
|
||||||
'uninstall': 'Uninstall', 'restart': 'Restart',
|
|
||||||
'start': 'Start', 'stop': 'Stop',
|
|
||||||
'update': 'Update', 'rebuild': 'Rebuild',
|
|
||||||
'backup': 'Backup', 'restore': 'Restore',
|
|
||||||
'delete': 'Delete Backup', 'delete_all': 'Delete All Backups',
|
|
||||||
'setup-config': 'Apply Configuration',
|
|
||||||
'setup-finalize': 'Finalize Setup'
|
|
||||||
};
|
|
||||||
let actionTitle = friendlyActionMap[action] || (action.charAt(0).toUpperCase() + action.slice(1));
|
|
||||||
// Tool tasks: override the generic "Tool" label with the tool's
|
// Tool tasks: override the generic "Tool" label with the tool's
|
||||||
// friendly name (e.g. "Manage Shortcuts") so completion toasts
|
// friendly name (e.g. "Manage Shortcuts") so completion toasts
|
||||||
// match what the user clicked.
|
// match what the user clicked.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user