Browse Source

Merge pull request #4 from cadtoolbox/copilot/update-print-methods-file-manager

Replace FileManagerPage queue mutation with Schedule dialog
Thomas Rambach 7 months ago
parent
commit
094d6ab513

+ 3 - 3
frontend/src/__tests__/pages/FileManagerPage.test.tsx

@@ -459,8 +459,8 @@ describe('FileManagerPage', () => {
     });
   });
 
-  describe('add to queue', () => {
-    it('shows add to queue button for sliced files', async () => {
+  describe('schedule print', () => {
+    it('shows schedule print button for sliced files', async () => {
       const user = userEvent.setup();
       render(<FileManagerPage />);
 
@@ -472,7 +472,7 @@ describe('FileManagerPage', () => {
       await user.click(screen.getByText('Select All'));
 
       await waitFor(() => {
-        expect(screen.getByText(/Add to Queue/)).toBeInTheDocument();
+        expect(screen.getByText(/Schedule Print/)).toBeInTheDocument();
       });
     });
   });

+ 1 - 0
frontend/src/i18n/locales/de.ts

@@ -1848,6 +1848,7 @@ export default {
     linkTo: 'Verknüpfen mit...',
     linkToProjectOrArchive: 'Mit Projekt oder Archiv verknüpfen',
     addToQueue: 'Zur Warteschlange',
+    schedulePrint: 'Druck planen',
     generateThumbnail: 'Vorschaubild generieren',
     generateThumbnails: 'Vorschaubilder generieren',
     generateThumbnailsForMissing: 'Vorschaubilder für STL-Dateien ohne Vorschau generieren',

+ 1 - 0
frontend/src/i18n/locales/en.ts

@@ -1848,6 +1848,7 @@ export default {
     linkTo: 'Link to...',
     linkToProjectOrArchive: 'Link to project or archive',
     addToQueue: 'Add to Queue',
+    schedulePrint: 'Schedule Print',
     generateThumbnail: 'Generate Thumbnail',
     generateThumbnails: 'Generate Thumbnails',
     generateThumbnailsForMissing: 'Generate thumbnails for STL files missing them',

+ 1 - 0
frontend/src/i18n/locales/ja.ts

@@ -1885,6 +1885,7 @@ export default {
     linkTo: 'リンク先...',
     printedCount: '{{count}}回印刷済み',
     addToQueue: 'キューに追加',
+    schedulePrint: '印刷をスケジュール',
     adding: '追加中...',
     folderCreated: 'フォルダを作成しました',
     folderDeleted: 'フォルダを削除しました',

+ 35 - 33
frontend/src/pages/FileManagerPage.tsx

@@ -1015,7 +1015,7 @@ function FileCard({ file, isSelected, isMobile, onSelect, onDelete, onDownload,
                   title={!hasPermission('queue:create') ? t('fileManager.noPermissionAddToQueue') : undefined}
                 >
                   <Clock className="w-3.5 h-3.5" />
-                  {t('fileManager.addToQueue')}
+                  {t('fileManager.schedulePrint')}
                 </button>
               )}
               <button
@@ -1104,6 +1104,7 @@ export function FileManagerPage() {
   const [deleteConfirm, setDeleteConfirm] = useState<{ type: 'file' | 'folder' | 'bulk'; id: number; count?: number } | null>(null);
   const [printFile, setPrintFile] = useState<LibraryFileListItem | null>(null);
   const [printMultiFile, setPrintMultiFile] = useState<LibraryFileListItem | null>(null);
+  const [scheduleFile, setScheduleFile] = useState<LibraryFileListItem | null>(null);
   const [renameItem, setRenameItem] = useState<{ type: 'file' | 'folder'; id: number; name: string } | null>(null);
   const [thumbnailVersions, setThumbnailVersions] = useState<Record<number, number>>({});
   const [viewMode, setViewMode] = useState<'grid' | 'list'>(() => {
@@ -1353,31 +1354,6 @@ export function FileManagerPage() {
     onError: (error: Error) => showToast(error.message, 'error'),
   });
 
-  const addToQueueMutation = useMutation({
-    mutationFn: (fileIds: number[]) => api.addLibraryFilesToQueue(fileIds),
-    onSuccess: (result) => {
-      queryClient.invalidateQueries({ queryKey: ['library-files'] });
-      queryClient.invalidateQueries({ queryKey: ['queue'] });
-      queryClient.invalidateQueries({ queryKey: ['archives'] }); // Archives are created when adding to queue
-      setSelectedFiles([]);
-
-      if (result.added.length > 0 && result.errors.length === 0) {
-        showToast(
-          t('fileManager.toast.addedToQueue', { count: result.added.length }),
-          'success'
-        );
-      } else if (result.added.length > 0 && result.errors.length > 0) {
-        showToast(
-          t('fileManager.toast.addedToQueuePartial', { added: result.added.length, failed: result.errors.length }),
-          'success'
-        );
-      } else {
-        showToast(t('fileManager.toast.failedToAddToQueue', { error: result.errors[0]?.error || 'Unknown error' }), 'error');
-      }
-    },
-    onError: (error: Error) => showToast(error.message, 'error'),
-  });
-
   const renameFileMutation = useMutation({
     mutationFn: ({ id, filename }: { id: number; filename: string }) =>
       api.updateLibraryFile(id, { filename }),
@@ -1859,12 +1835,15 @@ export function FileManagerPage() {
                       <Button
                         variant={selectedSlicedFiles.length === 1 ? 'secondary' : 'primary'}
                         size="sm"
-                        onClick={() => addToQueueMutation.mutate(selectedSlicedFiles.map(f => f.id))}
-                        disabled={addToQueueMutation.isPending || !hasPermission('queue:create')}
+                        // Note: Schedule dialog (PrintModal) is designed for single file at a time
+                        // but supports scheduling to multiple printers. This provides more control
+                        // over scheduling options compared to the previous bulk queue mutation.
+                        onClick={() => setScheduleFile(selectedSlicedFiles[0])}
+                        disabled={!hasPermission('queue:create')}
                         title={!hasPermission('queue:create') ? t('fileManager.noPermissionAddToQueue') : undefined}
                       >
                         <Clock className="w-4 h-4 sm:mr-1" />
-                        <span className="hidden sm:inline">{addToQueueMutation.isPending ? t('fileManager.adding') : `${t('fileManager.addToQueue')}${selectedSlicedFiles.length < selectedFiles.length ? ` (${selectedSlicedFiles.length})` : ''}`}</span>
+                        <span className="hidden sm:inline">{`${t('fileManager.schedulePrint')}${selectedSlicedFiles.length < selectedFiles.length ? ` (${selectedSlicedFiles.length})` : ''}`}</span>
                       </Button>
                     )}
                     <Button
@@ -1963,7 +1942,10 @@ export function FileManagerPage() {
                     onSelect={handleFileSelect}
                     onDelete={(id) => setDeleteConfirm({ type: 'file', id })}
                     onDownload={handleDownload}
-                    onAddToQueue={(id) => addToQueueMutation.mutate([id])}
+                    onAddToQueue={(id) => {
+                      const file = files?.find(f => f.id === id);
+                      if (file) setScheduleFile(file);
+                    }}
                     onPrint={setPrintFile}
                     onRename={(f) => setRenameItem({ type: 'file', id: f.id, name: f.filename })}
                     onGenerateThumbnail={(f) => singleThumbnailMutation.mutate(f.id)}
@@ -2068,14 +2050,18 @@ export function FileManagerPage() {
                             <Printer className="w-4 h-4" />
                           </button>
                           <button
-                            onClick={() => hasPermission('queue:create') && addToQueueMutation.mutate([file.id])}
+                            onClick={() => {
+                              if (hasPermission('queue:create')) {
+                                setScheduleFile(file);
+                              }
+                            }}
                             className={`p-1.5 rounded transition-colors ${
                               hasPermission('queue:create')
                                 ? 'hover:bg-bambu-dark text-bambu-gray hover:text-white'
                                 : 'text-bambu-gray/50 cursor-not-allowed'
                             }`}
-                            title={hasPermission('queue:create') ? t('fileManager.addToQueue') : t('fileManager.noPermissionAddToQueue')}
-                            disabled={addToQueueMutation.isPending || !hasPermission('queue:create')}
+                            title={hasPermission('queue:create') ? t('fileManager.schedulePrint') : t('fileManager.noPermissionAddToQueue')}
+                            disabled={!hasPermission('queue:create')}
                           >
                             <Clock className="w-4 h-4" />
                           </button>
@@ -2236,6 +2222,22 @@ export function FileManagerPage() {
         />
       )}
 
+      {scheduleFile && (
+        <PrintModal
+          mode="add-to-queue"
+          libraryFileId={scheduleFile.id}
+          archiveName={scheduleFile.print_name || scheduleFile.filename}
+          onClose={() => setScheduleFile(null)}
+          onSuccess={() => {
+            setScheduleFile(null);
+            setSelectedFiles([]);
+            queryClient.invalidateQueries({ queryKey: ['library-files'] });
+            queryClient.invalidateQueries({ queryKey: ['queue'] });
+            queryClient.invalidateQueries({ queryKey: ['archives'] });
+          }}
+        />
+      )}
+
       {renameItem && (
         <RenameModal
           type={renameItem.type}

File diff suppressed because it is too large
+ 0 - 0
static/assets/index-D3RdYLqK.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-ChuiDDfR.js"></script>
+    <script type="module" crossorigin src="/assets/index-D3RdYLqK.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-Mcnrrd7v.css">
   </head>
   <body>

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