1import{g as Ve,r as o,I as He,aj as j,p as e,eT as Ue,S as Q,T as I,L as N,ag as je,B as c,af as Se,y as Z,bj as S,J as Ke,bp as D,q as me,D as We,v as te,w as q,bh as J,bE as qe,bn as Je,bm as Ye,aI as Ge,ak as Ze,aZ as Qe,N as Y,z as Xe}from"./index-C9IH3k-2.js";import{N as et,J as tt,g as be,a8 as at,D as st,a2 as nt,aa as ot}from"./TemplateUtil-D1DzmWLm.js";import{R as ge,a as fe,B as lt,r as rt,b as it}from"./BulkPropertyPickerModal-D1tUwAuz.js";import{a as xe}from"./AuditConstant-C6syQHOu.js";import{u as ct}from"./HelperMethods-C-ewwU_x.js";import{P as ve}from"./PageDescription-BrOUsEZE.js";import{C as dt}from"./ContactDetails-BvKMn_Ck.js";import{C as ut}from"./ContactImportModal-DTGgpDln.js";import{P as pt}from"./index-C0dhduHx.js";import{a as ht}from"./MainApp-BoiAvjMg.js";import{R as mt}from"./FileAddOutlined-AdYKRQbz.js";import{F as bt}from"./Table-isZ0WXp4.js";import"./Wrapper-ChjuDa3w.js";import"./index-CmSVNJzc.js";import"./index-Bv3SRNsl.js";import"./CalendarOutlined-DyzsKNdO.js";import"./ClockCircleOutlined-Cym7vptW.js";import"./ContactNotesPanel-Dw1brjVq.js";import"./index-DNqpjC0Z.js";import"./Pagination-D1z-xPUv.js";import"./papaparse.min-CbyEf3Jx.js";import"./ContactUtil-CNNd5h8z.js";import"./InfoCircleOutlined-B7sKwm1k.js";import"./InboxOutlined-C0X09Vz7.js";import"./index-BOwvFOZJ.js";import"./HolderOutlined-YOHjCGKZ.js";var G={},Ce;function gt(){if(Ce)return G;Ce=1,Object.defineProperty(G,"__esModule",{value:!0});var u={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M251.2 387H320v68.8c0 1.8 1.8 3.2 4 3.2h48c2.2 0 4-1.4 4-3.3V387h68.8c1.8 0 3.2-1.8 3.2-4v-48c0-2.2-1.4-4-3.3-4H376v-68.8c0-1.8-1.8-3.2-4-3.2h-48c-2.2 0-4 1.4-4 3.2V331h-68.8c-1.8 0-3.2 1.8-3.2 4v48c0 2.2 1.4 4 3.2 4zm328 0h193.6c1.8 0 3.2-1.8 3.2-4v-48c0-2.2-1.4-4-3.3-4H579.2c-1.8 0-3.2 1.8-3.2 4v48c0 2.2 1.4 4 3.2 4zm0 265h193.6c1.8 0 3.2-1.8 3.2-4v-48c0-2.2-1.4-4-3.3-4H579.2c-1.8 0-3.2 1.8-3.2 4v48c0 2.2 1.4 4 3.2 4zm0 104h193.6c1.8 0 3.2-1.8 3.2-4v-48c0-2.2-1.4-4-3.3-4H579.2c-1.8 0-3.2 1.8-3.2 4v48c0 2.2 1.4 4 3.2 4zm-195.7-81l61.2-74.9c4.3-5.2.7-13.1-5.9-13.1H388c-2.3 0-4.5 1-5.9 2.9l-34 41.6-34-41.6a7.85 7.85 0 00-5.9-2.9h-50.9c-6.6 0-10.2 7.9-5.9 13.1l61.2 74.9-62.7 76.8c-4.4 5.2-.8 13.1 5.8 13.1h50.8c2.3 0 4.5-1 5.9-2.9l35.5-43.5 35.5 43.5c1.5 1.8 3.7 2.9 5.9 2.9h50.8c6.6 0 10.2-7.9 5.9-13.1L383.5 675zM880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-36 732H180V180h664v664z"}}]},name:"calculator",theme:"outlined"};return G.default=u,G}var ft=gt();const xt=Ve(ft);function se(){return se=Object.assign?Object.assign.bind():function(u){for(var x=1;x<arguments.length;x++){var C=arguments[x];for(var v in C)Object.prototype.hasOwnProperty.call(C,v)&&(u[v]=C[v])}return u},se.apply(this,arguments)}const Ct=(u,x)=>o.createElement(He,se({},u,{ref:x,icon:xt})),yt=o.forwardRef(Ct),{Option:ye}=Q,{Text:jt}=I,St=({visible:u,onCancel:x,contactAttributes:C,contactLabel:v,onContactCreated:F})=>{const[T]=j.useForm(),[$,E]=o.useState(!1),z=j.useWatch("attributes",T),k=(l,p)=>(z||[]).some((y,w)=>w!==p&&y?.attributeId===l),V=(l,p)=>{p||T.setFieldValue(["attributes",l,"attributeValue"],void 0)},B=async()=>{try{const l=await T.validateFields(),p=(l.attributes||[]).reduce((m,d)=>(d?.attributeId&&d?.attributeValue&&(m[d.attributeId]=d.attributeValue),m),{}),y={receiverNumber:`+${l.receiverNumber.countryCode}${l.receiverNumber.phoneNumber}`,attributes:p,labels:l.labels||[]};E(!0),(await Z("/api/v1/contact/save",y))?.status===200&&(S.success({title:"Contact Created",description:"New contact has been successfully created.",placement:"topRight"}),F(),T.resetFields(),x())}catch(l){console.error("Create contact failed:",l)}finally{E(!1)}},H=(l,p)=>p?.phoneNumber?/^[0-9]{6,15}$/.test(String(p.phoneNumber))?Promise.resolve():Promise.reject(new Error("Please enter a valid phone number!")):Promise.reject(new Error("Please input contact phone number!"));return e.jsxs(et,{title:e.jsx(N,{children:e.jsx("span",{children:"Create Contact"})}),open:u,onOk:B,onCancel:x,confirmLoading:$,okText:"Save Contact",children:[e.jsx(ve,{children:'Fill in the phone number, then pick any labels and attributes you want on the contact. Choosing an attribute unlocks its value box, and "Add another attribute" gives you an extra row. Everything on screen is saved when you click "Save Contact" â rows you leave blank are ignored.'}),e.jsxs(j,{form:T,layout:"vertical",autoComplete:"off",requiredMark:"optional",style:{marginTop:8},children:[e.jsx(j.Item,{name:"receiverNumber",label:"Phone Number",validateTrigger:"onSubmit",rules:[{validator:H,required:!0}],children:e.jsx(Ue,{})}),e.jsx(j.Item,{name:"labels",label:"Label(s)",children:e.jsx(Q,{mode:"multiple",placeholder:"Select label(s)",style:{width:"100%"},showSearch:!0,optionFilterProp:"children",children:v?.map(l=>e.jsx(ye,{value:l.id,children:l.name},l.id))})}),e.jsx(j.Item,{label:"Attribute(s)",style:{marginBottom:0},children:C?.length?e.jsx(j.List,{name:"attributes",initialValue:[{}],children:(l,{add:p,remove:y})=>e.jsxs("div",{children:[l.map((w,m)=>e.jsxs(N,{gap:8,align:"flex-start",children:[e.jsx(j.Item,{name:[m,"attributeId"],style:{flex:1},children:e.jsx(Q,{placeholder:"Select attribute",showSearch:!0,optionFilterProp:"children",allowClear:!0,onChange:d=>V(m,d),children:C.map(d=>e.jsx(ye,{value:d.id,disabled:k(d.id,m),children:d.name},d.id))})}),e.jsx(j.Item,{name:[m,"attributeValue"],style:{flex:1},children:e.jsx(je,{placeholder:"Enter value",disabled:!z?.[m]?.attributeId})}),l.length>1&&e.jsx(c,{icon:e.jsx(tt,{}),onClick:()=>y(m),type:"text",danger:!0})]},w.key)),l.length<C.length&&e.jsx(c,{type:"dashed",size:"small",icon:e.jsx(Se,{}),onClick:()=>p(),children:"Add another attribute"})]})}):e.jsx(jt,{type:"secondary",children:"No attributes set up yet. You can create them from Contact â Contact Attribute."})})]})]})},vt="/api/v1/contact/upload",ae="contacts_selected_attribute_columns",Tt="contacts-virtual-table",kt=100,Qt=()=>{const{token:u}
1=Ke.useToken(),[x,C]=o.useState(null),[v,F]=o.useState([]),[T,$]=o.useState([]),[E,z]=o.useState(!1),[k,V]=o.useState([]),[B,H]=o.useState(!1),[l,p]=o.useState(!1),[y,w]=o.useState(!1),[m,d]=o.useState(null),[_,ne]=o.useState(()=>{const t=localStorage.getItem(ae);return t?JSON.parse(t):[]}),[Te,ke]=o.useState(!1),[oe,le]=o.useState(!0),[re,X]=o.useState(null),[we,ie]=o.useState(!1),ee={pagination:{current:1,pageSize:D},order:[{fieldName:"id",dir:"desc"}],search:[]},[A,ce]=o.useState(ee),f=me(t=>t.contactAttributes),U=me(t=>t.contactLabel),Ie=o.useRef(null),Ne=o.useRef(null),de=o.useRef({loading:!1,hasMore:!0,tableData:[],tableParams:ee}),ue=We(),h=ct(),[L,K]=o.useState([]),[M,pe]=o.useState(!1),[_e,P]=o.useState(null);de.current={loading:B,hasMore:oe,tableData:k,tableParams:A};const W=(t,a,s)=>{a(),ce(n=>({...n,search:[...n.search.filter(r=>r.fieldName!==s),{fieldName:s,value:t[0]}]}))};o.useEffect(()=>{if(f?.length>0){const t=f.map(s=>s.id),a=_.filter(s=>t.includes(s));a.length!==_.length&&(ne(a),localStorage.setItem(ae,JSON.stringify(a)))}},[f]);const Ae=t=>{ne(t),localStorage.setItem(ae,JSON.stringify(t))},Le=f?.map(t=>({label:t.name,value:t.id})).sort((t,a)=>t.label.localeCompare(a.label)),he=(t,a)=>({filterDropdown:({setSelectedKeys:s,selectedKeys:n,confirm:r,clearFilters:i,close:b})=>e.jsxs(N,{gap:"small",vertical:!0,style:{padding:8},onKeyDown:g=>g.stopPropagation(),children:[e.jsx(je,{ref:Ie,placeholder:`Search ${a}`,value:n[0],onChange:g=>s(g.target.value?[g.target.value]:[]),onPressEnter:()=>W(n,r,t)}),e.jsxs(te,{children:[e.jsx(c,{type:"primary",onClick:()=>W(n,r,t),icon:e.jsx(Qe,{}),size:"small",children:"Search"}),e.jsx(c,{type:"link",onClick:()=>b(),size:"small",children:"Close"})]})]})}),Pe=async t=>{d(t);const a=`delete-${t}`;try{Y.loading({content:"Deleting contact...",key:a});const s=await Xe(`/api/v1/contact/${t}`);s?.data?.success?(V(n=>n.filter(r=>r.id!==t)),X(n=>n!==null?Math.max(0,n-1):n),Y.success({content:"Contact deleted successfully!",key:a})):Y.error({content:s?.data?.message||"Failed to delete contact. Please try again.",key:a})}catch(s){console.error("Failed to delete contact:",s),Y.error({content:"Failed to delete contact. Please try again.",key:a})}finally{d(null)}},Re=[{title:"Id",dataIndex:"id",key:"id"},{title:"Whatsapp Name",dataIndex:"whatsappName",key:"whatsappName",...he("whatsappName","Whatsapp Name")},{title:"Phone Number",dataIndex:"receiverNumber",key:"receiverNumber",...he("receiverNumber","Phone Number")},..._.map(t=>({title:f?.find(s=>s.id===t)?.name||t,dataIndex:["attributes",t],key:`attribute_${t}`,render:(s,n)=>e.jsx(I.Text,{children:n?.attributes?.[t]||"-"})})),{title:"Creation Time",dataIndex:"creationTime",key:"creationTime",sorter:(t,a)=>!0,...xe("creationTime","Creation Time",()=>{},()=>{},W),render:(t,a)=>e.jsx(I.Text,{children:be(a.creationTime)})},{title:"Last Update Time",dataIndex:"lastUpdateTime",key:"lastUpdateTime",sorter:(t,a)=>!0,...xe("lastUpdateTime","Last Update Time",()=>{},()=>{},W),render:(t,a)=>e.jsx(I.Text,{children:be(a.lastUpdateTime)})},{title:"Action",key:"action",render:(t,a)=>e.jsxs(te,{size:"middle",children:[e.jsx(q,{title:h("view_contacts")?"":J,children:e.jsx(c,{type:"link",onClick:()=>Fe(a),disabled:!h("view_contacts"),children:"View Profile"})}),e.jsx(pt,{title:"Delete contact",description:"Are you sure you want to delete this contact?",onConfirm:()=>Pe(a.id),okText:"Yes",cancelText:"No",okButtonProps:{loading:m===a.id},disabled:!h("manage_contacts"),children:e.jsx(q,{title:h("manage_contacts")?"":J,children:e.jsx(c,{loading:m===a.id,disabled:!h("manage_contacts"),children:e.jsx(qe,{})})})})]})}];o.useEffect(()=>{U?.length===0&&ze(),f?.length===0&&Ee(),R(A)},[]);const Oe=t=>{const{loading:a,hasMore:s,tableData:n,tableParams:r}=de.current;if(a||!s||n.length===0)return;const{scrollTop:i,scrollHeight:b,clientHeight:g}=t.target;if(b-i-g>kt)return;const O=n[n.length-1]?.id;O&&R(r,{append:!0,cursorId:O})},R=async(t,{append:a=!1,cursorId:s=null}={})=>{H(!0);try{const n=(t.search??[]).filter(g=>g.fieldName!=="id"),r=s?[...n,{fieldName:"id",value:[s],operator:"lt"}]:n,i={pagination:{current:1,pageSize:D},order:t.order,search:r},b=await Z("/api/v1/contact/lists",i,!1);if(b?.status===200){const g=b.data.results??[];V(O=>a?[...O,...g]:g),le(g.length===D),ce(O=>({...O,order:t.order,search:n,pagination:{current:1,pageSize:D}}))}}catch(n){S.error({title:"Failed to fetch contacts data",description:n.response?.data?.detail||"An error occurred while fetching contacts data. Please try again."})}finally{H(!1)}},De=async()=>{ie(!0);try{const t={pagination:{current:1,pageSize:D},order:A.order,search:(A.search??[]).filter(s=>s.fieldName!=="id")},a=await Z("/api/v1/contact/count",t,!1);a?.status===200&&X(a.data.total)}catch(t){S.error({title:"Failed to fetch total count",description:t.response?.data?.detail||"An error occurred while fetching total count. Please try again."})}finally{ie(!1)}},Ee=async()=>
1{const a=await at({order:[{fieldName:"creationTime",dir:"desc"}]});a?.status===200&&ue(Je(a.data.results))},ze=async()=>{const a=await Z("/api/v1/contact/label/list",{order:[{fieldName:"creationTime",dir:"desc"}]});a?.status===200&&ue(Ye(a.data.results))},Be={addLabel:"setLabel",removeLabel:"deleteLabel",setAttribute:"setAttribute",removeAttribute:"deleteAttribute"},Me=async(t,a={})=>{if(L.length){pe(!0);try{const s=await rt({url:it.contact[t],body:{selection:{ids:L},...a}});if(!s.ok){S.error({title:"Bulk action failed",description:"Please try again."});return}s.mode==="SYNC"?(S.success({title:"Success",description:`Updated ${s.affectedCount} contact${s.affectedCount===1?"":"s"}`}),K([]),R(A)):(K([]),S.info({title:"Bulk operation in progress",description:"It's running in the background â refresh in a bit to see the result."}))}catch(s){const n=s?.response?.status;n===429?S.warning({title:"Another bulk operation is running",description:"Please wait for it to finish and try again."}):n===400?S.error({title:"Selection too large",description:"This selection exceeds the bulk limit."}):S.error({title:"Bulk action failed",description:s?.response?.data?.detail||"Please try again."})}finally{pe(!1)}}},Fe=t=>{C(t),z(!0);const a=[],s=[];if(t?.attributes&&Object.entries(t.attributes)?.forEach(([n,r])=>{const i=f?.find(b=>b.id===n);i?a.push({label:i.name,value:r,id:i.id}):a.push({label:n,value:r,id:n})}),t?.labels&&t?.labels?.length>0)for(let n=0;n<t.labels.length;n++){const r=U?.find(i=>i.id===t.labels[n]);r?s.push({id:r.id,name:r.name,colorCode:r.colorCode}):s.push({id:t.labels[n],name:t.labels[n],colorCode:"#000000"})}$(s),F(a)},$e=(t,a,s)=>{const n=s&&Object.keys(s).length!==0&&s.order?[{fieldName:s.columnKey,dir:s.order==="descend"?"desc":"asc"}]:ee.order,r=Object.entries(a??{}).map(([i,b])=>({fieldName:i,value:b!==null?i!=="creationTime"&&i!=="lastUpdateTime"?b:b.map(ot):null})).filter(({value:i})=>i);X(null),le(!0),R({pagination:{current:1,pageSize:D},search:r,order:n})};return e.jsxs(N,{vertical:!0,gap:"large",children:[e.jsxs(N,{justify:"space-between",wrap:!0,children:[e.jsx(I.Title,{level:4,style:{margin:0},children:"Contacts"}),e.jsxs(N,{gap:"small",wrap:!0,children:[e.jsx(c,{icon:e.jsx(yt,{}),onClick:De,loading:we,children:re!==null?`Total: ${re}`:"Get Total Count"}),e.jsx(st,{trigger:["click"],open:Te,onOpenChange:ke,popupRender:()=>e.jsxs("div",{style:{backgroundColor:u.colorBgContainer,padding:"12px",borderRadius:"8px",minWidth:"250px"},children:[e.jsx(I.Text,{strong:!0,style:{display:"block",marginBottom:"8px"},children:"Select Attribute Columns"}),e.jsx(Q,{mode:"multiple",style:{width:"100%"},placeholder:"Search and select attributes",value:_,onChange:Ae,options:Le,showSearch:{filterOption:(t,a)=>a.label.toLowerCase().includes(t.toLowerCase())},maxTagCount:"responsive",allowClear:!0})]}),children:e.jsxs(c,{icon:e.jsx(ht,{}),disabled:!f||f.length===0,children:["Columns ",_.length>0&&`(${_.length})`]})}),e.jsx(q,{title:h("manage_contacts")?"":J,children:e.jsx(c,{onClick:()=>{w(!0)},icon:e.jsx(Se,{}),disabled:!h("manage_contacts"),children:"Create Contact"})}),e.jsx(q,{title:h("manage_contacts")?"":J,children:e.jsx(c,{onClick:()=>{p(!0)},icon:e.jsx(mt,{}),type:"primary",disabled:!h("manage_contacts"),children:"Import Contacts"})})]})]}),e.jsx(ve,{children:`This page displays all your WhatsApp contacts that were created automatically through incoming messages or added via bulk upload. To import multiple contacts at once, click the "Import Contacts" button. You can view a contact's complete profile or delete a contact using the options in the "Action" column and add attributes and labels to the contacts.`}),y&&e.jsx(St,{visible:y,onCancel:()=>w(!1),contactAttributes:f,contactLabel:U,onContactCreated:()=>{R(A)}}),L.length>0&&e.jsxs(N,{align:"center",justify:"space-between",gap:8,wrap:!0,style:{padding:"8px 12px",border:`1px solid ${u.colorBorderSecondary}`,borderRadius:8,background:u.colorFillQuaternary},children:[e.jsxs(I.Text,{strong:!0,children:[L.length," selected"]}),e.jsxs(te,{wrap:!0,children:[e.jsx(c,{size:"small",icon:e.jsx(ge,{}),disabled:M||!h("set_contact_properties"),onClick:()=>P("addLabel"),children:"Add label"}),e.jsx(c,{size:"small",icon:e.jsx(ge,{}),disabled:M||!h("set_contact_properties"),onClick:()=>P("removeLabel"),children:"Remove label"}),e.jsx(c,{size:"small",icon:e.jsx(fe,{}),disabled:M||!h("set_contact_properties"),onClick:()=>P("setAttribute"),children:"Set attribute"}),e.jsx(c,{size:"small",icon:e.jsx(fe,{}),disabled:M||!h("set_contact_properties"),onClick:()=>P("removeAttribute"),children:"Remove attribute"}),e.jsx(c,{size:"small",type:"text",icon:e.jsx(Ge,{}),onClick:()=>K([]),children:"Clear"})]})]}),e.jsx(lt,{picker:_e,count:L.length,busy:M,onClose:()=>P(null),onSubmit:(t,a)=>{Me(Be[t],a),P(null)}}),e.jsxs("div",{ref:Ne,className:Tt,style:{position:"relative",height:"calc(100vh - 200px)",overflow:"hidden",flex:1},children:[e.jsx(bt,{columns:Re,dataSource:k,onChange:$e,onScroll:Oe,rowKey:t=>t.id,rowSelection:{selectedRowKeys:L,onChange:K,preserveSelectedRowKeys:!0},pagination:!1,loading:B&&k.length===0,scroll:{y:"calc(100vh - 250px)",x:"max-content"},style:{tableLayout:"fixed"}}),B&&k.length>0&&e.jsx("div",{style:{textAlign:"center",padding:"16px 0",position:"absolute",bottom:0,width:"100%",background:u.colorBg
1Container},children:e.jsx(Ze,{size:"small"})}),!oe&&k.length>0&&e.jsx(nt,{plain:!0,children:"No more contacts"})]}),E&&e.jsx(dt,{contact:x,drawerOpen:E,setDrawerOpen:z,attributesList:v,contactLabelList:T,contactAttributes:f,contactLabel:U,getContactsData:R,setContactLabelList:$,setAttributesList:F}),l&&e.jsx(ut,{title:"Import Contacts",visible:l,onCancel:()=>p(!1),uploadContactType:vt,hideAttributes:!1})]})};export{Qt as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.