Browse Source

Compact SpoolBuddy settings Device tab to fit without scrolling

  Remove branding/about card, fold Device ID into Device Info card,
  place Backend/Auth config and diagnostic buttons side by side in a
  2-column grid, remove redundant online/offline status from Device
  Info, and tighten spacing throughout.
maziggy 2 months ago
parent
commit
504a0f9970

+ 1 - 1
CHANGELOG.md

@@ -11,7 +11,7 @@ All notable changes to Bambuddy will be documented in this file.
 - **External Folder Mounting for File Manager** ([#124](https://github.com/maziggy/bambuddy/issues/124)) — Host directories (NAS shares, USB drives, network storage) can now be mounted into the File Manager without copying files. Click "Link External" to point at a Docker bind-mounted path. Files are indexed into the database on scan but accessed directly from their original location — nothing is copied. Supports read-only mode (default, blocks uploads/moves/deletes), hidden file filtering, and automatic thumbnail extraction for 3MF, STL, gcode, and image files. External folders show a distinct icon and info bar with a rescan button. Deleting an external folder only removes the database index, never the actual files. Requested by @S1N4X.
 
 ### Improved
-- **SpoolBuddy Settings Device Tab No Longer Scrolls** — Removed the branding card, folded Device ID into the Device Info card, made diagnostic buttons a horizontal 3-column row, and put the API token input and Save button on the same line. The Device tab now fits on the small SpoolBuddy touchscreen without scrolling.
+- **SpoolBuddy Settings Device Tab No Longer Scrolls** — Removed the branding card, folded Device ID into the Device Info card, placed Backend/Auth config and diagnostic buttons side by side in a 2-column layout, removed the redundant online/offline status row from Device Info, and tightened spacing throughout. The Device tab now fits on the small SpoolBuddy touchscreen without scrolling.
 - **Spool Notes in Assign Spool Modal** ([#793](https://github.com/maziggy/bambuddy/issues/793)) — Spool cards in the Assign Spool modal now show the spool's note as a hover tooltip, making it easier to identify spools by tracking IDs or other metadata stored in notes. Works with both internal inventory and Spoolman-synced spools. Requested by @LegionCanadian.
 - **WiFi Safeguard for SpoolBuddy Pi** — The install script now drops an APT hook (`/etc/apt/apt.conf.d/80-preserve-wifi`) that backs up NetworkManager WiFi connections before every `apt upgrade` and restores them if they get wiped. Prevents headless SpoolBuddy Pis from losing WiFi connectivity after Raspberry Pi OS package upgrades (observed with Bookworm kernel/raspi-config updates that clear `/etc/NetworkManager/system-connections/`).
 - **SpoolBuddy Install Script Now Upgrades System Packages** — The install script now runs `apt-get upgrade -y` after installing required packages and the WiFi safeguard. This ensures the Pi is fully up to date before SpoolBuddy is deployed, and the WiFi safeguard protects connectivity during the upgrade.

+ 60 - 66
frontend/src/pages/spoolbuddy/SpoolBuddySettingsPage.tsx

@@ -134,15 +134,6 @@ function DeviceTab({ device }: { device: SpoolBuddyDevice }) {
               <span className="text-zinc-500">{t('spoolbuddy.settings.uptime', 'Uptime')}</span>
               <span className="text-zinc-300">{formatUptime(device.uptime_s)}</span>
             </div>
-            <div className="flex justify-between items-center">
-              <span className="text-zinc-500">{t('spoolbuddy.status.status', 'Status')}</span>
-              <div className="flex items-center gap-1.5">
-                <div className={`w-2 h-2 rounded-full ${device.online ? 'bg-green-500' : 'bg-zinc-600'}`} />
-                <span className={device.online ? 'text-green-400' : 'text-zinc-500'}>
-                  {device.online ? t('spoolbuddy.status.online', 'Online') : t('spoolbuddy.status.offline', 'Offline')}
-                </span>
-              </div>
-            </div>
             <div className="flex justify-between">
               <span className="text-zinc-500">ID</span>
               <span className="text-zinc-400 font-mono truncate ml-2">{device.device_id}</span>
@@ -151,69 +142,72 @@ function DeviceTab({ device }: { device: SpoolBuddyDevice }) {
         </div>
       </div>
 
-      {/* Backend/Auth Config */}
-      <div className="bg-zinc-800 rounded-lg p-3 space-y-2">
-        <h3 className="text-sm font-semibold text-zinc-300">
-          {t('spoolbuddy.settings.systemConfig', 'Backend & Auth')}
-        </h3>
-        <input
-          value={backendUrl}
-          onChange={(e) => setBackendUrl(e.target.value)}
-          placeholder="http://192.168.1.100:5000"
-          className="w-full px-2 py-1.5 rounded bg-zinc-900 border border-zinc-700 text-zinc-100 text-xs"
-        />
-        <div className="flex gap-2">
+      {/* Backend/Auth + Diagnostics side by side */}
+      <div className="grid grid-cols-2 gap-2">
+        {/* Backend/Auth Config */}
+        <div className="bg-zinc-800 rounded-lg p-3 space-y-2">
+          <h3 className="text-sm font-semibold text-zinc-300">
+            {t('spoolbuddy.settings.systemConfig', 'Backend & Auth')}
+          </h3>
           <input
-            type="password"
-            value={apiToken}
-            onChange={(e) => setApiToken(e.target.value)}
-            placeholder={t('spoolbuddy.settings.apiTokenPlaceholder', 'Enter API token')}
-            className="flex-1 px-2 py-1.5 rounded bg-zinc-900 border border-zinc-700 text-zinc-100 text-xs"
+            value={backendUrl}
+            onChange={(e) => setBackendUrl(e.target.value)}
+            placeholder="http://192.168.1.100:5000"
+            className="w-full px-2 py-1.5 rounded bg-zinc-900 border border-zinc-700 text-zinc-100 text-xs"
           />
+          <div className="flex gap-2">
+            <input
+              type="password"
+              value={apiToken}
+              onChange={(e) => setApiToken(e.target.value)}
+              placeholder={t('spoolbuddy.settings.apiTokenPlaceholder', 'API token')}
+              className="flex-1 px-2 py-1.5 rounded bg-zinc-900 border border-zinc-700 text-zinc-100 text-xs"
+            />
+            <button
+              onClick={saveConfig}
+              disabled={systemBusy}
+              className="px-3 py-1.5 rounded bg-green-700 hover:bg-green-600 disabled:bg-zinc-700 text-xs font-medium text-zinc-100"
+            >
+              {t('spoolbuddy.settings.saveConfig', 'Save')}
+            </button>
+          </div>
+          {systemMsg && (
+            <div className={`text-xs ${systemMsg.type === 'ok' ? 'text-green-400' : 'text-red-400'}`}>
+              {systemMsg.text}
+            </div>
+          )}
+        </div>
+
+        {/* Diagnostic Buttons */}
+        <div className="bg-zinc-800 rounded-lg p-3 flex flex-col gap-2">
           <button
-            onClick={saveConfig}
-            disabled={systemBusy}
-            className="px-3 py-1.5 rounded bg-green-700 hover:bg-green-600 disabled:bg-zinc-700 text-xs font-medium text-zinc-100"
+            onClick={() => setDiagnosticOpen('nfc')}
+            className="flex-1 bg-blue-700 hover:bg-blue-600 transition-colors rounded-lg p-2 flex items-center gap-2"
           >
-            {t('spoolbuddy.settings.saveConfig', 'Save')}
+            <Wand2 className="w-4 h-4 text-blue-300 shrink-0" />
+            <span className="text-xs font-medium text-blue-100">
+              {t('spoolbuddy.settings.nfcDiagnostic', 'NFC Diagnostic')}
+            </span>
+          </button>
+          <button
+            onClick={() => setDiagnosticOpen('scale')}
+            className="flex-1 bg-yellow-700 hover:bg-yellow-600 transition-colors rounded-lg p-2 flex items-center gap-2"
+          >
+            <Zap className="w-4 h-4 text-yellow-300 shrink-0" />
+            <span className="text-xs font-medium text-yellow-100">
+              {t('spoolbuddy.settings.scaleDiagnostic', 'Scale Diagnostic')}
+            </span>
+          </button>
+          <button
+            onClick={() => setDiagnosticOpen('read_tag')}
+            className="flex-1 bg-emerald-700 hover:bg-emerald-600 transition-colors rounded-lg p-2 flex items-center gap-2"
+          >
+            <FileText className="w-4 h-4 text-emerald-300 shrink-0" />
+            <span className="text-xs font-medium text-emerald-100">
+              {t('spoolbuddy.settings.readTagDiagnostic', 'Read Tag')}
+            </span>
           </button>
         </div>
-        {systemMsg && (
-          <div className={`text-xs ${systemMsg.type === 'ok' ? 'text-green-400' : 'text-red-400'}`}>
-            {systemMsg.text}
-          </div>
-        )}
-      </div>
-
-      {/* Diagnostic Buttons — horizontal row */}
-      <div className="grid grid-cols-3 gap-2">
-        <button
-          onClick={() => setDiagnosticOpen('nfc')}
-          className="bg-blue-700 hover:bg-blue-600 transition-colors rounded-lg p-2 text-center"
-        >
-          <Wand2 className="w-4 h-4 text-blue-300 mx-auto mb-1" />
-          <span className="text-xs font-medium text-blue-100">
-            {t('spoolbuddy.settings.nfcDiagnostic', 'NFC Diagnostic')}
-          </span>
-        </button>
-        <button
-          onClick={() => setDiagnosticOpen('scale')}
-          className="bg-yellow-700 hover:bg-yellow-600 transition-colors rounded-lg p-2 text-center"
-        >
-          <Zap className="w-4 h-4 text-yellow-300 mx-auto mb-1" />
-          <span className="text-xs font-medium text-yellow-100">
-            {t('spoolbuddy.settings.scaleDiagnostic', 'Scale Diagnostic')}
-          </span>
-        </button>
-        <button
-          onClick={() => setDiagnosticOpen('read_tag')}
-          className="bg-emerald-700 hover:bg-emerald-600 transition-colors rounded-lg p-2 text-center"
-        >
-          <FileText className="w-4 h-4 text-emerald-300 mx-auto mb-1" />
-          <span className="text-xs font-medium text-emerald-100">
-            {t('spoolbuddy.settings.readTagDiagnostic', 'Read Tag')}
-          </span>
-        </button>
       </div>
 
       {/* Diagnostic Modal */}

File diff suppressed because it is too large
+ 0 - 0
static/assets/index-Dw3sIiDq.js


+ 1 - 1
static/index.html

@@ -23,7 +23,7 @@
 
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="/assets/index-7pAdVCMH.js"></script>
+    <script type="module" crossorigin src="/assets/index-Dw3sIiDq.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-DTsgpL4e.css">
   </head>
   <body>

Some files were not shown because too many files changed in this diff