Fix views/controllers/router: command palette, create form, admin views
- Consolidate the duplicated command palette to a single overlay + init in the footer; fix New Ticket to route to /ticket/create (was a 404 /create); keep the CSP nonce and all commands - TicketController create(): trim title, require a non-empty description, and honor the posted status (validated against the canonical list) instead of silently discarding it - UserActivityView: 'Active Users' counts only users active in the selected range, not every registered user - layout_footer/DashboardView: local esc() now escapes quotes so values used in HTML attributes can't break out - TicketView: comments tab badge shows the true total, not just page one - layout_header: gate the 'View activity log' link behind the admin flag - index.php: validate /admin/user-activity date params; anchor the legacy /ticket.php route; align the audit action-type whitelist with the dropdown - ApiKeysView: correct the external API sample to /create_ticket_api.php Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+18
-2
@@ -138,10 +138,13 @@
|
||||
var themeBtn = document.getElementById('lt-theme-btn');
|
||||
if (themeBtn) themeBtn.addEventListener('click', function() { lt.theme.toggle(); });
|
||||
|
||||
// Command palette — global navigation commands available on all pages
|
||||
// Command palette — single global instance (overlay DOM above; base.js binds Ctrl/Cmd+K)
|
||||
var _cpCmds = [
|
||||
{ id: 'nav-dashboard', group: 'Navigation', icon: '~', label: 'Dashboard', kbd: 'G D', action: function() { window.location.href = '/'; } },
|
||||
{ id: 'nav-new-ticket', group: 'Navigation', icon: '+', label: 'New Ticket', kbd: 'N', action: function() { window.location.href = '/ticket/create'; } },
|
||||
{ id: 'filter-mine', group: 'Filter', icon: '◈', label: 'My Open Tickets', action: function() { window.location.href = '/?assigned_to=me&status=Open,In+Progress,Pending'; } },
|
||||
{ id: 'filter-unassigned', group: 'Filter', icon: '◌', label: 'Unassigned Tickets', action: function() { window.location.href = '/?assigned_to=unassigned'; } },
|
||||
{ id: 'filter-critical', group: 'Filter', icon: '!', label: 'P1 Critical Tickets', action: function() { window.location.href = '/?priority=1'; } },
|
||||
{ id: 'help-shortcuts', group: 'Help', icon: '?', label: 'Keyboard Shortcuts', kbd: '?', action: function() { lt.modal.open('lt-keys-help'); } },
|
||||
{ id: 'help-theme', group: 'Help', icon: '*', label: 'Toggle Theme', action: function() { lt.theme.toggle(); } },
|
||||
];
|
||||
@@ -156,7 +159,20 @@
|
||||
{ id: 'admin-api-keys', group: 'Admin', icon: 'K', label: 'API Keys', action: function() { window.location.href = '/admin/api-keys'; } },
|
||||
]);
|
||||
<?php endif ?>
|
||||
// Recently viewed tickets from localStorage
|
||||
try {
|
||||
var _recent = JSON.parse(localStorage.getItem('lt_recent_tickets') || '[]');
|
||||
_recent.slice(0, 5).forEach(function(id) {
|
||||
_cpCmds.push({ id: 'recent-' + id, group: 'Recent', icon: '◷', label: 'Ticket #' + id, tags: ['ticket'], action: function(tid) { return function() { window.location.href = '/ticket/' + tid; }; }(id) });
|
||||
});
|
||||
} catch (_e) { /* ignore malformed localStorage */ }
|
||||
lt.cmdPalette.init(_cpCmds);
|
||||
|
||||
// Bind the header ⌘K trigger button (no inline onclick — CSP blocks inline handlers)
|
||||
var _cmdTrigger = document.getElementById('lt-cmd-trigger');
|
||||
if (_cmdTrigger) {
|
||||
_cmdTrigger.addEventListener('click', function() { lt.cmdPalette.open(); });
|
||||
}
|
||||
}
|
||||
|
||||
// Patch lt.api mutating methods to auto-rotate CSRF token when server returns a new one
|
||||
@@ -194,7 +210,7 @@
|
||||
return Math.floor(diff / 86400) + 'd ago';
|
||||
}
|
||||
|
||||
function esc(s) { return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); }
|
||||
function esc(s) { return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,'''); }
|
||||
|
||||
function renderNotifications(data) {
|
||||
lt.notif.set(bell, data.unread_count || 0);
|
||||
|
||||
Reference in New Issue
Block a user