@dropins/storefront-quote-management 0.0.1-alpha29 → 0.0.1-alpha30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/api/graphql/NegotiableQuoteTemplateFragment.d.ts +1 -1
  2. package/api/sendForReview/index.d.ts +1 -1
  3. package/api/sendForReview/sendForReview.d.ts +3 -0
  4. package/api/sendQuoteTemplateForReview/sendQuoteTemplateForReview.d.ts +7 -0
  5. package/api.js +8 -56
  6. package/api.js.map +1 -1
  7. package/chunks/AttachedFilesList.js +4 -0
  8. package/chunks/AttachedFilesList.js.map +1 -0
  9. package/chunks/ChevronDown.js +1 -1
  10. package/chunks/ChevronDown.js.map +1 -1
  11. package/chunks/ConfirmationModal.js +1 -1
  12. package/chunks/ConfirmationModal.js.map +1 -1
  13. package/chunks/ItemsQuoted.js +1 -1
  14. package/chunks/ItemsQuoted.js.map +1 -1
  15. package/chunks/ItemsQuotedTemplate.js +1 -1
  16. package/chunks/ItemsQuotedTemplate.js.map +1 -1
  17. package/chunks/LineItemNoteModal.js +4 -0
  18. package/chunks/LineItemNoteModal.js.map +1 -0
  19. package/chunks/NegotiableQuoteTemplateFragment.js +6 -0
  20. package/chunks/NegotiableQuoteTemplateFragment.js.map +1 -1
  21. package/chunks/OrderSummaryLine.js +1 -1
  22. package/chunks/OrderSummaryLine.js.map +1 -1
  23. package/chunks/QuoteCommentsList.js +1 -1
  24. package/chunks/QuoteCommentsList.js.map +1 -1
  25. package/chunks/QuoteCommentsList3.js +1 -1
  26. package/chunks/QuoteCommentsList3.js.map +1 -1
  27. package/chunks/RenameQuoteModal.js +4 -0
  28. package/chunks/RenameQuoteModal.js.map +1 -0
  29. package/chunks/ShippingAddressDisplay.js +1 -1
  30. package/chunks/ShippingAddressDisplay.js.map +1 -1
  31. package/chunks/addQuoteTemplateLineItemNote.js +33 -0
  32. package/chunks/addQuoteTemplateLineItemNote.js.map +1 -0
  33. package/chunks/duplicateNegotiableQuote.js +8 -8
  34. package/chunks/duplicateNegotiableQuote.js.map +1 -1
  35. package/chunks/openQuoteTemplate.js +28 -8
  36. package/chunks/openQuoteTemplate.js.map +1 -1
  37. package/chunks/requestNegotiableQuote.js +25 -0
  38. package/chunks/requestNegotiableQuote.js.map +1 -0
  39. package/chunks/setLineItemNote.js +1 -1
  40. package/chunks/transform-quote-template.js +1 -1
  41. package/chunks/transform-quote-template.js.map +1 -1
  42. package/chunks/transform-quote.js +1 -1
  43. package/chunks/uploadFile.js +2 -23
  44. package/chunks/uploadFile.js.map +1 -1
  45. package/components/AttachedFilesList/AttachedFilesList.d.ts +16 -0
  46. package/components/AttachedFilesList/index.d.ts +11 -0
  47. package/components/LineItemNoteModal/LineItemNoteModal.d.ts +1 -0
  48. package/components/ManageNegotiableQuote/ManageNegotiableQuote.d.ts +2 -0
  49. package/components/ManageNegotiableQuoteTemplate/ManageNegotiableQuoteTemplate.d.ts +3 -2
  50. package/components/ProductListTable/ProductListTable.d.ts +1 -0
  51. package/components/QuoteCommentsList/QuoteCommentsList.d.ts +4 -0
  52. package/components/ReferenceDocumentFormModal/ReferenceDocumentFormModal.d.ts +30 -0
  53. package/components/ReferenceDocumentFormModal/index.d.ts +11 -0
  54. package/components/ReferenceDocumentsList/ReferenceDocumentsList.d.ts +18 -0
  55. package/components/ReferenceDocumentsList/index.d.ts +11 -0
  56. package/components/RequestNegotiableQuoteForm/RequestNegotiableQuoteForm.d.ts +1 -0
  57. package/components/index.d.ts +3 -0
  58. package/containers/ItemsQuoted.js +1 -1
  59. package/containers/ItemsQuotedTemplate/ItemsQuotedTemplate.d.ts +6 -0
  60. package/containers/ItemsQuotedTemplate.js +1 -1
  61. package/containers/ManageNegotiableQuote/ManageNegotiableQuote.d.ts +22 -0
  62. package/containers/ManageNegotiableQuote.js +1 -1
  63. package/containers/ManageNegotiableQuote.js.map +1 -1
  64. package/containers/ManageNegotiableQuoteTemplate/ManageNegotiableQuoteTemplate.d.ts +28 -5
  65. package/containers/ManageNegotiableQuoteTemplate.js +3 -1
  66. package/containers/ManageNegotiableQuoteTemplate.js.map +1 -1
  67. package/containers/OrderSummary.js +1 -1
  68. package/containers/OrderSummary.js.map +1 -1
  69. package/containers/OrderSummaryLine.js +1 -1
  70. package/containers/QuoteSummaryList.js +1 -1
  71. package/containers/QuoteSummaryList.js.map +1 -1
  72. package/containers/QuoteTemplatesListTable.js +1 -1
  73. package/containers/QuoteTemplatesListTable.js.map +1 -1
  74. package/containers/QuotesListTable.js +1 -1
  75. package/containers/QuotesListTable.js.map +1 -1
  76. package/containers/RequestNegotiableQuoteForm/RequestNegotiableQuoteForm.d.ts +10 -0
  77. package/containers/RequestNegotiableQuoteForm.js +1 -1
  78. package/containers/RequestNegotiableQuoteForm.js.map +1 -1
  79. package/containers/ShippingAddressDisplay/ShippingAddressDisplay.d.ts +2 -2
  80. package/data/models/negotiable-quote-template-model.d.ts +2 -0
  81. package/data/transforms/__fixtures__/negotiableQuoteTemplateData.d.ts +55 -0
  82. package/hooks/useItemsQuotedTemplate.d.ts +16 -0
  83. package/hooks/useReferenceDocumentLinks.d.ts +34 -0
  84. package/hooks/useRemoveTemplateItems.d.ts +25 -0
  85. package/hooks/useRenameTemplate.d.ts +71 -0
  86. package/hooks/useUpdateTemplateQuantities.d.ts +27 -0
  87. package/i18n/en_US.json.d.ts +102 -3
  88. package/package.json +1 -1
  89. package/render.js +5 -5
  90. package/render.js.map +1 -1
  91. package/utils/fileUtils.d.ts +46 -0
  92. package/chunks/QuotePricesSummary.js +0 -4
  93. package/chunks/QuotePricesSummary.js.map +0 -1
  94. package/chunks/TabbedContent.js +0 -4
  95. package/chunks/TabbedContent.js.map +0 -1
@@ -1,4 +1,4 @@
1
1
  /*! Copyright 2025 Adobe
2
2
  All Rights Reserved. */
