mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-09 07:25:44 +02:00
Merge branch '0.2.0b' into feature/mobile_view_fix
This commit is contained in:
@@ -28,6 +28,7 @@ All notable changes to Bambuddy will be documented in this file.
|
||||
- **K-Profile Selection Corrupts Existing Profiles on X1C/P1S** — The `extrusion_cali_sel` command included a `setting_id` field that BambuStudio never sends, causing firmware to mislink calibration data. The `extrusion_cali_set` command was sent unconditionally, overwriting existing profile metadata. Now `setting_id` is removed from selection commands, and `extrusion_cali_set` is only sent when no existing profile is selected (`cali_idx < 0`).
|
||||
- **AMS Slot Configure — Black Filament Color Not Pre-Populated** — When re-opening the Configure AMS Slot modal for a slot with black filament, the color field was empty despite the preset and K-profile being correctly pre-selected. The color pre-population logic excluded hex `000000` (black) as a guard against empty slots, but empty slots already skip color data entirely. Removed the unnecessary check so black is now pre-populated like any other color.
|
||||
- **Archive List View Not Labeling Failed Prints** ([#365](https://github.com/maziggy/bambuddy/issues/365)) — The archive grid view displayed a red "Failed" / "Cancelled" badge on failed and aborted prints, but the list view had no equivalent indicator. Now shows an inline status badge next to the print name in list view.
|
||||
- **Reprint Fails with SD Card Error for Archives Without 3MF File** ([#376](https://github.com/maziggy/bambuddy/issues/376)) — When a print was sent from an external slicer and Bambuddy couldn't download the 3MF from the printer during auto-archiving, the fallback archive had no file. Attempting to reprint such an archive tried to upload the data directory as a file, causing a confusing "SD card error." The backend now returns a clear error for file-less archives, and the frontend disables Print/Schedule/Open in Slicer buttons with a tooltip explaining that the 3MF file is unavailable.
|
||||
- **Inventory Spool Weight Resets After Print Completes** — After a print, the usage tracker correctly updated `weight_used` (e.g., +1.6g), but periodic AMS status updates recalculated `weight_used` from the AMS remain% sensor and overwrote the precise value. For small prints on large spools (e.g., 1.6g on 1000g), the AMS remain% stays at 100% (integer resolution = 10g steps), resetting `weight_used` back to 0. The AMS weight sync now only increases `weight_used`, never decreases it, preserving precise values from the usage tracker.
|
||||
|
||||
### Improved
|
||||
|
||||
@@ -2738,8 +2738,14 @@ async def reprint_archive(
|
||||
raise HTTPException(400, "Printer is not connected")
|
||||
|
||||
# Get the sliced 3MF file path
|
||||
if not archive.file_path:
|
||||
raise HTTPException(
|
||||
404,
|
||||
"No 3MF file available for this archive. "
|
||||
"The file could not be downloaded from the printer when the print was recorded.",
|
||||
)
|
||||
file_path = settings.base_dir / archive.file_path
|
||||
if not file_path.exists():
|
||||
if not file_path.is_file():
|
||||
raise HTTPException(404, "Archive file not found")
|
||||
|
||||
# Upload file to printer via FTP
|
||||
|
||||
@@ -610,6 +610,7 @@ export default {
|
||||
slicedFor: 'Geslict für {{model}}',
|
||||
uploadedBy: 'Hochgeladen von',
|
||||
noPermissionReprint: 'Sie haben keine Berechtigung, erneut zu drucken',
|
||||
noFileForReprint: 'Keine 3MF-Datei verfügbar — die Datei konnte beim Aufzeichnen des Drucks nicht vom Drucker heruntergeladen werden',
|
||||
noPermissionEdit: 'Sie haben keine Berechtigung, Archive zu bearbeiten',
|
||||
noPermissionDelete: 'Sie haben keine Berechtigung, Archive zu löschen',
|
||||
reprint: 'Drucken',
|
||||
|
||||
@@ -610,6 +610,7 @@ export default {
|
||||
slicedFor: 'Sliced for {{model}}',
|
||||
uploadedBy: 'Uploaded By',
|
||||
noPermissionReprint: 'You do not have permission to reprint',
|
||||
noFileForReprint: 'No 3MF file available — the file could not be downloaded from the printer when the print was recorded',
|
||||
noPermissionEdit: 'You do not have permission to edit archives',
|
||||
noPermissionDelete: 'You do not have permission to delete archives',
|
||||
reprint: 'Reprint',
|
||||
|
||||
@@ -610,6 +610,7 @@ export default {
|
||||
slicedFor: 'Découpé pour {{model}}',
|
||||
uploadedBy: 'Téléversé par',
|
||||
noPermissionReprint: 'Pas d\'autorisation de réimpression',
|
||||
noFileForReprint: 'Aucun fichier 3MF disponible — le fichier n\'a pas pu être téléchargé depuis l\'imprimante lors de l\'enregistrement',
|
||||
noPermissionEdit: 'Pas d\'autorisation de modification',
|
||||
noPermissionDelete: 'Pas d\'autorisation de suppression',
|
||||
reprint: 'Réimprimer',
|
||||
|
||||
@@ -601,6 +601,7 @@ export default {
|
||||
slicedFor: 'Sliced per {{model}}',
|
||||
uploadedBy: 'Caricato da',
|
||||
noPermissionReprint: 'Non hai il permesso di ristampare',
|
||||
noFileForReprint: 'Nessun file 3MF disponibile — il file non è stato scaricato dalla stampante durante la registrazione',
|
||||
noPermissionEdit: 'Non hai il permesso di modificare archivi',
|
||||
noPermissionDelete: 'Non hai il permesso di eliminare archivi',
|
||||
reprint: 'Ristampa',
|
||||
|
||||
@@ -623,6 +623,7 @@ export default {
|
||||
slicedFor: '{{model}}用にスライス',
|
||||
uploadedBy: 'アップロード者',
|
||||
noPermissionReprint: '再印刷する権限がありません',
|
||||
noFileForReprint: '3MFファイルがありません — 印刷記録時にプリンターからファイルをダウンロードできませんでした',
|
||||
noPermissionDelete: 'アーカイブを削除する権限がありません',
|
||||
openInBambuStudio: 'スライサーで開く',
|
||||
openInBambuStudioToSlice: 'スライサーでスライス',
|
||||
|
||||
@@ -303,15 +303,15 @@ function ArchiveCard({
|
||||
label: t('archives.menu.print'),
|
||||
icon: <Printer className="w-4 h-4" />,
|
||||
onClick: () => setShowReprint(true),
|
||||
disabled: !canModify('archives', 'reprint', archive.created_by_id),
|
||||
title: !canModify('archives', 'reprint', archive.created_by_id) ? t('archives.permission.noReprint') : undefined,
|
||||
disabled: !archive.file_path || !canModify('archives', 'reprint', archive.created_by_id),
|
||||
title: !archive.file_path ? t('archives.card.noFileForReprint') : !canModify('archives', 'reprint', archive.created_by_id) ? t('archives.permission.noReprint') : undefined,
|
||||
},
|
||||
{
|
||||
label: t('archives.menu.schedule'),
|
||||
icon: <Calendar className="w-4 h-4" />,
|
||||
onClick: () => setShowSchedule(true),
|
||||
disabled: !hasPermission('queue:create'),
|
||||
title: !hasPermission('queue:create') ? t('archives.permission.noAddToQueue') : undefined,
|
||||
disabled: !archive.file_path || !hasPermission('queue:create'),
|
||||
title: !archive.file_path ? t('archives.card.noFileForReprint') : !hasPermission('queue:create') ? t('archives.permission.noAddToQueue') : undefined,
|
||||
},
|
||||
{
|
||||
label: t('archives.menu.openInBambuStudio'),
|
||||
@@ -321,6 +321,8 @@ function ArchiveCard({
|
||||
const downloadUrl = `${window.location.origin}${api.getArchiveForSlicer(archive.id, filename)}`;
|
||||
openInSlicer(downloadUrl, preferredSlicer);
|
||||
},
|
||||
disabled: !archive.file_path,
|
||||
title: !archive.file_path ? t('archives.card.noFileForReprint') : undefined,
|
||||
},
|
||||
] : [
|
||||
{
|
||||
@@ -926,8 +928,8 @@ function ArchiveCard({
|
||||
size="sm"
|
||||
className="flex-1 min-w-0"
|
||||
onClick={() => setShowReprint(true)}
|
||||
disabled={!canModify('archives', 'reprint', archive.created_by_id)}
|
||||
title={!canModify('archives', 'reprint', archive.created_by_id) ? t('archives.card.noPermissionReprint') : undefined}
|
||||
disabled={!archive.file_path || !canModify('archives', 'reprint', archive.created_by_id)}
|
||||
title={!archive.file_path ? t('archives.card.noFileForReprint') : !canModify('archives', 'reprint', archive.created_by_id) ? t('archives.card.noPermissionReprint') : undefined}
|
||||
>
|
||||
<Printer className="w-3 h-3 flex-shrink-0" />
|
||||
<span className="hidden sm:inline">{t('archives.card.reprint')}</span>
|
||||
@@ -937,8 +939,8 @@ function ArchiveCard({
|
||||
size="sm"
|
||||
className="flex-1 min-w-0"
|
||||
onClick={() => setShowSchedule(true)}
|
||||
disabled={!hasPermission('queue:create')}
|
||||
title={!hasPermission('queue:create') ? t('archives.permission.noAddToQueue') : t('archives.card.schedulePrint')}
|
||||
disabled={!archive.file_path || !hasPermission('queue:create')}
|
||||
title={!archive.file_path ? t('archives.card.noFileForReprint') : !hasPermission('queue:create') ? t('archives.permission.noAddToQueue') : t('archives.card.schedulePrint')}
|
||||
>
|
||||
<Calendar className="w-3 h-3 flex-shrink-0" />
|
||||
<span className="hidden sm:inline">{t('archives.card.schedule')}</span>
|
||||
@@ -1438,15 +1440,15 @@ function ArchiveListRow({
|
||||
label: t('archives.menu.print'),
|
||||
icon: <Printer className="w-4 h-4" />,
|
||||
onClick: () => setShowReprint(true),
|
||||
disabled: !canModify('archives', 'reprint', archive.created_by_id),
|
||||
title: !canModify('archives', 'reprint', archive.created_by_id) ? t('archives.permission.noReprint') : undefined,
|
||||
disabled: !archive.file_path || !canModify('archives', 'reprint', archive.created_by_id),
|
||||
title: !archive.file_path ? t('archives.card.noFileForReprint') : !canModify('archives', 'reprint', archive.created_by_id) ? t('archives.permission.noReprint') : undefined,
|
||||
},
|
||||
{
|
||||
label: t('archives.menu.schedule'),
|
||||
icon: <Calendar className="w-4 h-4" />,
|
||||
onClick: () => setShowSchedule(true),
|
||||
disabled: !hasPermission('queue:create'),
|
||||
title: !hasPermission('queue:create') ? t('archives.permission.noAddToQueue') : undefined,
|
||||
disabled: !archive.file_path || !hasPermission('queue:create'),
|
||||
title: !archive.file_path ? t('archives.card.noFileForReprint') : !hasPermission('queue:create') ? t('archives.permission.noAddToQueue') : undefined,
|
||||
},
|
||||
{
|
||||
label: t('archives.menu.openInBambuStudio'),
|
||||
@@ -1456,6 +1458,8 @@ function ArchiveListRow({
|
||||
const downloadUrl = `${window.location.origin}${api.getArchiveForSlicer(archive.id, filename)}`;
|
||||
openInSlicer(downloadUrl, preferredSlicer);
|
||||
},
|
||||
disabled: !archive.file_path,
|
||||
title: !archive.file_path ? t('archives.card.noFileForReprint') : undefined,
|
||||
},
|
||||
] : [
|
||||
{
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -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-C9JxyacH.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-DgABqL-m.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-OqmBOPoC.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user