diff --git a/frontend/src/components/AssignSpoolModal.tsx b/frontend/src/components/AssignSpoolModal.tsx index 06e43f74f..ec8bc3c2d 100644 --- a/frontend/src/components/AssignSpoolModal.tsx +++ b/frontend/src/components/AssignSpoolModal.tsx @@ -312,7 +312,7 @@ export function AssignSpoolModal({ isOpen, onClose, printerId, amsId, trayId, tr return ( <> -
+
f?f.filter(x=>{if(!u)return!0;const _=u.toLowerCase();return x.filament_name&&x.filament_name.toLowerCase().includes(_)||x.filament_vendor&&x.filament_vendor.toLowerCase().includes(_)||x.filament_material&&x.filament_material.toLowerCase().includes(_)||String(x.id).includes(_)}):[],[f,u]),g=it({mutationFn:x=>se.linkSpool(x,{spoolTag:p,printerId:i,amsId:s,trayId:o}),onSuccess:()=>{c.invalidateQueries({queryKey:["unlinked-spools"]}),c.invalidateQueries({queryKey:["linked-spools"]}),c.invalidateQueries({queryKey:["spoolman-slot-assignments"]}),d(l("spoolman.linkSuccess"),"success"),e()},onError:x=>{d(x.message||l("spoolman.linkFailed"),"error")}});return t?r.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",children:[r.jsx("div",{className:"absolute inset-0 bg-black/60 backdrop-blur-sm",onClick:e}),r.jsxs("div",{className:"relative bg-bambu-dark-secondary rounded-xl shadow-xl w-full max-w-md mx-4 max-h-[80vh] flex flex-col border border-bambu-dark-tertiary",children:[r.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-white/10",children:[r.jsxs("div",{children:[r.jsxs("h3",{className:"text-lg font-semibold text-white flex items-center gap-2",children:[r.jsx(Wy,{className:"w-5 h-5 text-bambu-green"}),l("spoolman.selectSpool")]}),r.jsxs("p",{className:"text-xs text-bambu-gray mt-1",children:["AMS ",s," T",o," · Printer #",i]})]}),r.jsx("button",{onClick:e,className:"p-1 text-bambu-gray hover:text-white rounded transition-colors",children:r.jsx(Ht,{className:"w-5 h-5"})})]}),r.jsxs("div",{className:"p-4 border-b border-white/10",children:[r.jsxs("div",{className:"relative",children:[r.jsx(Sr,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-bambu-gray"}),r.jsx("input",{type:"text",value:u,onChange:x=>m(x.target.value),placeholder:l("inventory.searchSpools"),className:"w-full pl-9 pr-3 py-2 bg-bambu-dark rounded-lg border border-white/10 text-white text-sm placeholder:text-bambu-gray focus:outline-none focus:border-bambu-green"})]}),(a||n)&&r.jsxs("p",{className:"text-xs text-bambu-gray mt-2 font-mono truncate",title:a||n,children:["Tag: ",a||n]})]}),r.jsx("div",{className:"flex-1 overflow-y-auto p-2 min-h-0",children:b?r.jsx("div",{className:"flex justify-center py-8",children:r.jsx(pt,{className:"w-6 h-6 animate-spin text-bambu-green"})}):w.length===0?r.jsx("p",{className:"text-center text-bambu-gray py-8 text-sm",children:l("inventory.noSpoolsMatch")}):w.map(x=>r.jsxs("button",{onClick:()=>g.mutate(x.id),disabled:g.isPending||!p,className:"w-full flex items-center gap-3 p-3 rounded-lg hover:bg-white/5 transition-colors text-left",children:[r.jsx("span",{className:"w-6 h-6 rounded-full border border-black/20 flex-shrink-0",style:{backgroundColor:x.filament_color_hex?`#${x.filament_color_hex}`:"#808080"}}),r.jsxs("div",{className:"flex-1 min-w-0",children:[r.jsx("div",{className:"text-sm text-white font-medium truncate",children:x.filament_name||l("spoolman.spoolId")}),r.jsxs("div",{className:"text-xs text-bambu-gray truncate",children:[x.filament_vendor?`${x.filament_vendor} · `:"",x.filament_material||"Unknown"," · #",x.id]})]}),r.jsx("span",{className:"text-xs text-bambu-gray",children:x.remaining_weight!=null?`${Math.round(x.remaining_weight)}g`:"—"})]},x.id))}),r.jsx("div",{className:"p-4 border-t border-white/10 flex justify-end",children:r.jsx(Me,{variant:"ghost",onClick:e,children:l("inventory.cancel")||"Cancel"})})]})]}):null}function s7e(t,e){if(!e)return!0;const n=e.toLowerCase();return String(t.id).includes(n)||t.material.toLowerCase().includes(n)||(t.brand?.toLowerCase().includes(n)??!1)||(t.color_name?.toLowerCase().includes(n)??!1)||(t.subtype?.toLowerCase().includes(n)??!1)||(t.note?.toLowerCase().includes(n)??!1)||(t.slicer_filament_name?.toLowerCase().includes(n)??!1)||(t.storage_location?.toLowerCase().includes(n)??!1)}function aI(t,e){return e?t.filter(n=>s7e(n,e)):t}function Oie({isOpen:t,onClose:e,printerId:n,amsId:a,trayId:i,trayInfo:s,spoolmanEnabled:o}){const{t:l}=kt(),c=en(),{showToast:d}=rn(),[u,m]=y.useState(!1),[p,f]=y.useState(null),[b,w]=y.useState(null);y.useEffect(()=>{f(null),w(null)},[u]);const[g,x]=y.useState(""),[_,N]=y.useState(null),[C,P]=y.useState(!1),[T,A]=y.useState(null);y.useEffect(()=>{t&&m(!1)},[t]);const{data:F,isLoading:S}=Ve({queryKey:["inventory-spools","assign-modal"],queryFn:()=>se.getSpools(!0),enabled:t&&!o}),{data:E}=Ve({queryKey:["spool-assignments"],queryFn:()=>se.getAssignments(),enabled:t}),{data:U}=Ve({queryKey:["settings"],queryFn:()=>se.getSettings(),enabled:t}),{data:I,isLoading:H}=Ve({queryKey:["spoolman-inventory-spools","assign-modal"],queryFn:()=>se.getSpoolmanInventorySpools(!1),enabled:t&&!!o}),{data:R}=Ve({queryKey:["spoolman-slot-assignments-all"],queryFn:()=>se.getSpoolmanSlotAssignments(),enabled:t&&!!o}),Q=y.useMemo(()=>R?new Set(R.filter(W=>!(W.printer_id===n&&W.ams_id===a&&W.tray_id===i)).map(W=>W.spoolman_spool_id)):new Set,[R,n,a,i]),re=it({mutationFn:W=>se.assignSpool({spool_id:W,printer_id:n,ams_id:a,tray_id:i}),onSuccess:W=>{c.setQueryData(["spool-assignments"],D=>{const j=(D||[]).filter(B=>!(B.printer_id===n&&B.ams_id===a&&B.tray_id===i));return j.push(W),j}),c.invalidateQueries({queryKey:["spool-assignments"]}),d(l("inventory.assignSuccess"),"success"),P(!1),N(null),A(null),e()},onError:W=>{d(`${l("inventory.assignFailed")}: ${W.message}`,"error")}}),J=it({mutationFn:W=>se.assignSpoolmanSlot({spoolman_spool_id:W,printer_id:n,ams_id:a,tray_id:i}),onSuccess:()=>{c.invalidateQueries({queryKey:["spoolman-inventory-spools"]}),c.invalidateQueries({queryKey:["spoolman-slot-assignments"]}),d(l("inventory.assignSuccess"),"success"),e()},onError:W=>{d(`${l("inventory.assignFailed")}: ${W.message}`,"error")}}),de=W=>(W??"").trim().toUpperCase(),pe=(W,D)=>{const j=de(W),B=de(D);return!j||!B?"none":j===B?"exact":B.includes(j)||j.includes(B)?"partial":"none"},ue=W=>W.split("@")[0].trim(),X=(W,D)=>{const j=ue(de(W)),B=ue(de(D));return!j||!B?!1:j===B};if(!t)return null;const ae=new Set((E||[]).filter(W=>!(W.printer_id===n&&W.ams_id===a&&W.tray_id===i)).map(W=>W.spool_id)),me=F?.filter(W=>!W.archived_at&&(u||!ae.has(W.id)));let be=me;if(!u){const W=ue(de(s?.profile)),D=de(s?.material||s?.type);(W||D)&&(be=be?.filter(j=>{const B=ue(de(j.slicer_filament_name||j.slicer_filament)),Y=de(j.material);return W&&B&&B===W?!0:D&&Y?Y===D||D.includes(Y)||Y.includes(D):!B&&!Y}))}g&&be&&(be=aI(be,g));const Ce=()=>{if(b!==null){J.mutate(b);return}if(!p)return;const W=F?.find(D=>D.id===p);if(!W){d(l("inventory.assignFailed"),"error");return}if(!U?.disable_filament_warnings&&s){const D=s.material||s.type,j=pe(W.material,D),B=W.slicer_filament_name||W.slicer_filament,Y=s.profile||s.type,O=X(B,Y);if(j!=="exact"||!O){let ie="profile";j==="none"&&!O?ie="material_profile":j==="partial"&&!O?ie="partial_profile":j==="none"?ie="material":j==="partial"&&(ie="partial"),N(p),A({type:ie,spoolMaterial:W.material||"",trayMaterial:D||"",spoolProfile:B||void 0,trayProfile:Y||void 0}),P(!0);return}}re.mutate(p)},$=()=>{_&&(re.mutate(_),P(!1),N(null))};return r.jsxs(r.Fragment,{children:[r.jsxs("div",{className:"fixed inset-0 z-50 flex items-start sm:items-center justify-center p-4 overflow-y-auto",children:[r.jsx("div",{className:"absolute inset-0 bg-black/60 backdrop-blur-sm",onClick:e}),r.jsxs("div",{className:"relative w-full max-w-2xl bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-xl shadow-2xl max-h-[90vh] overflow-hidden flex flex-col my-auto",children:[r.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-bambu-dark-tertiary",children:[r.jsxs("div",{className:"flex items-center gap-2",children:[r.jsx(Br,{className:"w-5 h-5 text-bambu-green"}),r.jsx("h2",{className:"text-lg font-semibold text-white",children:l("inventory.assignSpool")})]}),r.jsx("button",{onClick:e,className:"p-1 text-bambu-gray hover:text-white rounded transition-colors",children:r.jsx(Ht,{className:"w-5 h-5"})})]}),r.jsxs("div",{className:"p-4 space-y-4 overflow-y-auto",children:[s&&r.jsxs("div",{className:"p-3 bg-bambu-dark rounded-lg border border-bambu-dark-tertiary",children:[r.jsxs("p",{className:"text-xs text-bambu-gray mb-1",children:[l("inventory.selectSpool"),":"]}),r.jsxs("div",{className:"flex items-center gap-2",children:[s.color&&r.jsx("span",{className:"w-4 h-4 rounded-full border border-black/20",style:{backgroundColor:`#${s.color}`}}),r.jsx("span",{className:"text-white font-medium",children:s.type||l("ams.emptySlot")}),r.jsxs("span",{className:"text-bambu-gray",children:["(",s.location,")"]})]})]}),r.jsxs("div",{className:"relative",children:[r.jsx(Sr,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-bambu-gray"}),r.jsx("input",{type:"text",value:g,onChange:W=>x(W.target.value),placeholder:l("inventory.searchSpools"),className:"w-full pl-9 pr-3 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white text-sm placeholder:text-bambu-gray focus:outline-none focus:border-bambu-green"})]}),r.jsxs("div",{className:"space-y-3",children:[!o&&(S?r.jsx("div",{className:"flex justify-center py-8",children:r.jsx(pt,{className:"w-6 h-6 text-bambu-green animate-spin"})}):be&&be.length>0?r.jsx("div",{className:"max-h-96 overflow-y-auto grid grid-cols-2 sm:grid-cols-3 gap-2",children:be.map(W=>r.jsxs("button",{onClick:()=>{f(W.id),w(null)},title:W.note||void 0,className:`p-2.5 rounded-lg border text-left transition-colors ${p===W.id?"bg-bambu-green/20 border-bambu-green":"bg-bambu-dark border-bambu-dark-tertiary hover:border-bambu-gray"}`,children:[r.jsxs("p",{className:"text-white text-sm font-medium truncate",children:[W.brand?`${W.brand} `:"",W.material,W.subtype?` ${W.subtype}`:""]}),r.jsxs("div",{className:"flex items-center gap-1.5 mt-1",children:[W.rgba&&r.jsx("span",{className:"w-3 h-3 rounded-full border border-black/20 flex-shrink-0",style:{backgroundColor:`#${W.rgba.substring(0,6)}`}}),r.jsx("span",{className:"text-xs text-bambu-gray truncate",children:W.color_name||""})]}),W.label_weight&&r.jsxs("p",{className:"text-xs text-bambu-gray mt-1",children:[Math.max(0,Math.round(W.label_weight-W.weight_used))," / ",W.label_weight,"g"]})]},W.id))}):me&&me.length===0?r.jsxs("div",{className:"text-center py-8 text-bambu-gray",children:[r.jsx("p",{children:l("inventory.noAvailableSpools")}),F&&r.jsxs("p",{className:"text-[10px] mt-2 opacity-60",children:[F.length," fetched · ",F.filter(W=>W.archived_at).length," archived ·"," ",F.filter(W=>ae.has(W.id)).length," assigned to other slots"]})]}):r.jsxs("div",{className:"text-center py-8 text-bambu-gray",children:[r.jsx("p",{children:l("inventory.noSpoolsMatch")}),me&&r.jsxs("p",{className:"text-[10px] mt-2 opacity-60",children:[me.length," unassigned spools — ",me.length-(be?.length??0),' filtered by tray match. Try "Show all spools".']})]})),o&&r.jsx(r.Fragment,{children:H?r.jsx("div",{className:"flex justify-center py-4",children:r.jsx(pt,{className:"w-5 h-5 text-bambu-green animate-spin"})}):I&&I.filter(W=>!W.archived_at&&!Q.has(W.id)).length>0?r.jsxs(r.Fragment,{children:[r.jsx("p",{className:"text-xs font-medium text-bambu-gray uppercase tracking-wide pt-1",children:l("inventory.spoolmanSpools")}),r.jsx("div",{className:"max-h-64 overflow-y-auto grid grid-cols-2 sm:grid-cols-3 gap-2",children:aI(I.filter(W=>!W.archived_at&&!Q.has(W.id)),g).map(W=>r.jsxs("button",{onClick:()=>{w(W.id),f(null)},title:W.note||void 0,className:`p-2.5 rounded-lg border text-left transition-colors ${b===W.id?"bg-bambu-green/20 border-bambu-green":"bg-bambu-dark border-bambu-dark-tertiary hover:border-bambu-gray"}`,children:[r.jsxs("p",{className:"text-white text-sm font-medium truncate",children:[W.brand?`${W.brand} `:"",W.material,W.subtype?` ${W.subtype}`:""]}),r.jsxs("div",{className:"flex items-center gap-1.5 mt-1",children:[W.rgba&&r.jsx("span",{className:"w-3 h-3 rounded-full border border-black/20 flex-shrink-0",style:{backgroundColor:`#${W.rgba.substring(0,6)}`}}),r.jsx("span",{className:"text-xs text-bambu-gray truncate",children:W.color_name||""})]}),W.label_weight&&r.jsxs("p",{className:"text-xs text-bambu-gray mt-1",children:[Math.max(0,Math.round(W.label_weight-W.weight_used))," / ",W.label_weight,"g"]})]},`spoolman-${W.id}`))})]}):null})]})]}),r.jsxs("div",{className:"flex justify-between items-center p-4 border-t border-bambu-dark-tertiary",children:[r.jsxs("div",{className:"flex items-center gap-2",children:[r.jsx("input",{id:"disable-filtering-toggle",type:"checkbox",checked:u,onChange:()=>m(W=>!W),className:"accent-bambu-green w-4 h-4 rounded focus:ring-0 border-bambu-dark-tertiary"}),r.jsx("label",{htmlFor:"disable-filtering-toggle",className:"text-xs text-bambu-gray select-none cursor-pointer",children:l("inventory.showAllSpools")})]}),r.jsxs("div",{className:"flex gap-2",children:[r.jsx(Me,{variant:"secondary",onClick:e,children:l("common.cancel")}),r.jsx(Me,{onClick:Ce,disabled:!p&&b===null||re.isPending||J.isPending,children:re.isPending||J.isPending?r.jsxs(r.Fragment,{children:[r.jsx(pt,{className:"w-4 h-4 animate-spin"}),l("inventory.assigning")]}):r.jsxs(r.Fragment,{children:[r.jsx(Br,{className:"w-4 h-4"}),l("inventory.assignSpool")]})})]})]}),re.isError&&r.jsx("div",{className:"mx-4 mb-4 p-2 bg-red-500/20 border border-red-500/50 rounded text-sm text-red-400",children:re.error.message})]})]}),C&&s&&p&&T&&(()=>{let W="";return T.type==="material"?W=l("inventory.assignMismatchMessage",{spoolMaterial:T.spoolMaterial,trayMaterial:T.trayMaterial,location:s.location}):T.type==="partial"?W=l("inventory.assignPartialMismatchMessage",{spoolMaterial:T.spoolMaterial,trayMaterial:T.trayMaterial,location:s.location}):T.type==="material_profile"?W=`${l("inventory.assignMismatchMessage",{spoolMaterial:T.spoolMaterial,trayMaterial:T.trayMaterial,location:s.location})} + `})]})]})}function Iie({isOpen:t,onClose:e,tagUid:n,trayUuid:a,printerId:i,amsId:s,trayId:o}){const{t:l}=kt(),c=en(),{showToast:d}=rn(),[u,m]=y.useState(""),p=a||n,{data:f,isLoading:b}=Ve({queryKey:["unlinked-spools"],queryFn:se.getUnlinkedSpools,enabled:t}),w=y.useMemo(()=>f?f.filter(x=>{if(!u)return!0;const _=u.toLowerCase();return x.filament_name&&x.filament_name.toLowerCase().includes(_)||x.filament_vendor&&x.filament_vendor.toLowerCase().includes(_)||x.filament_material&&x.filament_material.toLowerCase().includes(_)||String(x.id).includes(_)}):[],[f,u]),g=it({mutationFn:x=>se.linkSpool(x,{spoolTag:p,printerId:i,amsId:s,trayId:o}),onSuccess:()=>{c.invalidateQueries({queryKey:["unlinked-spools"]}),c.invalidateQueries({queryKey:["linked-spools"]}),c.invalidateQueries({queryKey:["spoolman-slot-assignments"]}),d(l("spoolman.linkSuccess"),"success"),e()},onError:x=>{d(x.message||l("spoolman.linkFailed"),"error")}});return t?r.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",children:[r.jsx("div",{className:"absolute inset-0 bg-black/60 backdrop-blur-sm",onClick:e}),r.jsxs("div",{className:"relative bg-bambu-dark-secondary rounded-xl shadow-xl w-full max-w-md mx-4 max-h-[80vh] flex flex-col border border-bambu-dark-tertiary",children:[r.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-white/10",children:[r.jsxs("div",{children:[r.jsxs("h3",{className:"text-lg font-semibold text-white flex items-center gap-2",children:[r.jsx(Wy,{className:"w-5 h-5 text-bambu-green"}),l("spoolman.selectSpool")]}),r.jsxs("p",{className:"text-xs text-bambu-gray mt-1",children:["AMS ",s," T",o," · Printer #",i]})]}),r.jsx("button",{onClick:e,className:"p-1 text-bambu-gray hover:text-white rounded transition-colors",children:r.jsx(Ht,{className:"w-5 h-5"})})]}),r.jsxs("div",{className:"p-4 border-b border-white/10",children:[r.jsxs("div",{className:"relative",children:[r.jsx(Sr,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-bambu-gray"}),r.jsx("input",{type:"text",value:u,onChange:x=>m(x.target.value),placeholder:l("inventory.searchSpools"),className:"w-full pl-9 pr-3 py-2 bg-bambu-dark rounded-lg border border-white/10 text-white text-sm placeholder:text-bambu-gray focus:outline-none focus:border-bambu-green"})]}),(a||n)&&r.jsxs("p",{className:"text-xs text-bambu-gray mt-2 font-mono truncate",title:a||n,children:["Tag: ",a||n]})]}),r.jsx("div",{className:"flex-1 overflow-y-auto p-2 min-h-0",children:b?r.jsx("div",{className:"flex justify-center py-8",children:r.jsx(pt,{className:"w-6 h-6 animate-spin text-bambu-green"})}):w.length===0?r.jsx("p",{className:"text-center text-bambu-gray py-8 text-sm",children:l("inventory.noSpoolsMatch")}):w.map(x=>r.jsxs("button",{onClick:()=>g.mutate(x.id),disabled:g.isPending||!p,className:"w-full flex items-center gap-3 p-3 rounded-lg hover:bg-white/5 transition-colors text-left",children:[r.jsx("span",{className:"w-6 h-6 rounded-full border border-black/20 flex-shrink-0",style:{backgroundColor:x.filament_color_hex?`#${x.filament_color_hex}`:"#808080"}}),r.jsxs("div",{className:"flex-1 min-w-0",children:[r.jsx("div",{className:"text-sm text-white font-medium truncate",children:x.filament_name||l("spoolman.spoolId")}),r.jsxs("div",{className:"text-xs text-bambu-gray truncate",children:[x.filament_vendor?`${x.filament_vendor} · `:"",x.filament_material||"Unknown"," · #",x.id]})]}),r.jsx("span",{className:"text-xs text-bambu-gray",children:x.remaining_weight!=null?`${Math.round(x.remaining_weight)}g`:"—"})]},x.id))}),r.jsx("div",{className:"p-4 border-t border-white/10 flex justify-end",children:r.jsx(Me,{variant:"ghost",onClick:e,children:l("inventory.cancel")||"Cancel"})})]})]}):null}function s7e(t,e){if(!e)return!0;const n=e.toLowerCase();return String(t.id).includes(n)||t.material.toLowerCase().includes(n)||(t.brand?.toLowerCase().includes(n)??!1)||(t.color_name?.toLowerCase().includes(n)??!1)||(t.subtype?.toLowerCase().includes(n)??!1)||(t.note?.toLowerCase().includes(n)??!1)||(t.slicer_filament_name?.toLowerCase().includes(n)??!1)||(t.storage_location?.toLowerCase().includes(n)??!1)}function aI(t,e){return e?t.filter(n=>s7e(n,e)):t}function Oie({isOpen:t,onClose:e,printerId:n,amsId:a,trayId:i,trayInfo:s,spoolmanEnabled:o}){const{t:l}=kt(),c=en(),{showToast:d}=rn(),[u,m]=y.useState(!1),[p,f]=y.useState(null),[b,w]=y.useState(null);y.useEffect(()=>{f(null),w(null)},[u]);const[g,x]=y.useState(""),[_,N]=y.useState(null),[C,P]=y.useState(!1),[T,A]=y.useState(null);y.useEffect(()=>{t&&m(!1)},[t]);const{data:F,isLoading:S}=Ve({queryKey:["inventory-spools","assign-modal"],queryFn:()=>se.getSpools(!0),enabled:t&&!o}),{data:E}=Ve({queryKey:["spool-assignments"],queryFn:()=>se.getAssignments(),enabled:t}),{data:U}=Ve({queryKey:["settings"],queryFn:()=>se.getSettings(),enabled:t}),{data:I,isLoading:H}=Ve({queryKey:["spoolman-inventory-spools","assign-modal"],queryFn:()=>se.getSpoolmanInventorySpools(!1),enabled:t&&!!o}),{data:R}=Ve({queryKey:["spoolman-slot-assignments-all"],queryFn:()=>se.getSpoolmanSlotAssignments(),enabled:t&&!!o}),Q=y.useMemo(()=>R?new Set(R.filter(W=>!(W.printer_id===n&&W.ams_id===a&&W.tray_id===i)).map(W=>W.spoolman_spool_id)):new Set,[R,n,a,i]),re=it({mutationFn:W=>se.assignSpool({spool_id:W,printer_id:n,ams_id:a,tray_id:i}),onSuccess:W=>{c.setQueryData(["spool-assignments"],D=>{const j=(D||[]).filter(B=>!(B.printer_id===n&&B.ams_id===a&&B.tray_id===i));return j.push(W),j}),c.invalidateQueries({queryKey:["spool-assignments"]}),d(l("inventory.assignSuccess"),"success"),P(!1),N(null),A(null),e()},onError:W=>{d(`${l("inventory.assignFailed")}: ${W.message}`,"error")}}),J=it({mutationFn:W=>se.assignSpoolmanSlot({spoolman_spool_id:W,printer_id:n,ams_id:a,tray_id:i}),onSuccess:()=>{c.invalidateQueries({queryKey:["spoolman-inventory-spools"]}),c.invalidateQueries({queryKey:["spoolman-slot-assignments"]}),d(l("inventory.assignSuccess"),"success"),e()},onError:W=>{d(`${l("inventory.assignFailed")}: ${W.message}`,"error")}}),de=W=>(W??"").trim().toUpperCase(),pe=(W,D)=>{const j=de(W),B=de(D);return!j||!B?"none":j===B?"exact":B.includes(j)||j.includes(B)?"partial":"none"},ue=W=>W.split("@")[0].trim(),X=(W,D)=>{const j=ue(de(W)),B=ue(de(D));return!j||!B?!1:j===B};if(!t)return null;const ae=new Set((E||[]).filter(W=>!(W.printer_id===n&&W.ams_id===a&&W.tray_id===i)).map(W=>W.spool_id)),me=F?.filter(W=>!W.archived_at&&(u||!ae.has(W.id)));let be=me;if(!u){const W=ue(de(s?.profile)),D=de(s?.material||s?.type);(W||D)&&(be=be?.filter(j=>{const B=ue(de(j.slicer_filament_name||j.slicer_filament)),Y=de(j.material);return W&&B&&B===W?!0:D&&Y?Y===D||D.includes(Y)||Y.includes(D):!B&&!Y}))}g&&be&&(be=aI(be,g));const Ce=()=>{if(b!==null){J.mutate(b);return}if(!p)return;const W=F?.find(D=>D.id===p);if(!W){d(l("inventory.assignFailed"),"error");return}if(!U?.disable_filament_warnings&&s){const D=s.material||s.type,j=pe(W.material,D),B=W.slicer_filament_name||W.slicer_filament,Y=s.profile||s.type,O=X(B,Y);if(j!=="exact"||!O){let ie="profile";j==="none"&&!O?ie="material_profile":j==="partial"&&!O?ie="partial_profile":j==="none"?ie="material":j==="partial"&&(ie="partial"),N(p),A({type:ie,spoolMaterial:W.material||"",trayMaterial:D||"",spoolProfile:B||void 0,trayProfile:Y||void 0}),P(!0);return}}re.mutate(p)},$=()=>{_&&(re.mutate(_),P(!1),N(null))};return r.jsxs(r.Fragment,{children:[r.jsxs("div",{className:"fixed inset-0 z-[100] flex items-start sm:items-center justify-center p-4 overflow-y-auto",children:[r.jsx("div",{className:"absolute inset-0 bg-black/60 backdrop-blur-sm",onClick:e}),r.jsxs("div",{className:"relative w-full max-w-2xl bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-xl shadow-2xl max-h-[90vh] overflow-hidden flex flex-col my-auto",children:[r.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-bambu-dark-tertiary",children:[r.jsxs("div",{className:"flex items-center gap-2",children:[r.jsx(Br,{className:"w-5 h-5 text-bambu-green"}),r.jsx("h2",{className:"text-lg font-semibold text-white",children:l("inventory.assignSpool")})]}),r.jsx("button",{onClick:e,className:"p-1 text-bambu-gray hover:text-white rounded transition-colors",children:r.jsx(Ht,{className:"w-5 h-5"})})]}),r.jsxs("div",{className:"p-4 space-y-4 overflow-y-auto",children:[s&&r.jsxs("div",{className:"p-3 bg-bambu-dark rounded-lg border border-bambu-dark-tertiary",children:[r.jsxs("p",{className:"text-xs text-bambu-gray mb-1",children:[l("inventory.selectSpool"),":"]}),r.jsxs("div",{className:"flex items-center gap-2",children:[s.color&&r.jsx("span",{className:"w-4 h-4 rounded-full border border-black/20",style:{backgroundColor:`#${s.color}`}}),r.jsx("span",{className:"text-white font-medium",children:s.type||l("ams.emptySlot")}),r.jsxs("span",{className:"text-bambu-gray",children:["(",s.location,")"]})]})]}),r.jsxs("div",{className:"relative",children:[r.jsx(Sr,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-bambu-gray"}),r.jsx("input",{type:"text",value:g,onChange:W=>x(W.target.value),placeholder:l("inventory.searchSpools"),className:"w-full pl-9 pr-3 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white text-sm placeholder:text-bambu-gray focus:outline-none focus:border-bambu-green"})]}),r.jsxs("div",{className:"space-y-3",children:[!o&&(S?r.jsx("div",{className:"flex justify-center py-8",children:r.jsx(pt,{className:"w-6 h-6 text-bambu-green animate-spin"})}):be&&be.length>0?r.jsx("div",{className:"max-h-96 overflow-y-auto grid grid-cols-2 sm:grid-cols-3 gap-2",children:be.map(W=>r.jsxs("button",{onClick:()=>{f(W.id),w(null)},title:W.note||void 0,className:`p-2.5 rounded-lg border text-left transition-colors ${p===W.id?"bg-bambu-green/20 border-bambu-green":"bg-bambu-dark border-bambu-dark-tertiary hover:border-bambu-gray"}`,children:[r.jsxs("p",{className:"text-white text-sm font-medium truncate",children:[W.brand?`${W.brand} `:"",W.material,W.subtype?` ${W.subtype}`:""]}),r.jsxs("div",{className:"flex items-center gap-1.5 mt-1",children:[W.rgba&&r.jsx("span",{className:"w-3 h-3 rounded-full border border-black/20 flex-shrink-0",style:{backgroundColor:`#${W.rgba.substring(0,6)}`}}),r.jsx("span",{className:"text-xs text-bambu-gray truncate",children:W.color_name||""})]}),W.label_weight&&r.jsxs("p",{className:"text-xs text-bambu-gray mt-1",children:[Math.max(0,Math.round(W.label_weight-W.weight_used))," / ",W.label_weight,"g"]})]},W.id))}):me&&me.length===0?r.jsxs("div",{className:"text-center py-8 text-bambu-gray",children:[r.jsx("p",{children:l("inventory.noAvailableSpools")}),F&&r.jsxs("p",{className:"text-[10px] mt-2 opacity-60",children:[F.length," fetched · ",F.filter(W=>W.archived_at).length," archived ·"," ",F.filter(W=>ae.has(W.id)).length," assigned to other slots"]})]}):r.jsxs("div",{className:"text-center py-8 text-bambu-gray",children:[r.jsx("p",{children:l("inventory.noSpoolsMatch")}),me&&r.jsxs("p",{className:"text-[10px] mt-2 opacity-60",children:[me.length," unassigned spools — ",me.length-(be?.length??0),' filtered by tray match. Try "Show all spools".']})]})),o&&r.jsx(r.Fragment,{children:H?r.jsx("div",{className:"flex justify-center py-4",children:r.jsx(pt,{className:"w-5 h-5 text-bambu-green animate-spin"})}):I&&I.filter(W=>!W.archived_at&&!Q.has(W.id)).length>0?r.jsxs(r.Fragment,{children:[r.jsx("p",{className:"text-xs font-medium text-bambu-gray uppercase tracking-wide pt-1",children:l("inventory.spoolmanSpools")}),r.jsx("div",{className:"max-h-64 overflow-y-auto grid grid-cols-2 sm:grid-cols-3 gap-2",children:aI(I.filter(W=>!W.archived_at&&!Q.has(W.id)),g).map(W=>r.jsxs("button",{onClick:()=>{w(W.id),f(null)},title:W.note||void 0,className:`p-2.5 rounded-lg border text-left transition-colors ${b===W.id?"bg-bambu-green/20 border-bambu-green":"bg-bambu-dark border-bambu-dark-tertiary hover:border-bambu-gray"}`,children:[r.jsxs("p",{className:"text-white text-sm font-medium truncate",children:[W.brand?`${W.brand} `:"",W.material,W.subtype?` ${W.subtype}`:""]}),r.jsxs("div",{className:"flex items-center gap-1.5 mt-1",children:[W.rgba&&r.jsx("span",{className:"w-3 h-3 rounded-full border border-black/20 flex-shrink-0",style:{backgroundColor:`#${W.rgba.substring(0,6)}`}}),r.jsx("span",{className:"text-xs text-bambu-gray truncate",children:W.color_name||""})]}),W.label_weight&&r.jsxs("p",{className:"text-xs text-bambu-gray mt-1",children:[Math.max(0,Math.round(W.label_weight-W.weight_used))," / ",W.label_weight,"g"]})]},`spoolman-${W.id}`))})]}):null})]})]}),r.jsxs("div",{className:"flex justify-between items-center p-4 border-t border-bambu-dark-tertiary",children:[r.jsxs("div",{className:"flex items-center gap-2",children:[r.jsx("input",{id:"disable-filtering-toggle",type:"checkbox",checked:u,onChange:()=>m(W=>!W),className:"accent-bambu-green w-4 h-4 rounded focus:ring-0 border-bambu-dark-tertiary"}),r.jsx("label",{htmlFor:"disable-filtering-toggle",className:"text-xs text-bambu-gray select-none cursor-pointer",children:l("inventory.showAllSpools")})]}),r.jsxs("div",{className:"flex gap-2",children:[r.jsx(Me,{variant:"secondary",onClick:e,children:l("common.cancel")}),r.jsx(Me,{onClick:Ce,disabled:!p&&b===null||re.isPending||J.isPending,children:re.isPending||J.isPending?r.jsxs(r.Fragment,{children:[r.jsx(pt,{className:"w-4 h-4 animate-spin"}),l("inventory.assigning")]}):r.jsxs(r.Fragment,{children:[r.jsx(Br,{className:"w-4 h-4"}),l("inventory.assignSpool")]})})]})]}),re.isError&&r.jsx("div",{className:"mx-4 mb-4 p-2 bg-red-500/20 border border-red-500/50 rounded text-sm text-red-400",children:re.error.message})]})]}),C&&s&&p&&T&&(()=>{let W="";return T.type==="material"?W=l("inventory.assignMismatchMessage",{spoolMaterial:T.spoolMaterial,trayMaterial:T.trayMaterial,location:s.location}):T.type==="partial"?W=l("inventory.assignPartialMismatchMessage",{spoolMaterial:T.spoolMaterial,trayMaterial:T.trayMaterial,location:s.location}):T.type==="material_profile"?W=`${l("inventory.assignMismatchMessage",{spoolMaterial:T.spoolMaterial,trayMaterial:T.trayMaterial,location:s.location})} ${l("inventory.assignProfileMismatchMessage",{spoolProfile:T.spoolProfile||l("common.unknown"),trayProfile:T.trayProfile||l("common.unknown"),location:s.location})}`:T.type==="partial_profile"?W=`${l("inventory.assignPartialMismatchMessage",{spoolMaterial:T.spoolMaterial,trayMaterial:T.trayMaterial,location:s.location})} diff --git a/static/index.html b/static/index.html index e8800202b..273dd8e43 100644 --- a/static/index.html +++ b/static/index.html @@ -26,7 +26,7 @@ - +