3
- import{jsx as t,jsxs as v,Fragment as ue}from"@dropins/tools/preact-jsx-runtime.js";import{useState as u,useEffect as S,useCallback as P}from"@dropins/tools/preact-compat.js";import{classes as ve,Slot as ne}from"@dropins/tools/lib.js";import{events as G}from"@dropins/tools/event-bus.js";import{Price as w,Input as Qe,Modal as he,Table as Ie,TextArea as _e,Button as oe,InLineAlert as E}from"@dropins/tools/components.js";/* empty css */import{I as ie,Q as Le,P as Te}from"./QuotePricesSummary.js";import{C as se}from"./ConfirmationModal.js";/* empty css *//* empty css *//* empty css */import{useText as ce}from"@dropins/tools/i18n.js";import"./state.js";import{u as re,s as Be,r as ke}from"./setLineItemNote.js";import{S as le,a as J}from"./WarningFilled.js";const xe=({className:F,open:N,item:i,onClose:M,onConfirm:p,isSubmitting:d=!1,errorBanner:U,successBanner:n,showCloseButton:B=!0})=>{const[Q,h]=u(""),[c,_]=u(i.quantity),[b,y]=u({}),r=ce({title:"NegotiableQuote.Manage.lineItemNote.title",productLabel:"NegotiableQuote.Manage.lineItemNote.productLabel",skuLabel:"NegotiableQuote.Manage.lineItemNote.skuLabel",priceLabel:"NegotiableQuote.Manage.lineItemNote.priceLabel",stockLabel:"NegotiableQuote.Manage.lineItemNote.stockLabel",quantityLabel:"NegotiableQuote.Manage.lineItemNote.quantityLabel",discountLabel:"NegotiableQuote.Manage.lineItemNote.discountLabel",subtotalLabel:"NegotiableQuote.Manage.lineItemNote.subtotalLabel",noteLabel:"NegotiableQuote.Manage.lineItemNote.noteLabel",notePlaceholder:"NegotiableQuote.Manage.lineItemNote.notePlaceholder",noteHelper:"NegotiableQuote.Manage.lineItemNote.noteHelper",confirmButton:"NegotiableQuote.Manage.lineItemNote.confirmButton",cancelButton:"NegotiableQuote.Manage.lineItemNote.cancelButton",noteError:"NegotiableQuote.Manage.lineItemNote.noteError",quantityError:"NegotiableQuote.Manage.lineItemNote.quantityError"});S(()=>{var l;if(N){const g=((l=i.noteFromBuyer)==null?void 0:l.filter(H=>H&&H.note))||[],x=g.length>0?g[0].note:"";h(x||""),_(i.quantity),y({})}},[N,i.quantity,i.noteFromBuyer]);const C=P(()=>{const l={};if(Q.trim()||(l.note=r.noteError),c<=0&&(l.quantity=r.quantityError),Object.keys(l).length>0){y(l);return}p(Q.trim(),c)},[Q,c,p,r]),k=P(()=>{h(""),_(i.quantity),y({}),M==null||M()},[M,i.quantity]);if(!N)return null;const L=i.discounts&&i.discounts.length>0?i.discounts.map(l=>l.label).join(", "):"-",f=[{label:r.productLabel,key:"productName"},{label:r.priceLabel,key:"price"},{label:r.stockLabel,key:"stock"},{label:r.quantityLabel,key:"quantity"},{label:r.discountLabel,key:"discount"},{label:r.subtotalLabel,key:"subtotal"}],j=[{productName:v("div",{className:"quote-management-line-item-note-modal__product-info",children:[t("div",{className:"quote-management-line-item-note-modal__product-name",children:i.product.name}),v("div",{className:"quote-management-line-item-note-modal__product-sku",children:[r.skuLabel,": ",i.product.sku]})]}),price:t(w,{amount:i.prices.originalItemPrice.value,currency:i.prices.originalItemPrice.currency}),stock:t("span",{className:"quote-management-line-item-note-modal__stock",children:i.stockStatus}),quantity:t(Qe,{name:"quantity",type:"number",min:"1",value:c.toString(),onInput:l=>{const g=parseInt(l.target.value,10)||0;_(g),y({...b,quantity:void 0})},disabled:d,error:!!b.quantity,required:!0,"data-testid":"line-item-note-quantity-input",className:"quote-management-line-item-note-modal__quantity-input"}),discount:t("span",{className:"quote-management-line-item-note-modal__discount",children:L}),subtotal:t(w,{amount:i.prices.rowTotal.value,currency:i.prices.rowTotal.currency})}];return v(he,{open:N,size:"medium",title:t(ue,{children:r.title}),onClose:k,clickToDismiss:!0,escapeToDismiss:!0,showCloseButton:B,className:ve(["quote-management-line-item-note-modal",F]),"data-testid":"line-item-note-modal",children:[U&&t("div",{className:"quote-management-line-item-note-modal__error-banner","data-testid":"line-item-note-modal-error-banner",children:U}),n&&t("div",{className:"quote-management-line-item-note-modal__success-banner","data-testid":"line-item-note-modal-success-banner",children:n}),v("div",{className:"quote-management-line-item-note-modal__content",children:[v("div",{className:"quote-management-line-item-note-modal__details",children:[t(Ie,{columns:f,rowData:j,"data-testid":"line-item-note-table",mobileLayout:"stacked",className:"quote-management-line-item-note-modal__details-table"}),b.quantity&&t("div",{className:"quote-management-line-item-note-modal__table-error",children:b.quantity})]}),v("div",{className:"quote-management-line-item-note-modal__form-field",children:[t(_e,{name:"note",placeholder:r.notePlaceholder,rows:4,value:Q,onInput:l=>{h(l.target.value),y({...b,note:void 0})},label:r.noteLabel,disabled:d,"data-testid":"line-item-note-textarea"}),!b.note&&t("span",{className:"quote-management-line-item-note-modal__helper-text",children:r.noteHelper}),b.note&&t("span",{className:"quote-management-line-item-note-modal__error-text",children:b.note})]})]}),v("div",{className:"quote-management-line-item-note-modal__actions",children:[t(oe,{variant:"secondary",size:"medium",onClick:k,disabled:d,className:"quote-management-line-item-note-modal__cancel-button","data-testid":"line-item-note-cancel-button",children:r.cancelButton}),t(oe,{variant:"primary",size:"medium",onClick:C,disabled:d,className:"quote-management-line-item-note-modal__confirm-button","data-testid":"line-item-note-confirm-button",children:r.confirmButton})]})]})},Ee=3e3,Ge=({quoteData:F,onItemCheckboxChange:N,onItemDropdownChange:i,onRemoveItemsRef:M,onRemoveModalStateChange:p,slots:d,...U})=>{const[n,B]=u(F),[Q,h]=u({}),[c,_]=u(null),[b,y]=u(!1),[r,C]=u(!1),[k,D]=u(""),[L,f]=u({type:null,message:""}),[j,l]=u(!1),[g,x]=u([]),[H,A]=u(!1),[O,I]=u({type:null,message:""}),[K,q]=u({}),[me,z]=u(!1),s=ce({subtotal:"NegotiableQuote.Manage.quotePricesSummary.subtotal.excludingTax",grandTotal:"NegotiableQuote.Manage.quotePricesSummary.grandTotal.includingTax",appliedTaxes:"NegotiableQuote.Manage.quotePricesSummary.appliedTaxes",modalTitle:"NegotiableQuote.Manage.updateQuantitiesModal.title",modalDescription:"NegotiableQuote.Manage.updateQuantitiesModal.description",modalCancelButton:"NegotiableQuote.Manage.updateQuantitiesModal.cancelButton",modalUpdateButton:"NegotiableQuote.Manage.updateQuantitiesModal.updateButton",successHeading:"NegotiableQuote.Manage.updateQuantitiesModal.successHeading",successMessage:"NegotiableQuote.Manage.updateQuantitiesModal.successMessage",errorHeading:"NegotiableQuote.Manage.updateQuantitiesModal.errorHeading",errorMessage:"NegotiableQuote.Manage.updateQuantitiesModal.errorMessage",removeModalTitle:"NegotiableQuote.Manage.removeItemsModal.title",removeModalDescription:"NegotiableQuote.Manage.removeItemsModal.description",removeModalCancelButton:"NegotiableQuote.Manage.removeItemsModal.cancelButton",removeModalConfirmButton:"NegotiableQuote.Manage.removeItemsModal.confirmButton",removeModalConfirmButtonRemoving:"NegotiableQuote.Manage.removeItemsModal.confirmButtonRemoving",removeSuccessHeading:"NegotiableQuote.Manage.removeItemsModal.successHeading",removeSuccessMessage:"NegotiableQuote.Manage.removeItemsModal.successMessage",removeErrorHeading:"NegotiableQuote.Manage.removeItemsModal.errorHeading",removeErrorMessage:"NegotiableQuote.Manage.removeItemsModal.errorMessage"});S(()=>{const a=G.on("quote-management/quote-data",e=>{B(e.quote),h({}),f({type:null,message:""}),q({})},{eager:!0});return()=>a==null?void 0:a.off()},[]),S(()=>{const a=G.on("quote-management/quantities-updated",e=>{B(e.quote),h({}),f({type:"success",message:s.successMessage}),setTimeout(()=>{y(!1),f({type:null,message:""})},3e3)});return()=>a==null?void 0:a.off()},[s.successMessage]),S(()=>{const a=G.on("quote-management/quote-items-removed",e=>{B(e.quote),x([]),A(!1),I({type:"success",message:s.removeSuccessMessage}),setTimeout(()=>{l(!1),I({type:null,message:""}),p==null||p(!1)},Ee)});return()=>a==null?void 0:a.off()},[s.removeSuccessMessage,p]);const W=P(a=>{!a||a.length===0||(x(a),I({type:null,message:""}),l(!0))},[]);S(()=>{M==null||M(W)},[W,M]);const V=()=>{I({type:null,message:""})},X=(a,e)=>{const o=a;if(e==="edit"){_(o),C(!0),q(m=>({...m,[o.uid]:""}));return}if(e==="remove"){q(m=>({...m,[o.uid]:e})),W([o]),i==null||i(o,e),q(m=>({...m,[o.uid]:""}));return}e&&(i==null||i(o,e)),q(m=>{if(!(o.uid in m))return m;const T={...m};return delete T[o.uid],T})},de=async()=>{if(!n||g.length===0)return;const a=g.map(e=>e.uid);A(!0),I({type:null,message:""});try{await ke({quoteUid:n.uid,quoteItemUids:a})}catch(e){const o=e instanceof Error?e.message:s.removeErrorMessage;if(I({type:"error",message:o}),g.length===1){const m=g[0];q(T=>{if(!(m.uid in T))return T;const ae={...T};return delete ae[m.uid],ae})}A(!1)}},ge=()=>{if(l(!1),I({type:null,message:""}),p==null||p(!1),g.length===1){const a=g[0];q(e=>{if(!(a.uid in e))return e;const o={...e};return delete o[a.uid],o})}x([])},Y=P(()=>{c&&q(a=>{const e={...a};return delete e[c.uid],e}),C(!1),_(null),z(!1),D("")},[c]),pe=P(async(a,e)=>{if(!(!c||!n)){z(!0);try{e!==c.quantity&&await re({quoteUid:n.uid,items:[{quoteItemUid:c.uid,quantity:e}]}),await Be({quoteUid:n.uid,itemUid:c.uid,note:a,quantity:e}),Y()}catch(o){console.error("Failed to set line item note:",o);const m=o instanceof Error?o.message:"Unable to update the item. Please try again.";D(m),z(!1)}}},[c,n,Y]);if(!n)return t(ie,{loading:!0});const Z=!!n.canUpdateQuote,R=(a,e)=>{h(o=>({...o,[a.uid]:e}))},ee=a=>{a.preventDefault(),f({type:null,message:""}),y(!0)},be=async()=>{if(!n)return;if(Object.keys(Q).length===0){y(!1);return}f({type:null,message:""});const a=Object.entries(Q).map(([e,o])=>({quoteItemUid:e,quantity:o}));try{await re({quoteUid:n.uid,items:a})}catch(e){const o=e instanceof Error?e.message:s.errorMessage;f({type:"error",message:o}),console.error("Failed to update quantities:",e)}},ye=()=>{y(!1),f({type:null,message:""})},te=()=>{f({type:null,message:""})},$=[];n.prices.subtotalExcludingTax&&$.push({label:s.subtotal,id:"subtotal",value:t(w,{amount:n.prices.subtotalExcludingTax.value,currency:n.prices.subtotalExcludingTax.currency,weight:"normal"})}),n.prices.grandTotal&&$.push({label:s.grandTotal,id:"total",value:t(w,{amount:n.prices.grandTotal.value,currency:n.prices.grandTotal.currency}),strong:!0});const fe=L.type==="success"?t(E,{type:"success",variant:"primary",icon:t(le,{}),heading:s.successHeading,description:L.message,onDismiss:te,"data-testid":"update-quantities-success-banner"}):L.type==="error"?t(E,{type:"error",variant:"primary",icon:t(J,{}),heading:s.errorHeading,description:L.message,onDismiss:te,"data-testid":"update-quantities-error-banner"}):null,Me=N?(a,e)=>{N(a,e)}:void 0,Ne=O.type==="success"?t(E,{type:"success",variant:"primary",icon:t(le,{}),heading:s.removeSuccessHeading,description:O.message,onDismiss:V,"data-testid":"remove-items-success-banner"}):O.type==="error"?t(E,{type:"error",variant:"primary",icon:t(J,{}),heading:s.removeErrorHeading,description:O.message,onDismiss:V,"data-testid":"remove-items-error-banner"}):null,qe=k?t(E,{type:"error",variant:"primary",icon:t(J,{}),heading:s.errorHeading,description:k,onDismiss:()=>D(""),"data-testid":"line-item-note-error-banner"}):null;return v(ue,{children:[t(ie,{"data-testid":"items-quoted-container",...U,loading:!1,table:t(ne,{name:"ProductListTable",slot:d==null?void 0:d.ProductListTable,context:{items:n.items,canEdit:Z,readOnly:n.readOnly,onItemCheckboxChange:N,onItemDropdownChange:X,onQuantityChange:R,onUpdate:ee,dropdownSelections:K},children:t(Te,{items:n.items,canEdit:Z,onItemCheckboxChange:Me,readOnly:n.readOnly,onItemDropdownChange:X,onQuantityChange:R,onUpdate:ee,dropdownSelections:K})}),pricesSummary:t(ne,{name:"QuotePricesSummary",slot:d==null?void 0:d.QuotePricesSummary,context:{items:n.items,prices:n.prices},children:t(Le,{entries:$})})}),t(se,{open:b,title:s.modalTitle,message:s.modalDescription,cancelLabel:s.modalCancelButton,confirmLabel:s.modalUpdateButton,onCancel:ye,onConfirm:be,confirmationBanner:fe,"data-testid":"update-quantities-modal"}),t(se,{open:j,title:s.removeModalTitle,message:s.removeModalDescription,cancelLabel:s.removeModalCancelButton,confirmLabel:H?s.removeModalConfirmButtonRemoving:s.removeModalConfirmButton,onCancel:ge,onConfirm:de,confirmationBanner:Ne,"data-testid":"remove-items-modal"}),c&&t(xe,{open:r,item:c,onClose:Y,onConfirm:pe,isSubmitting:me,errorBanner:qe||void 0})]})};export{Ge as I};
3
+ import{jsx as n,jsxs as ye,Fragment as be}from"@dropins/tools/preact-jsx-runtime.js";import{useState as i,useEffect as T,useCallback as H}from"@dropins/tools/preact-compat.js";import{Slot as K}from"@dropins/tools/lib.js";import{events as P}from"@dropins/tools/event-bus.js";import{Price as V,InLineAlert as y}from"@dropins/tools/components.js";/* empty css */import{I as X,Q as Qe,P as ve,L as Ne}from"./LineItemNoteModal.js";import{C as Z}from"./ConfirmationModal.js";/* empty css *//* empty css */import"./state.js";import{u as R,s as Te,r as Ie}from"./setLineItemNote.js";import{S as ee,a as D}from"./WarningFilled.js";import{useText as he}from"@dropins/tools/i18n.js";const qe=3e3,ke=({quoteData:te,onItemCheckboxChange:I,onItemDropdownChange:g,onRemoveItemsRef:b,onRemoveModalStateChange:d,slots:p,...ae})=>{const[s,h]=i(te),[F,q]=i({}),[u,j]=i(null),[se,Q]=i(!1),[oe,A]=i(!1),[k,B]=i(""),[v,l]=i({type:null,message:""}),[ne,x]=i(!1),[f,S]=i([]),[re,C]=i(!1),[N,m]=i({type:null,message:""}),[_,c]=i({}),[ie,U]=i(!1),o=he({subtotal:"NegotiableQuote.Manage.quotePricesSummary.subtotal.excludingTax",grandTotal:"NegotiableQuote.Manage.quotePricesSummary.grandTotal.includingTax",appliedTaxes:"NegotiableQuote.Manage.quotePricesSummary.appliedTaxes",modalTitle:"NegotiableQuote.Manage.updateQuantitiesModal.title",modalDescription:"NegotiableQuote.Manage.updateQuantitiesModal.description",modalCancelButton:"NegotiableQuote.Manage.updateQuantitiesModal.cancelButton",modalUpdateButton:"NegotiableQuote.Manage.updateQuantitiesModal.updateButton",successHeading:"NegotiableQuote.Manage.updateQuantitiesModal.successHeading",successMessage:"NegotiableQuote.Manage.updateQuantitiesModal.successMessage",errorHeading:"NegotiableQuote.Manage.updateQuantitiesModal.errorHeading",errorMessage:"NegotiableQuote.Manage.updateQuantitiesModal.errorMessage",removeModalTitle:"NegotiableQuote.Manage.removeItemsModal.title",removeModalDescription:"NegotiableQuote.Manage.removeItemsModal.description",removeModalCancelButton:"NegotiableQuote.Manage.removeItemsModal.cancelButton",removeModalConfirmButton:"NegotiableQuote.Manage.removeItemsModal.confirmButton",removeModalConfirmButtonRemoving:"NegotiableQuote.Manage.removeItemsModal.confirmButtonRemoving",removeSuccessHeading:"NegotiableQuote.Manage.removeItemsModal.successHeading",removeSuccessMessage:"NegotiableQuote.Manage.removeItemsModal.successMessage",removeErrorHeading:"NegotiableQuote.Manage.removeItemsModal.errorHeading",removeErrorMessage:"NegotiableQuote.Manage.removeItemsModal.errorMessage"});T(()=>{const t=P.on("quote-management/quote-data",e=>{h(e.quote),q({}),l({type:null,message:""}),c({})},{eager:!0});return()=>t==null?void 0:t.off()},[]),T(()=>{const t=P.on("quote-management/quantities-updated",e=>{h(e.quote),q({}),l({type:"success",message:o.successMessage}),setTimeout(()=>{Q(!1),l({type:null,message:""})},3e3)});return()=>t==null?void 0:t.off()},[o.successMessage]),T(()=>{const t=P.on("quote-management/quote-items-removed",e=>{h(e.quote),S([]),C(!1),m({type:"success",message:o.removeSuccessMessage}),setTimeout(()=>{x(!1),m({type:null,message:""}),d==null||d(!1)},qe)});return()=>t==null?void 0:t.off()},[o.removeSuccessMessage,d]);const O=H(t=>{!t||t.length===0||(S(t),m({type:null,message:""}),x(!0))},[]);T(()=>{b==null||b(O)},[O,b]);const W=()=>{m({type:null,message:""})},w=(t,e)=>{const a=t;if(e==="edit"){j(a),A(!0),c(r=>({...r,[a.uid]:""}));return}if(e==="remove"){c(r=>({...r,[a.uid]:e})),O([a]),g==null||g(a,e),c(r=>({...r,[a.uid]:""}));return}e&&(g==null||g(a,e)),c(r=>{if(!(a.uid in r))return r;const M={...r};return delete M[a.uid],M})},ue=async()=>{if(!s||f.length===0)return;const t=f.map(e=>e.uid);C(!0),m({type:null,message:""});try{await Ie({quoteUid:s.uid,quoteItemUids:t})}catch(e){const a=e instanceof Error?e.message:o.removeErrorMessage;if(m({type:"error",message:a}),f.length===1){const r=f[0];c(M=>{if(!(r.uid in M))return M;const J={...M};return delete J[r.uid],J})}C(!1)}},le=()=>{if(x(!1),m({type:null,message:""}),d==null||d(!1),f.length===1){const t=f[0];c(e=>{if(!(t.uid in e))return e;const a={...e};return delete a[t.uid],a})}S([])},E=H(()=>{u&&c(t=>{const e={...t};return delete e[u.uid],e}),A(!1),j(null),U(!1),B("")},[u]),ce=H(async(t,e)=>{if(!(!u||!s)){U(!0);try{e!==u.quantity&&await R({quoteUid:s.uid,items:[{quoteItemUid:u.uid,quantity:e}]}),await Te({quoteUid:s.uid,itemUid:u.uid,note:t,quantity:e}),E()}catch(a){console.error("Failed to set line item note:",a);const r=a instanceof Error?a.message:"Unable to update the item. Please try again.";B(r),U(!1)}}},[u,s,E]);if(!s)return n(X,{loading:!0});const Y=!!s.canUpdateQuote,$=(t,e)=>{q(a=>({...a,[t.uid]:e}))},z=t=>{t.preventDefault(),l({type:null,message:""}),Q(!0)},de=async()=>{if(!s)return;if(Object.keys(F).length===0){Q(!1);return}l({type:null,message:""});const t=Object.entries(F).map(([e,a])=>({quoteItemUid:e,quantity:a}));try{await R({quoteUid:s.uid,items:t})}catch(e){const a=e instanceof Error?e.message:o.errorMessage;l({type:"error",message:a}),console.error("Failed to update quantities:",e)}},me=()=>{Q(!1),l({type:null,message:""})},G=()=>{l({type:null,message:""})},L=[];s.prices.subtotalExcludingTax&&L.push({label:o.subtotal,id:"subtotal",value:n(V,{amount:s.prices.subtotalExcludingTax.value,currency:s.prices.subtotalExcludingTax.currency,weight:"normal"})}),s.prices.grandTotal&&L.push({label:o.grandTotal,id:"total",value:n(V,{amount:s.prices.grandTotal.value,currency:s.prices.grandTotal.currency}),strong:!0});const ge=v.type==="success"?n(y,{type:"success",variant:"primary",icon:n(ee,{}),heading:o.successHeading,description:v.message,onDismiss:G,"data-testid":"update-quantities-success-banner"}):v.type==="error"?n(y,{type:"error",variant:"primary",icon:n(D,{}),heading:o.errorHeading,description:v.message,onDismiss:G,"data-testid":"update-quantities-error-banner"}):null,pe=I?(t,e)=>{I(t,e)}:void 0,fe=N.type==="success"?n(y,{type:"success",variant:"primary",icon:n(ee,{}),heading:o.removeSuccessHeading,description:N.message,onDismiss:W,"data-testid":"remove-items-success-banner"}):N.type==="error"?n(y,{type:"error",variant:"primary",icon:n(D,{}),heading:o.removeErrorHeading,description:N.message,onDismiss:W,"data-testid":"remove-items-error-banner"}):null,Me=k?n(y,{type:"error",variant:"primary",icon:n(D,{}),heading:o.errorHeading,description:k,onDismiss:()=>B(""),"data-testid":"line-item-note-error-banner"}):null;return ye(be,{children:[n(X,{"data-testid":"items-quoted-container",...ae,loading:!1,table:n(K,{name:"ProductListTable",slot:p==null?void 0:p.ProductListTable,context:{items:s.items,canEdit:Y,readOnly:s.readOnly,onItemCheckboxChange:I,onItemDropdownChange:w,onQuantityChange:$,onUpdate:z,dropdownSelections:_},children:n(ve,{items:s.items,canEdit:Y,onItemCheckboxChange:pe,readOnly:s.readOnly,onItemDropdownChange:w,onQuantityChange:$,onUpdate:z,dropdownSelections:_})}),pricesSummary:n(K,{name:"QuotePricesSummary",slot:p==null?void 0:p.QuotePricesSummary,context:{items:s.items,prices:s.prices},children:n(Qe,{entries:L})})}),n(Z,{open:se,title:o.modalTitle,message:o.modalDescription,cancelLabel:o.modalCancelButton,confirmLabel:o.modalUpdateButton,onCancel:me,onConfirm:de,confirmationBanner:ge,"data-testid":"update-quantities-modal"}),n(Z,{open:ne,title:o.removeModalTitle,message:o.removeModalDescription,cancelLabel:o.removeModalCancelButton,confirmLabel:re?o.removeModalConfirmButtonRemoving:o.removeModalConfirmButton,onCancel:le,onConfirm:ue,confirmationBanner:fe,"data-testid":"remove-items-modal"}),u&&n(Ne,{open:oe,item:u,onClose:E,onConfirm:ce,isSubmitting:ie,errorBanner:Me||void 0})]})};export{ke as I};
4
4
  //# sourceMappingURL=ItemsQuoted.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ItemsQuoted.js","sources":["/@dropins/storefront-quote-management/src/components/LineItemNoteModal/LineItemNoteModal.tsx","/@dropins/storefront-quote-management/src/containers/ItemsQuoted/ItemsQuoted.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { FunctionComponent, VNode } from 'preact';\nimport {\n HTMLAttributes,\n useCallback,\n useEffect,\n useState,\n} from 'preact/compat';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport {\n Button,\n TextArea,\n Input,\n Modal,\n Price,\n Table,\n} from '@adobe-commerce/elsie/components';\nimport { NegotiableQuoteCartItem } from '@/quote-management/data/models/negotiable-quote-model';\nimport '@/quote-management/components/LineItemNoteModal/LineItemNoteModal.css';\n\nexport interface LineItemNoteModalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n open: boolean;\n item: NegotiableQuoteCartItem;\n onClose?: () => void;\n onConfirm: (note: string, quantity: number) => void;\n isSubmitting?: boolean;\n errorBanner?: VNode;\n successBanner?: VNode;\n showCloseButton?: boolean;\n}\n\nexport const LineItemNoteModal: FunctionComponent<LineItemNoteModalProps> = ({\n className,\n open,\n item,\n onClose,\n onConfirm,\n isSubmitting = false,\n errorBanner,\n successBanner,\n showCloseButton = true,\n}) => {\n const [note, setNote] = useState('');\n const [quantity, setQuantity] = useState(item.quantity);\n const [errors, setErrors] = useState<{ note?: string; quantity?: string }>(\n {}\n );\n\n const dictionary = useText({\n title: 'NegotiableQuote.Manage.lineItemNote.title',\n productLabel: 'NegotiableQuote.Manage.lineItemNote.productLabel',\n skuLabel: 'NegotiableQuote.Manage.lineItemNote.skuLabel',\n priceLabel: 'NegotiableQuote.Manage.lineItemNote.priceLabel',\n stockLabel: 'NegotiableQuote.Manage.lineItemNote.stockLabel',\n quantityLabel: 'NegotiableQuote.Manage.lineItemNote.quantityLabel',\n discountLabel: 'NegotiableQuote.Manage.lineItemNote.discountLabel',\n subtotalLabel: 'NegotiableQuote.Manage.lineItemNote.subtotalLabel',\n noteLabel: 'NegotiableQuote.Manage.lineItemNote.noteLabel',\n notePlaceholder: 'NegotiableQuote.Manage.lineItemNote.notePlaceholder',\n noteHelper: 'NegotiableQuote.Manage.lineItemNote.noteHelper',\n confirmButton: 'NegotiableQuote.Manage.lineItemNote.confirmButton',\n cancelButton: 'NegotiableQuote.Manage.lineItemNote.cancelButton',\n noteError: 'NegotiableQuote.Manage.lineItemNote.noteError',\n quantityError: 'NegotiableQuote.Manage.lineItemNote.quantityError',\n });\n\n // Reset form when modal opens with new item\n useEffect(() => {\n if (open) {\n // Get the most recent valid note from buyer (if exists)\n const validNotes =\n item.noteFromBuyer?.filter((note) => note && note.note) || [];\n const existingNote = validNotes.length > 0 ? validNotes[0].note : '';\n setNote(existingNote || '');\n setQuantity(item.quantity);\n setErrors({});\n }\n }, [open, item.quantity, item.noteFromBuyer]);\n\n const handleConfirm = useCallback(() => {\n const newErrors: { note?: string; quantity?: string } = {};\n\n // Check if the note field is empty\n if (!note.trim()) {\n newErrors.note = dictionary.noteError;\n }\n\n if (quantity <= 0) {\n newErrors.quantity = dictionary.quantityError;\n }\n\n if (Object.keys(newErrors).length > 0) {\n setErrors(newErrors);\n return;\n }\n\n onConfirm(note.trim(), quantity);\n }, [note, quantity, onConfirm, dictionary]);\n\n const handleCancel = useCallback(() => {\n setNote('');\n setQuantity(item.quantity);\n setErrors({});\n onClose?.();\n }, [onClose, item.quantity]);\n\n if (!open) {\n return null;\n }\n\n // Calculate discount display\n const hasDiscount = item.discounts && item.discounts.length > 0;\n const discountDisplay = hasDiscount\n ? item.discounts.map((d) => d.label).join(', ')\n : '-';\n\n // Define table columns\n const columns = [\n {\n label: dictionary.productLabel,\n key: 'productName',\n },\n {\n label: dictionary.priceLabel,\n key: 'price',\n },\n {\n label: dictionary.stockLabel,\n key: 'stock',\n },\n {\n label: dictionary.quantityLabel,\n key: 'quantity',\n },\n {\n label: dictionary.discountLabel,\n key: 'discount',\n },\n {\n label: dictionary.subtotalLabel,\n key: 'subtotal',\n },\n ];\n\n // Define table row data\n const rowData = [\n {\n productName: (\n <div className=\"quote-management-line-item-note-modal__product-info\">\n <div className=\"quote-management-line-item-note-modal__product-name\">\n {item.product.name}\n </div>\n <div className=\"quote-management-line-item-note-modal__product-sku\">\n {dictionary.skuLabel}: {item.product.sku}\n </div>\n </div>\n ),\n price: (\n <Price\n amount={item.prices.originalItemPrice.value}\n currency={item.prices.originalItemPrice.currency}\n />\n ),\n stock: (\n <span className=\"quote-management-line-item-note-modal__stock\">\n {item.stockStatus}\n </span>\n ),\n quantity: (\n <Input\n name=\"quantity\"\n type=\"number\"\n min=\"1\"\n value={quantity.toString()}\n onInput={(e: any) => {\n const newQuantity = parseInt(e.target.value, 10) || 0;\n setQuantity(newQuantity);\n setErrors({ ...errors, quantity: undefined });\n }}\n disabled={isSubmitting}\n error={!!errors.quantity}\n required\n data-testid=\"line-item-note-quantity-input\"\n className=\"quote-management-line-item-note-modal__quantity-input\"\n />\n ),\n discount: (\n <span className=\"quote-management-line-item-note-modal__discount\">\n {discountDisplay}\n </span>\n ),\n subtotal: (\n <Price\n amount={item.prices.rowTotal.value}\n currency={item.prices.rowTotal.currency}\n />\n ),\n },\n ];\n\n return (\n <Modal\n open={open}\n size=\"medium\"\n title={<>{dictionary.title}</>}\n onClose={handleCancel}\n clickToDismiss={true}\n escapeToDismiss={true}\n showCloseButton={showCloseButton}\n className={classes(['quote-management-line-item-note-modal', className])}\n data-testid=\"line-item-note-modal\"\n >\n {errorBanner && (\n <div\n className=\"quote-management-line-item-note-modal__error-banner\"\n data-testid=\"line-item-note-modal-error-banner\"\n >\n {errorBanner}\n </div>\n )}\n\n {successBanner && (\n <div\n className=\"quote-management-line-item-note-modal__success-banner\"\n data-testid=\"line-item-note-modal-success-banner\"\n >\n {successBanner}\n </div>\n )}\n\n <div className=\"quote-management-line-item-note-modal__content\">\n {/* Product Details Table */}\n <div className=\"quote-management-line-item-note-modal__details\">\n <Table\n columns={columns}\n rowData={rowData}\n data-testid=\"line-item-note-table\"\n mobileLayout=\"stacked\"\n className=\"quote-management-line-item-note-modal__details-table\"\n />\n {errors.quantity && (\n <div className=\"quote-management-line-item-note-modal__table-error\">\n {errors.quantity}\n </div>\n )}\n </div>\n\n {/* Note TextArea */}\n <div className=\"quote-management-line-item-note-modal__form-field\">\n <TextArea\n name=\"note\"\n placeholder={dictionary.notePlaceholder}\n rows={4}\n value={note}\n onInput={(e: any) => {\n setNote(e.target.value);\n setErrors({ ...errors, note: undefined });\n }}\n label={dictionary.noteLabel}\n disabled={isSubmitting}\n data-testid=\"line-item-note-textarea\"\n />\n {!errors.note && (\n <span className=\"quote-management-line-item-note-modal__helper-text\">\n {dictionary.noteHelper}\n </span>\n )}\n {errors.note && (\n <span className=\"quote-management-line-item-note-modal__error-text\">\n {errors.note}\n </span>\n )}\n </div>\n </div>\n\n <div className=\"quote-management-line-item-note-modal__actions\">\n <Button\n variant=\"secondary\"\n size=\"medium\"\n onClick={handleCancel}\n disabled={isSubmitting}\n className=\"quote-management-line-item-note-modal__cancel-button\"\n data-testid=\"line-item-note-cancel-button\"\n >\n {dictionary.cancelButton}\n </Button>\n <Button\n variant=\"primary\"\n size=\"medium\"\n onClick={handleConfirm}\n disabled={isSubmitting}\n className=\"quote-management-line-item-note-modal__confirm-button\"\n data-testid=\"line-item-note-confirm-button\"\n >\n {dictionary.confirmButton}\n </Button>\n </div>\n </Modal>\n );\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport {\n HTMLAttributes,\n useCallback,\n useEffect,\n useState,\n} from 'preact/compat';\nimport { Container, Slot, SlotProps } from '@adobe-commerce/elsie/lib';\nimport { events } from '@adobe-commerce/event-bus';\nimport { Price, InLineAlert } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport {\n NegotiableQuoteModel,\n NegotiableQuoteCartItem,\n} from '@/quote-management/data/models/negotiable-quote-model';\nimport {\n ProductListTable,\n ProductListTableItem,\n QuotePricesSummary,\n ItemsQuoted as ItemsQuotedComponent,\n} from '@/quote-management/components';\nimport { CheckWithCircle, WarningFilled } from '@adobe-commerce/elsie/icons';\nimport { ConfirmationModal } from '@/quote-management/components/ConfirmationModal';\nimport { LineItemNoteModal } from '@/quote-management/components/LineItemNoteModal';\nimport { updateQuantities, setLineItemNote } from '@/quote-management/api';\nimport { removeNegotiableQuoteItems } from '@/quote-management/api/removeNegotiableQuoteItems';\n\nconst NOTIFICATION_AUTO_DISMISS_DELAY = 3000;\n\nexport interface ItemsQuotedProps extends HTMLAttributes<HTMLDivElement> {\n quoteData?: NegotiableQuoteModel;\n onItemCheckboxChange?: (\n item: NegotiableQuoteCartItem,\n isSelected: boolean\n ) => void;\n onItemDropdownChange?: (\n item: NegotiableQuoteCartItem,\n action: string\n ) => void;\n onUpdate?: (e: SubmitEvent) => void;\n onRemoveItemsRef?: (\n handler: (items: NegotiableQuoteCartItem[]) => void\n ) => void;\n onRemoveModalStateChange?: (isOpen: boolean) => void;\n slots?: {\n ProductListTable?: SlotProps<{\n items: NegotiableQuoteModel['items'];\n canEdit: boolean;\n readOnly?: boolean;\n onItemCheckboxChange?: (\n item: NegotiableQuoteCartItem,\n isSelected: boolean\n ) => void;\n onItemDropdownChange?: (\n item: NegotiableQuoteCartItem,\n action: string\n ) => void;\n onQuantityChange?: (\n item: NegotiableQuoteCartItem,\n newQuantity: number\n ) => void;\n onUpdate?: (e: SubmitEvent) => void;\n dropdownSelections?: Record<string, string | undefined>;\n }>;\n QuotePricesSummary?: SlotProps<{\n items: NegotiableQuoteModel['items'];\n prices: NegotiableQuoteModel['prices'];\n }>;\n };\n}\n\nexport const ItemsQuoted: Container<ItemsQuotedProps> = ({\n quoteData: initialData,\n onItemCheckboxChange,\n onItemDropdownChange,\n onRemoveItemsRef,\n onRemoveModalStateChange,\n slots,\n ...props\n}) => {\n const [quoteData, setQuoteData] = useState<NegotiableQuoteModel | undefined>(\n initialData\n );\n const [quantityChanges, setQuantityChanges] = useState<{\n [itemUid: string]: number;\n }>({});\n const [selectedItem, setSelectedItem] =\n useState<NegotiableQuoteCartItem | null>(null);\n const [isUpdateQuantitiesModalOpen, setIsUpdateQuantitiesModalOpen] =\n useState(false);\n const [isLineItemNoteModalOpen, setIsLineItemNoteModalOpen] = useState(false);\n const [modalErrorMessage, setModalErrorMessage] = useState('');\n const [notificationState, setNotificationState] = useState<{\n type: 'success' | 'error' | null;\n message: string;\n }>({ type: null, message: '' });\n // State for remove items functionality\n const [isRemoveModalOpen, setIsRemoveModalOpen] = useState(false);\n const [itemsToRemove, setItemsToRemove] = useState<NegotiableQuoteCartItem[]>(\n []\n );\n const [isRemoving, setIsRemoving] = useState(false);\n const [removeNotificationState, setRemoveNotificationState] = useState<{\n type: 'success' | 'error' | null;\n message: string;\n }>({ type: null, message: '' });\n const [dropdownSelections, setDropdownSelections] = useState<\n Record<string, string>\n >({});\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const dictionary = useText({\n subtotal: 'NegotiableQuote.Manage.quotePricesSummary.subtotal.excludingTax',\n grandTotal:\n 'NegotiableQuote.Manage.quotePricesSummary.grandTotal.includingTax',\n appliedTaxes: 'NegotiableQuote.Manage.quotePricesSummary.appliedTaxes',\n modalTitle: 'NegotiableQuote.Manage.updateQuantitiesModal.title',\n modalDescription:\n 'NegotiableQuote.Manage.updateQuantitiesModal.description',\n modalCancelButton:\n 'NegotiableQuote.Manage.updateQuantitiesModal.cancelButton',\n modalUpdateButton:\n 'NegotiableQuote.Manage.updateQuantitiesModal.updateButton',\n successHeading:\n 'NegotiableQuote.Manage.updateQuantitiesModal.successHeading',\n successMessage:\n 'NegotiableQuote.Manage.updateQuantitiesModal.successMessage',\n errorHeading: 'NegotiableQuote.Manage.updateQuantitiesModal.errorHeading',\n errorMessage: 'NegotiableQuote.Manage.updateQuantitiesModal.errorMessage',\n removeModalTitle: 'NegotiableQuote.Manage.removeItemsModal.title',\n removeModalDescription:\n 'NegotiableQuote.Manage.removeItemsModal.description',\n removeModalCancelButton:\n 'NegotiableQuote.Manage.removeItemsModal.cancelButton',\n removeModalConfirmButton:\n 'NegotiableQuote.Manage.removeItemsModal.confirmButton',\n removeModalConfirmButtonRemoving:\n 'NegotiableQuote.Manage.removeItemsModal.confirmButtonRemoving',\n removeSuccessHeading:\n 'NegotiableQuote.Manage.removeItemsModal.successHeading',\n removeSuccessMessage:\n 'NegotiableQuote.Manage.removeItemsModal.successMessage',\n removeErrorHeading: 'NegotiableQuote.Manage.removeItemsModal.errorHeading',\n removeErrorMessage: 'NegotiableQuote.Manage.removeItemsModal.errorMessage',\n });\n\n useEffect(() => {\n const quoteDataEvent = events.on(\n 'quote-management/quote-data',\n\n (data: { quote: NegotiableQuoteModel }) => {\n setQuoteData(data.quote);\n setQuantityChanges({});\n setNotificationState({ type: null, message: '' });\n setDropdownSelections({});\n },\n\n {\n eager: true,\n }\n );\n return () => quoteDataEvent?.off();\n }, []);\n\n useEffect(() => {\n const quantitiesUpdatedEvent = events.on(\n 'quote-management/quantities-updated',\n (data: { quote: NegotiableQuoteModel }) => {\n setQuoteData(data.quote);\n setQuantityChanges({});\n setNotificationState({\n type: 'success',\n message: dictionary.successMessage,\n });\n // Auto-close success notification after 3 seconds\n setTimeout(() => {\n setIsUpdateQuantitiesModalOpen(false);\n setNotificationState({ type: null, message: '' });\n }, 3000);\n }\n );\n return () => quantitiesUpdatedEvent?.off();\n }, [dictionary.successMessage]);\n\n // Listen for quote items removed event\n useEffect(() => {\n const itemsRemovedEvent = events.on(\n 'quote-management/quote-items-removed',\n (data: { quote: NegotiableQuoteModel }) => {\n setQuoteData(data.quote);\n setItemsToRemove([]);\n setIsRemoving(false);\n setRemoveNotificationState({\n type: 'success',\n message: dictionary.removeSuccessMessage,\n });\n // Auto-close success notification after 3 seconds\n setTimeout(() => {\n setIsRemoveModalOpen(false);\n setRemoveNotificationState({ type: null, message: '' });\n onRemoveModalStateChange?.(false);\n }, NOTIFICATION_AUTO_DISMISS_DELAY);\n }\n );\n return () => itemsRemovedEvent?.off();\n }, [dictionary.removeSuccessMessage, onRemoveModalStateChange]);\n\n // Unified handler for removing items (single or multiple)\n const handleRemoveItems = useCallback((items: NegotiableQuoteCartItem[]) => {\n if (!items || items.length === 0) {\n return;\n }\n setItemsToRemove(items);\n setRemoveNotificationState({ type: null, message: '' });\n setIsRemoveModalOpen(true);\n }, []);\n\n // Expose handler to parent component\n useEffect(() => {\n onRemoveItemsRef?.(handleRemoveItems);\n }, [handleRemoveItems, onRemoveItemsRef]);\n\n const handleDismissRemoveBanner = () => {\n setRemoveNotificationState({ type: null, message: '' });\n };\n\n const handleItemDropdownChange = (\n item: ProductListTableItem,\n action: string\n ) => {\n const cartItem = item as NegotiableQuoteCartItem;\n // Handle edit action - open line item note modal\n if (action === 'edit') {\n setSelectedItem(cartItem);\n setIsLineItemNoteModalOpen(true);\n // Reset dropdown immediately\n setDropdownSelections((prev) => ({ ...prev, [cartItem.uid]: '' }));\n return;\n }\n\n // Handle remove action\n if (action === 'remove') {\n setDropdownSelections((prev) => ({\n ...prev,\n [cartItem.uid]: action,\n }));\n handleRemoveItems([cartItem]); // Use unified handler\n onItemDropdownChange?.(cartItem, action);\n // Reset dropdown immediately (consistent with edit action)\n setDropdownSelections((prev) => ({ ...prev, [cartItem.uid]: '' }));\n return;\n }\n\n // For any other actions, pass through to parent (but ignore empty/placeholder selections)\n if (action) {\n onItemDropdownChange?.(cartItem, action);\n }\n\n // Clear dropdown selection for non-edit/remove actions\n /* istanbul ignore next: defensive cleanup - custom actions shouldn't have dropdown state due to proper cleanup in edit/remove handlers */\n setDropdownSelections((prev) => {\n if (!(cartItem.uid in prev)) {\n return prev;\n }\n const next = { ...prev };\n delete next[cartItem.uid];\n return next;\n });\n };\n\n const handleConfirmRemove = async () => {\n /* istanbul ignore next */\n if (!quoteData || itemsToRemove.length === 0) {\n return;\n }\n\n const uidsToRemove = itemsToRemove.map((item) => item.uid);\n\n setIsRemoving(true);\n setRemoveNotificationState({ type: null, message: '' });\n\n try {\n await removeNegotiableQuoteItems({\n quoteUid: quoteData.uid,\n quoteItemUids: uidsToRemove,\n });\n // Success is handled by the event listener\n } catch (err) {\n const errorMessage =\n /* istanbul ignore next */\n err instanceof Error ? err.message : dictionary.removeErrorMessage;\n setRemoveNotificationState({\n type: 'error',\n message: errorMessage,\n });\n // Clear dropdown selections for failed items (single item only)\n /* istanbul ignore next */ // UI-driven state; covered by tests but line sometimes mis-attributed in source maps\n if (itemsToRemove.length === 1) {\n const failedItem = itemsToRemove[0];\n setDropdownSelections((prev) => {\n if (!(failedItem.uid in prev)) {\n return prev;\n }\n const next = { ...prev };\n delete next[failedItem.uid];\n return next;\n });\n }\n setIsRemoving(false);\n }\n };\n\n const handleCancelRemove = () => {\n setIsRemoveModalOpen(false);\n setRemoveNotificationState({ type: null, message: '' });\n onRemoveModalStateChange?.(false);\n // Clear dropdown selections for single item cancellation\n /* istanbul ignore next */ // UI-driven state; covered by tests but line sometimes mis-attributed in source maps\n if (itemsToRemove.length === 1) {\n const cancelledItem = itemsToRemove[0];\n setDropdownSelections((prev) => {\n if (!(cancelledItem.uid in prev)) {\n return prev;\n }\n const next = { ...prev };\n delete next[cancelledItem.uid];\n return next;\n });\n }\n setItemsToRemove([]);\n };\n\n // Handle modal close\n const handleModalClose = useCallback(() => {\n // Clean up dropdown selection for the selected item before clearing it\n /* istanbul ignore else: defensive check - selectedItem should always be truthy when modal is open */\n if (selectedItem) {\n setDropdownSelections((prev) => {\n const next = { ...prev };\n delete next[selectedItem.uid];\n return next;\n });\n }\n setIsLineItemNoteModalOpen(false);\n setSelectedItem(null);\n setIsSubmitting(false);\n setModalErrorMessage('');\n }, [selectedItem]);\n\n // Handle modal confirm - submit note and quantity\n const handleModalConfirm = useCallback(\n async (note: string, quantity: number) => {\n /* istanbul ignore next: defensive guard for async race conditions - unreachable in normal flow as modal only renders with selectedItem and quoteData */\n if (!selectedItem || !quoteData) return;\n\n setIsSubmitting(true);\n try {\n // Check if quantity has changed from the original\n const quantityChanged = quantity !== selectedItem.quantity;\n\n // If quantity changed, update it first\n if (quantityChanged) {\n await updateQuantities({\n quoteUid: quoteData.uid,\n items: [{ quoteItemUid: selectedItem.uid, quantity }],\n });\n }\n\n // Then set the line item note\n await setLineItemNote({\n quoteUid: quoteData.uid,\n itemUid: selectedItem.uid,\n note,\n quantity,\n });\n\n // Close modal on success\n handleModalClose();\n } catch (error) {\n console.error('Failed to set line item note:', error);\n // Extract error message from API\n const errorMessage =\n /* istanbul ignore next */\n error instanceof Error\n ? error.message\n : 'Unable to update the item. Please try again.';\n setModalErrorMessage(errorMessage);\n setIsSubmitting(false);\n }\n },\n [selectedItem, quoteData, handleModalClose]\n );\n\n if (!quoteData) {\n return <ItemsQuotedComponent loading={true} />;\n }\n\n const canEdit = Boolean(quoteData.canUpdateQuote);\n\n const handleQuantityChange = (\n item: ProductListTableItem,\n newQuantity: number\n ) => {\n setQuantityChanges((prev) => ({\n ...prev,\n [(item as NegotiableQuoteCartItem).uid]: newQuantity,\n }));\n };\n\n const handleUpdate = (e: SubmitEvent) => {\n e.preventDefault();\n setNotificationState({ type: null, message: '' });\n setIsUpdateQuantitiesModalOpen(true);\n };\n\n const handleConfirmUpdate = async () => {\n /* istanbul ignore next */\n if (!quoteData) {\n return;\n }\n\n if (Object.keys(quantityChanges).length === 0) {\n setIsUpdateQuantitiesModalOpen(false);\n return;\n }\n\n // Clear any previous notifications\n setNotificationState({ type: null, message: '' });\n\n const items = Object.entries(quantityChanges).map(\n ([quoteItemUid, quantity]) => ({\n quoteItemUid,\n quantity,\n })\n );\n\n try {\n await updateQuantities({\n quoteUid: quoteData.uid,\n items,\n });\n // Success is handled by the event listener\n } catch (err) {\n const errorMessage =\n /* istanbul ignore next */\n err instanceof Error ? err.message : dictionary.errorMessage;\n setNotificationState({\n type: 'error',\n message: errorMessage,\n });\n console.error('Failed to update quantities:', err);\n }\n };\n\n const handleCancelUpdate = () => {\n setIsUpdateQuantitiesModalOpen(false);\n setNotificationState({ type: null, message: '' });\n };\n\n const handleDismissBanner = () => {\n setNotificationState({ type: null, message: '' });\n };\n\n const quotePricesSummaryEntries = [];\n\n quoteData.prices.subtotalExcludingTax &&\n quotePricesSummaryEntries.push({\n label: dictionary.subtotal,\n id: 'subtotal',\n value: (\n <Price\n amount={quoteData.prices.subtotalExcludingTax.value}\n currency={quoteData.prices.subtotalExcludingTax.currency}\n weight=\"normal\"\n />\n ),\n });\n\n quoteData.prices.grandTotal &&\n quotePricesSummaryEntries.push({\n label: dictionary.grandTotal,\n id: 'total',\n value: (\n <Price\n amount={quoteData.prices.grandTotal.value}\n currency={quoteData.prices.grandTotal.currency}\n />\n ),\n strong: true,\n });\n\n // Create confirmation banner based on notification state\n const confirmationBanner =\n notificationState.type === 'success' ? (\n <InLineAlert\n type=\"success\"\n variant=\"primary\"\n icon={<CheckWithCircle />}\n heading={dictionary.successHeading}\n description={notificationState.message}\n onDismiss={handleDismissBanner}\n data-testid=\"update-quantities-success-banner\"\n />\n ) : notificationState.type === 'error' ? (\n <InLineAlert\n type=\"error\"\n variant=\"primary\"\n icon={<WarningFilled />}\n heading={dictionary.errorHeading}\n description={notificationState.message}\n onDismiss={handleDismissBanner}\n data-testid=\"update-quantities-error-banner\"\n />\n ) : null;\n\n // Create wrapper that converts ProductListTableItem back to NegotiableQuoteCartItem\n const handleItemCheckboxChange = onItemCheckboxChange\n ? (item: ProductListTableItem, isSelected: boolean) => {\n onItemCheckboxChange(item as NegotiableQuoteCartItem, isSelected);\n }\n : undefined;\n\n // Create remove confirmation banner based on notification state\n const removeConfirmationBanner =\n removeNotificationState.type === 'success' ? (\n <InLineAlert\n type=\"success\"\n variant=\"primary\"\n icon={<CheckWithCircle />}\n heading={dictionary.removeSuccessHeading}\n description={removeNotificationState.message}\n onDismiss={handleDismissRemoveBanner}\n data-testid=\"remove-items-success-banner\"\n />\n ) : removeNotificationState.type === 'error' ? (\n <InLineAlert\n type=\"error\"\n variant=\"primary\"\n icon={<WarningFilled />}\n heading={dictionary.removeErrorHeading}\n description={removeNotificationState.message}\n onDismiss={handleDismissRemoveBanner}\n data-testid=\"remove-items-error-banner\"\n />\n ) : null;\n\n // Create modal error banner\n const modalErrorBanner = modalErrorMessage ? (\n <InLineAlert\n type=\"error\"\n variant=\"primary\"\n icon={<WarningFilled />}\n heading={dictionary.errorHeading}\n description={modalErrorMessage}\n onDismiss={() => setModalErrorMessage('')}\n data-testid=\"line-item-note-error-banner\"\n />\n ) : null;\n\n return (\n <>\n <ItemsQuotedComponent\n data-testid=\"items-quoted-container\"\n {...props}\n loading={false}\n table={\n <Slot\n name=\"ProductListTable\"\n slot={slots?.ProductListTable}\n context={{\n items: quoteData.items,\n canEdit,\n readOnly: quoteData.readOnly,\n onItemCheckboxChange,\n onItemDropdownChange: handleItemDropdownChange,\n onQuantityChange: handleQuantityChange,\n onUpdate: handleUpdate,\n dropdownSelections,\n }}\n >\n <ProductListTable\n items={quoteData.items}\n canEdit={canEdit}\n onItemCheckboxChange={handleItemCheckboxChange}\n readOnly={quoteData.readOnly}\n onItemDropdownChange={handleItemDropdownChange}\n onQuantityChange={handleQuantityChange}\n onUpdate={handleUpdate}\n dropdownSelections={dropdownSelections}\n />\n </Slot>\n }\n pricesSummary={\n <Slot\n name=\"QuotePricesSummary\"\n slot={slots?.QuotePricesSummary}\n context={{\n items: quoteData.items,\n prices: quoteData.prices,\n }}\n >\n <QuotePricesSummary entries={quotePricesSummaryEntries} />\n </Slot>\n }\n />\n\n {/* Update Quantities Modal */}\n <ConfirmationModal\n open={isUpdateQuantitiesModalOpen}\n title={dictionary.modalTitle}\n message={dictionary.modalDescription}\n cancelLabel={dictionary.modalCancelButton}\n confirmLabel={dictionary.modalUpdateButton}\n onCancel={handleCancelUpdate}\n onConfirm={handleConfirmUpdate}\n confirmationBanner={confirmationBanner}\n data-testid=\"update-quantities-modal\"\n />\n\n {/* Remove Items Modal */}\n <ConfirmationModal\n open={isRemoveModalOpen}\n title={dictionary.removeModalTitle}\n message={dictionary.removeModalDescription}\n cancelLabel={dictionary.removeModalCancelButton}\n confirmLabel={\n isRemoving\n ? dictionary.removeModalConfirmButtonRemoving\n : dictionary.removeModalConfirmButton\n }\n onCancel={handleCancelRemove}\n onConfirm={handleConfirmRemove}\n confirmationBanner={removeConfirmationBanner}\n data-testid=\"remove-items-modal\"\n />\n {/* Line Item Note Modal */}\n {selectedItem && (\n <LineItemNoteModal\n open={isLineItemNoteModalOpen}\n item={selectedItem}\n onClose={handleModalClose}\n onConfirm={handleModalConfirm}\n isSubmitting={isSubmitting}\n errorBanner={modalErrorBanner || undefined}\n />\n )}\n </>\n );\n};\n"],"names":["LineItemNoteModal","className","open","item","onClose","onConfirm","isSubmitting","errorBanner","successBanner","showCloseButton","note","setNote","useState","quantity","setQuantity","errors","setErrors","dictionary","useText","useEffect","validNotes","_a","existingNote","handleConfirm","useCallback","newErrors","handleCancel","discountDisplay","d","columns","rowData","jsxs","jsx","Price","Input","e","newQuantity","Modal","Fragment","classes","Table","TextArea","Button","NOTIFICATION_AUTO_DISMISS_DELAY","ItemsQuoted","initialData","onItemCheckboxChange","onItemDropdownChange","onRemoveItemsRef","onRemoveModalStateChange","slots","props","quoteData","setQuoteData","quantityChanges","setQuantityChanges","selectedItem","setSelectedItem","isUpdateQuantitiesModalOpen","setIsUpdateQuantitiesModalOpen","isLineItemNoteModalOpen","setIsLineItemNoteModalOpen","modalErrorMessage","setModalErrorMessage","notificationState","setNotificationState","isRemoveModalOpen","setIsRemoveModalOpen","itemsToRemove","setItemsToRemove","isRemoving","setIsRemoving","removeNotificationState","setRemoveNotificationState","dropdownSelections","setDropdownSelections","setIsSubmitting","quoteDataEvent","events","data","quantitiesUpdatedEvent","itemsRemovedEvent","handleRemoveItems","items","handleDismissRemoveBanner","handleItemDropdownChange","action","cartItem","prev","next","handleConfirmRemove","uidsToRemove","removeNegotiableQuoteItems","err","errorMessage","failedItem","handleCancelRemove","cancelledItem","handleModalClose","handleModalConfirm","updateQuantities","setLineItemNote","error","ItemsQuotedComponent","canEdit","handleQuantityChange","handleUpdate","handleConfirmUpdate","quoteItemUid","handleCancelUpdate","handleDismissBanner","quotePricesSummaryEntries","confirmationBanner","InLineAlert","CheckWithCircle","WarningFilled","handleItemCheckboxChange","isSelected","removeConfirmationBanner","modalErrorBanner","Slot","ProductListTable","QuotePricesSummary","ConfirmationModal"],"mappings":"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"}
