Browse Source

Minor layout fixes

maziggy 4 months ago
parent
commit
2bc0ef122d

+ 45 - 23
frontend/src/components/GitHubBackupSettings.tsx

@@ -7,8 +7,6 @@ import {
   CheckCircle,
   CheckCircle,
   XCircle,
   XCircle,
   Loader2,
   Loader2,
-  Eye,
-  EyeOff,
   ExternalLink,
   ExternalLink,
   RefreshCw,
   RefreshCw,
   Download,
   Download,
@@ -28,6 +26,8 @@ import type {
   GitHubBackupTriggerResponse,
   GitHubBackupTriggerResponse,
   ScheduleType,
   ScheduleType,
   CloudAuthStatus,
   CloudAuthStatus,
+  Printer,
+  PrinterStatus,
 } from '../api/client';
 } from '../api/client';
 import { Card, CardContent, CardHeader } from './Card';
 import { Card, CardContent, CardHeader } from './Card';
 import { Button } from './Button';
 import { Button } from './Button';
@@ -102,7 +102,6 @@ export function GitHubBackupSettings() {
   const [repoUrl, setRepoUrl] = useState('');
   const [repoUrl, setRepoUrl] = useState('');
   const [accessToken, setAccessToken] = useState('');
   const [accessToken, setAccessToken] = useState('');
   const [branch, setBranch] = useState('main');
   const [branch, setBranch] = useState('main');
-  const [showToken, setShowToken] = useState(false);
   const [scheduleEnabled, setScheduleEnabled] = useState(false);
   const [scheduleEnabled, setScheduleEnabled] = useState(false);
   const [scheduleType, setScheduleType] = useState<ScheduleType>('daily');
   const [scheduleType, setScheduleType] = useState<ScheduleType>('daily');
   const [backupKProfiles, setBackupKProfiles] = useState(true);
   const [backupKProfiles, setBackupKProfiles] = useState(true);
@@ -144,6 +143,23 @@ export function GitHubBackupSettings() {
     queryFn: api.getCloudStatus,
     queryFn: api.getCloudStatus,
   });
   });
 
 
