Fixed collapsed sidebar layout; Added button to show/hide disconnected printers

This commit is contained in:
Martin Ziegler
2025-11-28 12:49:07 +01:00
parent 53c94deade
commit 05530e1c75
5 changed files with 170 additions and 121 deletions
+39 -17
View File
@@ -79,14 +79,12 @@ export function Layout() {
className={`${sidebarExpanded ? 'w-64' : 'w-16'} bg-bambu-dark-secondary border-r border-bambu-dark-tertiary flex flex-col fixed inset-y-0 left-0 z-30 transition-all duration-300`}
>
{/* Logo */}
<div className="p-4 border-b border-bambu-dark-tertiary flex items-center justify-center overflow-hidden">
<div className={`${sidebarExpanded ? '' : 'w-10 h-10 overflow-hidden'}`}>
<img
src={theme === 'dark' ? '/img/bambusy_logo_dark.png' : '/img/bambusy_logo_light.png'}
alt="Bambusy"
className={sidebarExpanded ? 'h-16 w-auto' : 'h-10 w-auto max-w-none'}
/>
</div>
<div className={`border-b border-bambu-dark-tertiary flex items-center justify-center ${sidebarExpanded ? 'p-4' : 'p-2'}`}>
<img
src={theme === 'dark' ? '/img/bambusy_logo_dark.png' : '/img/bambusy_logo_light.png'}
alt="Bambusy"
className={sidebarExpanded ? 'h-16 w-auto' : 'h-8 w-8 object-cover object-left'}
/>
</div>
{/* Navigation */}
@@ -128,9 +126,37 @@ export function Layout() {
{/* Footer */}
<div className="p-2 border-t border-bambu-dark-tertiary">
<div className={`flex items-center ${sidebarExpanded ? 'justify-between px-2' : 'flex-col gap-2'}`}>
{sidebarExpanded && <span className="text-sm text-bambu-gray">v0.1.2</span>}
<div className="flex items-center gap-1">
{sidebarExpanded ? (
<div className="flex items-center justify-between px-2">
<span className="text-sm text-bambu-gray">v0.1.2</span>
<div className="flex items-center gap-1">
<a
href="https://github.com/maziggy/bambusy"
target="_blank"
rel="noopener noreferrer"
className="p-2 rounded-lg hover:bg-bambu-dark-tertiary transition-colors text-bambu-gray-light hover:text-white"
title="View on GitHub"
>
<Github className="w-5 h-5" />
</a>
<button
onClick={() => setShowShortcuts(true)}
className="p-2 rounded-lg hover:bg-bambu-dark-tertiary transition-colors text-bambu-gray-light hover:text-white"
title="Keyboard shortcuts (?)"
>
<Keyboard className="w-5 h-5" />
</button>
<button
onClick={toggleTheme}
className="p-2 rounded-lg hover:bg-bambu-dark-tertiary transition-colors text-bambu-gray-light hover:text-white"
title={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
>
{theme === 'dark' ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
</button>
</div>
</div>
) : (
<div className="flex flex-col items-center gap-1">
<a
href="https://github.com/maziggy/bambusy"
target="_blank"
@@ -152,14 +178,10 @@ export function Layout() {
className="p-2 rounded-lg hover:bg-bambu-dark-tertiary transition-colors text-bambu-gray-light hover:text-white"
title={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
>
{theme === 'dark' ? (
<Sun className="w-5 h-5" />
) : (
<Moon className="w-5 h-5" />
)}
{theme === 'dark' ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
</button>
</div>
</div>
)}
</div>
</aside>
+33 -6
View File
@@ -74,7 +74,7 @@ function CoverImage({ url, printName }: { url: string | null; printName?: string
);
}
function PrinterCard({ printer }: { printer: Printer }) {
function PrinterCard({ printer, hideIfDisconnected }: { printer: Printer; hideIfDisconnected?: boolean }) {
const queryClient = useQueryClient();
const [showMenu, setShowMenu] = useState(false);
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
@@ -86,6 +86,9 @@ function PrinterCard({ printer }: { printer: Printer }) {
refetchInterval: 30000, // Fallback polling, WebSocket handles real-time
});
// Determine if this card should be hidden
const shouldHide = hideIfDisconnected && status && !status.connected;
const deleteMutation = useMutation({
mutationFn: () => api.deletePrinter(printer.id),
onSuccess: () => {
@@ -100,6 +103,10 @@ function PrinterCard({ printer }: { printer: Printer }) {
},
});
if (shouldHide) {
return null;
}
return (
<Card className="relative">
<CardContent>
@@ -429,6 +436,9 @@ function AddPrinterModal({
export function PrintersPage() {
const [showAddModal, setShowAddModal] = useState(false);
const [hideDisconnected, setHideDisconnected] = useState(() => {
return localStorage.getItem('hideDisconnectedPrinters') === 'true';
});
const queryClient = useQueryClient();
const { data: printers, isLoading } = useQuery({
@@ -444,6 +454,12 @@ export function PrintersPage() {
},
});
const toggleHideDisconnected = () => {
const newValue = !hideDisconnected;
setHideDisconnected(newValue);
localStorage.setItem('hideDisconnectedPrinters', String(newValue));
};
return (
<div className="p-8">
<div className="flex items-center justify-between mb-8">
@@ -451,10 +467,21 @@ export function PrintersPage() {
<h1 className="text-2xl font-bold text-white">Printers</h1>
<p className="text-bambu-gray">Manage your Bambu Lab printers</p>
</div>
<Button onClick={() => setShowAddModal(true)}>
<Plus className="w-4 h-4" />
Add Printer
</Button>
<div className="flex items-center gap-4">
<label className="flex items-center gap-2 text-sm text-bambu-gray cursor-pointer">
<input
type="checkbox"
checked={hideDisconnected}
onChange={toggleHideDisconnected}
className="rounded border-bambu-dark-tertiary bg-bambu-dark text-bambu-green focus:ring-bambu-green"
/>
Hide offline
</label>
<Button onClick={() => setShowAddModal(true)}>
<Plus className="w-4 h-4" />
Add Printer
</Button>
</div>
</div>
{isLoading ? (
@@ -472,7 +499,7 @@ export function PrintersPage() {
) : (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{printers?.map((printer) => (
<PrinterCard key={printer.id} printer={printer} />
<PrinterCard key={printer.id} printer={printer} hideIfDisconnected={hideDisconnected} />
))}
</div>
)}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -7,8 +7,8 @@
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png" />
<script type="module" crossorigin src="/assets/index-CjLW6Pu8.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DyMfP52F.css">
<script type="module" crossorigin src="/assets/index-BWObUI22.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DUSeheuZ.css">
</head>
<body>
<div id="root"></div>