Просмотр исходного кода

Compact SpoolBuddy settings Device tab to avoid scrolling

  Remove the branding/about card, fold Device ID into the Device Info
  card, make diagnostic buttons a horizontal 3-column row, and put the
  API token input and Save button on the same line. Tighten spacing
  throughout so the tab fits on the small touchscreen without scrolling.
maziggy 2 месяцев назад
Родитель
Сommit
73aeee7bdf

+ 1 - 0
CHANGELOG.md

@@ -11,6 +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.
 - **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.

+ 65 - 112
frontend/src/pages/spoolbuddy/SpoolBuddySettingsPage.tsx

@@ -75,18 +75,9 @@ function DeviceTab({ device }: { device: SpoolBuddyDevice }) {
   };
 
   return (
-    <div className="space-y-4">
-      {/* About */}
-      <div className="bg-zinc-800 rounded-lg p-4">
-        <div className="flex items-center gap-3 mb-2">
-          <img src="/img/spoolbuddy_logo_dark_small.png" alt="SpoolBuddy" className="h-7 w-auto" />
-        </div>
-        <p className="text-xs text-zinc-500 mb-1">Part of Bambuddy</p>
-        <span className="text-xs text-zinc-500">github.com/maziggy/bambuddy</span>
-      </div>
-
+    <div className="space-y-2">
       {/* NFC Reader + Device Info side by side */}
-      <div className="grid grid-cols-2 gap-3">
+      <div className="grid grid-cols-2 gap-2">
         {/* NFC Reader */}
         <div className="bg-zinc-800 rounded-lg p-3">
           <h3 className="text-sm font-semibold text-zinc-300 mb-2">
@@ -152,115 +143,77 @@ function DeviceTab({ device }: { device: SpoolBuddyDevice }) {
                 </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>
+            </div>
           </div>
         </div>
       </div>
 
-      {/* Device ID (full width, below cards) */}
-      <div className="bg-zinc-800 rounded-lg px-3 py-2 flex justify-between items-center text-xs">
-        <span className="text-zinc-500">Device ID</span>
-        <span className="text-zinc-400 font-mono">{device.device_id}</span>
-      </div>
-
-      <div className="grid grid-cols-1 lg:grid-cols-2 gap-3">
-        {/* Backend/Auth Config */}
-        <div className="bg-zinc-800 rounded-lg p-4 space-y-3">
-          <h3 className="text-sm font-semibold text-zinc-300">
-            {t('spoolbuddy.settings.systemConfig', 'Backend & Auth')}
-          </h3>
-
-          <div className="space-y-2">
-            <label className="text-xs text-zinc-500 block">
-              {t('spoolbuddy.settings.backendUrl', 'Bambuddy Backend URL')}
-            </label>
-            <input
-              value={backendUrl}
-              onChange={(e) => setBackendUrl(e.target.value)}
-              placeholder="http://192.168.1.100:5000"
-              className="w-full px-3 py-2 rounded bg-zinc-900 border border-zinc-700 text-zinc-100 text-sm"
-            />
-          </div>
-
-          <div className="space-y-2">
-            <label className="text-xs text-zinc-500 block">
-              {t('spoolbuddy.settings.apiToken', 'API Token')}
-            </label>
-            <input
-              type="password"
-              value={apiToken}
-              onChange={(e) => setApiToken(e.target.value)}
-              placeholder={t('spoolbuddy.settings.apiTokenPlaceholder', 'Enter API token')}
-              className="w-full px-3 py-2 rounded bg-zinc-900 border border-zinc-700 text-zinc-100 text-sm"
-            />
-          </div>
-
-          <div className="flex gap-2">
-            <button
-              onClick={saveConfig}
-              disabled={systemBusy}
-              className="px-3 py-2 rounded bg-green-700 hover:bg-green-600 disabled:bg-zinc-700 text-sm font-medium text-zinc-100"
-            >
-              {t('spoolbuddy.settings.saveConfig', 'Save Config')}
-            </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-4 space-y-3">
-          {/* NFC Diagnostic Button */}
-          <button
-            onClick={() => setDiagnosticOpen('nfc')}
-            className="w-full bg-blue-700 hover:bg-blue-600 transition-colors rounded-lg p-3 text-left"
-          >
-            <div className="flex items-center gap-2 mb-1">
-              <Wand2 className="w-4 h-4 text-blue-300" />
-              <span className="text-sm font-semibold text-blue-100">
-                {t('spoolbuddy.settings.nfcDiagnostic', 'NFC Diagnostic')}
-              </span>
-            </div>
-            <p className="text-xs text-blue-200/70">
-              {t('spoolbuddy.settings.testNfc', 'Test reader')}
-            </p>
-          </button>
-
-          {/* Scale Diagnostic Button */}
-          <button
-            onClick={() => setDiagnosticOpen('scale')}
-            className="w-full bg-yellow-700 hover:bg-yellow-600 transition-colors rounded-lg p-3 text-left"
-          >
-            <div className="flex items-center gap-2 mb-1">
-              <Zap className="w-4 h-4 text-yellow-300" />
-              <span className="text-sm font-semibold text-yellow-100">
-                {t('spoolbuddy.settings.scaleDiagnostic', 'Scale Diagnostic')}
-              </span>
-            </div>
-            <p className="text-xs text-yellow-200/70">
-              {t('spoolbuddy.settings.testScale', 'Test accuracy')}
-            </p>
-          </button>
-
-          {/* Read Tag Diagnostic Button */}
+      {/* 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">
+          <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"
+          />
           <button
-            onClick={() => setDiagnosticOpen('read_tag')}
-            className="w-full bg-emerald-700 hover:bg-emerald-600 transition-colors rounded-lg p-3 text-left"
+            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"
           >
-            <div className="flex items-center gap-2 mb-1">
-              <FileText className="w-4 h-4 text-emerald-300" />
-              <span className="text-sm font-semibold text-emerald-100">
-                {t('spoolbuddy.settings.readTagDiagnostic', 'Read Tag Diagnostic')}
-              </span>
-            </div>
-            <p className="text-xs text-emerald-200/70">
-              {t('spoolbuddy.settings.testReadTag', 'Run read_tag.py')}
-            </p>
+            {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 — 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 */}

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
static/assets/index-7pAdVCMH.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
static/assets/index-DTsgpL4e.css


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
static/assets/index-_-nC2GSJ.css


+ 2 - 2
static/index.html

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

Некоторые файлы не были показаны из-за большого количества измененных файлов