Преглед изворни кода

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

Martin Ziegler пре 6 месеци
родитељ
комит
05530e1c75

+ 39 - 17
frontend/src/components/Layout.tsx

@@ -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`}
         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 */}
         {/* 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>
         </div>
 
 
         {/* Navigation */}
         {/* Navigation */}
@@ -128,9 +126,37 @@ export function Layout() {
 
 
         {/* Footer */}
         {/* Footer */}
         <div className="p-2 border-t border-bambu-dark-tertiary">
         <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
               <a
                 href="https://github.com/maziggy/bambusy"
                 href="https://github.com/maziggy/bambusy"
                 target="_blank"
                 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"
                 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'}
                 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>
               </button>
             </div>
             </div>
-          </div>
+          )}
         </div>
         </div>
       </aside>
       </aside>
 
 

+ 33 - 6
frontend/src/pages/PrintersPage.tsx

@@ -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 queryClient = useQueryClient();
   const [showMenu, setShowMenu] = useState(false);
   const [showMenu, setShowMenu] = useState(false);
   const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
   const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
@@ -86,6 +86,9 @@ function PrinterCard({ printer }: { printer: Printer }) {
     refetchInterval: 30000, // Fallback polling, WebSocket handles real-time
     refetchInterval: 30000, // Fallback polling, WebSocket handles real-time
   });
   });
 
 
+  // Determine if this card should be hidden
+  const shouldHide = hideIfDisconnected && status && !status.connected;
+
   const deleteMutation = useMutation({
   const deleteMutation = useMutation({
     mutationFn: () => api.deletePrinter(printer.id),
     mutationFn: () => api.deletePrinter(printer.id),
     onSuccess: () => {
     onSuccess: () => {
@@ -100,6 +103,10 @@ function PrinterCard({ printer }: { printer: Printer }) {
     },
     },
   });
   });
 
 
+  if (shouldHide) {
+    return null;
+  }
+
   return (
   return (
     <Card className="relative">
     <Card className="relative">
       <CardContent>
       <CardContent>
@@ -429,6 +436,9 @@ function AddPrinterModal({
 
 
 export function PrintersPage() {
 export function PrintersPage() {
   const [showAddModal, setShowAddModal] = useState(false);
   const [showAddModal, setShowAddModal] = useState(false);
+  const [hideDisconnected, setHideDisconnected] = useState(() => {
+    return localStorage.getItem('hideDisconnectedPrinters') === 'true';
+  });
   const queryClient = useQueryClient();
   const queryClient = useQueryClient();
 
 
   const { data: printers, isLoading } = useQuery({
   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 (
   return (
     <div className="p-8">
     <div className="p-8">
       <div className="flex items-center justify-between mb-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>
           <h1 className="text-2xl font-bold text-white">Printers</h1>
           <p className="text-bambu-gray">Manage your Bambu Lab printers</p>
           <p className="text-bambu-gray">Manage your Bambu Lab printers</p>
         </div>
         </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>
       </div>
 
 
       {isLoading ? (
       {isLoading ? (
@@ -472,7 +499,7 @@ export function PrintersPage() {
       ) : (
       ) : (
         <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
         <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
           {printers?.map((printer) => (
           {printers?.map((printer) => (
-            <PrinterCard key={printer.id} printer={printer} />
+            <PrinterCard key={printer.id} printer={printer} hideIfDisconnected={hideDisconnected} />
           ))}
           ))}
         </div>
         </div>
       )}
       )}

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
static/assets/index-BWObUI22.js


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
static/assets/index-DUSeheuZ.css


+ 2 - 2
static/index.html

@@ -7,8 +7,8 @@
     <link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png" />
     <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="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png" />
     <link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.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>
   </head>
   <body>
   <body>
     <div id="root"></div>
     <div id="root"></div>

Неке датотеке нису приказане због велике количине промена