SpoolBuddyInventoryPage-ATD_v0AM.js 17 KB

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