From fbed6a904a792a0767c6ada433311a8976235ad9 Mon Sep 17 00:00:00 2001 From: paxx12 <245230251+paxx12@users.noreply.github.com> Date: Mon, 1 Jun 2026 10:11:07 +0200 Subject: [PATCH 1/3] feat(afc): Enhance Spoolman integration in AFC widgets Align AFC lane body with Spoolman data: use information from Spoolman or directly from the AFC component instead of deducing values or hardcoding defaults such as `initial_weight` of 1000. Expand the spool reel tooltip to show ID, vendor, filament name, material with extruder/bed temps, and remaining/used weight from Spoolman when available. Make the filament name row a clickable link to `/spool/show/{id}` on the Spoolman UI when configured; falls back to plain text otherwise. Add `initial_weight` and `filament_name` to `AfcLaneState` typings. Signed-off-by: paxx12 <245230251+paxx12@users.noreply.github.com> --- .../widgets/afc/AfcCardUnitLaneBody.vue | 89 ++++++++++++++----- src/locales/en.yaml | 1 - src/typings/klipper.d.ts | 2 + 3 files changed, 67 insertions(+), 25 deletions(-) diff --git a/src/components/widgets/afc/AfcCardUnitLaneBody.vue b/src/components/widgets/afc/AfcCardUnitLaneBody.vue index 80626eabfd..a4792455ea 100644 --- a/src/components/widgets/afc/AfcCardUnitLaneBody.vue +++ b/src/components/widgets/afc/AfcCardUnitLaneBody.vue @@ -21,9 +21,26 @@ - #{{ spoolId }} | {{ spoolVendor }} + ID #{{ spoolId }}
- {{ spoolFilamentName }} + {{ spoolFilamentName }} + +
- {{ spoolRemainingWeightOutput }} + +
- - {{ spoolFilamentName }} - + {{ spoolFilamentName }} + {{ spoolFilamentName }}
@@ -147,39 +172,51 @@ export default class AfcCardUnitLaneBody extends Mixins(StateMixin, AfcMixin) { return this.lane?.color || '#000000' } - get spoolRemainingWeight (): number { - if (this.afcExistsSpoolman && this.spool?.remaining_weight != null) { - return Math.round(this.spool.remaining_weight) - } - return Math.round(this.lane?.weight ?? 0) - } - - get spoolRemainingWeightOutput (): string { - return `${this.spoolRemainingWeight} g` + get spoolRemainingWeight (): number | undefined { + return this.spool?.remaining_weight ?? this.lane?.weight } - get spoolFullWeight (): number { - return this.spool?.initial_weight ?? 1000 + get spoolFullWeight (): number | undefined { + return this.spool?.initial_weight ?? this.lane?.initial_weight } get spoolPercent (): number { + if (this.spoolRemainingWeight == null || this.spoolFullWeight == null) return 100 if (this.spoolFullWeight === 0) return 100 return Math.round((this.spoolRemainingWeight / this.spoolFullWeight) * 100) } get spoolMaterial (): string { - return this.lane?.material || '--' + return this.spool?.filament?.material ?? this.lane?.material ?? '' + } + + get spoolFilamentVendor (): string | undefined { + return this.spool?.filament?.vendor?.name + } + + get spoolFilamentName (): string | undefined { + return this.spool?.filament?.name || + this.lane?.filament_name || + undefined + } + + get spoolUrl (): string | undefined { + const base: string | undefined = this.$typedGetters['spoolman/getSpoolmanUrl'] + if (!base || !this.spoolId) return undefined + return `${base.replace(/\/$/, '')}/spool/show/${this.spoolId}` } - get spoolVendor (): string { - return this.spool?.filament?.vendor?.name ?? this.$t('app.afc.Unknown').toString() + get spoolExtruderTemp (): number | undefined { + return this.spool?.filament?.settings_extruder_temp } - get spoolFilamentName (): string { - return this.afcExistsSpoolman - ? this.spool?.filament?.name ?? this.$t('app.afc.Unknown').toString() - : '' + get spoolBedTemp (): number | undefined { + return this.spool?.filament?.settings_bed_temp + } + + get spoolUsedWeight (): number | undefined { + return this.spool?.used_weight } get tdPresent (): boolean { @@ -246,4 +283,8 @@ export default class AfcCardUnitLaneBody extends Mixins(StateMixin, AfcMixin) { .position-relative { position: relative !important; } + +.filament-link { + color: inherit !important; +} diff --git a/src/locales/en.yaml b/src/locales/en.yaml index a11cdd2c06..9258f7c8cc 100644 --- a/src/locales/en.yaml +++ b/src/locales/en.yaml @@ -86,7 +86,6 @@ app: ShowTd1Color: "Show TD-1 Color" Unloading: "Unloading" UnloadLane: "Unload Lane" - Unknown: "Unknown" Weight: "Weight" WeightSubtitle: "The weight of the filament in grams (without spool)." bedmesh: diff --git a/src/typings/klipper.d.ts b/src/typings/klipper.d.ts index 0a22a085eb..872279e69c 100644 --- a/src/typings/klipper.d.ts +++ b/src/typings/klipper.d.ts @@ -815,9 +815,11 @@ declare namespace Klipper { density?: number; diameter?: number; empty_spool_weight?: number; + initial_weight?: number; spool_id: number | null; color: string | null; weight: number; + filament_name?: string; extruder_temp: number | null; runout_lane: string | null; filament_status: 'In Tool' | 'Ready' | 'Prep' | 'Not Ready'; From b441fec53c509e41b826c1dc09b8e5eb95f27023 Mon Sep 17 00:00:00 2001 From: paxx12 <245230251+paxx12@users.noreply.github.com> Date: Mon, 1 Jun 2026 12:19:48 +0200 Subject: [PATCH 2/3] fix(afc): Address PR review comments in `AfcCardUnitLaneBody` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add `rel="noopener noreferrer"` to external Spoolman link to prevent reverse-tabnabbing via `target="_blank"` - Keep `!this.spoolId` guard in `spoolUrl` — spool ID `0` is invalid in Spoolman so the falsy check is correct and consistent with `spool` getter - Replace hard-coded English strings in tooltip with i18n keys (`app.afc.WeightRemaining`, `app.afc.WeightUsed`); fix `spoolUsedWeight` guard from truthy to `!= null` so `0 g used` is displayed correctly Signed-off-by: paxx12 <245230251+paxx12@users.noreply.github.com> --- src/components/widgets/afc/AfcCardUnitLaneBody.vue | 7 ++++--- src/locales/en.yaml | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/widgets/afc/AfcCardUnitLaneBody.vue b/src/components/widgets/afc/AfcCardUnitLaneBody.vue index a4792455ea..7a5eef63bf 100644 --- a/src/components/widgets/afc/AfcCardUnitLaneBody.vue +++ b/src/components/widgets/afc/AfcCardUnitLaneBody.vue @@ -36,9 +36,9 @@