SpoolBuddyInventoryPage-BmxJPbmk.js 17 KB

1
  1. import{i as e}from"./chunk-aKtaBQYM.js";import{C as t,D as n,a as r,v as i,w as a}from"./client-BdOyoZJz.js";import{n as o}from"./QueryClientProvider-Clbyr4Jg.js";import{t as s}from"./useQuery-CCy0EwsM.js";import{t as c}from"./useMutation-qh3Iyscy.js";import{t as l}from"./check-D1Pn8T1J.js";import{n as u}from"./ToastContext-VFOrCCoA.js";import{t as d}from"./package-D9xR0eOt.js";import{t as f}from"./search-BpAJdxRw.js";import{t as p}from"./triangle-alert-gIik0G2C.js";import{t as m}from"./unlink-DJBJ04VB.js";import{t as h}from"./x-Dctff5l9.js";import{H as g,Hn as _,Kt as v,ft as y,lt as b,ot as x,pt as S}from"./index-BoVbGTav.js";import{n as C,t as w}from"./spoolPaint-CrvpHqdD.js";import{t as T}from"./AssignToAmsModal-kr-0EzwV.js";import{t as E}from"./inventorySearch-yJim1_Yj.js";import{n as D,r as O,t as k}from"./SpoolIcon-OZKzbEc8.js";var A=e(n(),1),j=t(),M=`spoolbuddy-default-core-weight`;function N(){try{let e=localStorage.getItem(M);if(e){let t=parseInt(e,10);if(t>=0&&t<=500)return t}}catch{}return 250}function P({spool:e,liveScaleWeight:t,persistedGrossWeight:n,onClose:o,onSyncWeight:c,onAssignToAms:u,isAssigned:d,onUnassignFromAms:f,className:h}){let{t:g}=a(),[_,b]=(0,A.useState)(!1),[x,C]=(0,A.useState)(!1),[w,T]=(0,A.useState)(null),{data:E}=s({queryKey:[`spool-k-profiles`,e.id],queryFn:()=>r.getSpoolKProfiles(e.id),enabled:!e.k_profiles||e.k_profiles.length===0,staleTime:300*1e3}),D=e.k_profiles&&e.k_profiles.length>0?e.k_profiles:E,O=S(e.rgba),M=y(e.color_name,e.rgba,e.color_name_is_synthesized),P=e.core_weight&&e.core_weight>0?e.core_weight:N(),F=t===null?null:Math.round(Math.max(0,t)),I=w??(n===void 0?F:n===null?null:Math.round(Math.max(0,n))),L=Math.round(Math.max(0,(e.label_weight||0)-(e.weight_used||0))),R=F!==null&&F>=10?Math.round(Math.max(0,F-P)):L,z=Math.round(e.label_weight||1e3),B=z>0?Math.min(100,Math.round(R/z*100)):null,V=B===null?`#808080`:B>50?`#22c55e`:B>20?`#eab308`:`#ef4444`,H=Math.max(0,(e.label_weight||0)-(e.weight_used||0))+P,U=F===null?null:F-H,W=U===null?null:Math.abs(U)<=50,G=I??Math.round(H),K=e.nozzle_temp_min!=null&&e.nozzle_temp_max!=null?`${e.nozzle_temp_min}-${e.nozzle_temp_max}\u00B0C`:null,q=e.slicer_filament_name||e.slicer_filament||null,J=e.note?.trim()||null,Y=D&&D.length>0?Array.from(new Set(D.map(e=>e.k_value.toFixed(3)))).join(`, `):null,X=async()=>{if(t===null)return;let n=Math.round(Math.max(0,t));b(!0);try{await i.updateSpoolWeight(e.id,n),T(n),C(!0),c?.(),setTimeout(()=>C(!1),3e3)}catch(e){console.error(`Failed to sync weight:`,e)}finally{b(!1)}};return(0,j.jsxs)(`div`,{className:`flex flex-col items-center space-y-4 max-w-md ${h??``}`,children:[(0,j.jsxs)(`div`,{className:`flex items-start gap-5`,children:[(0,j.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,j.jsx)(k,{color:O,isEmpty:!1,size:100,spool:e}),B!==null&&(0,j.jsxs)(`div`,{className:`absolute -bottom-2 -right-2 px-2 py-0.5 rounded-full text-xs font-bold text-white shadow-lg`,style:{backgroundColor:V},children:[B,`%`]})]}),(0,j.jsxs)(`div`,{className:`flex-1 min-w-0 pt-1`,children:[(0,j.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,j.jsx)(`h3`,{className:`text-lg font-semibold text-zinc-100`,children:M||g(`spoolbuddy.spool.unknownColor`)}),(0,j.jsxs)(`span`,{className:`text-xs font-mono text-zinc-500 shrink-0`,children:[`#`,e.id]})]}),(0,j.jsxs)(`p`,{className:`text-sm text-zinc-400`,children:[e.brand,` • `,e.material,e.subtype&&` ${e.subtype}`]}),(0,j.jsxs)(`div`,{className:`mt-3`,children:[(0,j.jsxs)(`div`,{className:`flex items-baseline gap-2`,children:[(0,j.jsxs)(`span`,{className:`text-3xl font-bold font-mono text-zinc-100`,children:[R,`g`]}),(0,j.jsxs)(`span`,{className:`text-sm text-zinc-500`,children:[`/ `,z,`g`]})]}),(0,j.jsx)(`p`,{className:`text-xs text-zinc-500 mt-0.5`,children:g(`spoolbuddy.spool.remaining`,`Remaining`)}),(0,j.jsx)(`div`,{className:`mt-2 max-w-xs`,children:(0,j.jsx)(`div`,{className:`h-2 bg-zinc-700 rounded-full overflow-hidden`,children:(0,j.jsx)(`div`,{className:`h-full rounded-full transition-all duration-500`,style:{width:`${B??0}%`,backgroundColor:V}})})})]})]})]}),(0,j.jsxs)(`div`,{className:`grid grid-cols-2 gap-x-6 gap-y-2 text-sm bg-zinc-800 rounded-lg p-4 w-full`,children:[(0,j.jsxs)(`div`,{className:`flex justify-between`,children:[(0,j.jsx)(`span`,{className:`text-zinc-500`,children:g(`spoolbuddy.dashboard.grossWeight`,`Gross weight`)}),(0,j.jsxs)(`span`,{className:`font-mono text-zinc-300`,children:[G,`g`]})]}),(0,j.jsxs)(`div`,{className:`flex justify-between`,children:[(0,j.jsx)(`span`,{className:`text-zinc-500`,children:g(`spoolbuddy.spool.coreWeight`,`Core`)}),(0,j.jsxs)(`span`,{className:`font-mono text-zinc-300`,children:[P,`g`]})]}),(0,j.jsxs)(`div`,{className:`flex justify-between`,children:[(0,j.jsx)(`span`,{className:`text-zinc-500`,children:g(`spoolbuddy.dashboard.spoolSize`,`Spool size`)}),(0,j.jsxs)(`span`,{className:`font-mono text-zinc-300`,children:[z,`g`]})]}),(0,j.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,j.jsx)(`span`,{className:`text-zinc-500`,children:g(`spoolbuddy.spool.scaleWeight`,`Scale`)}),F===null?(0,j.jsx)(`span`,{className:`text-zinc-500`,children:`—`}):(0,j.jsxs)(`span`,{className:`flex items-center gap-1 font-mono ${W?`text-green-500`:`text-yellow-500`}`,children:[F,`g`,W?(0,j.jsx)(l,{className:`w-3.5 h-3.5`}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(p,{className:`w-3.5 h-3.5`}),(0,j.jsx)(`button`,{onClick:X,className:`p-1 hover:bg-green-500/20 rounded transition-colors text-green-500`,title:g(`spoolbuddy.dashboard.syncWeight`,`Sync Weight`),children:(0,j.jsx)(v,{className:`w-4 h-4`})})]})]})]}),(0,j.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,j.jsx)(`span`,{className:`text-zinc-500`,children:g(`spoolbuddy.dashboard.tagId`,`Tag`)}),(0,j.jsx)(`span`,{className:`font-mono text-xs text-zinc-400 truncate max-w-[120px]`,title:e.tag_uid||``,children:e.tag_uid?e.tag_uid.slice(-8):`—`})]}),K&&(0,j.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,j.jsx)(`span`,{className:`text-zinc-500`,children:g(`spoolbuddy.inventory.nozzleTemp`,`Nozzle`)}),(0,j.jsx)(`span`,{className:`font-mono text-zinc-300`,children:K})]}),e.cost_per_kg!=null&&e.cost_per_kg>0&&(0,j.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,j.jsx)(`span`,{className:`text-zinc-500`,children:g(`spoolbuddy.inventory.costPerKg`,`Cost/kg`)}),(0,j.jsxs)(`span`,{className:`font-mono text-zinc-300`,children:[e.cost_per_kg.toFixed(2),`/kg`]})]}),Y&&(0,j.jsxs)(`div`,{className:`flex justify-between items-center`,children:[(0,j.jsx)(`span`,{className:`text-zinc-500`,children:g(`spoolbuddy.inventory.kProfiles`,`K-Profile`)}),(0,j.jsx)(`span`,{className:`font-mono text-zinc-300 truncate max-w-[220px] text-right`,title:Y,children:Y})]}),q&&(0,j.jsxs)(`div`,{className:`min-w-0`,children:[(0,j.jsx)(`p`,{className:`text-xs text-zinc-500 mb-1`,children:g(`spoolbuddy.inventory.slicerFilament`,`Slicer Filament`)}),(0,j.jsx)(`p`,{className:`text-sm text-zinc-300 whitespace-pre-wrap break-words`,children:q})]}),J&&(0,j.jsxs)(`div`,{className:`col-span-2`,children:[(0,j.jsx)(`p`,{className:`text-xs text-zinc-500 mb-1`,children:g(`spoolbuddy.inventory.note`,`Note`)}),(0,j.jsx)(`p`,{className:`text-sm leading-5 text-zinc-300 whitespace-pre-wrap break-words max-h-[3.75rem] overflow-y-auto pr-1`,children:J})]})]}),(0,j.jsxs)(`div`,{className:`flex gap-2 justify-center`,children:[u&&(0,j.jsx)(`button`,{onClick:d?void 0:u,disabled:!!d,className:`px-5 py-2.5 rounded-lg text-sm font-medium bg-green-600 text-white hover:bg-green-700 transition-colors min-h-[44px] disabled:opacity-50 disabled:cursor-not-allowed`,children:g(`spoolbuddy.modal.assignToAms`,`Assign to AMS`)}),f&&(0,j.jsxs)(`button`,{onClick:f,className:`px-5 py-2.5 rounded-lg text-sm font-medium bg-red-600/20 text-red-400 hover:bg-red-600/30 transition-colors min-h-[44px]`,children:[(0,j.jsx)(m,{className:`w-4 h-4 inline mr-1`}),g(`inventory.unassignSpool`)]}),(0,j.jsx)(`button`,{onClick:X,disabled:t===null||_,className:`px-5 py-2.5 rounded-lg text-sm font-medium transition-colors min-h-[44px] ${x?`bg-green-600/20 text-green-400`:u?`bg-zinc-700 text-zinc-300 hover:bg-zinc-600 disabled:opacity-40 disabled:cursor-not-allowed`:`bg-green-600 text-white hover:bg-green-700 disabled:opacity-40 disabled:cursor-not-allowed`}`,children:_?`...`:x?g(`spoolbuddy.dashboard.weightSynced`,`Synced!`):g(`spoolbuddy.dashboard.syncWeight`,`Sync Weight`)}),o&&(0,j.jsx)(`button`,{onClick:o,className:`px-5 py-2.5 rounded-lg text-sm font-medium bg-zinc-700 text-zinc-300 hover:bg-zinc-600 transition-colors min-h-[44px]`,children:g(`spoolbuddy.dashboard.close`,`Close`)})]})]})}function F(e){return S(e.rgba)}function I(e){return Math.max(0,e.label_weight-e.weight_used)}function L(e){return e.label_weight<=0?0:Math.max(0,Math.min(100,(e.label_weight-e.weight_used)/e.label_weight*100))}function R(e){let t=[e.material];return e.subtype&&t.push(e.subtype),t.join(` `)}function z(e){let t=e.ams_id===254||e.ams_id===255,n=!t&&e.ams_id>=128;return g(e.ams_id,e.tray_id,n,t)}function B({color:e,spool:t,size:n=56}){return w(t)?(0,j.jsxs)(`div`,{className:`relative shrink-0`,style:{width:n,height:n},children:[(0,j.jsx)(D,{spool:t,size:n,inset:2/56}),(0,j.jsx)(O,{inset:8/56}),(0,j.jsxs)(`svg`,{className:`absolute inset-0`,width:n,height:n,viewBox:`0 0 56 56`,children:[(0,j.jsx)(`ellipse`,{cx:`20`,cy:`20`,rx:`6`,ry:`4`,fill:`white`,opacity:`0.3`}),(0,j.jsx)(`circle`,{cx:`28`,cy:`28`,r:`8`,fill:`#2d2d2d`}),(0,j.jsx)(`circle`,{cx:`28`,cy:`28`,r:`5`,fill:`#1a1a1a`})]})]}):(0,j.jsxs)(`svg`,{width:n,height:n,viewBox:`0 0 56 56`,children:[(0,j.jsx)(`circle`,{cx:`28`,cy:`28`,r:`26`,fill:e}),(0,j.jsx)(`circle`,{cx:`28`,cy:`28`,r:`20`,fill:e,style:{filter:`brightness(0.85)`}}),(0,j.jsx)(`ellipse`,{cx:`20`,cy:`20`,rx:`6`,ry:`4`,fill:`white`,opacity:`0.3`}),(0,j.jsx)(`circle`,{cx:`28`,cy:`28`,r:`8`,fill:`#2d2d2d`}),(0,j.jsx)(`circle`,{cx:`28`,cy:`28`,r:`5`,fill:`#1a1a1a`})]})}function V(){let{sbState:e,selectedPrinterId:t}=_(),{t:n}=a(),i=x(),{showToast:l}=u(),p=o(),[m,g]=(0,A.useState)(``),[v,y]=(0,A.useState)(`all`),[b,S]=(0,A.useState)(null),[C,w]=(0,A.useState)(!1),{data:D}=s({queryKey:[`spoolman-settings`],queryFn:r.getSpoolmanSettings,staleTime:300*1e3}),O=D?.spoolman_enabled===`true`&&!!D?.spoolman_url,{data:k=[],isLoading:M,refetch:N}=s({queryKey:O?[`spoolman-inventory-spools`]:[`inventory-spools`],queryFn:()=>O?r.getSpoolmanInventorySpools(!1):r.getSpools(!1),enabled:D!==void 0,refetchInterval:3e4}),{data:P=[]}=s({queryKey:[`spool-assignments`],queryFn:()=>r.getAssignments(),refetchInterval:3e4,enabled:!O}),{data:F=[]}=s({queryKey:[`spoolman-slot-assignments`],queryFn:()=>r.getSpoolmanSlotAssignments(),refetchInterval:3e4,enabled:O}),I=c({mutationFn:e=>r.unassignSpoolmanSlot(e),onSuccess:()=>{p.invalidateQueries({queryKey:[`spoolman-slot-assignments`]}),p.invalidateQueries({queryKey:[`spoolman-inventory-spools`]})},onError:()=>l(n(`inventory.unassignFailed`,`Failed to unassign spool`),`error`)}),L=(0,A.useMemo)(()=>{if(O){let e={};return F.forEach(t=>{e[t.spoolman_spool_id]={ams_id:t.ams_id,tray_id:t.tray_id}}),e}let e={};return P.forEach(t=>{e[t.spool_id]={ams_id:t.ams_id,tray_id:t.tray_id,printer_name:t.printer_name}}),e},[O,P,F]),R=(0,A.useMemo)(()=>k.filter(e=>!e.archived_at),[k]),z=(0,A.useMemo)(()=>new Set(Object.keys(L).map(Number)),[L]),B=(0,A.useMemo)(()=>R.filter(e=>z.has(e.id)).length,[R,z]),V=(0,A.useMemo)(()=>{let e=new Set;return R.forEach(t=>e.add(t.material)),Array.from(e).sort()},[R]),G=(0,A.useMemo)(()=>{let e=R;return v===`in_ams`?e=e.filter(e=>z.has(e.id)):v!==`all`&&(e=e.filter(e=>e.material===v)),e=E(e,m.trim()),[...e].sort((e,t)=>{let n=+!z.has(e.id),r=+!z.has(t.id);return n===r?new Date(t.updated_at).getTime()-new Date(e.updated_at).getTime():n-r})},[R,v,m,z,i]);return(0,j.jsxs)(`div`,{className:`h-full flex flex-col`,children:[(0,j.jsxs)(`div`,{className:`px-3 pt-3 pb-2 space-y-2.5`,children:[(0,j.jsxs)(`div`,{className:`relative`,children:[(0,j.jsx)(f,{className:`absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-white/40`}),(0,j.jsx)(`input`,{type:`text`,value:m,onChange:e=>g(e.target.value),placeholder:n(`spoolbuddy.inventory.searchPlaceholder`,`Search spools...`),className:`w-full pl-9 pr-8 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-sm text-white placeholder-white/30 focus:outline-none focus:border-bambu-green`}),m&&(0,j.jsx)(`button`,{onClick:()=>g(``),className:`absolute right-2 top-1/2 -translate-y-1/2 text-white/40 hover:text-white/60`,children:(0,j.jsx)(h,{className:`w-4 h-4`})})]}),(0,j.jsxs)(`div`,{className:`flex gap-1.5 overflow-x-auto no-scrollbar`,children:[(0,j.jsx)(H,{active:v===`all`,onClick:()=>y(`all`),label:`${n(`spoolbuddy.inventory.all`,`All`)} (${R.length})`,green:!0}),B>0&&(0,j.jsx)(H,{active:v===`in_ams`,onClick:()=>y(`in_ams`),label:`${n(`spoolbuddy.inventory.inAms`,`In AMS`)} (${B})`}),V.map(e=>(0,j.jsx)(H,{active:v===e,onClick:()=>y(v===e?`all`:e),label:e},e))]})]}),(0,j.jsx)(`div`,{className:`flex-1 overflow-y-auto px-3 pb-3`,children:M?(0,j.jsx)(`div`,{className:`flex items-center justify-center py-16`,children:(0,j.jsx)(`div`,{className:`w-8 h-8 border-2 border-bambu-green border-t-transparent rounded-full animate-spin`})}):G.length===0?(0,j.jsxs)(`div`,{className:`flex flex-col items-center justify-center py-16 text-white/30`,children:[(0,j.jsx)(d,{className:`w-12 h-12 mb-3`}),(0,j.jsx)(`p`,{className:`text-sm`,children:m||v!==`all`?n(`spoolbuddy.inventory.noResults`,`No spools match your filters`):n(`spoolbuddy.inventory.empty`,`No spools in inventory`)})]}):(0,j.jsx)(`div`,{className:`grid grid-cols-[repeat(auto-fill,minmax(130px,1fr))] gap-2`,children:G.map(e=>(0,j.jsx)(U,{spool:e,assignment:L[e.id],onClick:()=>S(e.id)},e.id))})}),b!=null&&(()=>{let n=k.find(e=>e.id===b);return n?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(W,{spool:n,assignment:L[n.id],sbState:e,onSyncWeight:()=>{N()},onAssignToAms:()=>w(!0),onUnassignFromAms:O&&L[n.id]?()=>I.mutate(n.id):void 0,onClose:()=>{S(null),w(!1)}}),(0,j.jsx)(T,{isOpen:C,onClose:()=>w(!1),spool:n,printerId:t,variant:`kiosk`,spoolmanMode:O})]}):null})()]})}function H({active:e,onClick:t,label:n,green:r}){return(0,j.jsx)(`button`,{onClick:t,className:`px-4 py-1.5 rounded-full text-sm font-medium border whitespace-nowrap shrink-0 transition-colors ${e?r?`bg-bambu-green/20 text-bambu-green border-bambu-green/50`:`bg-white/10 text-white border-white/20`:`bg-transparent text-white/40 border-bambu-dark-tertiary hover:text-white/60`}`,children:n})}function U({spool:e,assignment:t,onClick:n}){let r=F(e),i=L(e),a=I(e),o=y(e.color_name,e.rgba,e.color_name_is_synthesized);return(0,j.jsxs)(`button`,{onClick:n,className:`bg-bambu-dark-secondary rounded-xl p-3 flex flex-col items-center text-center gap-1.5 border border-transparent hover:border-bambu-green/50 transition-colors`,children:[(0,j.jsx)(B,{color:r,spool:e,size:56}),(0,j.jsx)(`p`,{className:`text-xs font-semibold text-white leading-tight truncate w-full`,children:R(e)}),(0,j.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 max-w-full`,children:[(0,j.jsx)(`span`,{className:`w-2.5 h-2.5 rounded-full shrink-0 border border-white/10`,style:C(e)??b(e.rgba)}),(0,j.jsx)(`span`,{className:`text-[11px] text-white/50 truncate`,children:o||`-`})]}),(0,j.jsxs)(`div`,{className:`w-full space-y-0.5`,children:[(0,j.jsx)(`div`,{className:`h-1.5 bg-bambu-dark-tertiary rounded-full overflow-hidden`,children:(0,j.jsx)(`div`,{className:`h-full rounded-full ${i>50?`bg-bambu-green`:i>20?`bg-yellow-500`:`bg-red-500`}`,style:{width:`${Math.min(i,100)}%`}})}),(0,j.jsxs)(`p`,{className:`text-[11px] text-white/40`,children:[Math.round(a),`g (`,Math.round(i),`%)`]})]}),t&&(0,j.jsx)(`span`,{className:`px-2 py-0.5 rounded text-[10px] font-bold bg-bambu-green/20 text-bambu-green`,children:z(t)})]})}function W({spool:e,assignment:t,sbState:n,onSyncWeight:r,onAssignToAms:i,onUnassignFromAms:a,onClose:o}){let s=n.deviceOnline&&n.weight!==null?Math.round(n.weight):null,c=e.last_scale_weight==null?null:Math.round(e.last_scale_weight);return(0,j.jsx)(`div`,{className:`fixed inset-0 z-50 bg-black/70 flex items-center justify-center p-4`,onClick:o,children:(0,j.jsx)(`div`,{className:`w-full max-w-md bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-2xl p-4 overflow-y-auto max-h-[90vh]`,onClick:e=>e.stopPropagation(),children:(0,j.jsxs)(`div`,{className:`space-y-3`,children:[t&&(0,j.jsxs)(`div`,{className:`flex items-center justify-center gap-2`,children:[(0,j.jsx)(`span`,{className:`px-2.5 py-1 rounded-md text-xs font-bold bg-bambu-green/20 text-bambu-green`,children:z(t)}),t.printer_name&&(0,j.jsx)(`span`,{className:`text-xs text-zinc-400`,children:t.printer_name})]}),(0,j.jsx)(`div`,{className:`flex justify-center`,children:(0,j.jsx)(P,{spool:e,liveScaleWeight:s,persistedGrossWeight:c,onSyncWeight:r,onAssignToAms:i,isAssigned:!!t,onUnassignFromAms:a,onClose:o,className:`max-w-md`})})]})})})}export{V as SpoolBuddyInventoryPage};