fix(admin): UX Control Center — даты Inbox, bulk, фильтры событий, палитра по ID
CI / test (push) Successful in 1m52s
CI / push-image (push) Successful in 6m57s
CI / ci-done (push) Successful in 0s

Refs EventHub/EventHubFrontAdmin#32

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-14 20:53:58 +03:00
parent 3251c76478
commit b7d572ea8e
17 changed files with 398 additions and 105 deletions
+36 -10
View File
@@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Search } from 'lucide-react';
import { useAuthStore } from '@/store/authStore';
import { NAV_GROUPS, filterNavGroupsByRole } from '@/config/adminAccess';
import { NAV_GROUPS, filterNavGroupsByRole, canAccessRoute } from '@/config/adminAccess';
import {
Dialog,
DialogContent,
@@ -24,6 +24,9 @@ interface CommandPaletteProps {
onOpenChange: (open: boolean) => void;
}
/** Looks like EventHub entity ids (base64url-ish). */
const ENTITY_ID_RE = /^[A-Za-z0-9_-]{16,40}$/;
export function CommandPalette({ open, onOpenChange }: CommandPaletteProps) {
const { t } = useTranslation();
const navigate = useNavigate();
@@ -54,15 +57,38 @@ export function CommandPalette({ open, onOpenChange }: CommandPaletteProps) {
}, [role, t]);
const filtered = useMemo(() => {
const q = query.trim().toLowerCase();
if (!q) return items;
return items.filter(
(item) =>
item.label.toLowerCase().includes(q) ||
item.group.toLowerCase().includes(q) ||
item.path.toLowerCase().includes(q)
);
}, [items, query]);
const q = query.trim();
const qLower = q.toLowerCase();
const navHits = !qLower
? items
: items.filter(
(item) =>
item.label.toLowerCase().includes(qLower) ||
item.group.toLowerCase().includes(qLower) ||
item.path.toLowerCase().includes(qLower)
);
if (!ENTITY_ID_RE.test(q)) return navHits;
const jumps: PaletteItem[] = [];
const pushIf = (path: string, labelKey: string, id: string) => {
if (canAccessRoute(path.split('?')[0], role)) {
jumps.push({
id,
label: `${t(labelKey)} · ${q}`,
group: t('layout.paletteJumpGroup'),
path,
});
}
};
pushIf(`/inbox/reports?selected=${encodeURIComponent(q)}`, 'layout.paletteOpenReportInbox', `jump-report-inbox-${q}`);
pushIf(`/reports/${encodeURIComponent(q)}`, 'layout.paletteOpenReport', `jump-report-${q}`);
pushIf(`/inbox/tickets?selected=${encodeURIComponent(q)}`, 'layout.paletteOpenTicketInbox', `jump-ticket-inbox-${q}`);
pushIf(`/tickets/${encodeURIComponent(q)}`, 'layout.paletteOpenTicket', `jump-ticket-${q}`);
pushIf(`/events/${encodeURIComponent(q)}`, 'layout.paletteOpenEvent', `jump-event-${q}`);
pushIf(`/users/${encodeURIComponent(q)}`, 'layout.paletteOpenUser', `jump-user-${q}`);
return [...jumps, ...navHits];
}, [items, query, role, t]);
useEffect(() => {
setActiveIndex(0);