1
+ {"version":3,"file":"ItemsQuoted.js","sources":["/@dropins/storefront-quote-management/src/containers/ItemsQuoted/ItemsQuoted.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport {\n HTMLAttributes,\n useCallback,\n useEffect,\n useState,\n} from 'preact/compat';\nimport { Container, Slot, SlotProps } from '@adobe-commerce/elsie/lib';\nimport { events } from '@adobe-commerce/event-bus';\nimport { Price, InLineAlert } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport {\n NegotiableQuoteModel,\n NegotiableQuoteCartItem,\n} from '@/quote-management/data/models/negotiable-quote-model';\nimport {\n ProductListTable,\n ProductListTableItem,\n QuotePricesSummary,\n ItemsQuoted as ItemsQuotedComponent,\n} from '@/quote-management/components';\nimport { CheckWithCircle, WarningFilled } from '@adobe-commerce/elsie/icons';\nimport { ConfirmationModal } from '@/quote-management/components/ConfirmationModal';\nimport { LineItemNoteModal } from '@/quote-management/components/LineItemNoteModal';\nimport { updateQuantities, setLineItemNote } from '@/quote-management/api';\nimport { removeNegotiableQuoteItems } from '@/quote-management/api/removeNegotiableQuoteItems';\n\nconst NOTIFICATION_AUTO_DISMISS_DELAY = 3000;\n\nexport interface ItemsQuotedProps extends HTMLAttributes<HTMLDivElement> {\n quoteData?: NegotiableQuoteModel;\n onItemCheckboxChange?: (\n item: NegotiableQuoteCartItem,\n isSelected: boolean\n ) => void;\n onItemDropdownChange?: (\n item: NegotiableQuoteCartItem,\n action: string\n ) => void;\n onUpdate?: (e: SubmitEvent) => void;\n onRemoveItemsRef?: (\n handler: (items: NegotiableQuoteCartItem[]) => void\n ) => void;\n onRemoveModalStateChange?: (isOpen: boolean) => void;\n slots?: {\n ProductListTable?: SlotProps<{\n items: NegotiableQuoteModel['items'];\n canEdit: boolean;\n readOnly?: boolean;\n onItemCheckboxChange?: (\n item: NegotiableQuoteCartItem,\n isSelected: boolean\n ) => void;\n onItemDropdownChange?: (\n item: NegotiableQuoteCartItem,\n action: string\n ) => void;\n onQuantityChange?: (\n item: NegotiableQuoteCartItem,\n newQuantity: number\n ) => void;\n onUpdate?: (e: SubmitEvent) => void;\n dropdownSelections?: Record<string, string | undefined>;\n }>;\n QuotePricesSummary?: SlotProps<{\n items: NegotiableQuoteModel['items'];\n prices: NegotiableQuoteModel['prices'];\n }>;\n };\n}\n\nexport const ItemsQuoted: Container<ItemsQuotedProps> = ({\n quoteData: initialData,\n onItemCheckboxChange,\n onItemDropdownChange,\n onRemoveItemsRef,\n onRemoveModalStateChange,\n slots,\n ...props\n}) => {\n const [quoteData, setQuoteData] = useState<NegotiableQuoteModel | undefined>(\n initialData\n );\n const [quantityChanges, setQuantityChanges] = useState<{\n [itemUid: string]: number;\n }>({});\n const [selectedItem, setSelectedItem] =\n useState<NegotiableQuoteCartItem | null>(null);\n const [isUpdateQuantitiesModalOpen, setIsUpdateQuantitiesModalOpen] =\n useState(false);\n const [isLineItemNoteModalOpen, setIsLineItemNoteModalOpen] = useState(false);\n const [modalErrorMessage, setModalErrorMessage] = useState('');\n const [notificationState, setNotificationState] = useState<{\n type: 'success' | 'error' | null;\n message: string;\n }>({ type: null, message: '' });\n // State for remove items functionality\n const [isRemoveModalOpen, setIsRemoveModalOpen] = useState(false);\n const [itemsToRemove, setItemsToRemove] = useState<NegotiableQuoteCartItem[]>(\n []\n );\n const [isRemoving, setIsRemoving] = useState(false);\n const [removeNotificationState, setRemoveNotificationState] = useState<{\n type: 'success' | 'error' | null;\n message: string;\n }>({ type: null, message: '' });\n const [dropdownSelections, setDropdownSelections] = useState<\n Record<string, string>\n >({});\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const dictionary = useText({\n subtotal: 'NegotiableQuote.Manage.quotePricesSummary.subtotal.excludingTax',\n grandTotal:\n 'NegotiableQuote.Manage.quotePricesSummary.grandTotal.includingTax',\n appliedTaxes: 'NegotiableQuote.Manage.quotePricesSummary.appliedTaxes',\n modalTitle: 'NegotiableQuote.Manage.updateQuantitiesModal.title',\n modalDescription:\n 'NegotiableQuote.Manage.updateQuantitiesModal.description',\n modalCancelButton:\n 'NegotiableQuote.Manage.updateQuantitiesModal.cancelButton',\n modalUpdateButton:\n 'NegotiableQuote.Manage.updateQuantitiesModal.updateButton',\n successHeading:\n 'NegotiableQuote.Manage.updateQuantitiesModal.successHeading',\n successMessage:\n 'NegotiableQuote.Manage.updateQuantitiesModal.successMessage',\n errorHeading: 'NegotiableQuote.Manage.updateQuantitiesModal.errorHeading',\n errorMessage: 'NegotiableQuote.Manage.updateQuantitiesModal.errorMessage',\n removeModalTitle: 'NegotiableQuote.Manage.removeItemsModal.title',\n removeModalDescription:\n 'NegotiableQuote.Manage.removeItemsModal.description',\n removeModalCancelButton:\n 'NegotiableQuote.Manage.removeItemsModal.cancelButton',\n removeModalConfirmButton:\n 'NegotiableQuote.Manage.removeItemsModal.confirmButton',\n removeModalConfirmButtonRemoving:\n 'NegotiableQuote.Manage.removeItemsModal.confirmButtonRemoving',\n removeSuccessHeading:\n 'NegotiableQuote.Manage.removeItemsModal.successHeading',\n removeSuccessMessage:\n 'NegotiableQuote.Manage.removeItemsModal.successMessage',\n removeErrorHeading: 'NegotiableQuote.Manage.removeItemsModal.errorHeading',\n removeErrorMessage: 'NegotiableQuote.Manage.removeItemsModal.errorMessage',\n });\n\n useEffect(() => {\n const quoteDataEvent = events.on(\n 'quote-management/quote-data',\n\n (data: { quote: NegotiableQuoteModel }) => {\n setQuoteData(data.quote);\n setQuantityChanges({});\n setNotificationState({ type: null, message: '' });\n setDropdownSelections({});\n },\n\n {\n eager: true,\n }\n );\n return () => quoteDataEvent?.off();\n }, []);\n\n useEffect(() => {\n const quantitiesUpdatedEvent = events.on(\n 'quote-management/quantities-updated',\n (data: { quote: NegotiableQuoteModel }) => {\n setQuoteData(data.quote);\n setQuantityChanges({});\n setNotificationState({\n type: 'success',\n message: dictionary.successMessage,\n });\n // Auto-close success notification after 3 seconds\n setTimeout(() => {\n setIsUpdateQuantitiesModalOpen(false);\n setNotificationState({ type: null, message: '' });\n }, 3000);\n }\n );\n return () => quantitiesUpdatedEvent?.off();\n }, [dictionary.successMessage]);\n\n // Listen for quote items removed event\n useEffect(() => {\n const itemsRemovedEvent = events.on(\n 'quote-management/quote-items-removed',\n (data: { quote: NegotiableQuoteModel }) => {\n setQuoteData(data.quote);\n setItemsToRemove([]);\n setIsRemoving(false);\n setRemoveNotificationState({\n type: 'success',\n message: dictionary.removeSuccessMessage,\n });\n // Auto-close success notification after 3 seconds\n setTimeout(() => {\n setIsRemoveModalOpen(false);\n setRemoveNotificationState({ type: null, message: '' });\n onRemoveModalStateChange?.(false);\n }, NOTIFICATION_AUTO_DISMISS_DELAY);\n }\n );\n return () => itemsRemovedEvent?.off();\n }, [dictionary.removeSuccessMessage, onRemoveModalStateChange]);\n\n // Unified handler for removing items (single or multiple)\n const handleRemoveItems = useCallback((items: NegotiableQuoteCartItem[]) => {\n if (!items || items.length === 0) {\n return;\n }\n setItemsToRemove(items);\n setRemoveNotificationState({ type: null, message: '' });\n setIsRemoveModalOpen(true);\n }, []);\n\n // Expose handler to parent component\n useEffect(() => {\n onRemoveItemsRef?.(handleRemoveItems);\n }, [handleRemoveItems, onRemoveItemsRef]);\n\n const handleDismissRemoveBanner = () => {\n setRemoveNotificationState({ type: null, message: '' });\n };\n\n const handleItemDropdownChange = (\n item: ProductListTableItem,\n action: string\n ) => {\n const cartItem = item as NegotiableQuoteCartItem;\n // Handle edit action - open line item note modal\n if (action === 'edit') {\n setSelectedItem(cartItem);\n setIsLineItemNoteModalOpen(true);\n // Reset dropdown immediately\n setDropdownSelections((prev) => ({ ...prev, [cartItem.uid]: '' }));\n return;\n }\n\n // Handle remove action\n if (action === 'remove') {\n setDropdownSelections((prev) => ({\n ...prev,\n [cartItem.uid]: action,\n }));\n handleRemoveItems([cartItem]); // Use unified handler\n onItemDropdownChange?.(cartItem, action);\n // Reset dropdown immediately (consistent with edit action)\n setDropdownSelections((prev) => ({ ...prev, [cartItem.uid]: '' }));\n return;\n }\n\n // For any other actions, pass through to parent (but ignore empty/placeholder selections)\n if (action) {\n onItemDropdownChange?.(cartItem, action);\n }\n\n // Clear dropdown selection for non-edit/remove actions\n /* istanbul ignore next: defensive cleanup - custom actions shouldn't have dropdown state due to proper cleanup in edit/remove handlers */\n setDropdownSelections((prev) => {\n if (!(cartItem.uid in prev)) {\n return prev;\n }\n const next = { ...prev };\n delete next[cartItem.uid];\n return next;\n });\n };\n\n const handleConfirmRemove = async () => {\n /* istanbul ignore next */\n if (!quoteData || itemsToRemove.length === 0) {\n return;\n }\n\n const uidsToRemove = itemsToRemove.map((item) => item.uid);\n\n setIsRemoving(true);\n setRemoveNotificationState({ type: null, message: '' });\n\n try {\n await removeNegotiableQuoteItems({\n quoteUid: quoteData.uid,\n quoteItemUids: uidsToRemove,\n });\n // Success is handled by the event listener\n } catch (err) {\n const errorMessage =\n /* istanbul ignore next */\n err instanceof Error ? err.message : dictionary.removeErrorMessage;\n setRemoveNotificationState({\n type: 'error',\n message: errorMessage,\n });\n // Clear dropdown selections for failed items (single item only)\n /* istanbul ignore next */ // UI-driven state; covered by tests but line sometimes mis-attributed in source maps\n if (itemsToRemove.length === 1) {\n const failedItem = itemsToRemove[0];\n setDropdownSelections((prev) => {\n if (!(failedItem.uid in prev)) {\n return prev;\n }\n const next = { ...prev };\n delete next[failedItem.uid];\n return next;\n });\n }\n setIsRemoving(false);\n }\n };\n\n const handleCancelRemove = () => {\n setIsRemoveModalOpen(false);\n setRemoveNotificationState({ type: null, message: '' });\n onRemoveModalStateChange?.(false);\n // Clear dropdown selections for single item cancellation\n /* istanbul ignore next */ // UI-driven state; covered by tests but line sometimes mis-attributed in source maps\n if (itemsToRemove.length === 1) {\n const cancelledItem = itemsToRemove[0];\n setDropdownSelections((prev) => {\n if (!(cancelledItem.uid in prev)) {\n return prev;\n }\n const next = { ...prev };\n delete next[cancelledItem.uid];\n return next;\n });\n }\n setItemsToRemove([]);\n };\n\n // Handle modal close\n const handleModalClose = useCallback(() => {\n // Clean up dropdown selection for the selected item before clearing it\n /* istanbul ignore else: defensive check - selectedItem should always be truthy when modal is open */\n if (selectedItem) {\n setDropdownSelections((prev) => {\n const next = { ...prev };\n delete next[selectedItem.uid];\n return next;\n });\n }\n setIsLineItemNoteModalOpen(false);\n setSelectedItem(null);\n setIsSubmitting(false);\n setModalErrorMessage('');\n }, [selectedItem]);\n\n // Handle modal confirm - submit note and quantity\n const handleModalConfirm = useCallback(\n async (note: string, quantity: number) => {\n /* istanbul ignore next: defensive guard for async race conditions - unreachable in normal flow as modal only renders with selectedItem and quoteData */\n if (!selectedItem || !quoteData) return;\n\n setIsSubmitting(true);\n try {\n // Check if quantity has changed from the original\n const quantityChanged = quantity !== selectedItem.quantity;\n\n // If quantity changed, update it first\n if (quantityChanged) {\n await updateQuantities({\n quoteUid: quoteData.uid,\n items: [{ quoteItemUid: selectedItem.uid, quantity }],\n });\n }\n\n // Then set the line item note\n await setLineItemNote({\n quoteUid: quoteData.uid,\n itemUid: selectedItem.uid,\n note,\n quantity,\n });\n\n // Close modal on success\n handleModalClose();\n } catch (error) {\n console.error('Failed to set line item note:', error);\n // Extract error message from API\n const errorMessage =\n /* istanbul ignore next */\n error instanceof Error\n ? error.message\n : 'Unable to update the item. Please try again.';\n setModalErrorMessage(errorMessage);\n setIsSubmitting(false);\n }\n },\n [selectedItem, quoteData, handleModalClose]\n );\n\n if (!quoteData) {\n return <ItemsQuotedComponent loading={true} />;\n }\n\n const canEdit = Boolean(quoteData.canUpdateQuote);\n\n const handleQuantityChange = (\n item: ProductListTableItem,\n newQuantity: number\n ) => {\n setQuantityChanges((prev) => ({\n ...prev,\n [(item as NegotiableQuoteCartItem).uid]: newQuantity,\n }));\n };\n\n const handleUpdate = (e: SubmitEvent) => {\n e.preventDefault();\n setNotificationState({ type: null, message: '' });\n setIsUpdateQuantitiesModalOpen(true);\n };\n\n const handleConfirmUpdate = async () => {\n /* istanbul ignore next */\n if (!quoteData) {\n return;\n }\n\n if (Object.keys(quantityChanges).length === 0) {\n setIsUpdateQuantitiesModalOpen(false);\n return;\n }\n\n // Clear any previous notifications\n setNotificationState({ type: null, message: '' });\n\n const items = Object.entries(quantityChanges).map(\n ([quoteItemUid, quantity]) => ({\n quoteItemUid,\n quantity,\n })\n );\n\n try {\n await updateQuantities({\n quoteUid: quoteData.uid,\n items,\n });\n // Success is handled by the event listener\n } catch (err) {\n const errorMessage =\n /* istanbul ignore next */\n err instanceof Error ? err.message : dictionary.errorMessage;\n setNotificationState({\n type: 'error',\n message: errorMessage,\n });\n console.error('Failed to update quantities:', err);\n }\n };\n\n const handleCancelUpdate = () => {\n setIsUpdateQuantitiesModalOpen(false);\n setNotificationState({ type: null, message: '' });\n };\n\n const handleDismissBanner = () => {\n setNotificationState({ type: null, message: '' });\n };\n\n const quotePricesSummaryEntries = [];\n\n quoteData.prices.subtotalExcludingTax &&\n quotePricesSummaryEntries.push({\n label: dictionary.subtotal,\n id: 'subtotal',\n value: (\n <Price\n amount={quoteData.prices.subtotalExcludingTax.value}\n currency={quoteData.prices.subtotalExcludingTax.currency}\n weight=\"normal\"\n />\n ),\n });\n\n quoteData.prices.grandTotal &&\n quotePricesSummaryEntries.push({\n label: dictionary.grandTotal,\n id: 'total',\n value: (\n <Price\n amount={quoteData.prices.grandTotal.value}\n currency={quoteData.prices.grandTotal.currency}\n />\n ),\n strong: true,\n });\n\n // Create confirmation banner based on notification state\n const confirmationBanner =\n notificationState.type === 'success' ? (\n <InLineAlert\n type=\"success\"\n variant=\"primary\"\n icon={<CheckWithCircle />}\n heading={dictionary.successHeading}\n description={notificationState.message}\n onDismiss={handleDismissBanner}\n data-testid=\"update-quantities-success-banner\"\n />\n ) : notificationState.type === 'error' ? (\n <InLineAlert\n type=\"error\"\n variant=\"primary\"\n icon={<WarningFilled />}\n heading={dictionary.errorHeading}\n description={notificationState.message}\n onDismiss={handleDismissBanner}\n data-testid=\"update-quantities-error-banner\"\n />\n ) : null;\n\n // Create wrapper that converts ProductListTableItem back to NegotiableQuoteCartItem\n const handleItemCheckboxChange = onItemCheckboxChange\n ? (item: ProductListTableItem, isSelected: boolean) => {\n onItemCheckboxChange(item as NegotiableQuoteCartItem, isSelected);\n }\n : undefined;\n\n // Create remove confirmation banner based on notification state\n const removeConfirmationBanner =\n removeNotificationState.type === 'success' ? (\n <InLineAlert\n type=\"success\"\n variant=\"primary\"\n icon={<CheckWithCircle />}\n heading={dictionary.removeSuccessHeading}\n description={removeNotificationState.message}\n onDismiss={handleDismissRemoveBanner}\n data-testid=\"remove-items-success-banner\"\n />\n ) : removeNotificationState.type === 'error' ? (\n <InLineAlert\n type=\"error\"\n variant=\"primary\"\n icon={<WarningFilled />}\n heading={dictionary.removeErrorHeading}\n description={removeNotificationState.message}\n onDismiss={handleDismissRemoveBanner}\n data-testid=\"remove-items-error-banner\"\n />\n ) : null;\n\n // Create modal error banner\n const modalErrorBanner = modalErrorMessage ? (\n <InLineAlert\n type=\"error\"\n variant=\"primary\"\n icon={<WarningFilled />}\n heading={dictionary.errorHeading}\n description={modalErrorMessage}\n onDismiss={() => setModalErrorMessage('')}\n data-testid=\"line-item-note-error-banner\"\n />\n ) : null;\n\n return (\n <>\n <ItemsQuotedComponent\n data-testid=\"items-quoted-container\"\n {...props}\n loading={false}\n table={\n <Slot\n name=\"ProductListTable\"\n slot={slots?.ProductListTable}\n context={{\n items: quoteData.items,\n canEdit,\n readOnly: quoteData.readOnly,\n onItemCheckboxChange,\n onItemDropdownChange: handleItemDropdownChange,\n onQuantityChange: handleQuantityChange,\n onUpdate: handleUpdate,\n dropdownSelections,\n }}\n >\n <ProductListTable\n items={quoteData.items}\n canEdit={canEdit}\n onItemCheckboxChange={handleItemCheckboxChange}\n readOnly={quoteData.readOnly}\n onItemDropdownChange={handleItemDropdownChange}\n onQuantityChange={handleQuantityChange}\n onUpdate={handleUpdate}\n dropdownSelections={dropdownSelections}\n />\n </Slot>\n }\n pricesSummary={\n <Slot\n name=\"QuotePricesSummary\"\n slot={slots?.QuotePricesSummary}\n context={{\n items: quoteData.items,\n prices: quoteData.prices,\n }}\n >\n <QuotePricesSummary entries={quotePricesSummaryEntries} />\n </Slot>\n }\n />\n\n {/* Update Quantities Modal */}\n <ConfirmationModal\n open={isUpdateQuantitiesModalOpen}\n title={dictionary.modalTitle}\n message={dictionary.modalDescription}\n cancelLabel={dictionary.modalCancelButton}\n confirmLabel={dictionary.modalUpdateButton}\n onCancel={handleCancelUpdate}\n onConfirm={handleConfirmUpdate}\n confirmationBanner={confirmationBanner}\n data-testid=\"update-quantities-modal\"\n />\n\n {/* Remove Items Modal */}\n <ConfirmationModal\n open={isRemoveModalOpen}\n title={dictionary.removeModalTitle}\n message={dictionary.removeModalDescription}\n cancelLabel={dictionary.removeModalCancelButton}\n confirmLabel={\n isRemoving\n ? dictionary.removeModalConfirmButtonRemoving\n : dictionary.removeModalConfirmButton\n }\n onCancel={handleCancelRemove}\n onConfirm={handleConfirmRemove}\n confirmationBanner={removeConfirmationBanner}\n data-testid=\"remove-items-modal\"\n />\n {/* Line Item Note Modal */}\n {selectedItem && (\n <LineItemNoteModal\n open={isLineItemNoteModalOpen}\n item={selectedItem}\n onClose={handleModalClose}\n onConfirm={handleModalConfirm}\n isSubmitting={isSubmitting}\n errorBanner={modalErrorBanner || undefined}\n />\n )}\n </>\n );\n};\n"],"names":["NOTIFICATION_AUTO_DISMISS_DELAY","ItemsQuoted","initialData","onItemCheckboxChange","onItemDropdownChange","onRemoveItemsRef","onRemoveModalStateChange","slots","props","quoteData","setQuoteData","useState","quantityChanges","setQuantityChanges","selectedItem","setSelectedItem","isUpdateQuantitiesModalOpen","setIsUpdateQuantitiesModalOpen","isLineItemNoteModalOpen","setIsLineItemNoteModalOpen","modalErrorMessage","setModalErrorMessage","notificationState","setNotificationState","isRemoveModalOpen","setIsRemoveModalOpen","itemsToRemove","setItemsToRemove","isRemoving","setIsRemoving","removeNotificationState","setRemoveNotificationState","dropdownSelections","setDropdownSelections","isSubmitting","setIsSubmitting","dictionary","useText","useEffect","quoteDataEvent","events","data","quantitiesUpdatedEvent","itemsRemovedEvent","handleRemoveItems","useCallback","items","handleDismissRemoveBanner","handleItemDropdownChange","item","action","cartItem","prev","next","handleConfirmRemove","uidsToRemove","removeNegotiableQuoteItems","err","errorMessage","failedItem","handleCancelRemove","cancelledItem","handleModalClose","handleModalConfirm","note","quantity","updateQuantities","setLineItemNote","error","jsx","ItemsQuotedComponent","canEdit","handleQuantityChange","newQuantity","handleUpdate","e","handleConfirmUpdate","quoteItemUid","handleCancelUpdate","handleDismissBanner","quotePricesSummaryEntries","Price","confirmationBanner","InLineAlert","CheckWithCircle","WarningFilled","handleItemCheckboxChange","isSelected","removeConfirmationBanner","modalErrorBanner","jsxs","Fragment","Slot","ProductListTable","QuotePricesSummary","ConfirmationModal","LineItemNoteModal"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  /*! Copyright 2025 Adobe
2
2
  All Rights Reserved. */
3
- import{jsx as t}from"@dropins/tools/preact-jsx-runtime.js";import{useState as d,useEffect as g}from"@dropins/tools/preact-compat.js";import{Slot as u}from"@dropins/tools/lib.js";import{events as T}from"@dropins/tools/event-bus.js";import{Price as m}from"@dropins/tools/components.js";/* empty css */import{I as n,Q as b,P as x}from"./QuotePricesSummary.js";/* empty css *//* empty css *//* empty css */import{useText as f}from"@dropins/tools/i18n.js";const N=({templateData:c,slots:a,...l})=>{const[e,s]=d(c),i=f({subtotal:"NegotiableQuoteTemplate.Manage.quotePricesSummary.subtotal.excludingTax",grandTotal:"NegotiableQuoteTemplate.Manage.quotePricesSummary.grandTotal.includingTax",appliedTaxes:"NegotiableQuoteTemplate.Manage.quotePricesSummary.appliedTaxes"});if(g(()=>{const o=T.on("quote-management/quote-template-data",p=>{s(p.quoteTemplate)},{eager:!0});return()=>o==null?void 0:o.off()},[]),!e)return t(n,{loading:!0});const r=[];return e.prices.subtotalExcludingTax&&r.push({label:i.subtotal,id:"subtotal",value:t(m,{amount:e.prices.subtotalExcludingTax.value,currency:e.prices.subtotalExcludingTax.currency,weight:"normal"})}),e.prices.grandTotal&&r.push({label:i.grandTotal,id:"total",value:t(m,{amount:e.prices.grandTotal.value,currency:e.prices.grandTotal.currency}),strong:!0}),t(n,{"data-testid":"items-quoted-template-container",...l,loading:!1,table:t(u,{name:"ProductListTable",slot:a==null?void 0:a.ProductListTable,context:{items:e.items,canEdit:!1},children:t(x,{items:e.items,canEdit:!1})}),pricesSummary:t(u,{name:"QuotePricesSummary",slot:a==null?void 0:a.QuotePricesSummary,context:{items:e.items,prices:e.prices},children:t(b,{entries:r})})})};export{N as I};
3
+ import{jsx as o,jsxs as ne,Fragment as se}from"@dropins/tools/preact-jsx-runtime.js";import{useState as l,useEffect as O,useCallback as p}from"@dropins/tools/preact-compat.js";import{Slot as W}from"@dropins/tools/lib.js";import{events as H}from"@dropins/tools/event-bus.js";import{InLineAlert as B,Price as Y}from"@dropins/tools/components.js";/* empty css */import{I as $,Q as re,P as ie,L as le}from"./LineItemNoteModal.js";import{C as me}from"./ConfirmationModal.js";/* empty css *//* empty css */import"./state.js";import{r as de,u as ue,a as ce}from"./addQuoteTemplateLineItemNote.js";import{S as z,a as U}from"./WarningFilled.js";import{useText as pe}from"@dropins/tools/i18n.js";const ge=3e3,Me=b=>{const{templateId:r,onRemoveModalStateChange:a,removeSuccessMessage:e,removeErrorMessage:T}=b,[i,g]=l(!1),[M,s]=l([]),[u,m]=l(!1),[S,n]=l({type:null,message:""});O(()=>{const d=H.on("quote-management/quote-template-data",()=>{s([]),m(!1),n({type:"success",message:e}),setTimeout(()=>{g(!1),n({type:null,message:""}),a==null||a(!1)},ge)});return()=>d==null?void 0:d.off()},[e,a]);const N=p(d=>{!d||d.length===0||(s(d),n({type:null,message:""}),g(!0))},[]),Q=p(async()=>{if(!r||M.length===0)return;const d=M.map(I=>I.uid).filter(Boolean);if(d.length!==0){m(!0),n({type:null,message:""});try{await de({templateId:r,itemUids:d})}catch(I){const c=I instanceof Error?I.message:T;n({type:"error",message:c}),m(!1)}}},[r,M,T]),t=p(()=>{g(!1),n({type:null,message:""}),a==null||a(!1),s([])},[a]);return{handleRemoveItems:N,handleConfirmRemove:Q,handleCancelRemove:t,isRemoveModalOpen:i,itemsToRemove:M,isRemoving:u,removeNotificationState:S}},fe=b=>{const{handleRemoveItems:r}=b,[a,e]=l({}),T=p(()=>{},[]),i=p((g,M)=>{const s=g;if(M==="remove"){e(u=>({...u,[s.uid||""]:M})),r([s]),e(u=>({...u,[s.uid||""]:""}));return}e(u=>{if(!s.uid||!(s.uid in u))return u;const m={...u};return delete m[s.uid],m})},[r]);return{dropdownSelections:a,handleItemDropdownChange:i,handleDismissRemoveBanner:T}},ve=3e3,Te=b=>{const{templateId:r,onUpdateModalStateChange:a,updateSuccessMessage:e,updateErrorMessage:T}=b,[i,g]=l({}),[M,s]=l(!1),[u,m]=l(!1),[S,n]=l({type:null,message:""});O(()=>{const c=H.on("quote-management/quote-template-data",()=>{g({}),m(!1),n({type:"success",message:e}),setTimeout(()=>{s(!1),n({type:null,message:""}),a==null||a(!1)},ve)});return()=>c==null?void 0:c.off()},[e,a]);const N=p((c,y)=>{const h=c;if(!h.uid)return;const C=h.uid;g(R=>({...R,[C]:y}))},[]),Q=p(c=>{c.preventDefault(),n({type:null,message:""}),s(!0)},[]),t=p(async()=>{if(!r||Object.keys(i).length===0){s(!1);return}m(!0),n({type:null,message:""});const c=Object.entries(i).map(([y,h])=>({itemId:y,quantity:h}));try{await ue({templateId:r,items:c})}catch(y){const h=y instanceof Error?y.message:T;n({type:"error",message:h}),m(!1)}},[r,i,T]),d=p(()=>{s(!1),n({type:null,message:""}),a==null||a(!1),g({})},[a]),I=p(()=>{n({type:null,message:""})},[]);return{quantityChanges:i,handleQuantityChange:N,handleUpdate:Q,handleConfirmUpdate:t,handleCancelUpdate:d,handleDismissBanner:I,isUpdateModalOpen:M,isUpdating:u,updateNotificationState:S}},Ue=({templateData:b,slots:r,...a})=>{const[e,T]=l(b),[i,g]=l(null),[M,s]=l(!1),[u,m]=l(!1),[S,n]=l(""),[N,Q]=l({}),t=pe({subtotal:"NegotiableQuoteTemplate.Manage.quotePricesSummary.subtotal.excludingTax",grandTotal:"NegotiableQuoteTemplate.Manage.quotePricesSummary.grandTotal.includingTax",appliedTaxes:"NegotiableQuoteTemplate.Manage.quotePricesSummary.appliedTaxes",removeModalTitle:"NegotiableQuoteTemplate.Manage.removeItemsModal.title",removeModalDescription:"NegotiableQuoteTemplate.Manage.removeItemsModal.description",removeModalCancelButton:"NegotiableQuoteTemplate.Manage.removeItemsModal.cancelButton",removeModalConfirmButton:"NegotiableQuoteTemplate.Manage.removeItemsModal.confirmButton",removeModalConfirmButtonRemoving:"NegotiableQuoteTemplate.Manage.removeItemsModal.confirmButtonRemoving",removeSuccessHeading:"NegotiableQuoteTemplate.Manage.removeItemsModal.successHeading",removeSuccessMessage:"NegotiableQuoteTemplate.Manage.removeItemsModal.successMessage",removeErrorHeading:"NegotiableQuoteTemplate.Manage.removeItemsModal.errorHeading",removeErrorMessage:"NegotiableQuoteTemplate.Manage.removeItemsModal.errorMessage",updateModalTitle:"NegotiableQuoteTemplate.Manage.updateQuantitiesModal.title",updateModalDescription:"NegotiableQuoteTemplate.Manage.updateQuantitiesModal.description",updateModalCancelButton:"NegotiableQuoteTemplate.Manage.updateQuantitiesModal.cancelButton",updateModalUpdateButton:"NegotiableQuoteTemplate.Manage.updateQuantitiesModal.updateButton",updateSuccessHeading:"NegotiableQuoteTemplate.Manage.updateQuantitiesModal.successHeading",updateSuccessMessage:"NegotiableQuoteTemplate.Manage.updateQuantitiesModal.successMessage",updateErrorHeading:"NegotiableQuoteTemplate.Manage.updateQuantitiesModal.errorHeading",updateErrorMessage:"NegotiableQuoteTemplate.Manage.updateQuantitiesModal.errorMessage",errorHeading:"NegotiableQuoteTemplate.Manage.lineItemNoteModal.errorHeading"}),{handleRemoveItems:d,handleConfirmRemove:I,handleCancelRemove:c,isRemoveModalOpen:y,isRemoving:h,removeNotificationState:C}=Me({templateId:e==null?void 0:e.id,removeSuccessMessage:t.removeSuccessMessage,removeErrorMessage:t.removeErrorMessage}),{dropdownSelections:R,handleItemDropdownChange:P,handleDismissRemoveBanner:q}=fe({handleRemoveItems:d}),{handleQuantityChange:L,handleUpdate:A,handleConfirmUpdate:G,handleCancelUpdate:J,handleDismissBanner:F,isUpdateModalOpen:K,updateNotificationState:E}=Te({templateId:e==null?void 0:e.id,updateSuccessMessage:t.updateSuccessMessage,updateErrorMessage:t.updateErrorMessage});O(()=>{const v=H.on("quote-management/quote-template-data",f=>{T(f.quoteTemplate),Q({})},{eager:!0});return()=>v==null?void 0:v.off()},[]);const _=p((v,f)=>{const D=v;if(f==="edit"){g(D),s(!0),Q(oe=>({...oe,[D.uid||""]:""}));return}P(v,f)},[P]),k={...R,...N},w=p(()=>{i&&Q(v=>{const f={...v};return delete f[i.uid||""],f}),s(!1),g(null),m(!1),n("")},[i]),V=p(async v=>{if(!(!i||!e)){m(!0),n("");try{await ce({templateId:e.id,itemId:i.uid||"",note:v}),w()}catch(f){console.error("Failed to set template line item note:",f);const D=f instanceof Error?f.message:"Unable to update the item. Please try again.";n(D),m(!1)}}},[i,e,w]),X=C.type==="success"?o(B,{type:"success",variant:"primary",icon:o(z,{}),heading:t.removeSuccessHeading,description:C.message,onDismiss:q,"data-testid":"remove-items-success-banner"}):C.type==="error"?o(B,{type:"error",variant:"primary",icon:o(U,{}),heading:t.removeErrorHeading,description:C.message,onDismiss:q,"data-testid":"remove-items-error-banner"}):null,Z=E.type==="success"?o(B,{type:"success",variant:"primary",icon:o(z,{}),heading:t.updateSuccessHeading,description:E.message,onDismiss:F,"data-testid":"update-quantities-success-banner"}):E.type==="error"?o(B,{type:"error",variant:"primary",icon:o(U,{}),heading:t.updateErrorHeading,description:E.message,onDismiss:F,"data-testid":"update-quantities-error-banner"}):null;if(!e)return o($,{loading:!0});const ee=y?{open:!0,title:t.removeModalTitle,message:t.removeModalDescription,cancelLabel:t.removeModalCancelButton,confirmLabel:h?t.removeModalConfirmButtonRemoving:t.removeModalConfirmButton,onCancel:c,onConfirm:I,confirmationBanner:X}:null,te=K?{open:!0,title:t.updateModalTitle,message:t.updateModalDescription,cancelLabel:t.updateModalCancelButton,confirmLabel:t.updateModalUpdateButton,onCancel:J,onConfirm:G,confirmationBanner:Z}:null,j=ee||te,x=[];e.prices.subtotalExcludingTax&&x.push({label:t.subtotal,id:"subtotal",value:o(Y,{amount:e.prices.subtotalExcludingTax.value,currency:e.prices.subtotalExcludingTax.currency,weight:"normal"})}),e.prices.grandTotal&&x.push({label:t.grandTotal,id:"total",value:o(Y,{amount:e.prices.grandTotal.value,currency:e.prices.grandTotal.currency}),strong:!0});const ae=S?o(B,{type:"error",variant:"primary",icon:o(U,{}),heading:t.errorHeading,description:S,onDismiss:()=>n(""),"data-testid":"line-item-note-error-banner"}):null;return ne(se,{children:[o($,{"data-testid":"items-quoted-template-container",...a,loading:!1,table:o(W,{name:"ProductListTable",slot:r==null?void 0:r.ProductListTable,context:{items:e.items,canEdit:e.canSendForReview,dropdownSelections:k,handleItemDropdownChange:_,handleQuantityChange:L,handleUpdate:A},children:o(ie,{items:e.items,canEdit:e.canSendForReview,showActions:e.canEditTemplateItems,onItemDropdownChange:_,onQuantityChange:L,onUpdate:A,dropdownSelections:k})}),pricesSummary:o(W,{name:"QuotePricesSummary",slot:r==null?void 0:r.QuotePricesSummary,context:{items:e.items,prices:e.prices},children:o(re,{entries:x})})}),j&&o(me,{...j}),i&&o(le,{open:M,item:i,onClose:w,onConfirm:V,isSubmitting:u,readOnlyQuantity:!0,errorBanner:ae||void 0})]})};export{Ue as I};
4
4
  //# sourceMappingURL=ItemsQuotedTemplate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ItemsQuotedTemplate.js","sources":["/@dropins/storefront-quote-management/src/containers/ItemsQuotedTemplate/ItemsQuotedTemplate.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { HTMLAttributes, useEffect, useState } from 'preact/compat';\nimport { Container, Slot, SlotProps } from '@adobe-commerce/elsie/lib';\nimport { events } from '@adobe-commerce/event-bus';\nimport { Price } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { NegotiableQuoteTemplateModel } from '@/quote-management/data/models/negotiable-quote-template-model';\nimport { QuotePricesSummary, ProductListTable, ItemsQuoted as ItemsQuotedComponent } from '@/quote-management/components';\n\nexport interface ItemsQuotedTemplateProps extends HTMLAttributes<HTMLDivElement> {\n templateData?: NegotiableQuoteTemplateModel;\n slots?: {\n ProductListTable?: SlotProps<{\n items: NegotiableQuoteTemplateModel['items'];\n canEdit: boolean;\n }>;\n QuotePricesSummary?: SlotProps<{\n items: NegotiableQuoteTemplateModel['items'];\n prices: NegotiableQuoteTemplateModel['prices'];\n }>;\n }\n}\n\nexport const ItemsQuotedTemplate: Container<ItemsQuotedTemplateProps> = ({\n templateData: initialData,\n slots,\n ...props\n}) => {\n const [templateData, setTemplateData] = useState<NegotiableQuoteTemplateModel | undefined>(initialData);\n\n const dictionary = useText({\n subtotal: 'NegotiableQuoteTemplate.Manage.quotePricesSummary.subtotal.excludingTax',\n grandTotal: 'NegotiableQuoteTemplate.Manage.quotePricesSummary.grandTotal.includingTax',\n appliedTaxes: 'NegotiableQuoteTemplate.Manage.quotePricesSummary.appliedTaxes',\n });\n\n useEffect(() => {\n const templateDataEvent = events.on('quote-management/quote-template-data', (payload) => {\n setTemplateData(payload.quoteTemplate);\n }, { eager: true });\n\n return () => templateDataEvent?.off();\n }, []);\n\n if (!templateData) {\n return <ItemsQuotedComponent loading={true} />;\n }\n\n const quotePricesSummaryEntries = [];\n\n templateData.prices.subtotalExcludingTax && quotePricesSummaryEntries.push({\n label: dictionary.subtotal,\n id: 'subtotal',\n value: <Price amount={templateData.prices.subtotalExcludingTax.value} currency={templateData.prices.subtotalExcludingTax.currency} weight='normal' />,\n });\n\n templateData.prices.grandTotal && quotePricesSummaryEntries.push({\n label: dictionary.grandTotal,\n id: 'total',\n value: <Price amount={templateData.prices.grandTotal.value} currency={templateData.prices.grandTotal.currency} />,\n strong: true,\n })\n\n return (\n <ItemsQuotedComponent data-testid=\"items-quoted-template-container\" {...props} loading={false}\n table={\n <Slot name=\"ProductListTable\" slot={slots?.ProductListTable}\n context={{\n items: templateData.items,\n canEdit: false,\n }}>\n\n <ProductListTable items={templateData.items} canEdit={false} />\n </Slot>\n }\n pricesSummary={<Slot name=\"QuotePricesSummary\" slot={slots?.QuotePricesSummary} context={{\n items: templateData.items,\n prices: templateData.prices,\n }}>\n <QuotePricesSummary entries={quotePricesSummaryEntries} />\n </Slot>\n }\n />\n );\n};\n"],"names":["ItemsQuotedTemplate","initialData","slots","props","templateData","setTemplateData","useState","dictionary","useText","useEffect","templateDataEvent","events","payload","jsx","ItemsQuotedComponent","quotePricesSummaryEntries","Price","Slot","ProductListTable","QuotePricesSummary"],"mappings":"4gBA+BO,MAAMA,EAA2D,CAAC,CACvE,aAAcC,EACd,MAAAC,EACA,GAAGC,CACL,IAAM,CACJ,KAAM,CAACC,EAAcC,CAAe,EAAIC,EAAmDL,CAAW,EAEhGM,EAAaC,EAAQ,CACzB,SAAU,0EACV,WAAY,4EACZ,aAAc,gEAAA,CACf,EAUD,GARAC,EAAU,IAAM,CACd,MAAMC,EAAoBC,EAAO,GAAG,uCAAyCC,GAAY,CACvFP,EAAgBO,EAAQ,aAAa,CACvC,EAAG,CAAE,MAAO,GAAM,EAElB,MAAO,IAAMF,GAAA,YAAAA,EAAmB,KAClC,EAAG,CAAA,CAAE,EAED,CAACN,EACH,OAAOS,EAACC,EAAA,CAAqB,QAAS,EAAA,CAAM,EAG9C,MAAMC,EAA4B,CAAA,EAElC,OAAAX,EAAa,OAAO,sBAAwBW,EAA0B,KAAK,CACzE,MAAOR,EAAW,SAClB,GAAI,WACJ,MAAOM,EAACG,EAAA,CAAM,OAAQZ,EAAa,OAAO,qBAAqB,MAAO,SAAUA,EAAa,OAAO,qBAAqB,SAAU,OAAO,QAAA,CAAS,CAAA,CACpJ,EAEDA,EAAa,OAAO,YAAcW,EAA0B,KAAK,CAC/D,MAAOR,EAAW,WAClB,GAAI,QACJ,MAAOM,EAACG,EAAA,CAAM,OAAQZ,EAAa,OAAO,WAAW,MAAO,SAAUA,EAAa,OAAO,WAAW,QAAA,CAAU,EAC/G,OAAQ,EAAA,CACT,EAGCS,EAACC,EAAA,CAAqB,cAAY,kCAAmC,GAAGX,EAAO,QAAS,GACtF,MACEU,EAACI,EAAA,CAAK,KAAK,mBAAmB,KAAMf,GAAA,YAAAA,EAAO,iBACzC,QAAS,CACP,MAAOE,EAAa,MACpB,QAAS,EAAA,EAGX,WAACc,EAAA,CAAiB,MAAOd,EAAa,MAAO,QAAS,EAAA,CAAO,CAAA,CAAA,EAGjE,gBAAgBa,EAAA,CAAK,KAAK,qBAAqB,KAAMf,GAAA,YAAAA,EAAO,mBAAoB,QAAS,CACvF,MAAOE,EAAa,MACpB,OAAQA,EAAa,MAAA,EAErB,SAAAS,EAACM,EAAA,CAAmB,QAASJ,EAA2B,CAAA,CAC1D,CAAA,CAAA,CAIN"}
1
+ {"version":3,"file":"ItemsQuotedTemplate.js","sources":["/@dropins/storefront-quote-management/src/hooks/useRemoveTemplateItems.ts","/@dropins/storefront-quote-management/src/hooks/useItemsQuotedTemplate.ts","/@dropins/storefront-quote-management/src/hooks/useUpdateTemplateQuantities.ts","/@dropins/storefront-quote-management/src/containers/ItemsQuotedTemplate/ItemsQuotedTemplate.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { useState, useEffect, useCallback } from 'preact/compat';\nimport { events } from '@adobe-commerce/event-bus';\nimport { removeQuoteTemplateItems } from '@/quote-management/api/removeQuoteTemplateItems';\nimport { QuoteTemplateCartItem } from '@/quote-management/data/models/negotiable-quote-template-model';\n\nconst NOTIFICATION_AUTO_DISMISS_DELAY = 3000;\n\nexport interface UseRemoveTemplateItemsReturn {\n handleRemoveItems: (items: QuoteTemplateCartItem[]) => void;\n handleConfirmRemove: () => Promise<void>;\n handleCancelRemove: () => void;\n isRemoveModalOpen: boolean;\n itemsToRemove: QuoteTemplateCartItem[];\n isRemoving: boolean;\n removeNotificationState: {\n type: 'success' | 'error' | null;\n message: string;\n };\n}\n\nexport interface UseRemoveTemplateItemsParams {\n templateId?: string;\n onRemoveModalStateChange?: (isOpen: boolean) => void;\n removeSuccessMessage: string;\n removeErrorMessage: string;\n}\n\n/**\n * Custom hook to manage removing items from a quote template\n */\nexport const useRemoveTemplateItems = (\n params: UseRemoveTemplateItemsParams\n): UseRemoveTemplateItemsReturn => {\n const {\n templateId,\n onRemoveModalStateChange,\n removeSuccessMessage,\n removeErrorMessage,\n } = params;\n\n const [isRemoveModalOpen, setIsRemoveModalOpen] = useState(false);\n const [itemsToRemove, setItemsToRemove] = useState<QuoteTemplateCartItem[]>([]);\n const [isRemoving, setIsRemoving] = useState(false);\n const [removeNotificationState, setRemoveNotificationState] = useState<{\n type: 'success' | 'error' | null;\n message: string;\n }>({ type: null, message: '' });\n\n // Listen for quote template data event (successful removal)\n useEffect(() => {\n const templateDataEvent = events.on(\n 'quote-management/quote-template-data',\n () => {\n setItemsToRemove([]);\n setIsRemoving(false);\n setRemoveNotificationState({\n type: 'success',\n message: removeSuccessMessage,\n });\n // Auto-close success notification after delay\n setTimeout(() => {\n setIsRemoveModalOpen(false);\n setRemoveNotificationState({ type: null, message: '' });\n onRemoveModalStateChange?.(false);\n }, NOTIFICATION_AUTO_DISMISS_DELAY);\n }\n );\n return () => templateDataEvent?.off();\n }, [removeSuccessMessage, onRemoveModalStateChange]);\n\n // Unified handler for removing items (single or multiple)\n const handleRemoveItems = useCallback((items: QuoteTemplateCartItem[]) => {\n if (!items || items.length === 0) {\n return;\n }\n setItemsToRemove(items);\n setRemoveNotificationState({ type: null, message: '' });\n setIsRemoveModalOpen(true);\n }, []);\n\n const handleConfirmRemove = useCallback(async () => {\n if (!templateId || itemsToRemove.length === 0) {\n return;\n }\n\n const uidsToRemove = itemsToRemove.map((item) => item.uid).filter(Boolean) as string[];\n\n if (uidsToRemove.length === 0) {\n return;\n }\n\n setIsRemoving(true);\n setRemoveNotificationState({ type: null, message: '' });\n\n try {\n await removeQuoteTemplateItems({\n templateId,\n itemUids: uidsToRemove,\n });\n // Success is handled by the event listener\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : removeErrorMessage;\n setRemoveNotificationState({\n type: 'error',\n message: errorMessage,\n });\n setIsRemoving(false);\n }\n }, [templateId, itemsToRemove, removeErrorMessage]);\n\n const handleCancelRemove = useCallback(() => {\n setIsRemoveModalOpen(false);\n setRemoveNotificationState({ type: null, message: '' });\n onRemoveModalStateChange?.(false);\n setItemsToRemove([]);\n }, [onRemoveModalStateChange]);\n\n return {\n handleRemoveItems,\n handleConfirmRemove,\n handleCancelRemove,\n isRemoveModalOpen,\n itemsToRemove,\n isRemoving,\n removeNotificationState,\n };\n};\n\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { useState, useCallback } from 'preact/compat';\nimport { ProductListTableItem } from '@/quote-management/components';\nimport { QuoteTemplateCartItem } from '@/quote-management/data/models/negotiable-quote-template-model';\n\nexport interface UseItemsQuotedTemplateReturn {\n dropdownSelections: Record<string, string | undefined>;\n handleItemDropdownChange: (item: ProductListTableItem, action: string) => void;\n handleDismissRemoveBanner: () => void;\n}\n\nexport interface UseItemsQuotedTemplateParams {\n handleRemoveItems: (items: QuoteTemplateCartItem[]) => void;\n}\n\n/**\n * Custom hook to manage dropdown selections and item actions for quote template items\n */\nexport const useItemsQuotedTemplate = (\n params: UseItemsQuotedTemplateParams\n): UseItemsQuotedTemplateReturn => {\n const { handleRemoveItems } = params;\n\n const [dropdownSelections, setDropdownSelections] = useState<\n Record<string, string | undefined>\n >({});\n\n const handleDismissRemoveBanner = useCallback(() => {\n // The hook manages its own notification state, but we can add custom dismiss logic if needed\n }, []);\n\n const handleItemDropdownChange = useCallback(\n (item: ProductListTableItem, action: string) => {\n const cartItem = item as QuoteTemplateCartItem;\n\n // Handle remove action\n if (action === 'remove') {\n setDropdownSelections((prev) => ({\n ...prev,\n [cartItem.uid || '']: action,\n }));\n handleRemoveItems([cartItem]);\n // Reset dropdown immediately\n setDropdownSelections((prev) => ({ ...prev, [cartItem.uid || '']: '' }));\n return;\n }\n\n // Clear dropdown selection for other actions\n setDropdownSelections((prev) => {\n if (!cartItem.uid || !(cartItem.uid in prev)) {\n return prev;\n }\n const next = { ...prev };\n delete next[cartItem.uid];\n return next;\n });\n },\n [handleRemoveItems]\n );\n\n return {\n dropdownSelections,\n handleItemDropdownChange,\n handleDismissRemoveBanner,\n };\n};\n\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { useState, useEffect, useCallback } from 'preact/compat';\nimport { events } from '@adobe-commerce/event-bus';\nimport { updateQuoteTemplateItemQuantities } from '@/quote-management/api/updateQuoteTemplateItemQuantities';\nimport { QuoteTemplateCartItem } from '@/quote-management/data/models/negotiable-quote-template-model';\nimport { ProductListTableItem } from '@/quote-management/components';\n\nconst NOTIFICATION_AUTO_DISMISS_DELAY = 3000;\n\nexport interface UseUpdateTemplateQuantitiesReturn {\n quantityChanges: Record<string, number>;\n handleQuantityChange: (item: ProductListTableItem, newQuantity: number) => void;\n handleUpdate: (e: SubmitEvent) => void;\n handleConfirmUpdate: () => Promise<void>;\n handleCancelUpdate: () => void;\n handleDismissBanner: () => void;\n isUpdateModalOpen: boolean;\n isUpdating: boolean;\n updateNotificationState: {\n type: 'success' | 'error' | null;\n message: string;\n };\n}\n\nexport interface UseUpdateTemplateQuantitiesParams {\n templateId?: string;\n onUpdateModalStateChange?: (isOpen: boolean) => void;\n updateSuccessMessage: string;\n updateErrorMessage: string;\n}\n\n/**\n * Custom hook to manage updating quantities of items in a quote template\n */\nexport const useUpdateTemplateQuantities = (\n params: UseUpdateTemplateQuantitiesParams\n): UseUpdateTemplateQuantitiesReturn => {\n const {\n templateId,\n onUpdateModalStateChange,\n updateSuccessMessage,\n updateErrorMessage,\n } = params;\n\n const [quantityChanges, setQuantityChanges] = useState<Record<string, number>>({});\n const [isUpdateModalOpen, setIsUpdateModalOpen] = useState(false);\n const [isUpdating, setIsUpdating] = useState(false);\n const [updateNotificationState, setUpdateNotificationState] = useState<{\n type: 'success' | 'error' | null;\n message: string;\n }>({ type: null, message: '' });\n\n // Listen for quote template data event (successful update)\n useEffect(() => {\n const templateDataEvent = events.on(\n 'quote-management/quote-template-data',\n () => {\n setQuantityChanges({});\n setIsUpdating(false);\n setUpdateNotificationState({\n type: 'success',\n message: updateSuccessMessage,\n });\n // Auto-close success notification after delay\n setTimeout(() => {\n setIsUpdateModalOpen(false);\n setUpdateNotificationState({ type: null, message: '' });\n onUpdateModalStateChange?.(false);\n }, NOTIFICATION_AUTO_DISMISS_DELAY);\n }\n );\n return () => templateDataEvent?.off();\n }, [updateSuccessMessage, onUpdateModalStateChange]);\n\n const handleQuantityChange = useCallback(\n (item: ProductListTableItem, newQuantity: number) => {\n const cartItem = item as QuoteTemplateCartItem;\n if (!cartItem.uid) {\n return;\n }\n const itemUid = cartItem.uid;\n setQuantityChanges((prev) => ({\n ...prev,\n [itemUid]: newQuantity,\n }));\n },\n []\n );\n\n const handleUpdate = useCallback((e: SubmitEvent) => {\n e.preventDefault();\n setUpdateNotificationState({ type: null, message: '' });\n setIsUpdateModalOpen(true);\n }, []);\n\n const handleConfirmUpdate = useCallback(async () => {\n if (!templateId || Object.keys(quantityChanges).length === 0) {\n setIsUpdateModalOpen(false);\n return;\n }\n\n setIsUpdating(true);\n setUpdateNotificationState({ type: null, message: '' });\n\n // Map quantity changes to API format\n const items = Object.entries(quantityChanges).map(([itemId, quantity]) => ({\n itemId,\n quantity,\n }));\n\n try {\n await updateQuoteTemplateItemQuantities({\n templateId,\n items,\n });\n // Success is handled by the event listener\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : updateErrorMessage;\n setUpdateNotificationState({\n type: 'error',\n message: errorMessage,\n });\n setIsUpdating(false);\n }\n }, [templateId, quantityChanges, updateErrorMessage]);\n\n const handleCancelUpdate = useCallback(() => {\n setIsUpdateModalOpen(false);\n setUpdateNotificationState({ type: null, message: '' });\n onUpdateModalStateChange?.(false);\n setQuantityChanges({});\n }, [onUpdateModalStateChange]);\n\n const handleDismissBanner = useCallback(() => {\n setUpdateNotificationState({ type: null, message: '' });\n }, []);\n\n return {\n quantityChanges,\n handleQuantityChange,\n handleUpdate,\n handleConfirmUpdate,\n handleCancelUpdate,\n handleDismissBanner,\n isUpdateModalOpen,\n isUpdating,\n updateNotificationState,\n };\n};\n\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport {\n HTMLAttributes,\n useCallback,\n useEffect,\n useState,\n} from 'preact/compat';\nimport { Container, Slot, SlotProps } from '@adobe-commerce/elsie/lib';\nimport { events } from '@adobe-commerce/event-bus';\nimport { Price, InLineAlert } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { CheckWithCircle, WarningFilled } from '@adobe-commerce/elsie/icons';\nimport {\n NegotiableQuoteTemplateModel,\n QuoteTemplateCartItem,\n} from '@/quote-management/data/models/negotiable-quote-template-model';\nimport {\n QuotePricesSummary,\n ProductListTable,\n ItemsQuoted as ItemsQuotedComponent,\n ProductListTableItem,\n ConfirmationModal,\n} from '@/quote-management/components';\nimport { LineItemNoteModal } from '@/quote-management/components/LineItemNoteModal';\nimport { addQuoteTemplateLineItemNote } from '@/quote-management/api';\nimport { useRemoveTemplateItems } from '@/quote-management/hooks/useRemoveTemplateItems';\nimport { useItemsQuotedTemplate } from '@/quote-management/hooks/useItemsQuotedTemplate';\nimport { useUpdateTemplateQuantities } from '@/quote-management/hooks/useUpdateTemplateQuantities';\n\nexport interface ItemsQuotedTemplateProps\n extends HTMLAttributes<HTMLDivElement> {\n templateData?: NegotiableQuoteTemplateModel;\n slots?: {\n ProductListTable?: SlotProps<{\n items: NegotiableQuoteTemplateModel['items'];\n canEdit: boolean;\n dropdownSelections: Record<string, string | undefined>;\n handleItemDropdownChange: (item: ProductListTableItem, action: string) => void;\n handleQuantityChange: (item: ProductListTableItem, newQuantity: number) => void;\n handleUpdate: (e: SubmitEvent) => void;\n onItemDropdownChange?: (item: any, action: string) => void;\n }>;\n QuotePricesSummary?: SlotProps<{\n items: NegotiableQuoteTemplateModel['items'];\n prices: NegotiableQuoteTemplateModel['prices'];\n }>;\n };\n}\n\nexport const ItemsQuotedTemplate: Container<ItemsQuotedTemplateProps> = ({\n templateData: initialData,\n slots,\n ...props\n}) => {\n const [templateData, setTemplateData] = useState<\n NegotiableQuoteTemplateModel | undefined\n >(initialData);\n const [selectedItem, setSelectedItem] =\n useState<QuoteTemplateCartItem | null>(null);\n const [isLineItemNoteModalOpen, setIsLineItemNoteModalOpen] = useState(false);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [modalErrorMessage, setModalErrorMessage] = useState('');\n const [dropdownSelections, setDropdownSelections] = useState<\n Record<string, string>\n >({});\n\n const dictionary = useText({\n subtotal:\n 'NegotiableQuoteTemplate.Manage.quotePricesSummary.subtotal.excludingTax',\n grandTotal:\n 'NegotiableQuoteTemplate.Manage.quotePricesSummary.grandTotal.includingTax',\n appliedTaxes:\n 'NegotiableQuoteTemplate.Manage.quotePricesSummary.appliedTaxes',\n removeModalTitle: 'NegotiableQuoteTemplate.Manage.removeItemsModal.title',\n removeModalDescription: 'NegotiableQuoteTemplate.Manage.removeItemsModal.description',\n removeModalCancelButton: 'NegotiableQuoteTemplate.Manage.removeItemsModal.cancelButton',\n removeModalConfirmButton: 'NegotiableQuoteTemplate.Manage.removeItemsModal.confirmButton',\n removeModalConfirmButtonRemoving: 'NegotiableQuoteTemplate.Manage.removeItemsModal.confirmButtonRemoving',\n removeSuccessHeading: 'NegotiableQuoteTemplate.Manage.removeItemsModal.successHeading',\n removeSuccessMessage: 'NegotiableQuoteTemplate.Manage.removeItemsModal.successMessage',\n removeErrorHeading: 'NegotiableQuoteTemplate.Manage.removeItemsModal.errorHeading',\n removeErrorMessage: 'NegotiableQuoteTemplate.Manage.removeItemsModal.errorMessage',\n updateModalTitle: 'NegotiableQuoteTemplate.Manage.updateQuantitiesModal.title',\n updateModalDescription: 'NegotiableQuoteTemplate.Manage.updateQuantitiesModal.description',\n updateModalCancelButton: 'NegotiableQuoteTemplate.Manage.updateQuantitiesModal.cancelButton',\n updateModalUpdateButton: 'NegotiableQuoteTemplate.Manage.updateQuantitiesModal.updateButton',\n updateSuccessHeading: 'NegotiableQuoteTemplate.Manage.updateQuantitiesModal.successHeading',\n updateSuccessMessage: 'NegotiableQuoteTemplate.Manage.updateQuantitiesModal.successMessage',\n updateErrorHeading: 'NegotiableQuoteTemplate.Manage.updateQuantitiesModal.errorHeading',\n updateErrorMessage: 'NegotiableQuoteTemplate.Manage.updateQuantitiesModal.errorMessage',\n errorHeading:\n 'NegotiableQuoteTemplate.Manage.lineItemNoteModal.errorHeading',\n });\n\n // Use the remove template items hook\n const {\n handleRemoveItems,\n handleConfirmRemove,\n handleCancelRemove,\n isRemoveModalOpen,\n isRemoving,\n removeNotificationState,\n } = useRemoveTemplateItems({\n templateId: templateData?.id,\n removeSuccessMessage: dictionary.removeSuccessMessage,\n removeErrorMessage: dictionary.removeErrorMessage,\n });\n\n // Use the items quoted template hook for dropdown and interaction logic\n const {\n dropdownSelections: hookDropdownSelections,\n handleItemDropdownChange: hookHandleItemDropdownChange,\n handleDismissRemoveBanner,\n } = useItemsQuotedTemplate({\n handleRemoveItems,\n });\n\n // Use the update template quantities hook\n const {\n handleQuantityChange,\n handleUpdate,\n handleConfirmUpdate,\n handleCancelUpdate,\n handleDismissBanner,\n isUpdateModalOpen,\n updateNotificationState,\n } = useUpdateTemplateQuantities({\n templateId: templateData?.id,\n updateSuccessMessage: dictionary.updateSuccessMessage,\n updateErrorMessage: dictionary.updateErrorMessage,\n });\n\n useEffect(() => {\n const templateDataEvent = events.on(\n 'quote-management/quote-template-data',\n (payload) => {\n setTemplateData(payload.quoteTemplate);\n setDropdownSelections({});\n },\n { eager: true }\n );\n\n return () => templateDataEvent?.off();\n }, []);\n\n // Combined handler for dropdown selection that handles both remove (via hook) and edit (for line item notes)\n const handleItemDropdownChange = useCallback(\n (item: ProductListTableItem, action: string) => {\n const templateItem = item as QuoteTemplateCartItem;\n \n // Handle edit action - open line item note modal\n if (action === 'edit') {\n setSelectedItem(templateItem);\n setIsLineItemNoteModalOpen(true);\n // Reset dropdown immediately\n setDropdownSelections((prev) => ({\n ...prev,\n [templateItem.uid || '']: '',\n }));\n return;\n }\n\n // For remove and other actions, delegate to hook handler\n hookHandleItemDropdownChange(item, action);\n },\n [hookHandleItemDropdownChange]\n );\n\n // Merge dropdown selections from hook and local state\n const mergedDropdownSelections = { ...hookDropdownSelections, ...dropdownSelections };\n\n // Handle modal close\n const handleModalClose = useCallback(() => {\n // Clean up dropdown selection for the selected item before clearing it\n /* istanbul ignore else: defensive check - selectedItem should always be truthy when modal is open */\n if (selectedItem) {\n setDropdownSelections((prev) => {\n const next = { ...prev };\n delete next[selectedItem.uid || ''];\n return next;\n });\n }\n setIsLineItemNoteModalOpen(false);\n setSelectedItem(null);\n setIsSubmitting(false);\n setModalErrorMessage('');\n }, [selectedItem]);\n\n // Handle modal confirm - submit note only (quantity is read-only for templates)\n const handleModalConfirm = useCallback(\n async (note: string) => {\n /* istanbul ignore next: defensive guard for async race conditions - unreachable in normal flow as modal only renders with selectedItem and templateData */\n if (!selectedItem || !templateData) return;\n\n setIsSubmitting(true);\n setModalErrorMessage('');\n\n try {\n // Set the line item note\n await addQuoteTemplateLineItemNote({\n templateId: templateData.id,\n itemId: selectedItem.uid || '',\n note,\n });\n\n // Close modal on success\n handleModalClose();\n } catch (error) {\n console.error('Failed to set template line item note:', error);\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Unable to update the item. Please try again.';\n setModalErrorMessage(errorMessage);\n setIsSubmitting(false);\n }\n },\n [selectedItem, templateData, handleModalClose]\n );\n\n // Create remove confirmation banner based on notification state\n const removeConfirmationBanner =\n removeNotificationState.type === 'success' ? (\n <InLineAlert\n type=\"success\"\n variant=\"primary\"\n icon={<CheckWithCircle />}\n heading={dictionary.removeSuccessHeading}\n description={removeNotificationState.message}\n onDismiss={handleDismissRemoveBanner}\n data-testid=\"remove-items-success-banner\"\n />\n ) : removeNotificationState.type === 'error' ? (\n <InLineAlert\n type=\"error\"\n variant=\"primary\"\n icon={<WarningFilled />}\n heading={dictionary.removeErrorHeading}\n description={removeNotificationState.message}\n onDismiss={handleDismissRemoveBanner}\n data-testid=\"remove-items-error-banner\"\n />\n ) : null;\n\n // Create update quantities confirmation banner based on notification state\n const updateConfirmationBanner =\n updateNotificationState.type === 'success' ? (\n <InLineAlert\n type=\"success\"\n variant=\"primary\"\n icon={<CheckWithCircle />}\n heading={dictionary.updateSuccessHeading}\n description={updateNotificationState.message}\n onDismiss={handleDismissBanner}\n data-testid=\"update-quantities-success-banner\"\n />\n ) : updateNotificationState.type === 'error' ? (\n <InLineAlert\n type=\"error\"\n variant=\"primary\"\n icon={<WarningFilled />}\n heading={dictionary.updateErrorHeading}\n description={updateNotificationState.message}\n onDismiss={handleDismissBanner}\n data-testid=\"update-quantities-error-banner\"\n />\n ) : null;\n\n if (!templateData) {\n return <ItemsQuotedComponent loading={true} />;\n }\n\n const removeConfirmationModalProps = isRemoveModalOpen ? {\n open: true,\n title: dictionary.removeModalTitle,\n message: dictionary.removeModalDescription,\n cancelLabel: dictionary.removeModalCancelButton,\n confirmLabel: isRemoving\n ? dictionary.removeModalConfirmButtonRemoving\n : dictionary.removeModalConfirmButton,\n onCancel: handleCancelRemove,\n onConfirm: handleConfirmRemove,\n confirmationBanner: removeConfirmationBanner,\n } : null;\n\n const updateConfirmationModalProps = isUpdateModalOpen ? {\n open: true,\n title: dictionary.updateModalTitle,\n message: dictionary.updateModalDescription,\n cancelLabel: dictionary.updateModalCancelButton,\n confirmLabel: dictionary.updateModalUpdateButton,\n onCancel: handleCancelUpdate,\n onConfirm: handleConfirmUpdate,\n confirmationBanner: updateConfirmationBanner,\n } : null;\n\n // Only define a single confirmation modal\n const confirmationModalProps = removeConfirmationModalProps || updateConfirmationModalProps;\n\n const quotePricesSummaryEntries = [];\n\n templateData.prices.subtotalExcludingTax &&\n quotePricesSummaryEntries.push({\n label: dictionary.subtotal,\n id: 'subtotal',\n value: (\n <Price\n amount={templateData.prices.subtotalExcludingTax.value}\n currency={templateData.prices.subtotalExcludingTax.currency}\n weight=\"normal\"\n />\n ),\n });\n\n templateData.prices.grandTotal &&\n quotePricesSummaryEntries.push({\n label: dictionary.grandTotal,\n id: 'total',\n value: (\n <Price\n amount={templateData.prices.grandTotal.value}\n currency={templateData.prices.grandTotal.currency}\n />\n ),\n strong: true,\n });\n\n // Create modal error banner\n const modalErrorBanner = modalErrorMessage ? (\n <InLineAlert\n type=\"error\"\n variant=\"primary\"\n icon={<WarningFilled />}\n heading={dictionary.errorHeading}\n description={modalErrorMessage}\n onDismiss={() => setModalErrorMessage('')}\n data-testid=\"line-item-note-error-banner\"\n />\n ) : null;\n\n return (\n <>\n <ItemsQuotedComponent\n data-testid=\"items-quoted-template-container\"\n {...props}\n loading={false}\n table={\n <Slot\n name=\"ProductListTable\"\n slot={slots?.ProductListTable}\n context={{\n items: templateData.items,\n canEdit: templateData.canSendForReview,\n dropdownSelections: mergedDropdownSelections,\n handleItemDropdownChange,\n handleQuantityChange,\n handleUpdate,\n }}\n >\n <ProductListTable\n items={templateData.items as ProductListTableItem[]}\n canEdit={templateData.canSendForReview}\n showActions={templateData.canEditTemplateItems}\n onItemDropdownChange={handleItemDropdownChange}\n onQuantityChange={handleQuantityChange}\n onUpdate={handleUpdate}\n dropdownSelections={mergedDropdownSelections}\n />\n </Slot>\n }\n pricesSummary={\n <Slot\n name=\"QuotePricesSummary\"\n slot={slots?.QuotePricesSummary}\n context={{\n items: templateData.items,\n prices: templateData.prices,\n }}\n >\n <QuotePricesSummary entries={quotePricesSummaryEntries} />\n </Slot>\n }\n />\n {/* Confirmation Modal for remove/update */}\n {confirmationModalProps && (\n <ConfirmationModal\n {...confirmationModalProps}\n />\n )}\n {/* Line Item Note Modal */}\n {selectedItem && (\n <LineItemNoteModal\n open={isLineItemNoteModalOpen}\n item={selectedItem as any}\n onClose={handleModalClose}\n onConfirm={handleModalConfirm}\n isSubmitting={isSubmitting}\n readOnlyQuantity={true}\n errorBanner={modalErrorBanner || undefined}\n />\n )}\n </>\n );\n};\n"],"names":["NOTIFICATION_AUTO_DISMISS_DELAY","useRemoveTemplateItems","params","templateId","onRemoveModalStateChange","removeSuccessMessage","removeErrorMessage","isRemoveModalOpen","setIsRemoveModalOpen","useState","itemsToRemove","setItemsToRemove","isRemoving","setIsRemoving","removeNotificationState","setRemoveNotificationState","useEffect","templateDataEvent","events","handleRemoveItems","useCallback","items","handleConfirmRemove","uidsToRemove","item","removeQuoteTemplateItems","err","errorMessage","handleCancelRemove","useItemsQuotedTemplate","dropdownSelections","setDropdownSelections","handleDismissRemoveBanner","handleItemDropdownChange","action","cartItem","prev","next","useUpdateTemplateQuantities","onUpdateModalStateChange","updateSuccessMessage","updateErrorMessage","quantityChanges","setQuantityChanges","isUpdateModalOpen","setIsUpdateModalOpen","isUpdating","setIsUpdating","updateNotificationState","setUpdateNotificationState","handleQuantityChange","newQuantity","itemUid","handleUpdate","e","handleConfirmUpdate","itemId","quantity","updateQuoteTemplateItemQuantities","handleCancelUpdate","handleDismissBanner","ItemsQuotedTemplate","initialData","slots","props","templateData","setTemplateData","selectedItem","setSelectedItem","isLineItemNoteModalOpen","setIsLineItemNoteModalOpen","isSubmitting","setIsSubmitting","modalErrorMessage","setModalErrorMessage","dictionary","useText","hookDropdownSelections","hookHandleItemDropdownChange","payload","templateItem","mergedDropdownSelections","handleModalClose","handleModalConfirm","note","addQuoteTemplateLineItemNote","error","removeConfirmationBanner","jsx","InLineAlert","CheckWithCircle","WarningFilled","updateConfirmationBanner","ItemsQuotedComponent","removeConfirmationModalProps","updateConfirmationModalProps","confirmationModalProps","quotePricesSummaryEntries","Price","modalErrorBanner","jsxs","Fragment","Slot","ProductListTable","QuotePricesSummary","ConfirmationModal","LineItemNoteModal"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /*! Copyright 2025 Adobe
2
+ All Rights Reserved. */
3
+ import{jsx as t,jsxs as o,Fragment as G}from"@dropins/tools/preact-jsx-runtime.js";import{classes as v,VComponent as E}from"@dropins/tools/lib.js";/* empty css */import{Skeleton as C,SkeletonRow as ee,Input as V,Picker as te,Price as Q,Checkbox as ae,Button as F,Table as W,Accordion as ne,AccordionSection as oe,Modal as le,TextArea as ie}from"@dropins/tools/components.js";import{h as z}from"@dropins/tools/preact.js";import{useState as R,useEffect as se}from"@dropins/tools/preact-hooks.js";import{g as ue}from"./dateUtils.js";import{useText as Z}from"@dropins/tools/i18n.js";import{useState as D,useEffect as re,useCallback as O}from"@dropins/tools/preact-compat.js";const ye=({className:N,loading:c,table:a,pricesSummary:u,...i})=>c?t(ce,{}):o("div",{className:v(["quote-management-items-quoted",N]),...i,children:[a&&t(E,{node:a,className:v(["quote-management-items-quoted__table"]),"data-testid":"quote-management-items-quoted__table"}),u&&t(E,{node:u,className:v(["quote-management-items-quoted__prices-summary"]),"data-testid":"quote-management-items-quoted__prices-summary"})]}),ce=()=>t(C,{"data-testid":"items-quoted-skeleton",children:t(ee,{variant:"row",fullWidth:!0,size:"medium",lines:4,multilineGap:"xsmall"})}),ve=({className:N,items:c,canEdit:a,readOnly:u=!1,showActions:i,onItemCheckboxChange:d,onItemDropdownChange:p,onQuantityChange:k,onUpdate:M,dropdownSelections:q,..._})=>{const[T,f]=R({}),[h,b]=R({});se(()=>{const e={};c.forEach(s=>{e[s.uid]=s.quantity}),f(e),b(e)},[c]);const y=Object.keys(h).some(e=>h[e]!==T[e]),n=Z({updateButton:"NegotiableQuote.Manage.productListTable.submitButton",productNameHeader:"NegotiableQuote.Manage.productListTable.headers.productName",skuHeader:"NegotiableQuote.Manage.productListTable.headers.sku",priceHeader:"NegotiableQuote.Manage.productListTable.headers.price",quantityHeader:"NegotiableQuote.Manage.productListTable.headers.quantity",discountHeader:"NegotiableQuote.Manage.productListTable.headers.discount",subtotalHeader:"NegotiableQuote.Manage.productListTable.headers.subtotal",actionsHeader:"NegotiableQuote.Manage.productListTable.headers.actions",editNoteToSeller:"NegotiableQuote.Manage.productListTable.actions.editNoteToSeller",remove:"NegotiableQuote.Manage.productListTable.actions.remove",notesHeader:"NegotiableQuote.Manage.productListTable.notes.header",leftANote:"NegotiableQuote.Manage.productListTable.notes.leftANote",buyer:"NegotiableQuote.Manage.productListTable.notes.buyer"}),I=[{label:n.productNameHeader,key:"productName"},{label:n.skuHeader,key:"sku"},{label:n.priceHeader,key:"price"},{label:n.quantityHeader,key:"quantity"},{label:n.discountHeader,key:"discount"},{label:n.subtotalHeader,key:"subtotal"}];a&&!u&&I.unshift({label:"",key:"checkbox"}),(i??a)&&!u&&I.push({label:n.actionsHeader,key:"actions"});const j=(e,s)=>{const l=e.target.checked;d==null||d(s,l)},S=(e,s)=>{const l=e.target.value;p==null||p(s,l)},B=(e,s)=>{const l=parseInt(e.target.value,10);!isNaN(l)&&l>0&&(b(g=>({...g,[s.uid]:l})),k==null||k(s,l))},$=e=>{e.preventDefault(),M==null||M(e)},r=(e,s)=>e>0?o("div",{className:"quote-management-product-list-table__discount-container",children:[o("span",{className:"quote-management-product-list-table__discount-percent",children:[s,"%"]}),o("span",{className:"quote-management-product-list-table__discount-price",children:["(",t(Q,{amount:e}),")"]})]}):void 0,L=e=>{var g,H;const s=(g=e.configurableOptions)==null?void 0:g.map(m=>o("div",{className:"quote-management-product-list-table__configurable-option",children:[o("span",{className:"quote-management-product-list-table__configurable-option-label",children:[m.optionLabel,":"]}),t("span",{className:"quote-management-product-list-table__configurable-option-value",children:m.valueLabel})]},m.optionLabel)),l=(H=e.bundleOptions)==null?void 0:H.map(m=>o("div",{className:"quote-management-product-list-table__bundle-option",children:[t("span",{className:"quote-management-product-list-table__bundle-option-label",children:m.label}),t("div",{className:"quote-management-product-list-table__bundle-option-values",children:m.values.map(w=>o("span",{className:"quote-management-product-list-table__bundle-option-value",children:[o("span",{className:"quote-management-product-list-table__bundle-option-value-quantity",children:[w.quantity," x"]}),t("span",{className:"quote-management-product-list-table__bundle-option-value-label",children:w.label}),t(Q,{className:"quote-management-product-list-table__bundle-option-value-original-price",amount:w.originalPrice.value,currency:w.originalPrice.currency,weight:"normal"})]},w.label))})]},m.label));return o("div",{className:"quote-management-product-list-table__product-name-container",children:[t("span",{className:"quote-management-product-list-table__product-name",children:e.product.name}),s,l]})},A=e=>new Date(e).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit",hour12:!0,timeZone:ue()}),x=e=>{if(!e.noteFromBuyer||e.noteFromBuyer.length===0)return null;const s=e.noteFromBuyer.filter(l=>l&&l.note&&l.note.trim()!=="");return s.length===0?null:o("div",{className:"quote-management-product-list-table__notes-container","data-testid":`item-notes-${e.product.sku}`,children:[t("div",{className:"quote-management-product-list-table__notes-header",children:n.notesHeader}),t("div",{className:"quote-management-product-list-table__notes-list",children:s.map((l,g)=>o("div",{className:"quote-management-product-list-table__note-item",children:[o("div",{className:"quote-management-product-list-table__note-content",children:[o("strong",{className:"quote-management-product-list-table__note-meta",children:[A(l.createdAt)," (",n.buyer,")"]})," ",n.leftANote]}),o("div",{className:"quote-management-product-list-table__note-text",children:[l.note," "]})]},l.noteUid||g))})]})},J=c.flatMap(e=>{var H;const s=a?t(V,{className:"quote-management-product-list-table__quantity-input",type:"number",min:"1",value:((H=h[e.uid])==null?void 0:H.toString())||e.quantity.toString(),onChange:m=>B(m,e),disabled:u||!a,"data-testid":`quantity-input-${e.product.sku}`}):t("span",{className:"quote-management-product-list-table__quantity",children:e.quantity}),l={checkbox:t(ae,{className:"quote-management-product-list-table__checkbox",name:"itemSelected","data-testid":`item-checkbox-${e.product.sku}`,onChange:m=>j(m,e),value:e.product.sku}),productName:L(e),sku:t("span",{className:"quote-management-product-list-table__sku",children:e.product.sku}),price:t(Q,{className:"quote-management-product-list-table__price",amount:e.prices.originalItemPrice.value,currency:e.prices.originalItemPrice.currency}),quantity:s,discount:e.catalogDiscount?r(e.catalogDiscount.amountOff,e.catalogDiscount.percentOff):void 0,subtotal:t(Q,{className:"quote-management-product-list-table__subtotal",amount:e.prices.rowTotal.value,currency:e.prices.rowTotal.currency}),actions:t(te,{className:"quote-management-product-list-table__actions","data-testid":`item-dropdown-${e.product.sku}`,name:`item-dropdown-${e.product.sku}`,handleSelect:m=>S(m,e),placeholder:"Select",value:(q==null?void 0:q[e.uid])??"",options:[{text:n.editNoteToSeller,value:"edit"},{text:n.remove,value:"remove"}]})},g=x(e);return g?[l,{checkbox:"",productName:t("div",{className:"quote-management-product-list-table__notes-row-wrapper",children:g}),sku:"",price:"",quantity:"",discount:"",subtotal:"",actions:""}]:[l]}),K=t(W,{columns:I,rowData:J,"data-testid":"product-list-table",mobileLayout:"stacked"}),U=a?z("form",{}):z("div",{}),X=a?{onSubmit:$,..._}:_,Y=t(F,{type:"submit",disabled:u||!a||!y,"data-testid":"product-list-table-submit-button",children:n.updateButton});return o(E,{node:U,className:v(["quote-management-product-list-table-container",N]),"data-testid":"product-list-table-container",...X,children:[K,t("div",{className:"quote-management-product-list-table-container__submit-container",children:Y})]})},ke=({className:N,entries:c,...a})=>{const u=i=>{var p;const d=(p=i.children)==null?void 0:p.map(u);return t("div",{className:"quote-management-quote-prices-summary__entry","data-testid":`quote-prices-summary-entry-${i.id}`,children:d?t(ne,{className:"quote-management-quote-prices-summary__accordion","data-testid":`quote-prices-summary-entry-accordion-${i.id}`,children:t(oe,{className:"quote-management-quote-prices-summary__accordion-section",title:i.label,ariaLabelTitle:i.label,secondaryText:i.value,children:d})}):o(G,{children:[t("span",{className:v(["quote-management-quote-prices-summary__label",["quote-management-quote-prices-summary__label--strong",i.strong]]),"data-testid":`quote-prices-summary-entry-label-${i.id}`,children:i.label}),t("span",{className:"quote-management-quote-prices-summary__value","data-testid":`quote-prices-summary-entry-value-${i.id}`,children:i.value})]})},i.id)};return t("div",{className:v(["quote-management-quote-prices-summary",N]),"data-testid":"quote-prices-summary",...a,children:c==null?void 0:c.map(u)})},fe=({className:N,open:c,item:a,onClose:u,onConfirm:i,isSubmitting:d=!1,errorBanner:p,successBanner:k,showCloseButton:M=!0,readOnlyQuantity:q=!1})=>{const[_,T]=D(""),[f,h]=D(a.quantity),[b,y]=D({}),n=Z({title:"NegotiableQuote.Manage.lineItemNote.title",productLabel:"NegotiableQuote.Manage.lineItemNote.productLabel",skuLabel:"NegotiableQuote.Manage.lineItemNote.skuLabel",priceLabel:"NegotiableQuote.Manage.lineItemNote.priceLabel",stockLabel:"NegotiableQuote.Manage.lineItemNote.stockLabel",quantityLabel:"NegotiableQuote.Manage.lineItemNote.quantityLabel",discountLabel:"NegotiableQuote.Manage.lineItemNote.discountLabel",subtotalLabel:"NegotiableQuote.Manage.lineItemNote.subtotalLabel",noteLabel:"NegotiableQuote.Manage.lineItemNote.noteLabel",notePlaceholder:"NegotiableQuote.Manage.lineItemNote.notePlaceholder",noteHelper:"NegotiableQuote.Manage.lineItemNote.noteHelper",confirmButton:"NegotiableQuote.Manage.lineItemNote.confirmButton",cancelButton:"NegotiableQuote.Manage.lineItemNote.cancelButton",noteError:"NegotiableQuote.Manage.lineItemNote.noteError",quantityError:"NegotiableQuote.Manage.lineItemNote.quantityError"});re(()=>{var r;if(c){const L=((r=a.noteFromBuyer)==null?void 0:r.filter(x=>x&&x.note))||[],A=L.length>0?L[0].note:"";T(A||""),h(a.quantity),y({})}},[c,a.quantity,a.noteFromBuyer]);const I=O(()=>{const r={};if(_.trim()||(r.note=n.noteError),!q&&f<=0&&(r.quantity=n.quantityError),Object.keys(r).length>0){y(r);return}i(_.trim(),f)},[_,f,i,n,q]),P=O(()=>{T(""),h(a.quantity),y({}),u==null||u()},[u,a.quantity]);if(!c)return null;const S=a.discounts&&a.discounts.length>0?a.discounts.map(r=>r.label).join(", "):"-",B=[{label:n.productLabel,key:"productName"},{label:n.priceLabel,key:"price"},{label:n.stockLabel,key:"stock"},{label:n.quantityLabel,key:"quantity"},{label:n.discountLabel,key:"discount"},{label:n.subtotalLabel,key:"subtotal"}],$=[{productName:o("div",{className:"quote-management-line-item-note-modal__product-info",children:[t("div",{className:"quote-management-line-item-note-modal__product-name",children:a.product.name}),o("div",{className:"quote-management-line-item-note-modal__product-sku",children:[n.skuLabel,": ",a.product.sku]})]}),price:t(Q,{amount:a.prices.originalItemPrice.value,currency:a.prices.originalItemPrice.currency}),stock:t("span",{className:"quote-management-line-item-note-modal__stock",children:a.stockStatus}),quantity:q?t("span",{className:"quote-management-line-item-note-modal__quantity-readonly",children:a.quantity}):t(V,{name:"quantity",type:"number",min:"1",value:f.toString(),onInput:r=>{const L=parseInt(r.target.value,10)||0;h(L),y({...b,quantity:void 0})},disabled:d,error:!!b.quantity,required:!0,"data-testid":"line-item-note-quantity-input",className:"quote-management-line-item-note-modal__quantity-input"}),discount:t("span",{className:"quote-management-line-item-note-modal__discount",children:S}),subtotal:t(Q,{amount:a.prices.rowTotal.value,currency:a.prices.rowTotal.currency})}];return o(le,{open:c,size:"medium",title:t(G,{children:n.title}),onClose:P,clickToDismiss:!0,escapeToDismiss:!0,showCloseButton:M,className:v(["quote-management-line-item-note-modal",N]),"data-testid":"line-item-note-modal",children:[p&&t("div",{className:"quote-management-line-item-note-modal__error-banner","data-testid":"line-item-note-modal-error-banner",children:p}),k&&t("div",{className:"quote-management-line-item-note-modal__success-banner","data-testid":"line-item-note-modal-success-banner",children:k}),o("div",{className:"quote-management-line-item-note-modal__content",children:[o("div",{className:"quote-management-line-item-note-modal__details",children:[t(W,{columns:B,rowData:$,"data-testid":"line-item-note-table",mobileLayout:"stacked",className:"quote-management-line-item-note-modal__details-table"}),b.quantity&&t("div",{className:"quote-management-line-item-note-modal__table-error",children:b.quantity})]}),o("div",{className:"quote-management-line-item-note-modal__form-field",children:[t(ie,{name:"note",placeholder:n.notePlaceholder,rows:4,value:_,onInput:r=>{T(r.target.value),y({...b,note:void 0})},label:n.noteLabel,disabled:d,"data-testid":"line-item-note-textarea"}),!b.note&&t("span",{className:"quote-management-line-item-note-modal__helper-text",children:n.noteHelper}),b.note&&t("span",{className:"quote-management-line-item-note-modal__error-text",children:b.note})]})]}),o("div",{className:"quote-management-line-item-note-modal__actions",children:[t(F,{variant:"secondary",size:"medium",onClick:P,disabled:d,className:"quote-management-line-item-note-modal__cancel-button","data-testid":"line-item-note-cancel-button",children:n.cancelButton}),t(F,{variant:"primary",size:"medium",onClick:I,disabled:d,className:"quote-management-line-item-note-modal__confirm-button","data-testid":"line-item-note-confirm-button",children:n.confirmButton})]})]})};export{ye as I,fe as L,ve as P,ke as Q};
4
+ //# sourceMappingURL=LineItemNoteModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LineItemNoteModal.js","sources":["/@dropins/storefront-quote-management/src/components/ItemsQuoted/ItemsQuoted.tsx","/@dropins/storefront-quote-management/src/components/ProductListTable/ProductListTable.tsx","/@dropins/storefront-quote-management/src/components/QuotePricesSummary/QuotePricesSummary.tsx","/@dropins/storefront-quote-management/src/components/LineItemNoteModal/LineItemNoteModal.tsx"],"sourcesContent":["/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport '@/quote-management/components/ItemsQuoted/ItemsQuoted.css';\nimport { Skeleton, SkeletonRow } from '@adobe-commerce/elsie/components';\n\nexport interface ItemsQuotedProps extends Omit<HTMLAttributes<HTMLDivElement>, 'loading'> {\n loading?: boolean;\n table?: VNode;\n pricesSummary?: VNode;\n}\n\nexport const ItemsQuoted: FunctionComponent<ItemsQuotedProps> = ({\n className,\n loading,\n table,\n pricesSummary,\n ...props\n}) => {\n if (loading) {\n return <ItemsQuotedSkeleton />;\n }\n\n return (\n <div className={classes(['quote-management-items-quoted', className])} {...props}>\n {table && (\n <VComponent\n node={table}\n className={classes(['quote-management-items-quoted__table'])}\n data-testid=\"quote-management-items-quoted__table\"\n />\n )}\n {pricesSummary && (\n <VComponent\n node={pricesSummary}\n className={classes(['quote-management-items-quoted__prices-summary'])}\n data-testid=\"quote-management-items-quoted__prices-summary\"\n />\n )}\n </div>\n );\n};\n\nexport const ItemsQuotedSkeleton: FunctionComponent = () => {\n return (\n <Skeleton data-testid=\"items-quoted-skeleton\">\n <SkeletonRow variant=\"row\" fullWidth={true} size=\"medium\" lines={4} multilineGap='xsmall' />\n </Skeleton>\n );\n};","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { FunctionComponent, h } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { useState, useEffect } from 'preact/hooks';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport {\n Table,\n Checkbox,\n Picker,\n Price,\n Button,\n Input,\n} from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { getUserTimezone } from '@/quote-management/utils/dateUtils';\n\nimport '@/quote-management/components/ProductListTable/ProductListTable.css';\n\nexport interface ProductListTableItem {\n uid: string;\n product: {\n name: string;\n sku: string;\n };\n prices: {\n originalItemPrice: {\n value: number;\n currency: string;\n };\n rowTotal: {\n value: number;\n currency: string;\n };\n };\n quantity: number;\n catalogDiscount?: {\n amountOff: number;\n percentOff: number;\n };\n configurableOptions?: Array<{\n optionLabel: string;\n valueLabel: string;\n }>;\n bundleOptions?: Array<{\n label: string;\n values: Array<{\n label: string;\n quantity: number;\n originalPrice: {\n value: number;\n currency: string;\n };\n }>;\n }>;\n noteFromBuyer?: Array<{\n createdAt: string;\n creatorId: number;\n creatorType: number;\n negotiableQuoteItemUid: string;\n note: string;\n noteUid: string;\n }>;\n}\n\nexport interface ProductListTableProps\n extends HTMLAttributes<HTMLDivElement | HTMLFormElement> {\n items: ProductListTableItem[];\n canEdit: boolean;\n readOnly?: boolean;\n showActions?: boolean;\n onItemCheckboxChange?: (\n item: ProductListTableItem,\n isSelected: boolean\n ) => void;\n onItemDropdownChange?: (item: ProductListTableItem, action: string) => void;\n onQuantityChange?: (item: ProductListTableItem, newQuantity: number) => void;\n onUpdate?: (e: SubmitEvent) => void;\n dropdownSelections?: Record<string, string | undefined>;\n}\n\nexport const ProductListTable: FunctionComponent<ProductListTableProps> = ({\n className,\n items,\n canEdit,\n readOnly = false,\n showActions,\n onItemCheckboxChange,\n onItemDropdownChange,\n onQuantityChange,\n onUpdate,\n dropdownSelections,\n ...props\n}) => {\n // Track original quantities to detect changes\n const [originalQuantities, setOriginalQuantities] = useState<\n Record<string, number>\n >({});\n const [currentQuantities, setCurrentQuantities] = useState<\n Record<string, number>\n >({});\n\n // Initialize quantities when items change\n useEffect(() => {\n const quantities: Record<string, number> = {};\n items.forEach((item) => {\n quantities[item.uid] = item.quantity;\n });\n setOriginalQuantities(quantities);\n setCurrentQuantities(quantities);\n }, [items]);\n\n // Check if any quantities have changed\n const hasQuantityChanges = Object.keys(currentQuantities).some(\n (uid) => currentQuantities[uid] !== originalQuantities[uid]\n );\n\n const dictionary = useText({\n updateButton: 'NegotiableQuote.Manage.productListTable.submitButton',\n productNameHeader:\n 'NegotiableQuote.Manage.productListTable.headers.productName',\n skuHeader: 'NegotiableQuote.Manage.productListTable.headers.sku',\n priceHeader: 'NegotiableQuote.Manage.productListTable.headers.price',\n quantityHeader: 'NegotiableQuote.Manage.productListTable.headers.quantity',\n discountHeader: 'NegotiableQuote.Manage.productListTable.headers.discount',\n subtotalHeader: 'NegotiableQuote.Manage.productListTable.headers.subtotal',\n actionsHeader: 'NegotiableQuote.Manage.productListTable.headers.actions',\n editNoteToSeller:\n 'NegotiableQuote.Manage.productListTable.actions.editNoteToSeller',\n remove: 'NegotiableQuote.Manage.productListTable.actions.remove',\n notesHeader: 'NegotiableQuote.Manage.productListTable.notes.header',\n leftANote: 'NegotiableQuote.Manage.productListTable.notes.leftANote',\n buyer: 'NegotiableQuote.Manage.productListTable.notes.buyer',\n });\n\n const columns = [\n {\n label: dictionary.productNameHeader,\n key: 'productName',\n },\n {\n label: dictionary.skuHeader,\n key: 'sku',\n },\n {\n label: dictionary.priceHeader,\n key: 'price',\n },\n {\n label: dictionary.quantityHeader,\n key: 'quantity',\n },\n {\n label: dictionary.discountHeader,\n key: 'discount',\n },\n {\n label: dictionary.subtotalHeader,\n key: 'subtotal',\n },\n ];\n\n // Add checkbox column when canEdit (for bulk operations)\n if (canEdit && !readOnly) {\n columns.unshift({\n label: '',\n key: 'checkbox',\n });\n }\n\n // Add actions column when showActions is explicitly true, or when canEdit is true and showActions is not explicitly false\n const shouldShowActions = showActions ?? canEdit;\n if (shouldShowActions && !readOnly) {\n columns.push({\n label: dictionary.actionsHeader,\n key: 'actions',\n });\n }\n\n const handleItemCheckboxChange = (\n event: Event,\n item: ProductListTableItem\n ) => {\n const isSelected = (event.target as HTMLInputElement).checked;\n onItemCheckboxChange?.(item, isSelected);\n };\n\n const handleItemDropdownChange = (\n event: Event,\n item: ProductListTableItem\n ) => {\n const action = (event.target as HTMLSelectElement).value;\n onItemDropdownChange?.(item, action);\n };\n\n const handleQuantityChange = (event: Event, item: ProductListTableItem) => {\n const newQuantity = parseInt((event.target as HTMLInputElement).value, 10);\n if (!isNaN(newQuantity) && newQuantity > 0) {\n setCurrentQuantities((prev) => ({\n ...prev,\n [item.uid]: newQuantity,\n }));\n onQuantityChange?.(item, newQuantity);\n }\n };\n\n const handleUpdate = (event: SubmitEvent) => {\n event.preventDefault();\n onUpdate?.(event);\n };\n\n const discountElement = (amountOff: number, percentOff: number) => {\n return amountOff > 0 ? (\n <div className=\"quote-management-product-list-table__discount-container\">\n <span className=\"quote-management-product-list-table__discount-percent\">\n {percentOff}%\n </span>\n <span className=\"quote-management-product-list-table__discount-price\">\n (<Price amount={amountOff} />)\n </span>\n </div>\n ) : undefined;\n };\n\n const getProductNameContent = (item: ProductListTableItem) => {\n const configurableOptions = item.configurableOptions?.map((option) => (\n <div\n key={option.optionLabel}\n className=\"quote-management-product-list-table__configurable-option\"\n >\n <span className=\"quote-management-product-list-table__configurable-option-label\">\n {option.optionLabel}:\n </span>\n <span className=\"quote-management-product-list-table__configurable-option-value\">\n {option.valueLabel}\n </span>\n </div>\n ));\n\n const bundleOptions = item.bundleOptions?.map((option) => (\n <div\n key={option.label}\n className=\"quote-management-product-list-table__bundle-option\"\n >\n <span className=\"quote-management-product-list-table__bundle-option-label\">\n {option.label}\n </span>\n <div className=\"quote-management-product-list-table__bundle-option-values\">\n {option.values.map((value) => (\n <span\n key={value.label}\n className=\"quote-management-product-list-table__bundle-option-value\"\n >\n <span className=\"quote-management-product-list-table__bundle-option-value-quantity\">\n {value.quantity} x\n </span>\n <span className=\"quote-management-product-list-table__bundle-option-value-label\">\n {value.label}\n </span>\n <Price\n className=\"quote-management-product-list-table__bundle-option-value-original-price\"\n amount={value.originalPrice.value}\n currency={value.originalPrice.currency}\n weight=\"normal\"\n />\n </span>\n ))}\n </div>\n </div>\n ));\n\n return (\n <div className=\"quote-management-product-list-table__product-name-container\">\n <span className=\"quote-management-product-list-table__product-name\">\n {item.product.name}\n </span>\n {configurableOptions}\n {bundleOptions}\n </div>\n );\n };\n\n const formatNoteTimestamp = (timestamp: string) => {\n const date = new Date(timestamp);\n return date.toLocaleString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n hour12: true,\n timeZone: getUserTimezone(),\n });\n };\n\n const getNotesContent = (item: ProductListTableItem) => {\n // Check if notes exist and have valid data\n if (!item.noteFromBuyer || item.noteFromBuyer.length === 0) {\n return null;\n }\n\n // Filter out notes with null or empty note text\n const validNotes = item.noteFromBuyer.filter(\n (note) => note && note.note && note.note.trim() !== ''\n );\n\n if (validNotes.length === 0) {\n return null;\n }\n\n return (\n <div\n className=\"quote-management-product-list-table__notes-container\"\n data-testid={`item-notes-${item.product.sku}`}\n >\n <div className=\"quote-management-product-list-table__notes-header\">\n {dictionary.notesHeader}\n </div>\n <div className=\"quote-management-product-list-table__notes-list\">\n {validNotes.map((note, index) => (\n <div\n key={note.noteUid || index}\n className=\"quote-management-product-list-table__note-item\"\n >\n <div className=\"quote-management-product-list-table__note-content\">\n <strong className=\"quote-management-product-list-table__note-meta\">\n {/* TODO: When backend exposes creator_name for notes, replace (Buyer) with the actual name */}\n {formatNoteTimestamp(note.createdAt)} ({dictionary.buyer})\n </strong>{' '}\n {dictionary.leftANote}\n </div>\n <div className=\"quote-management-product-list-table__note-text\">\n {note.note}{' '}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n };\n\n const rowData = items.flatMap((item) => {\n const quantityElement = canEdit ? (\n <Input\n className=\"quote-management-product-list-table__quantity-input\"\n type=\"number\"\n min=\"1\"\n value={\n currentQuantities[item.uid]?.toString() || item.quantity.toString()\n }\n onChange={(e) => handleQuantityChange(e, item)}\n disabled={readOnly || !canEdit}\n data-testid={`quantity-input-${item.product.sku}`}\n />\n ) : (\n <span className=\"quote-management-product-list-table__quantity\">\n {item.quantity}\n </span>\n );\n\n const productRow = {\n checkbox: (\n <Checkbox\n className=\"quote-management-product-list-table__checkbox\"\n name=\"itemSelected\"\n data-testid={`item-checkbox-${item.product.sku}`}\n onChange={(e) => handleItemCheckboxChange(e, item)}\n value={item.product.sku}\n />\n ),\n productName: getProductNameContent(item),\n sku: (\n <span className=\"quote-management-product-list-table__sku\">\n {item.product.sku}\n </span>\n ),\n price: (\n <Price\n className=\"quote-management-product-list-table__price\"\n amount={item.prices.originalItemPrice.value}\n currency={item.prices.originalItemPrice.currency}\n />\n ),\n quantity: quantityElement,\n discount: item.catalogDiscount\n ? discountElement(\n item.catalogDiscount.amountOff,\n item.catalogDiscount.percentOff\n )\n : undefined,\n subtotal: (\n <Price\n className=\"quote-management-product-list-table__subtotal\"\n amount={item.prices.rowTotal.value}\n currency={item.prices.rowTotal.currency}\n />\n ),\n actions: (\n <Picker\n className=\"quote-management-product-list-table__actions\"\n data-testid={`item-dropdown-${item.product.sku}`}\n name={`item-dropdown-${item.product.sku}`}\n handleSelect={(e) => handleItemDropdownChange(e, item)}\n placeholder=\"Select\"\n value={dropdownSelections?.[item.uid] ?? ''}\n options={[\n { text: dictionary.editNoteToSeller, value: 'edit' },\n { text: dictionary.remove, value: 'remove' },\n ]}\n />\n ),\n };\n\n const notes = getNotesContent(item);\n\n // If there are notes, create a notes row\n if (notes) {\n const notesRow = {\n checkbox: '',\n productName: (\n <div className=\"quote-management-product-list-table__notes-row-wrapper\">\n {notes}\n </div>\n ),\n sku: '',\n price: '',\n quantity: '',\n discount: '',\n subtotal: '',\n actions: '',\n };\n return [productRow, notesRow];\n }\n\n return [productRow];\n });\n\n const table = (\n <Table\n columns={columns}\n rowData={rowData}\n data-testid=\"product-list-table\"\n mobileLayout=\"stacked\"\n />\n );\n\n // if can edit, the wrapper node should use the form element, else use the div element\n const wrapperNode = canEdit ? h('form', {}) : h('div', {});\n const wrapperProps = canEdit\n ? {\n onSubmit: handleUpdate,\n ...props,\n }\n : props;\n\n const submitButton = (\n <Button\n type=\"submit\"\n disabled={readOnly || !canEdit || !hasQuantityChanges}\n data-testid=\"product-list-table-submit-button\"\n >\n {dictionary.updateButton}\n </Button>\n );\n\n return (\n <VComponent\n node={wrapperNode}\n className={classes([\n 'quote-management-product-list-table-container',\n className,\n ])}\n data-testid=\"product-list-table-container\"\n {...wrapperProps}\n >\n {table}\n <div className=\"quote-management-product-list-table-container__submit-container\">\n {submitButton}\n </div>\n </VComponent>\n );\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n \nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport '@/quote-management/components/QuotePricesSummary/QuotePricesSummary.css';\nimport { Accordion, AccordionSection } from '@adobe-commerce/elsie/components';\n\ninterface Entry {\n label: string;\n id: string;\n value: VNode;\n strong?: boolean;\n children?: Entry[];\n}\n\nexport interface QuotePricesSummaryProps extends HTMLAttributes<HTMLDivElement> {\n entries?: Entry[];\n}\n\nexport const QuotePricesSummary: FunctionComponent<QuotePricesSummaryProps> = ({\n className,\n entries,\n ...props\n}) => {\n const createEntry = (entry: Entry) => {\n const children = entry.children?.map(createEntry);\n return (\n <div key={entry.id} className=\"quote-management-quote-prices-summary__entry\" data-testid={`quote-prices-summary-entry-${entry.id}`}>\n {children ? <Accordion\n className=\"quote-management-quote-prices-summary__accordion\"\n data-testid={`quote-prices-summary-entry-accordion-${entry.id}`}\n >\n <AccordionSection className=\"quote-management-quote-prices-summary__accordion-section\" title={entry.label} ariaLabelTitle={entry.label} secondaryText={entry.value}>\n {children}\n </AccordionSection>\n </Accordion>\n :\n <>\n <span className={classes(['quote-management-quote-prices-summary__label', ['quote-management-quote-prices-summary__label--strong', entry.strong]])} data-testid={`quote-prices-summary-entry-label-${entry.id}`}>{entry.label}</span>\n <span className=\"quote-management-quote-prices-summary__value\" data-testid={`quote-prices-summary-entry-value-${entry.id}`}>{entry.value}</span>\n </>\n }\n </div>\n );\n };\n\n return (\n <div className={classes(['quote-management-quote-prices-summary', className])} data-testid=\"quote-prices-summary\" {...props}>\n {entries?.map(createEntry)}\n </div>\n );\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this\n * file in accordance with the terms of the Adobe license agreement\n * accompanying it.\n *******************************************************************/\n\nimport { FunctionComponent, VNode } from 'preact';\nimport {\n HTMLAttributes,\n useCallback,\n useEffect,\n useState,\n} from 'preact/compat';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport {\n Button,\n TextArea,\n Input,\n Modal,\n Price,\n Table,\n} from '@adobe-commerce/elsie/components';\nimport { NegotiableQuoteCartItem } from '@/quote-management/data/models/negotiable-quote-model';\nimport '@/quote-management/components/LineItemNoteModal/LineItemNoteModal.css';\n\nexport interface LineItemNoteModalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n open: boolean;\n item: NegotiableQuoteCartItem;\n onClose?: () => void;\n onConfirm: (note: string, quantity: number) => void;\n isSubmitting?: boolean;\n errorBanner?: VNode;\n successBanner?: VNode;\n showCloseButton?: boolean;\n readOnlyQuantity?: boolean;\n}\n\nexport const LineItemNoteModal: FunctionComponent<LineItemNoteModalProps> = ({\n className,\n open,\n item,\n onClose,\n onConfirm,\n isSubmitting = false,\n errorBanner,\n successBanner,\n showCloseButton = true,\n readOnlyQuantity = false,\n}) => {\n const [note, setNote] = useState('');\n const [quantity, setQuantity] = useState(item.quantity);\n const [errors, setErrors] = useState<{ note?: string; quantity?: string }>(\n {}\n );\n\n const dictionary = useText({\n title: 'NegotiableQuote.Manage.lineItemNote.title',\n productLabel: 'NegotiableQuote.Manage.lineItemNote.productLabel',\n skuLabel: 'NegotiableQuote.Manage.lineItemNote.skuLabel',\n priceLabel: 'NegotiableQuote.Manage.lineItemNote.priceLabel',\n stockLabel: 'NegotiableQuote.Manage.lineItemNote.stockLabel',\n quantityLabel: 'NegotiableQuote.Manage.lineItemNote.quantityLabel',\n discountLabel: 'NegotiableQuote.Manage.lineItemNote.discountLabel',\n subtotalLabel: 'NegotiableQuote.Manage.lineItemNote.subtotalLabel',\n noteLabel: 'NegotiableQuote.Manage.lineItemNote.noteLabel',\n notePlaceholder: 'NegotiableQuote.Manage.lineItemNote.notePlaceholder',\n noteHelper: 'NegotiableQuote.Manage.lineItemNote.noteHelper',\n confirmButton: 'NegotiableQuote.Manage.lineItemNote.confirmButton',\n cancelButton: 'NegotiableQuote.Manage.lineItemNote.cancelButton',\n noteError: 'NegotiableQuote.Manage.lineItemNote.noteError',\n quantityError: 'NegotiableQuote.Manage.lineItemNote.quantityError',\n });\n\n // Reset form when modal opens with new item\n useEffect(() => {\n if (open) {\n // Get the most recent valid note from buyer (if exists)\n const validNotes =\n item.noteFromBuyer?.filter((note) => note && note.note) || [];\n const existingNote = validNotes.length > 0 ? validNotes[0].note : '';\n setNote(existingNote || '');\n setQuantity(item.quantity);\n setErrors({});\n }\n }, [open, item.quantity, item.noteFromBuyer]);\n\n const handleConfirm = useCallback(() => {\n const newErrors: { note?: string; quantity?: string } = {};\n\n // Check if the note field is empty\n if (!note.trim()) {\n newErrors.note = dictionary.noteError;\n }\n\n // Only validate quantity if it's editable\n if (!readOnlyQuantity && quantity <= 0) {\n newErrors.quantity = dictionary.quantityError;\n }\n\n if (Object.keys(newErrors).length > 0) {\n setErrors(newErrors);\n return;\n }\n\n onConfirm(note.trim(), quantity);\n }, [note, quantity, onConfirm, dictionary, readOnlyQuantity]);\n\n const handleCancel = useCallback(() => {\n setNote('');\n setQuantity(item.quantity);\n setErrors({});\n onClose?.();\n }, [onClose, item.quantity]);\n\n if (!open) {\n return null;\n }\n\n // Calculate discount display\n const hasDiscount = item.discounts && item.discounts.length > 0;\n const discountDisplay = hasDiscount\n ? item.discounts.map((d) => d.label).join(', ')\n : '-';\n\n // Define table columns\n const columns = [\n {\n label: dictionary.productLabel,\n key: 'productName',\n },\n {\n label: dictionary.priceLabel,\n key: 'price',\n },\n {\n label: dictionary.stockLabel,\n key: 'stock',\n },\n {\n label: dictionary.quantityLabel,\n key: 'quantity',\n },\n {\n label: dictionary.discountLabel,\n key: 'discount',\n },\n {\n label: dictionary.subtotalLabel,\n key: 'subtotal',\n },\n ];\n\n // Define table row data\n const rowData = [\n {\n productName: (\n <div className=\"quote-management-line-item-note-modal__product-info\">\n <div className=\"quote-management-line-item-note-modal__product-name\">\n {item.product.name}\n </div>\n <div className=\"quote-management-line-item-note-modal__product-sku\">\n {dictionary.skuLabel}: {item.product.sku}\n </div>\n </div>\n ),\n price: (\n <Price\n amount={item.prices.originalItemPrice.value}\n currency={item.prices.originalItemPrice.currency}\n />\n ),\n stock: (\n <span className=\"quote-management-line-item-note-modal__stock\">\n {item.stockStatus}\n </span>\n ),\n quantity: readOnlyQuantity ? (\n <span className=\"quote-management-line-item-note-modal__quantity-readonly\">\n {item.quantity}\n </span>\n ) : (\n <Input\n name=\"quantity\"\n type=\"number\"\n min=\"1\"\n value={quantity.toString()}\n onInput={(e: any) => {\n const newQuantity = parseInt(e.target.value, 10) || 0;\n setQuantity(newQuantity);\n setErrors({ ...errors, quantity: undefined });\n }}\n disabled={isSubmitting}\n error={!!errors.quantity}\n required\n data-testid=\"line-item-note-quantity-input\"\n className=\"quote-management-line-item-note-modal__quantity-input\"\n />\n ),\n discount: (\n <span className=\"quote-management-line-item-note-modal__discount\">\n {discountDisplay}\n </span>\n ),\n subtotal: (\n <Price\n amount={item.prices.rowTotal.value}\n currency={item.prices.rowTotal.currency}\n />\n ),\n },\n ];\n\n return (\n <Modal\n open={open}\n size=\"medium\"\n title={<>{dictionary.title}</>}\n onClose={handleCancel}\n clickToDismiss={true}\n escapeToDismiss={true}\n showCloseButton={showCloseButton}\n className={classes(['quote-management-line-item-note-modal', className])}\n data-testid=\"line-item-note-modal\"\n >\n {errorBanner && (\n <div\n className=\"quote-management-line-item-note-modal__error-banner\"\n data-testid=\"line-item-note-modal-error-banner\"\n >\n {errorBanner}\n </div>\n )}\n\n {successBanner && (\n <div\n className=\"quote-management-line-item-note-modal__success-banner\"\n data-testid=\"line-item-note-modal-success-banner\"\n >\n {successBanner}\n </div>\n )}\n\n <div className=\"quote-management-line-item-note-modal__content\">\n {/* Product Details Table */}\n <div className=\"quote-management-line-item-note-modal__details\">\n <Table\n columns={columns}\n rowData={rowData}\n data-testid=\"line-item-note-table\"\n mobileLayout=\"stacked\"\n className=\"quote-management-line-item-note-modal__details-table\"\n />\n {errors.quantity && (\n <div className=\"quote-management-line-item-note-modal__table-error\">\n {errors.quantity}\n </div>\n )}\n </div>\n\n {/* Note TextArea */}\n <div className=\"quote-management-line-item-note-modal__form-field\">\n <TextArea\n name=\"note\"\n placeholder={dictionary.notePlaceholder}\n rows={4}\n value={note}\n onInput={(e: any) => {\n setNote(e.target.value);\n setErrors({ ...errors, note: undefined });\n }}\n label={dictionary.noteLabel}\n disabled={isSubmitting}\n data-testid=\"line-item-note-textarea\"\n />\n {!errors.note && (\n <span className=\"quote-management-line-item-note-modal__helper-text\">\n {dictionary.noteHelper}\n </span>\n )}\n {errors.note && (\n <span className=\"quote-management-line-item-note-modal__error-text\">\n {errors.note}\n </span>\n )}\n </div>\n </div>\n\n <div className=\"quote-management-line-item-note-modal__actions\">\n <Button\n variant=\"secondary\"\n size=\"medium\"\n onClick={handleCancel}\n disabled={isSubmitting}\n className=\"quote-management-line-item-note-modal__cancel-button\"\n data-testid=\"line-item-note-cancel-button\"\n >\n {dictionary.cancelButton}\n </Button>\n <Button\n variant=\"primary\"\n size=\"medium\"\n onClick={handleConfirm}\n disabled={isSubmitting}\n className=\"quote-management-line-item-note-modal__confirm-button\"\n data-testid=\"line-item-note-confirm-button\"\n >\n {dictionary.confirmButton}\n </Button>\n </div>\n </Modal>\n );\n};\n"],"names":["ItemsQuoted","className","loading","table","pricesSummary","props","ItemsQuotedSkeleton","jsxs","classes","jsx","VComponent","Skeleton","SkeletonRow","ProductListTable","items","canEdit","readOnly","showActions","onItemCheckboxChange","onItemDropdownChange","onQuantityChange","onUpdate","dropdownSelections","originalQuantities","setOriginalQuantities","useState","currentQuantities","setCurrentQuantities","useEffect","quantities","item","hasQuantityChanges","uid","dictionary","useText","columns","handleItemCheckboxChange","event","isSelected","handleItemDropdownChange","action","handleQuantityChange","newQuantity","prev","handleUpdate","discountElement","amountOff","percentOff","Price","getProductNameContent","configurableOptions","_a","option","bundleOptions","_b","value","formatNoteTimestamp","timestamp","getUserTimezone","getNotesContent","validNotes","note","index","rowData","quantityElement","Input","e","productRow","Checkbox","Picker","notes","Table","wrapperNode","h","wrapperProps","submitButton","Button","QuotePricesSummary","entries","createEntry","entry","children","Accordion","AccordionSection","Fragment","LineItemNoteModal","open","onClose","onConfirm","isSubmitting","errorBanner","successBanner","showCloseButton","readOnlyQuantity","setNote","quantity","setQuantity","errors","setErrors","existingNote","handleConfirm","useCallback","newErrors","handleCancel","discountDisplay","d","Modal","TextArea"],"mappings":"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"}
@@ -185,6 +185,12 @@ const e=`
185
185
  }
186
186
  telephone
187
187
  }
188
+ reference_document_links {
189
+ link_id
190
+ document_name
191
+ document_identifier
192
+ reference_document_url
193
+ }
188
194
  }
189
195
  `;export{e as N};
190
196
  //# sourceMappingURL=NegotiableQuoteTemplateFragment.js.map