Bladeren bron

Merge pull request #387 from Keybored02/feature/ui_improvements

Fixed Archive object card clipping, added reprint icon to list view
MartinNYHC 3 maanden geleden
bovenliggende
commit
2cb1a7d8d6
3 gewijzigde bestanden met toevoegingen van 67 en 26 verwijderingen
  1. 1 1
      frontend/src/components/CalendarView.tsx
  2. 24 0
      frontend/src/index.css
  3. 42 25
      frontend/src/pages/ArchivesPage.tsx

+ 1 - 1
frontend/src/components/CalendarView.tsx

@@ -226,7 +226,7 @@ export function CalendarView({ archives, onArchiveClick, highlightedArchiveId }:
               })}
             </h3>
             {selectedArchives.length > 0 ? (
-              <div className="space-y-2 max-h-96 overflow-y-auto">
+              <div className="calendar-scroll space-y-2 max-h-96 overflow-y-auto">
                 {selectedArchives.map(archive => {
                   const isHighlighted = archive.id === selectedArchiveId || archive.id === highlightedArchiveId;
                   return (

+ 24 - 0
frontend/src/index.css

@@ -391,3 +391,27 @@ body {
 .card-shadow {
   box-shadow: var(--card-shadow);
 }
+
+/* Calendar selected-day list scrollbar theming */
+.calendar-scroll {
+  scrollbar-width: thin;
+  scrollbar-color: color-mix(in srgb, var(--text-muted) 60%, transparent) transparent;
+}
+
+.calendar-scroll::-webkit-scrollbar {
+  width: 8px;
+}
+
+.calendar-scroll::-webkit-scrollbar-track {
+  background: transparent;
+}
+
+.calendar-scroll::-webkit-scrollbar-thumb {
+  background-color: color-mix(in srgb, var(--text-muted) 60%, transparent);
+  border-radius: 999px;
+  border: 2px solid color-mix(in srgb, var(--bg-secondary) 70%, transparent);
+}
+
+.calendar-scroll::-webkit-scrollbar-thumb:hover {
+  background-color: color-mix(in srgb, var(--text-muted) 80%, transparent);
+}

+ 42 - 25
frontend/src/pages/ArchivesPage.tsx

@@ -46,6 +46,7 @@ import {
   ChevronRight,
   Settings,
   User,
+  Play,
   ClipboardList,
 } from 'lucide-react';
 import { api } from '../api/client';
@@ -683,7 +684,7 @@ function ArchiveCard({
         {/* Duplicate badge */}
         {archive.duplicate_count > 0 && (
           <div
-            className="absolute top-2 right-2 px-2 py-1 rounded text-xs bg-purple-500/80 text-white flex items-center gap-1"
+            className="absolute top-2 right-12 px-2 py-1 rounded text-xs bg-purple-500/80 text-white flex items-center gap-1"
             title={t('archives.card.duplicateTitle')}
           >
             <Copy className="w-3 h-3" />
@@ -722,10 +723,21 @@ function ArchiveCard({
             <Box className="w-4 h-4 text-cyan-400" />
           </button>
         )}
+        {/* 3D preview badge */}
+        <button
+          className="absolute bottom-2 right-2 p-1.5 rounded bg-black/60 hover:bg-black/80 transition-colors"
+          onClick={(e) => {
+            e.stopPropagation();
+            setShowViewer(true);
+          }}
+          title={t('archives.card.preview3d')}
+        >
+          <Layers className="w-4 h-4 text-white" />
+        </button>
         {/* Timelapse badge */}
         {archive.timelapse_path && (
           <button
-            className="absolute bottom-2 right-2 p-1.5 rounded bg-black/60 hover:bg-black/80 transition-colors"
+            className="absolute bottom-2 right-12 p-1.5 rounded bg-black/60 hover:bg-black/80 transition-colors"
             onClick={(e) => {
               e.stopPropagation();
               setShowTimelapse(true);
@@ -738,7 +750,7 @@ function ArchiveCard({
         {/* Photos badge */}
         {archive.photos && archive.photos.length > 0 && (
           <button
-            className={`absolute bottom-2 ${archive.timelapse_path ? 'right-12' : 'right-2'} p-1.5 rounded bg-black/60 hover:bg-black/80 transition-colors`}
+            className={`absolute bottom-2 ${archive.timelapse_path ? 'right-[5.5rem]' : 'right-12'} p-1.5 rounded bg-black/60 hover:bg-black/80 transition-colors`}
             onClick={(e) => {
               e.stopPropagation();
               setShowPhotos(true);
@@ -769,9 +781,21 @@ function ArchiveCard({
 
       <CardContent className="p-4 flex-1 flex flex-col">
         {/* Title */}
-        <h3 className="font-medium text-white mb-1 truncate">
-          {archive.print_name || archive.filename}
-        </h3>
+        <div className="flex items-center justify-between gap-2 mb-1">
+          <h3 className="min-w-0 font-medium text-white truncate">
+            {archive.print_name || archive.filename}
+          </h3>
+          <Button
+            variant="ghost"
+            size="sm"
+            className="p-1 sm:p-1.5 shrink-0"
+            onClick={() => setShowEdit(true)}
+            disabled={!canModify('archives', 'update', archive.created_by_id)}
+            title={!canModify('archives', 'update', archive.created_by_id) ? t('archives.card.noPermissionEdit') : t('archives.card.edit')}
+          >
+            <Pencil className="w-3 h-3 sm:w-4 sm:h-4" />
+          </Button>
+        </div>
         <div className="flex items-center gap-2 mb-3 flex-wrap">
           <p className="text-xs text-bambu-gray">{printerName}</p>
           {/* File type badge */}
@@ -989,15 +1013,6 @@ function ArchiveCard({
           >
             <Globe className={`w-3 h-3 sm:w-4 sm:h-4 ${!archive.external_url && !archive.makerworld_url ? 'opacity-20' : ''}`} />
           </Button>
-          <Button
-            variant="secondary"
-            size="sm"
-            className="min-w-0 p-1 sm:p-1.5"
-            onClick={() => setShowViewer(true)}
-            title={t('archives.card.preview3d')}
-          >
-            <Box className="w-3 h-3 sm:w-4 sm:h-4" />
-          </Button>
           <Button
             variant="secondary"
             size="sm"
@@ -1011,16 +1026,6 @@ function ArchiveCard({
           >
             <Download className="w-3 h-3 sm:w-4 sm:h-4" />
           </Button>
-          <Button
-            variant="ghost"
-            size="sm"
-            className="min-w-0 p-1 sm:p-1.5"
-            onClick={() => setShowEdit(true)}
-            disabled={!canModify('archives', 'update', archive.created_by_id)}
-            title={!canModify('archives', 'update', archive.created_by_id) ? t('archives.card.noPermissionEdit') : t('archives.card.edit')}
-          >
-            <Pencil className="w-3 h-3 sm:w-4 sm:h-4" />
-          </Button>
           <Button
             variant="ghost"
             size="sm"
@@ -1771,6 +1776,18 @@ function ArchiveListRow({
           {formatFileSize(archive.file_size)}
         </div>
         <div className="col-span-2 flex justify-end gap-1">
+          {isSlicedFile(archive.filename) && (
+            <Button
+              variant="ghost"
+              size="sm"
+              onClick={() => setShowReprint(true)}
+              disabled={!canModify('archives', 'reprint', archive.created_by_id)}
+              title={!canModify('archives', 'reprint', archive.created_by_id) ? t('archives.card.noPermissionReprint') : t('archives.card.reprint')}
+              className="text-bambu-green hover:text-bambu-green-light hover:bg-bambu-green/10"
+            >
+              <Play className="w-4 h-4" />
+            </Button>
+          )}
           <Button
             variant="ghost"
             size="sm"