Add emulator stats dashboard and refresh classic UI views

This commit is contained in:
Lorenzune
2026-05-25 10:10:40 +02:00
parent 4e1ceed53f
commit b038ca4542
38 changed files with 2476 additions and 336 deletions
@@ -1,5 +1,4 @@
import { FC } from 'react';
import { FaChevronRight, FaHome } from 'react-icons/fa';
import { LocalizeText } from '../../../../api';
import { useCatalog } from '../../../../hooks';
@@ -10,25 +9,20 @@ export const CatalogBreadcrumbView: FC<{}> = () =>
if(!activeNodes || activeNodes.length === 0)
{
return (
<div className="flex items-center gap-1.5 text-xs text-catalog-text-muted">
<FaHome className="text-[10px]" />
<div className="nitro-catalog-classic-breadcrumb">
<span>{ LocalizeText('catalog.title') }</span>
</div>
);
}
return (
<div className="flex items-center gap-1 text-[11px] text-catalog-text-muted overflow-hidden min-w-0">
<FaHome
className="text-[10px] cursor-pointer hover:text-catalog-accent transition-colors shrink-0"
onClick={ () => activateNode(activeNodes[0]) }
/>
{ activeNodes.map((node, i) => (
<span key={ node.pageId } className="flex items-center gap-1 min-w-0">
<FaChevronRight className="text-[7px] opacity-30 shrink-0" />
<div className="nitro-catalog-classic-breadcrumb">
{ activeNodes.map((node, index) => (
<span key={ node.pageId } className="nitro-catalog-classic-breadcrumb-segment">
<span className="nitro-catalog-classic-breadcrumb-separator">&rsaquo;</span>
<span
className={ `truncate ${ i === activeNodes.length - 1 ? 'text-catalog-text font-semibold' : 'cursor-pointer hover:text-catalog-accent transition-colors' }` }
onClick={ i < activeNodes.length - 1 ? () => activateNode(node) : undefined }
className={ `truncate ${ index === activeNodes.length - 1 ? 'font-semibold' : 'cursor-pointer hover:underline' }` }
onClick={ index < activeNodes.length - 1 ? () => activateNode(node) : undefined }
>
{ node.localization }
</span>
@@ -73,10 +73,10 @@ export const CatalogNavigationItemView: FC<CatalogNavigationItemViewProps> = pro
}, [ adminMode, node, catalogAdmin ]);
return (
<div className={ child ? 'pl-1.5 ml-1.5 border-l-2 border-card-grid-item-border' : '' }>
<div className={ `nitro-catalog-classic-navigation-node ${ child ? 'is-child' : '' }` }>
<div
ref={ dragRef }
className={ `group/nav flex items-center gap-1.5 px-1.5 py-[3px] mx-0.5 rounded cursor-pointer transition-all duration-100 text-[11px] ${ node.isActive ? 'bg-card-grid-item-active border border-card-grid-item-border-active shadow-inner1px font-bold' : 'border border-transparent hover:bg-card-grid-item-active' } ${ isDragOver ? 'ring-2 ring-primary ring-offset-1 bg-primary/10' : '' }` }
className={ `nitro-catalog-classic-navigation-item group/nav ${ node.isActive ? 'is-active' : '' } ${ node.isBranch ? 'is-branch' : 'is-leaf' } ${ node.isOpen ? 'is-open' : '' } ${ isDragOver ? 'is-drag-over' : '' }` }
draggable={ adminMode }
onClick={ () => activateNode(node) }
onDragLeave={ adminMode ? handleDragLeave : undefined }
@@ -85,13 +85,13 @@ export const CatalogNavigationItemView: FC<CatalogNavigationItemViewProps> = pro
onDrop={ adminMode ? handleDrop : undefined }
>
{ adminMode &&
<FaArrowsAlt className="text-[7px] text-muted cursor-grab shrink-0 opacity-0 group-hover/nav:opacity-60" /> }
<div className="w-5 h-5 flex items-center justify-center shrink-0">
<FaArrowsAlt className="nitro-catalog-classic-navigation-drag text-[7px] text-muted cursor-grab shrink-0 opacity-0 group-hover/nav:opacity-60" /> }
<div className="nitro-catalog-classic-navigation-icon">
<CatalogIconView icon={ node.iconId } />
</div>
<span className="flex-1 truncate" title={ adminMode ? `Page ID: ${ node.pageId }` : undefined }>{ node.localization }</span>
<span className="nitro-catalog-classic-navigation-label" title={ adminMode ? `Page ID: ${ node.pageId }` : undefined }>{ node.localization }</span>
{ adminMode &&
<div className="flex items-center gap-1 opacity-0 group-hover/nav:opacity-100 transition-opacity">
<div className="nitro-catalog-classic-navigation-admin flex items-center gap-1 opacity-0 group-hover/nav:opacity-100 transition-opacity">
<FaPlus
className="text-[8px] text-success hover:text-green-800"
title={ LocalizeText('catalog.admin.create.subpage') }
@@ -125,11 +125,11 @@ export const CatalogNavigationItemView: FC<CatalogNavigationItemViewProps> = pro
</div> }
{ !adminMode && node.pageId > 0 &&
<FaStar
className={ `text-[8px] transition-all duration-100 cursor-pointer shrink-0 ${ isFav ? 'text-warning opacity-100' : 'text-muted opacity-0 group-hover/nav:opacity-100 hover:text-warning' }` }
className={ `nitro-catalog-classic-navigation-favorite text-[8px] transition-all duration-100 cursor-pointer shrink-0 ${ isFav ? 'text-warning opacity-100' : 'text-muted opacity-0 group-hover/nav:opacity-100 hover:text-warning' }` }
onClick={ e => { e.stopPropagation(); toggleFavoritePage(node.pageId); } }
/> }
{ node.isBranch &&
<span className="text-[9px] text-muted shrink-0">
<span className="nitro-catalog-classic-navigation-caret text-[9px] text-muted shrink-0">
{ node.isOpen ? <FaCaretUp /> : <FaCaretDown /> }
</span> }
</div>
@@ -15,7 +15,7 @@ export const CatalogNavigationView: FC<CatalogNavigationViewProps> = props =>
const { searchResult = null } = useCatalog();
return (
<div className="flex flex-col gap-px px-0.5 py-0.5">
<div className="nitro-catalog-classic-navigation-list">
{ searchResult && (searchResult.filteredNodes.length > 0) && searchResult.filteredNodes.map((n, index) =>
{
return <CatalogNavigationItemView key={ index } node={ n } />;