+  // Fetch printers and their statuses for K-profile availability
+  const { data: printers } = useQuery<Printer[]>({
+    queryKey: ['printers'],
+    queryFn: api.getPrinters,
+  });
+
+  // Get printer statuses from cache (populated by WebSocket on other pages)
+  const printerStatuses = printers?.map(p => {
+    const status = queryClient.getQueryData<PrinterStatus>(['printerStatus', p.id]);
+    return { printer: p, connected: status?.connected ?? false };
+  }) ?? [];
+
+  const totalPrinters = printerStatuses.length;
+  const connectedPrinters = printerStatuses.filter(p => p.connected).length;
+  const noPrintersConnected = totalPrinters > 0 && connectedPrinters === 0;
+  const somePrintersDisconnected = connectedPrinters > 0 && connectedPrinters < totalPrinters;
+
   // Initialize form from config
   // Initialize form from config
   useEffect(() => {
   useEffect(() => {
     if (config) {
     if (config) {
@@ -276,7 +292,7 @@ export function GitHubBackupSettings() {
   });
   });
 
 
   const clearLogsMutation = useMutation<{ deleted: number; message: string }, Error>({
   const clearLogsMutation = useMutation<{ deleted: number; message: string }, Error>({
-    mutationFn: () => api.clearGitHubBackupLogs(10),
+    mutationFn: () => api.clearGitHubBackupLogs(0),
     onSuccess: (result) => {
     onSuccess: (result) => {
       queryClient.invalidateQueries({ queryKey: ['github-backup-logs'] });
       queryClient.invalidateQueries({ queryKey: ['github-backup-logs'] });
       showToast(`Cleared ${result.deleted} logs`);
       showToast(`Cleared ${result.deleted} logs`);
@@ -403,22 +419,13 @@ export function GitHubBackupSettings() {
                   <label className="block text-sm text-bambu-gray mb-1">
                   <label className="block text-sm text-bambu-gray mb-1">
                     Personal Access Token {config?.has_token && <span className="text-green-400">(saved)</span>}
                     Personal Access Token {config?.has_token && <span className="text-green-400">(saved)</span>}
                   </label>
                   </label>
-                  <div className="relative">
-                    <input
-                      type={showToken ? 'text' : 'password'}
-                      value={accessToken}
-                      onChange={(e) => { setAccessToken(e.target.value); setTestResult(null); }}
-                      placeholder={config?.has_token ? 'Enter new token to update' : 'ghp_xxxxxxxxxxxx'}
-                      className="w-full px-3 py-2 pr-10 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white focus:border-bambu-green focus:outline-none"
-                    />
-                    <button
-                      type="button"
-                      onClick={() => setShowToken(!showToken)}
-                      className="absolute right-3 top-1/2 -translate-y-1/2 text-bambu-gray hover:text-white"
-                    >
-                      {showToken ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
-                    </button>
-                  </div>
+                  <input
+                    type="password"
+                    value={accessToken}
+                    onChange={(e) => { setAccessToken(e.target.value); setTestResult(null); }}
+                    placeholder={config?.has_token ? 'Enter new token to update' : 'ghp_xxxxxxxxxxxx'}
+                    className="w-full px-3 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white focus:border-bambu-green focus:outline-none"
+                  />
                   <p className="text-xs text-bambu-gray mt-1">
                   <p className="text-xs text-bambu-gray mt-1">
                     Fine-grained token with Contents read/write permission
                     Fine-grained token with Contents read/write permission
                   </p>
                   </p>
@@ -462,15 +469,30 @@ export function GitHubBackupSettings() {
             <div>
             <div>
               <label className="block text-sm text-bambu-gray mb-2">Include in backup</label>
               <label className="block text-sm text-bambu-gray mb-2">Include in backup</label>
               <div className="space-y-2">
               <div className="space-y-2">
-                <label className="flex items-start gap-2 cursor-pointer">
+                <label className={`flex items-start gap-2 ${noPrintersConnected ? 'cursor-not-allowed opacity-60' : 'cursor-pointer'}`}>
                   <input
                   <input
                     type="checkbox"
                     type="checkbox"
                     checked={backupKProfiles}
                     checked={backupKProfiles}
                     onChange={(e) => setBackupKProfiles(e.target.checked)}
                     onChange={(e) => setBackupKProfiles(e.target.checked)}
                     className="w-4 h-4 mt-0.5 rounded border-bambu-dark-tertiary bg-bambu-dark text-bambu-green focus:ring-bambu-green"
                     className="w-4 h-4 mt-0.5 rounded border-bambu-dark-tertiary bg-bambu-dark text-bambu-green focus:ring-bambu-green"
+                    disabled={noPrintersConnected}
                   />
                   />
-                  <div>
-                    <span className="text-white text-sm">K-Profiles</span>
+                  <div className="flex-1">
+                    <div className="flex items-center gap-2">
+                      <span className={`text-sm ${noPrintersConnected ? 'text-bambu-gray' : 'text-white'}`}>K-Profiles</span>
+                      {noPrintersConnected && (
+                        <span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs bg-yellow-500/20 text-yellow-400">
+                          <AlertTriangle className="w-3 h-3" />
+                          No printers connected
+                        </span>
+                      )}
+                      {somePrintersDisconnected && (
+                        <span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs bg-yellow-500/20 text-yellow-400">
+                          <AlertTriangle className="w-3 h-3" />
+                          {connectedPrinters}/{totalPrinters} connected
+                        </span>
+                      )}
+                    </div>
                     <p className="text-xs text-bambu-gray">Pressure advance calibration from connected printers</p>
                     <p className="text-xs text-bambu-gray">Pressure advance calibration from connected printers</p>
                   </div>
                   </div>
                 </label>
                 </label>

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


+ 1 - 1
static/index.html

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

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