1import{r as l,u as _e,j as e,x as ye,z as ve,A as ge,E as Ne,H as be,h as b,I as B,a as v,k as G,J as fe,s as g,g as Ge,l as Oe,e as Me,B as Y,a0 as us,X as We,Z as xs,M as He,c as Ve,R as ps,t as he,K as $e,O as ue,p as xe,bD as ae,y as js,bl as fs,bA as ys,F as vs}from"./index-Ca4tXbhP.js";import{T as gs,a as Ns,b as pe,c as je}from"./tabs-7UjhhrtT.js";import{C as W,b as Z,c as J,d as te,a as H}from"./card-CDzwMRM_.js";import{S as ce,a as le,b as oe,c as de,d as ne}from"./select-DomlGSjs.js";import{C as Ie}from"./checkbox-HDjosks7.js";import{E as Fe}from"./eye-off-BXXQQD2O.js";import{E as De}from"./eye-Cup-pwZB.js";import{S as $}from"./switch-_S42s3Sv.js";import{M as bs}from"./Microsoft365ConfigDialog-BRFpGb5S.js";import{A as Ue,b as Qe,a as Le}from"./alert-DWwiNYR_.js";import{C as Pe}from"./circle-alert-BvHrzmIe.js";import{M as Ze}from"./message-square-Dfq00xQr.js";import{B as Te,W as Be}from"./webhook-D0Uf3clb.js";import{S as Je}from"./send-D1hpK9Im.js";import{T as Ce,a as ke,b as re,c as D,d as Ae,e as z}from"./table-BTHAs7El.js";import{P as ze}from"./plus-D6H_8kbB.js";import{T as qe}from"./trash-2-D91rMF1V.js";import{C as ws}from"./circle-play-BspkXJ9L.js";import{C as _s}from"./circle-check-big-ClXFTM3I.js";import{f as Xe}from"./formatDistanceToNow-BrOtZkA6.js";import{P as Re}from"./constants-C00Sdttl.js";import{C as Se}from"./circle-check-C7lElpJC.js";import{E as Ss}from"./external-link-BOJcJEBZ.js";import{A as es,h as ss,a as ts,b as as,c as ns,d as is,e as rs,f as cs,g as ls}from"./alert-dialog-w_l9UI0h.js";import{C as Cs}from"./copy-_Ulm3kQY.js";import{K as ks,N as As}from"./network-VtyvIt2O.js";import{f as Ee}from"./format-CSElo41U.js";import{I as Is}from"./info-BY7PNa0v.js";import{S as Ts}from"./settings-2-JjN1cono.js";import{P as Ms}from"./pencil-CJE6M_To.js";import{R as Ps}from"./refresh-ccw-D7EA6xG9.js";import{L as Es}from"./list-Ily9kVEr.js";import{K as Fs}from"./key-round-C1cG_ojr.js";import"./index-BBYs9_-K.js";import"./chevron-down-CehTtW6C.js";import"./en-US-DIpmK7ci.js";import"./endOfMonth-DRG_7ovb.js";import"./endOfDay-B7Bn6eKT.js";import"./startOfDay-_cpaJ4Ty.js";const Ds={openai:["gpt-4o","gpt-4o-mini"],gemini:["gemini-2.0-flash-exp","gemini-1.5-pro"],claude:["claude-3-5-sonnet-20241022","claude-3-5-haiku-20241022"],openrouter:["openai/gpt-4o-mini","openai/gpt-4o","anthropic/claude-3.5-sonnet","google/gemini-2.0-flash-exp","meta-llama/llama-3.3-70b-instruct","auto"]};function zs({open:c,onOpenChange:j,provider:t,existingConfig:d}){var i,w,N,s,a;const[_,C]=l.useState(""),[M,n]=l.useState(!1),[P,k]=l.useState((d==null?void 0:d.model_preference)||""),[S,y]=l.useState(!1),[I,r]=l.useState(!1),[p,A]=l.useState({suggestions:((i=d==null?void 0:d.enabled_features)==null?void 0:i.suggestions)??!0,triage:((w=d==null?void 0:d.enabled_features)==null?void 0:w.triage)??!0,replies:((N=d==null?void 0:d.enabled_features)==null?void 0:N.replies)??!0,knowledge_base:((s=d==null?void 0:d.enabled_features)==null?void 0:s.knowledge_base)??!1}),{toast:T}=_e(),x=async()=>{if(!_&&!d){T({title:"API Key Required",description:"Please enter an API key to test the connection.",variant:"destructive"});return}y(!0);try{const{data:u,error:m}=await g.functions.invoke("ai-provider",{body:{action:"test",provider:t.id,apiKey:_||void 0}});if(m)throw m;if(u.success)T({title:"Connection Successful",description:`Successfully connected to ${t.name}.`});else throw new Error(u.error||"Connection failed")}catch(u){T({title:"Connection Failed",description:u.message||"Failed to connect to the AI provider.",variant:"destructive"})}finally{y(!1)}},o=async()=>{if(!_&&!d){T({title:"API Key Required",description:"Please enter an API key.",variant:"destructive"});return}r(!0);try{const{data:u,error:m}=await g.functions.invoke("ai-provider",{body:{action:"save",provider:t.id,apiKey:_||void 0,modelPreference:P||void 0,enabledFeatures:p,isActive:!0}});if(m)throw m;if(u.success)T({title:"Settings Saved",description:`${t.name} has been configured successfully.`}),j(!1),window.location.reload();else throw new Error(u.error||"Failed to save settings")}catch(u){T({title:"Save Failed",description:u.message||"Failed to save AI provider settings.",variant:"destructive"})}finally{r(!1)}};return e.jsx(ye,{open:c,onOpenChange:j,children:e.jsxs(ve,{className:"sm:max-w-[500px]",children:[e.jsxs(ge,{children:[e.jsxs(Ne,{children:["Configure ",t.name]}),e.jsxs(be,{children:["Enter your API key and preferences to enable AI features powered by ",t.name,"."]})]}),e.jsxs("div",{className:"grid gap-4 py-4",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(b,{htmlFor:"api-key",children:"API Key"}),e.jsxs("div",{className:"relative",children:[e.jsx(B,{id:"api-key",type:M?"text":"password",placeholder:d?"â¢â¢â¢â¢â¢â¢â¢â¢â¢â¢â¢â¢â¢â¢â¢â¢":"Enter your API key",value:_,onCh
1ange:u=>C(u.target.value),className:"pr-10"}),e.jsx(v,{type:"button",variant:"ghost",size:"sm",className:"absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent",onClick:()=>n(!M),children:M?e.jsx(Fe,{className:"h-4 w-4"}):e.jsx(De,{className:"h-4 w-4"})})]}),!d&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"Your API key will be encrypted and stored securely."})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(b,{htmlFor:"model",children:"Preferred Model (Optional)"}),e.jsxs(ce,{value:P,onValueChange:k,children:[e.jsx(le,{id:"model",children:e.jsx(oe,{placeholder:"Select a model"})}),e.jsx(de,{children:(a=Ds[t.id])==null?void 0:a.map(u=>e.jsx(ne,{value:u,children:u},u))})]})]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsx(b,{children:"Enabled Features"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ie,{id:"suggestions-feature",checked:p.suggestions,onCheckedChange:u=>A(m=>({...m,suggestions:u}))}),e.jsx(b,{htmlFor:"suggestions-feature",className:"text-sm font-normal",children:"Ticket Suggestions"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ie,{id:"triage-feature",checked:p.triage,onCheckedChange:u=>A(m=>({...m,triage:u}))}),e.jsx(b,{htmlFor:"triage-feature",className:"text-sm font-normal",children:"Ticket Triage"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ie,{id:"replies-feature",checked:p.replies,onCheckedChange:u=>A(m=>({...m,replies:u}))}),e.jsx(b,{htmlFor:"replies-feature",className:"text-sm font-normal",children:"Comment Suggestions"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(Ie,{id:"knowledge-base-feature",checked:p.knowledge_base,onCheckedChange:u=>A(m=>({...m,knowledge_base:u}))}),e.jsx(b,{htmlFor:"knowledge-base-feature",className:"text-sm font-normal",children:"Knowledge Base Article Improvement"})]})]})]}),e.jsx(v,{variant:"outline",onClick:x,disabled:S||!_&&!d,children:S?e.jsxs(e.Fragment,{children:[e.jsx(G,{className:"mr-2 h-4 w-4 animate-spin"}),"Testing Connection..."]}):"Test Connection"})]}),e.jsxs(fe,{children:[e.jsx(v,{variant:"outline",onClick:()=>j(!1),disabled:I,children:"Cancel"}),e.jsx(v,{onClick:o,disabled:I||!_&&!d,children:I?e.jsxs(e.Fragment,{children:[e.jsx(G,{className:"mr-2 h-4 w-4 animate-spin"}),"Saving..."]}):"Save Configuration"})]})]})})}function os({open:c,onOpenChange:j,existingConfig:t}){var s,a,u,m,E,F;const[d,_]=l.useState(!1),[C,M]=l.useState(!1),[n,P]=l.useState(!1),[k,S]=l.useState([]),[y,I]=l.useState([]),[r,p]=l.useState({}),[A,T]=l.useState("credentials"),{toast:x}=_e(),[o,i]=l.useState({instanceUrl:((s=t==null?void 0:t.configuration)==null?void 0:s.instanceUrl)||"",clientId:((a=t==null?void 0:t.credentials)==null?void 0:a.clientId)||"",clientSecret:((u=t==null?void 0:t.credentials)==null?void 0:u.clientSecret)||"",syncDevices:((m=t==null?void 0:t.configuration)==null?void 0:m.syncDevices)??!0,syncAlerts:((E=t==null?void 0:t.configuration)==null?void 0:E.syncAlerts)??!0,syncInterval:((F=t==null?void 0:t.configuration)==null?void 0:F.syncInterval)||"60",isActive:(t==null?void 0:t.is_active)??!0});l.useEffect(()=>{c&&(async()=>{const{data:q}=await g.from("clients").select("id, name").eq("is_active",!0).order("name");q&&I(q)})()},[c]);const w=async()=>{if(!o.instanceUrl||!o.clientId||!o.clientSecret){x({title:"Validation Error",description:"Please fill in all required fields first.",variant:"destructive"});return}P(!0);try{const{data:h,error:q}=await g.functions.invoke("fetch-ninja-organizations",{body:{credentials:{instanceUrl:o.instanceUrl,clientId:o.clientId,clientSecret:o.clientSecret}}});if(q)throw q;h!=null&&h.organizations&&(S(h.organizations),T("mapping"),x({title:"Connection Successful",description:`Found ${h.organizations.length} organization(s). Please map them to your clients.`}))}catch(h){x({title:"Connection Failed",description:h.message||"Failed to connect to NinjaRMM. Please check your credentials.",variant:"destructive"})}finally{P(!1)}},N=async()=>{if(!o.instanceUrl||!o.clientId||!o.clientSecret){x({title:"Validation Error",description:"Please fill in all required fields.",variant:"destructive"});return}_(!0);try{const{data:{user:h}}=await g.auth.getUser(),q={name:"NinjaRMM",type:"ninjarmm",category:"monitoring",is_active:o.isActive,configuration:{instanceUrl:o.instanceUrl,syncDevices:o.syncDevices,syncAlerts:o.syncAlerts,syncInterval:parseInt(o.syncInterval)},credentials:{clientId:o.clientId,clientSecret:o.clientSecret},auth_type:"oauth2",created_by:h==null?void 0:h.id};let X;if(t?X=(await g.from("integrations").update(q).eq("id",t.id)).error:X=(await g.from("integrations").insert([q])).error,X)throw X;let ee=t==null?void 0:t.id;if(!ee){const{data:V}=await g.from("integrations").select("id").eq("type","ninjarmm").eq("created_by",h==null?void 0:h.id).order("created_at",{ascending:!1}).limit(1).single();ee=V==null?void 0:V.id}if(A==="mapping"&&ee){const V=Object.entries(r).map(([K,ie])=>{var me;return{integration_id:ee,ninja_org_id:K,ninja_org_name:((me=k.find(f=>f.id===K))==null?void 0:me.name)||"",client_id:ie.client_id,sync_devices:ie.sync_devices,sync_alerts:ie.sync_alerts,is_active:!0}});if(V.length>0){const{error:K}=await g.from("ninja_rmm_company_mappings").upsert(V,{onConflict:"integration_id,ninja_org_id"});if(K)throw K}}x({title:"Success",description:`NinjaRMM integration ${t?"updated":"configured"} successfully.`}),j(!1),T("credentials"),S([]),p({})}catch(h){x({title:"Error",description:h.message||"Failed to save configuration.",variant:"destructive"})}finally{_(!1)}};return e.jsx(ye,{open:c,onOpenChange:j,children:e.jsxs(ve,{className:"sm:max-w-[700px] max-h-[90vh] overflow-y-auto",children:[e.jsxs(ge,{children:[e.jsx(Ne,{children:"Configure NinjaRMM Integration"}),e.jsx(be,{children:A==="credentials"?"Connect your NinjaRMM account to sync device inventory, monitoring alerts, and asset data.":"Map NinjaRMM organizations to your clients for proper asset tracking."})]}),e.jsx("div",{className:"space-y-4 py-4",children:A==="credentials"?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"instanceUrl",children:"Instance URL *"}),e.jsx(B,{id:"instanceUrl",placeholder:"https://api.ninjarmm.com",value:o.instanceUrl,onChange:h=>i({...o,instanceUrl:h.target.value})}),o.instanceUrl&&o.instanceUrl.includes(".rmmservice.com")&&e.jsx("p",{className:"text-xs text-warning",children:"â ï¸ Use your API base host (e.g., https://api.ninjarmm.com), not your tenant domain"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Use your NinjaOne API base URL (e.g., https://api.ninjarmm.com or regional API host)"}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-2",children:[e.jsx("strong",{children:"OAuth Application Requirements:"}),' Ensure your NinjaOne OAuth app is configured with "API Services" platform and "Client Credentials" grant type enabled.']})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"clientId",children:"Client ID *"}),e.jsx(B,{id:"clientId",placeholder:"Enter your NinjaRMM Client ID",value:o.clientId,onChange:h=>i({...o,clientId:h.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"clientSecret",children:"Client Secret *"}),e.jsxs("div",{className:"relative",children:[e.jsx(B,{id:"clientSecret",type:C?"text":"password",placeholder:"Enter your NinjaRMM Client Secret",value:o.clientSecret,onChange:h=>i({...o,clientSecret:h.target.value}),className:"pr-10"}),e.jsx(v,{type:"button",variant:"ghost",size:"icon",className:"absolute right-0 top-0 h-full",onClick:()=>M(!C),children:C?e.jsx(Fe,{className:"h-4 w-4"}):e.jsx(De,{className:"h-4 w-4"})})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Get your Client ID and Secret from NinjaRMM Admin â API Access"})]}),e.jsxs("div",{className:"space-y-3 pt-2",children:[e.jsx(b,{children:"Sync Options"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(b,{htmlFor:"syncDevices",className:"text-sm font-normal",children:"Sync Devices"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Import device inventory as assets"})]}),e.jsx($,{id:"syncDevices",checked:o.syncDevices,onCheckedChange:h=>i({...o,syncDevices:h})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(b,{htmlFor:"syncAlerts",className:"text-sm font-normal",children:"Sync Monitoring Alerts"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Create tickets from monitoring alerts"})]}),e.jsx($,{id:"syncAlerts",checked:o.syncAlerts,onCheckedChange:h=>i({...o,syncAlerts:h})})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"syncInterval",children:"Sync Interval (minutes)"}),e.jsx(B,{id:"syncInterval",type:"number",min:"15",max:"1440",value:o.syncInterval,onChange:h=>i({...o,syncInterval:h.target.value})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"How often to sync data from NinjaRMM (15-1440 minutes)"})]}),e.jsxs("div",{className:"flex items-center justify-between pt-2",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(b,{htmlFor:"isActive",className:"text-sm font-normal",children:"Enable Integration"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Activate sync immediately after saving"})]}),e.jsx($,{id:"isActive",checked:o.isActive,onCheckedChange:h=>i({...o,isActive:h})})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs(W,{children:[e.jsxs(Z,{children:[e.jsxs(J,{className:"flex items-center gap-2",children:[e.jsx(Ge,{className:"h-5 w-5"}),"Company Mappings"]}),e.jsx(te,{children:"Map each NinjaRMM organization to the corresponding client in your system"})]}),e.jsx(H,{className:"space-y-4",children:k.map(h=>{var q,X,ee,V;return e.jsxs("div",{className:"border rounded-lg p-4 space-y-3",children:[e.jsx("div",{className:"flex items-start justify-between",children:e.jsxs("div",{className:"space-y-1",children:[e.jsx("h4",{className:"font-medium",children:h.name}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[h.deviceCount," device",h.deviceCount!==1?"s":""]})]})}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{children:"Map to Client"}),e.jsxs(ce,{value:((q=r[h.id])==null?void 0:q.client_id)||"",onValueChange:K=>{var ie,me;p({...r,[h.id]:{...r[h.id],ninja_org_id:h.id,client_id:K,sync_devices:((ie=r[h.id])==null?void 0:ie.sync_devices)??!0,sync_alerts:((me=r[h.id])==null?void 0:me.sync_alerts)??!0}})},children:[e.jsx(le,{children:e.jsx(oe,{placeholder:"Select a client..."})}),e.jsx(de,{children:y.map(K=>e.jsx(ne,{value:K.id,children:K.name},K.id))})]})]}),((X=r[h.id])==null?void 0:X.client_id)&&e.jsxs("div",{className:"flex gap-4 pt-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx($,{checked:((ee=r[h.id])==null?void 0:ee.sync_devices)??!0,onCheckedChange:K=>{p({...r,[h.id]:{...r[h.id],sync_devices:K}})}}),e.jsx(b,{className:"text-sm font-normal",children:"Sync Devices"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx($,{checked:((V=r[h.id])==null?void 0:V.sync_alerts)??!0,onCheckedChange:K=>{p({...r,[h.id]:{...r[h.id],sync_alerts:K}})}}),e.jsx(b,{className:"text-sm font-normal",children:"Sync Alerts"})]})]})]}
1,h.id)})})]}),e.jsx(v,{variant:"outline",onClick:()=>{T("credentials"),S([])},className:"w-full",children:"Back to Credentials"})]})}),e.jsx(fe,{children:A==="credentials"?e.jsxs(e.Fragment,{children:[e.jsx(v,{variant:"outline",onClick:()=>j(!1),disabled:d||n,children:"Cancel"}),e.jsxs(v,{onClick:w,disabled:d||n,children:[n&&e.jsx(G,{className:"mr-2 h-4 w-4 animate-spin"}),"Test Connection & Continue"]})]}):e.jsxs(e.Fragment,{children:[e.jsx(v,{variant:"outline",onClick:()=>{j(!1),T("credentials"),S([]),p({})},disabled:d,children:"Cancel"}),e.jsxs(v,{onClick:N,disabled:d||Object.keys(r).length===0,children:[d&&e.jsx(G,{className:"mr-2 h-4 w-4 animate-spin"}),"Save & Start Syncing"]})]})})]})})}function ds({open:c,onOpenChange:j,existingConfig:t}){var q,X,ee,V,K,ie,me;const[d,_]=l.useState(!1),[C,M]=l.useState(!1),[n,P]=l.useState(!1),[k,S]=l.useState(!1),[y,I]=l.useState(!1),[r,p]=l.useState([]),[A,T]=l.useState([]),[x,o]=l.useState("credentials"),[i,w]=l.useState(""),{toast:N}=_e(),[s,a]=l.useState({apiKey:((q=t==null?void 0:t.credentials)==null?void 0:q.apiKey)||"",selectedPhone:((X=t==null?void 0:t.configuration)==null?void 0:X.phoneNumber)||"",connectionId:((ee=t==null?void 0:t.configuration)==null?void 0:ee.connectionId)||"",smsEnabled:((K=(V=t==null?void 0:t.configuration)==null?void 0:V.features)==null?void 0:K.sms)??!0,voiceEnabled:((me=(ie=t==null?void 0:t.configuration)==null?void 0:ie.features)==null?void 0:me.voice)??!0,isActive:(t==null?void 0:t.is_active)??!0});l.useEffect(()=>{var f,R,U,se,O,Q,L;t&&a({apiKey:((f=t==null?void 0:t.credentials)==null?void 0:f.apiKey)||"",selectedPhone:((R=t==null?void 0:t.configuration)==null?void 0:R.phoneNumber)||"",connectionId:((U=t==null?void 0:t.configuration)==null?void 0:U.connectionId)||"",smsEnabled:((O=(se=t==null?void 0:t.configuration)==null?void 0:se.features)==null?void 0:O.sms)??!0,voiceEnabled:((L=(Q=t==null?void 0:t.configuration)==null?void 0:Q.features)==null?void 0:L.voice)??!0,isActive:(t==null?void 0:t.is_active)??!0})},[t]),l.useEffect(()=>{var f,R;c&&t&&((f=t.credentials)!=null&&f.apiKey)&&((R=t.configuration)!=null&&R.phoneNumber)?o("test"):c&&!t&&o("credentials")},[c,t]);const u=async()=>{var f;if(!s.apiKey){N({title:"Validation Error",description:"Please enter your Telnyx API Key first.",variant:"destructive"});return}P(!0);try{const R=await fetch("https://api.telnyx.com/v2/phone_numbers",{headers:{Authorization:`Bearer ${s.apiKey}`,"Content-Type":"application/json"}});if(!R.ok)throw new Error(`HTTP ${R.status}: ${R.statusText}`);const U=await R.json();if(U!=null&&U.data&&Array.isArray(U.data)){const se=U.data.map(O=>({id:O.id,phoneNumber:O.phone_number,features:O.features||[],status:O.status}));p(se)}try{const se=await fetch("https://api.telnyx.com/v2/credential_connections",{headers:{Authorization:`Bearer ${s.apiKey}`,"Content-Type":"application/json"}});if(se.ok){const O=await se.json();if(O!=null&&O.data&&Array.isArray(O.data)){const Q=O.data.map(L=>({id:L.id,connection_name:L.connection_name||L.user_name||"Unnamed Connection",active:L.active}));T(Q)}}}catch{console.log("Could not fetch credential connections, trying FQDN connections");try{const O=await fetch("https://api.telnyx.com/v2/fqdn_connections",{headers:{Authorization:`Bearer ${s.apiKey}`,"Content-Type":"application/json"}});if(O.ok){const Q=await O.json();if(Q!=null&&Q.data&&Array.isArray(Q.data)){const L=Q.data.map(Ke=>({id:Ke.id,connection_name:Ke.connection_name||"Unnamed Connection",active:Ke.active}));T(L)}}}catch{console.log("Could not fetch FQDN connections either")}}o("phone-select"),N({title:"Connection Successful",description:`Found ${((f=U==null?void 0:U.data)==null?void 0:f.length)||0} phone number(s) and ${A.length} connection(s).`})}catch(R){N({title:"Connection Failed",description:R.message||"Failed to connect to Telnyx. Please check your API key.",variant:"destructive"})}finally{P(!1)}},m=async()=>{var f,R,U,se,O;if(!i){N({title:"Validation Error",description:"Please enter a phone number to test.",variant:"destructive"});return}if(!i.match(/^\+[1-9]\d{1,14}$/)){N({title:"Invalid Phone Number",description:"Phone number must be in E.164 format (e.g., +12025551234)",variant:"destructive"});return}S(!0);try{const Q=await fetch("https://api.telnyx.com/v2/messages",{method:"POST",headers:{Authorization:`Bearer ${s.apiKey}`,"Content-Type":"application/json"},body:JSON.stringify({from:s.selectedPhone,to:i,text:"Test message from your Helpdesk system. Telnyx SMS is working!"})}),L=await Q.json();if(!Q.ok)throw new Error(((R=(f=L.errors)==null?void 0:f[0])==null?void 0:R.detail)||((se=(U=L.errors)==null?void 0:U[0])==null?void 0:se.title)||"Failed to send SMS");N({title:"SMS Sent Successfully",description:`Test SMS sent to ${i} (ID: ${(O=L.data)==null?void 0:O.id})`})}
1catch(Q){console.error("SMS test error:",Q);let L=Q.message||"Failed to send test SMS. Please check your configuration.";L.includes("messaging-enabled")?L+=" Tip: Assign this number to a Messaging Profile in Telnyx.":L.includes("trial")&&(L+=" Tip: Trial accounts have destination restrictions."),N({title:"SMS Test Failed",description:L,variant:"destructive"})}finally{S(!1)}},E=async()=>{if(!i){N({title:"Validation Error",description:"Please enter a phone number to test voice call.",variant:"destructive"});return}if(!s.connectionId){N({title:"Configuration Required",description:"Please select a Connection ID to enable voice calls.",variant:"destructive"});return}if(!i.match(/^\+[1-9]\d{1,14}$/)){N({title:"Invalid Phone Number",description:"Phone number must be in E.164 format (e.g., +12025551234)",variant:"destructive"});return}I(!0);try{const{data:f,error:R}=await g.functions.invoke("send-on-call-notification",{body:{test_mode:!0,target_phone:i,notification_type:"voice",message:"This is a test call from GRIT. Press 1 to acknowledge. Press 2 to reject and escalate."}});if(R)throw R;if(f!=null&&f.error)throw new Error(f.error);N({title:"Call Initiated",description:`Test call started to ${i}. You should hear a voice message shortly.`})}catch(f){console.error("Call test error:",f),N({title:"Call Test Failed",description:f.message||"Failed to initiate test call.",variant:"destructive"})}finally{I(!1)}},F=async()=>{if(!s.apiKey||!s.selectedPhone){N({title:"Validation Error",description:"Please complete all steps before saving.",variant:"destructive"});return}if(s.voiceEnabled&&!s.connectionId){N({title:"Voice Configuration Warning",description:"Voice calls require a Connection ID. Voice notifications will not work without it.",variant:"destructive"});return}_(!0);try{const{data:{user:f}}=await g.auth.getUser(),R={name:"Telnyx",type:"telnyx",category:"communication",is_active:s.isActive,configuration:{phoneNumber:s.selectedPhone,connectionId:s.connectionId,features:{sms:s.smsEnabled,voice:s.voiceEnabled}},credentials:{apiKey:s.apiKey},auth_type:"api_key",created_by:f==null?void 0:f.id};let U;if(t?U=(await g.from("integrations").update(R).eq("id",t.id)).error:U=(await g.from("integrations").insert([R])).error,U)throw U;N({title:"Success",description:`Telnyx integration ${t?"updated":"configured"} successfully.`}),j(!1),h()}catch(f){N({title:"Error",description:f.message||"Failed to save configuration.",variant:"destructive"})}finally{_(!1)}},h=()=>{o("credentials"),p([]),T([]),w(""),t||a({apiKey:"",selectedPhone:"",connectionId:"",smsEnabled:!0,voiceEnabled:!0,isActive:!0})};return e.jsx(ye,{open:c,onOpenChange:f=>{j(f),f||h()},children:e.jsxs(ve,{className:"sm:max-w-[600px] max-h-[90vh] overflow-y-auto",children:[e.jsxs(ge,{children:[e.jsx(Ne,{children:"Configure Telnyx Integration"}),e.jsxs(be,{children:[x==="credentials"&&"Enter your Telnyx API credentials to get started.",x==="phone-select"&&"Select the phone number and connection for notifications.",x==="test"&&"Test your configuration before saving."]})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[x==="credentials"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"apiKey",children:"Telnyx API Key *"}),e.jsxs("div",{className:"relative",children:[e.jsx(B,{id:"apiKey",type:C?"text":"password",placeholder:"Enter your Telnyx API Key (starts with KEY...)",value:s.apiKey,onChange:f=>a({...s,apiKey:f.target.value}),className:"pr-10"}),e.jsx(v,{type:"button",variant:"ghost",size:"icon",className:"absolute right-0 top-0 h-full",onClick:()=>M(!C),children:C?e.jsx(Fe,{className:"h-4 w-4"}):e.jsx(De,{className:"h-4 w-4"})})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Get your API Key from Telnyx Portal â API Keys"})]}),e.jsxs("div",{className:"space-y-3 pt-2",children:[e.jsx(b,{children:"Notification Features"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(b,{htmlFor:"smsEnabled",className:"text-sm font-normal",children:"SMS Notifications"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Send text message alerts"})]}),e.jsx($,{id:"smsEnabled",checked:s.smsEnabled,onCheckedChange:f=>a({...s,smsEnabled:f})})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(b,{htmlFor:"voiceEnabled",className:"text-sm font-normal",children:"Voice Call Notifications"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Make phone calls for critical alerts"})]}),e.jsx($,{id:"voiceEnabled",checked:s.voiceEnabled,onCheckedChange:f=>a({...s,voiceEnabled:f})})]})]}),e.jsxs("div",{className:"flex items-center justify-between pt-2",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(b,{htmlFor:"isActive",className:"text-sm font-normal",children:"Enable Integration"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Activate immediately after saving"})]}),e.jsx($,{id:"isActive",checked:s.isActive,onCheckedChange:f=>a({...s,isActive:f})})]})]}),x==="phone-select"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs(W,{children:[e.jsxs(Z,{children:[e.jsxs(J,{className:"flex items-center gap-2",children:[e.jsx(Oe,{className:"h-5 w-5"}),"Select Phone Number"]}),e.jsx(te,{children:"Choose which Telnyx phone number to use for sending notifications"})]}),e.jsx(H,{className:"space-y-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{children:"Phone Number *"}),e.jsxs(ce,{value:s.selectedPhone,onValueChange:f=>a({...s,selectedPhone:f}),children:[e.jsx(le,{children:e.jsx(oe,{placeholder:"Select a phone number..."})}),e.jsx(de,{children:r.map(f=>e.jsxs(ne,{value:f.phoneNumber,children:[f.phoneNumber," (",f.status,")"]},f.id))})]})]})})]}),s.voiceEnabled&&e.jsxs(W,{children:[e.jsxs(Z,{children:[e.jsxs(J,{className:"flex items-center gap-2",children:[e.jsx(Oe,{className:"h-5 w-5"}),"Voice Call Connection"]}),e.jsx(te,{children:"Required for voice calls - select a Telnyx Call Control Connection"})]}
1),e.jsxs(H,{className:"space-y-4",children:[A.length>0?e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{children:"Connection ID *"}),e.jsxs(ce,{value:s.connectionId,onValueChange:f=>a({...s,connectionId:f}),children:[e.jsx(le,{children:e.jsx(oe,{placeholder:"Select a connection..."})}),e.jsx(de,{children:A.map(f=>e.jsxs(ne,{value:f.id,children:[f.connection_name," ",f.active?"(Active)":"(Inactive)"]},f.id))})]})]}):e.jsxs(Ue,{variant:"destructive",children:[e.jsx(Pe,{className:"h-4 w-4"}),e.jsx(Qe,{children:"No Connections Found"}),e.jsx(Le,{children:'Voice calls require a Call Control Connection. Create one in your Telnyx portal under "Voice" â "Call Control" â "Create Connection".'})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{children:"Or enter Connection ID manually"}),e.jsx(B,{placeholder:"Enter Connection ID (e.g., 1234567890123456789)",value:s.connectionId,onChange:f=>a({...s,connectionId:f.target.value})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Find this in Telnyx Portal â Voice â Call Control â Your Connection"})]})]})]}),e.jsxs("div",{className:"flex gap-2",children:[s.selectedPhone&&e.jsx(v,{variant:"default",onClick:()=>o("test"),className:"flex-1",children:"Continue to Testing"}),e.jsx(v,{variant:"outline",onClick:()=>{o("credentials"),p([]),T([])},className:"flex-1",children:"Back to Credentials"})]})]}),x==="test"&&e.jsxs(W,{children:[e.jsxs(Z,{children:[e.jsxs(J,{className:"flex items-center gap-2",children:[e.jsx(Ze,{className:"h-5 w-5"}),"Test Configuration"]}),e.jsx(te,{children:"Send a test notification to verify everything works"})]}
1),e.jsxs(H,{className:"space-y-4",children:[t&&e.jsxs(v,{variant:"outline",onClick:()=>o("credentials"),className:"w-full",children:[e.jsx(Me,{className:"mr-2 h-4 w-4"}),"Edit API Key & Settings"]}),s.voiceEnabled&&!s.connectionId&&e.jsxs(Ue,{variant:"destructive",children:[e.jsx(Pe,{className:"h-4 w-4"}),e.jsx(Qe,{children:"Voice Calls Not Configured"}),e.jsx(Le,{children:"Voice notifications require a Connection ID. Go back to phone selection to configure."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{htmlFor:"testPhone",children:"Test Phone Number"}),e.jsx(B,{id:"testPhone",type:"tel",placeholder:"+12025551234 (E.164 format required)",value:i,onChange:f=>w(f.target.value)}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Enter phone number in E.164 format (e.g., +1 for US, +44 for UK)"})]}),e.jsxs("div",{className:"flex gap-2",children:[s.smsEnabled&&e.jsxs(v,{onClick:m,disabled:k||!i,className:"flex-1",children:[k&&e.jsx(G,{className:"mr-2 h-4 w-4 animate-spin"}),"Test SMS"]}),s.voiceEnabled&&e.jsxs(v,{onClick:E,disabled:y||!i||!s.connectionId,variant:"outline",className:"flex-1",children:[y&&e.jsx(G,{className:"mr-2 h-4 w-4 animate-spin"}),"Test Call"]})]}),e.jsxs("div",{className:"pt-2 space-y-2 text-sm text-muted-foreground",children:[e.jsx("p",{children:e.jsx("strong",{children:"Configuration Summary:"})}),e.jsxs("ul",{className:"list-disc list-inside space-y-1",children:[e.jsxs("li",{children:["From Number: ",s.selectedPhone||"Not selected"]}),e.jsxs("li",{children:["SMS: ",s.smsEnabled?"Enabled":"Disabled"]}),e.jsxs("li",{children:["Voice: ",s.voiceEnabled?s.connectionId?"Enabled":"Missing Connection ID":"Disabled"]}),s.connectionId&&e.jsxs("li",{children:["Connection ID: ",s.connectionId]})]})]}),e.jsx(v,{variant:"ghost",onClick:()=>o("phone-select"),className:"w-full",children:"Back to Phone Selection"})]})]})]}),e.jsxs(fe,{className:"gap-2",children:[e.jsx(v,{variant:"outline",onClick:()=>j(!1),children:"Cancel"}),x==="credentials"&&e.jsxs(v,{onClick:u,disabled:n||!s.apiKey,children:[n&&e.jsx(G,{className:"mr-2 h-4 w-4 animate-spin"}),"Continue"]}),x==="test"&&e.jsxs(v,{onClick:F,disabled:d||!s.selectedPhone,children:[d&&e.jsx(G,{className:"mr-2 h-4 w-4 animate-spin"}),t?"Update":"Save"," Configuration"]})]})]})})}const qs=[{id:"openai",name:"OpenAI",description:"Access GPT models for AI-powered features",icon:Te,category:"ai",features:["GPT-5 and GPT-4 models","Text generation and analysis","Function calling support"],status:"available"},{id:"gemini",name:"Google Gemini",description:"Leverage Gemini models for multimodal AI capabilities",icon:Te,category:"ai",features:["Gemini Pro and Flash models","Vision and text processing","Fast inference"],status:"available"},{id:"claude",name:"Anthropic Claude",description:"Integrate Claude for advanced reasoning and analysis",icon:Te,category:"ai",features:["Claude 4 models","Long context windows","Safety-focused responses"],status:"available"},{id:"openrouter",name:"OpenRouter",description:"Access multiple AI models through unified API",icon:Te,category:"ai",features:["Multi-provider access","Model comparison","Flexible routing"],status:"available"}
1,{id:"slack",name:"Slack",description:"Send notifications and alerts to Slack channels",icon:Ze,category:"communication",features:["Ticket notifications","SLA alerts","Team mentions"],status:"available"},{id:"teams",name:"Microsoft Teams",description:"Post updates to Teams channels",icon:Je,category:"communication",features:["Ticket updates","Project notifications"],status:"available"},{id:"zapier",name:"Zapier",description:"Connect to 5,000+ apps via Zapier",icon:xs,category:"automation",features:["Custom workflows","Automation triggers"],status:"available"},{id:"email",name:"Email Services",description:"Enhanced email delivery for notifications",icon:He,category:"email",features:["Transactional emails","Templates"],status:"available"},{id:"microsoft365",name:"Microsoft 365",description:"Integrate Outlook calendar and email for seamless ticket management",icon:He,category:"communication",features:["Sync Outlook calendar events","Inbound email â Auto-create tickets","Send ticket updates via email","Email threading and conversation tracking"],status:"available"},{id:"custom",name:"Custom Webhook",description:"Send data to any external service",icon:Be,category:"automation",features:["Custom HTTP endpoints","Payload configuration"],status:"available"},{id:"ninjarmm",name:"NinjaRMM",description:"Sync devices, monitoring, and asset data from NinjaRMM",icon:Ve,category:"rmm",features:["Device inventory sync","Monitoring alerts integration","Asset tracking and warranty info"],status:"available"},{id:"telnyx",name:"Telnyx",description:"Send SMS and voice calls for on-call notifications",icon:Oe,category:"communication",features:["SMS notifications for alerts","Voice calls with interactive prompts","Cost-effective rates","Delivery status tracking"],status:"available"}];function Ks(){var i,w,N,s;const[c,j]=l.useState({open:!1,provider:null,existingConfig:void 0}),[t,d]=l.useState({}),[_,C]=l.useState({}),[M,n]=l.useState({}),[P,k]=l.useState({}),{toast:S}=_e();l.useEffect(()=>{y(),I(),r(),p()},[]);const y=async()=>{try{const{data:a,error:u}=await g.from("ai_settings").select("*");if(u)throw u;const m=(a||[]).reduce((E,F)=>(E[F.provider]=F,E),{});d(m)}catch(a){console.error("Error loading AI configurations:",a)}},I=async()=>{try{const{data:a,error:u}=await g.from("integrations").select("*").eq("category","rmm");if(u)throw u;const m=(a||[]).reduce((E,F)=>(E[F.type]=F,E),{});C(m)}catch(a){console.error("Error loading RMM configurations:",a)}},r=async()=>{try{const{data:{user:a}}=await g.auth.getUser();if(!a)return;const{data:u,error:m}=await g.from("integrations").select("*").eq("type","microsoft365").eq("created_by",a.id);if(m)throw m;const E=(u||[]).reduce((F,h)=>(F[h.type]=h,F),{});n(E)}catch(a){console.error("Error loading Calendar configurations:",a)}},p=async()=>{try{const{data:a,error:u}=await g.from("integrations").select("*").eq("type","telnyx").eq("category","communication");if(u)throw u;const m=(a||[]).reduce((E,F)=>(E[F.type]=F,E),{});k(m)}catch(a){console.error("Error loading Telnyx configurations:",a)}},A=a=>{a.category==="ai"?j({open:!0,provider:a,existingConfig:t[a.id]}):a.category==="rmm"?j({open:!0,provider:a,existingConfig:_[a.id]}):a.id==="microsoft365"?j({open:!0,provider:a,existingConfig:M[a.id]}):a.id==="telnyx"&&j({open:!0,provider:a,existingConfig:P.telnyx})},T=async a=>{try{let u;if(a.category==="ai"?u=(await g.from("ai_settings").delete().eq("provider",a.id)).error:a.category==="rmm"?u=(await g.from("integrations").delete().eq("type",a.id)).error:a.id==="microsoft365"?u=(await g.from("integrations").delete().eq("type","microsoft365")).error:a.id==="telnyx"&&(u=(await g.from("integrations").delete().eq("type","telnyx")).error),u)throw u;S({title:"Integration Disconnected",description:`${a.name} has been disconnected.`}),y(),I(),r(),p()}catch(u){S({title:"Disconnect Failed",description:u.message||"Failed to disconnect the integration.",variant:"destructive"})}},x=(a,u)=>u==="ai"?!!t[a]:u==="rmm"?!!_[a]:a==="microsoft365"?!!M.microsoft365:a==="telnyx"?!!P.telnyx:!1,o=(a,u)=>{var m,E,F,h;return u==="ai"?((m=t[a])==null?void 0:m.is_active)||!1:u==="rmm"?((E=_[a])==null?void 0:E.is_active)||!1:a==="microsoft365"?((F=M.microsoft365)==null?void 0:F.is_active)||!1:a==="telnyx"&&((h=P.telnyx)==null?void 0:h.is_active)||!1};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"Available Integrations"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Connect your helpdesk with popular services and tools"})]}),e.jsx("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-3",children:qs.map(a=>{const u=a.icon,m=x(a.id,a.category),E=o(a.id,a.category);return e.jsxs(W,{children:[e.jsxs(Z,{children:[e.jsx("div",{className:"flex items-start justify-between",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 rounded-lg bg-primary/10",children:e.jsx(u,{className:"h-5 w-5 text-primary"})}),e.jsxs("div",{children:[e.jsx(J,{className:"text-base",children:a.name}),e.jsxs("div",{className:"flex gap-2 mt-1",children:[e.jsx(Y,{variant:"outline",className:"text-xs",children:a.category}),m&&e.jsx(Y,{variant:E?"default":"outline",className:"text-xs",children:E?e.
1jsxs(e.Fragment,{children:[e.jsx(us,{className:"h-3 w-3 mr-1"}),"Active"]}):e.jsxs(e.Fragment,{children:[e.jsx(We,{className:"h-3 w-3 mr-1"}),"Inactive"]})})]})]})]})}),e.jsx(te,{className:"mt-2",children:a.description})]}),e.jsx(H,{children:e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs font-medium text-muted-foreground mb-1",children:"Features:"}),e.jsx("ul",{className:"text-xs space-y-1",children:a.features.map((F,h)=>e.jsxs("li",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"h-1 w-1 rounded-full bg-primary"}),F]},h))})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(v,{className:"flex-1",variant:m||a.status==="coming-soon"?"outline":"default",disabled:a.status==="coming-soon",onClick:()=>A(a),children:a.status==="coming-soon"?"Coming Soon":m?"Configure":"Connect"}),m&&(a.category==="ai"||a.category==="rmm"||a.id==="microsoft365"||a.id==="telnyx")&&e.jsx(v,{variant:"destructive",size:"icon",onClick:()=>T(a),children:e.jsx(We,{className:"h-4 w-4"})})]})]})})]},a.id)})}),c.open&&((i=c.provider)==null?void 0:i.category)==="ai"&&e.jsx(zs,{open:c.open,onOpenChange:a=>{j({...c,open:a}),a||y()},provider:c.provider,existingConfig:c.existingConfig}),c.open&&((w=c.provider)==null?void 0:w.category)==="rmm"&&e.jsx(os,{open:c.open,onOpenChange:a=>{j({...c,open:a}),a||I()},existingConfig:c.existingConfig}),c.open&&((N=c.provider)==null?void 0:N.id)==="microsoft365"&&e.jsx(bs,{open:c.open,onOpenChange:a=>{j({...c,open:a}),a||r()},existingConfig:c.existingConfig}),c.open&&((s=c.provider)==null?void 0:s.id)==="telnyx"&&e.jsx(ds,{open:c.open,onOpenChange:a=>{j({...c,open:a}),a||p()},existingConfig:c.existingConfig})]})}function Rs({open:c,onOpenChange:j,integrationId:t,existingMappings:d,onSuccess:_}){const[C,M]=l.useState(!1),[n,P]=l.useState(!1),[k,S]=l.useState([]),[y,I]=l.useState([]),[r,p]=l.useState(""),[A,T]=l.useState(""),[x,o]=l.useState(!0),[i,w]=l.useState(!0),{toast:N}=_e(),s=async()=>{var m;P(!0);try{const{data:E,error:F}=await g.from("integrations").select("*").eq("id",t).single();if(F)throw F;const h=E.configuration,q=E.credentials,{data:X,error:ee}=await g.functions.invoke("fetch-ninja-organizations",{body:{credentials:{instanceUrl:(h==null?void 0:h.instanceUrl)||(q==null?void 0:q.instanceUrl),clientId:q==null?void 0:q.clientId,clientSecret:q==null?void 0:q.clientSecret}}});if(ee)throw ee;const V=((m=X==null?void 0:X.organizations)==null?void 0:m.filter(ie=>!d.includes(ie.id)))||[];S(V),V.length===0&&N({title:"No Organizations Available",description:"All NinjaRMM organizations are already mapped.",variant:"default"});const{data:K}=await g.from("clients").select("id, name").eq("is_active",!0).order("name");K&&I(K)}catch(E){N({title:"Error",description:E.message||"Failed to fetch organizations.",variant:"destructive"})}finally{P(!1)}},a=m=>{m&&k.length===0&&s(),j(m)},u=async()=>{if(!r||!A){N({title:"Validation Error",description:"Please select both an organization and a client.",variant:"destructive"});return}M(!0);try{const m=k.find(F=>F.id===r),{error:E}=await g.from("ninja_rmm_company_mappings").insert({integration_id:t,ninja_org_id:r,ninja_org_name:(m==null?void 0:m.name)||"",client_id:A,sync_devices:x,sync_alerts:i,is_active:!0});if(E)throw E;N({title:"Success",description:"Company mapping added successfully."}),_(),j(!1),p(""),T(""),o(!0),w(!0),S([])}catch(m){N({title:"Error",description:m.message||"Failed to add mapping.",variant:"destructive"})}finally{M(!1)}};return e.jsx(ye,{open:c,onOpenChange:a,children:e.jsxs(ve,{className:"sm:max-w-[500px]",children:[e.jsxs(ge,{children:[e.jsxs(Ne,{className:"flex items-center gap-2",children:[e.jsx(Ge,{className:"h-5 w-5"}),"Add Company Mapping"]}),e.jsx(be,{children:"Map a NinjaRMM organization to one of your clients"})]}),n?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(G,{className:"h-8 w-8 animate-spin"})}):e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{children:"NinjaRMM Organization"}),e.jsxs(ce,{value:r,onValueChange:p,children:[e.jsx(le,{children:e.jsx(oe,{placeholder:"Select an organization..."})}),e.jsx(de,{children:k.length===0?e.jsx("div",{className:"p-2 text-sm text-muted-foreground text-center",children:"No unmapped organizations available"}):k.map(m=>e.jsxs(ne,{value:m.id,children:[m.name," (",m.deviceCount," devices)"]},m.id))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{children:"Map to Client"}),e.jsxs(ce,{value:A,onValueChange:T,children:[e.jsx(le,{children:e.jsx(oe,{placeholder:"Select a client..."})}),e.jsx(de,{children:y.map(m=>e.jsx(ne,{value:m.id,children:m.name},m.id))})]})]}),e.jsxs("div",{className:"space-y-3 pt-2",children:[e.jsx(b,{children:"Sync Options"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(b,{htmlFor:"syncDevices",className:"text-sm font-normal",children:"Sync Devices"}),e.jsx($,{id:"syncDevices",checked:x,onCheckedChange:o})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(b,{htmlFor:"syncAlerts",className:"text-sm font-normal",children:"Sync Alerts"}),e.jsx($,{id:"syncAlerts",checked:i,onCheckedChange:w})]})]})]}),e.jsxs(fe,{children:[e.jsx(v,{variant:"outline",onClick:()=>j(!1),disabled:C,children:"Cancel"}),e.jsxs(v,{onClick:u,disabled:C||!r||!A||k.length===0,children:[C&&e.jsx(G,{className:"mr-2 h-4 w-4 animate-spin"}),"Add Mapping"]})]})]})})}function Os({integrationId:c}){const[j,t]=l.useState([]),[d,_]=l.useState(!0),[C,M]=l.useState(!1),[n,P]=l.useState(!1),[k,S]=l.useState(!1),[y,I]=l.useState(null),{toast:r}=_e(),p=async()=>{try{const{data:i}=await g.from("integrations").select("*").eq("id",c).single();i&&I(i);const{data:w,error:N}=await g.from("ninja_rmm_company_mappings").select(` 2 *, 3 clients!inner(name) 4 `).eq("integration_id",c).order("ninja_org_name");if(N)throw N;const s=(w==null?void 0:w.map(a=>({...a,client_name:a.clients.name})))||[];t(s)}catch{r({title:"Error",description:"Failed to load company mappings.",variant:"destructive"})}finally{_(!1)}};l.useEffect(()=>{p()},[c]);const A=async(i,w)=>{try{const{error:N}=await g.from("ninja_rmm_company_mappings").update({is_active:w}).eq("id",i);if(N)throw N;r({title:"Success",description:`Mapping ${w?"enabled":"disabled"} successfully.`}),p()}catch{r({title:"Error",description:"Failed to update mapping.",variant:"destructive"})}},T=async(i,w,N)=>{try{const{error:s}
4=await g.from("ninja_rmm_company_mappings").update({[w]:N}).eq("id",i);if(s)throw s;p()}catch{r({title:"Error",description:"Failed to update sync option.",variant:"destructive"})}},x=async()=>{M(!0);try{const{error:i}=await g.functions.invoke("sync-ninja-devices");if(i)throw i;r({title:"Sync Started",description:"Device sync has been triggered. This may take a few minutes."}),setTimeout(p,2e3)}catch(i){r({title:"Error",description:i.message||"Failed to trigger sync.",variant:"destructive"})}finally{M(!1)}},o=async i=>{if(confirm("Are you sure you want to delete this mapping? Existing synced assets will not be affected."))try{const{error:w}=await g.from("ninja_rmm_company_mappings").delete().eq("id",i);if(w)throw w;r({title:"Success",description:"Mapping deleted successfully."}),p()}catch{r({title:"Error",description:"Failed to delete mapping.",variant:"destructive"})}};return d?e.jsx("div",{className:"flex items-center justify-center p-8",children:e.jsx(G,{className:"h-8 w-8 animate-spin"})}):e.jsxs(e.Fragment,{children:[e.jsxs(W,{children:[e.jsx(Z,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs(J,{className:"flex items-center gap-2",children:[e.jsx(Ge,{className:"h-5 w-5"}),"Company Mappings"]}),e.jsx(te,{children:"Manage NinjaRMM organization to client mappings"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(v,{onClick:()=>P(!0),variant:"outline",size:"sm",children:[e.jsx(Me,{className:"h-4 w-4"}),e.jsx("span",{className:"ml-2",children:"Edit Integration"})]}),e.jsxs(v,{onClick:()=>S(!0),variant:"outline",size:"sm",children:[e.jsx(ze,{className:"h-4 w-4"}),e.jsx("span",{className:"ml-2",children:"Add Mapping"})]}),e.jsxs(v,{onClick:x,disabled:C,size:"sm",children:[C?e.jsx(G,{className:"h-4 w-4 animate-spin"}):e.jsx(ps,{className:"h-4 w-4"}),e.jsx("span",{className:"ml-2",children:"Sync Now"})]})]})]})}),e.jsx(H,{children:j.length===0?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"No company mappings configured. Please reconfigure the integration to add mappings."}):e.jsxs(Ce,{children:[e.jsx(ke,{children:e.jsxs(re,{children:[e.jsx(D,{children:"NinjaRMM Organization"}),e.jsx(D,{children:"Your Client"}),e.jsx(D,{children:"Status"}),e.jsx(D,{children:"Sync Options"}),e.jsx(D,{children:"Last Synced"}),e.jsx(D,{className:"text-right",children:"Actions"})]})}),e.jsx(Ae,{children:j.map(i=>e.jsxs(re,{children:[e.jsx(z,{className:"font-medium",children:i.ninja_org_name}),e.jsx(z,{children:i.client_name}),e.jsx(z,{children:e.jsx(Y,{variant:i.is_active?"default":"secondary",children:i.is_active?"Active":"Inactive"})}),e.jsx(z,{children:e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx($,{checked:i.sync_devices,onCheckedChange:w=>T(i.id,"sync_devices",w),disabled:!i.is_active}),e.jsx("span",{className:"text-sm",children:"Devices"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx($,{checked:i.sync_alerts,onCheckedChange:w=>T(i.id,"sync_alerts",w),disabled:!i.is_active}),e.jsx("span",{className:"text-sm",children:"Alerts"})]})]})}),e.jsx(z,{children:i.last_synced_at?new Date(i.last_synced_at).toLocaleString():"Never"}),e.jsx(z,{className:"text-right",children:e.jsxs("div",{className:"flex items-center justify-end gap-2",children:[e.jsx($,{checked:i.is_active,onCheckedChange:w=>A(i.id,w)}),e.jsx(v,{variant:"ghost",size:"icon",onClick:()=>o(i.id),children:e.jsx(qe,{className:"h-4 w-4 text-destructive"})})]})})]},i.id))})]})})]}),e.jsx(os,{open:n,onOpenChange:i=>{P(i),i||p()},existingConfig:y}),e.jsx(Rs,{open:k,onOpenChange:S,integrationId:c,existingMappings:j.map(i=>i.ninja_org_id),onSuccess:p})]})}function Us(){const[c,j]=l.useState(null),[t,d]=l.useState(null),[_,C]=l.useState(null),{data:M,isLoading:n,refetch:P}=he({queryKey:["integrations"],queryFn:async()=>{const{data:y,error:I}=await g.from("integrations").select("*").order("created_at",{ascending:!1});if(I)throw I;return y}}),k=(y,I)=>I?e.jsx(Pe,{className:"h-4 w-4 text-destructive"}):y?e.jsx(_s,{className:"h-4 w-4 text-success"}):null,S=(y,I)=>I?e.jsx(Y,{variant:"destructive",children:"Error"}):y?e.jsx(Y,{className:"bg-success text-success-foreground",children:"Active"}):e.jsx(Y,{variant:"secondary",children:"Disabled"});return e.jsxs(W,{children:[e.jsxs(Z,{children:[e.jsx(J,{children:"Active Integrations"}),e.jsx(te,{children:"Manage your configured integrations and webhooks"})]}),e.jsx(H,{children:n?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"Loading integrations..."}):M&&M.length>0?e.jsxs(Ce,{children:[e.jsx(ke,{children:e.jsxs(re,{children:[e.jsx(D,{children:"Name"}),e.jsx(D,{children:"Type"}),e.jsx(D,{children:"Category"}),e.jsx(D,{children:"Status"}),e.jsx(D,{children:"Last Sync"}),e.jsx(D,{className:"text-right",children:"Actions"})]})}),e.jsx(Ae,{children:M.map(y=>e.jsxs(re,{children:[e.jsx(z,{className:"font-medium",children:e.jsxs("div",{className:"flex items-center gap-2",children:[k(y.is_active,y.last_error),y.name]})}),e.jsx(z,{children:e.jsx(Y,{variant:"outline",children:y.type})}),e.jsx(z,{className:"capitalize",children:y.category}),e.jsx(z,{children:S(y.is_active,y.last_error)}),e.jsx(z,{className:"text-muted-foreground text-sm",children:y.last_sync_at?Xe(new Date(y.last_sync_at),{addSuffix:!0}):"Never"}),e.jsx(z,{className:"text-right",children:e.jsxs("div",{className:"flex items-center justify-end gap-2",children:[e.jsx(v,{variant:"ghost",size:"icon",children:e.jsx(ws,{className:"h-4 w-4"})}),y.type==="ninjarmm"&&e.jsx(v,{variant:"ghost",size:"icon",onClick:()=>j(y.id),title:"Manage Company Mappings",children:e.jsx(Me,{className:"h-4 w-4"})}),y.type==="telnyx"&&e.jsx(v,{variant:"ghost",size:"icon",onClick:()=>
4{d(y.id),C(y)},title:"Configure & Test Telnyx",children:e.jsx(Me,{className:"h-4 w-4"})}),e.jsx(v,{variant:"ghost",size:"icon",children:e.jsx(qe,{className:"h-4 w-4"})})]})})]},y.id))})]}):e.jsxs("div",{className:"text-center py-12",children:[e.jsx("p",{className:"text-muted-foreground mb-4",children:"No integrations configured yet"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:'Go to the "Available" tab to connect your first integration'})]})}),e.jsx(ye,{open:!!c,onOpenChange:()=>j(null),children:e.jsxs(ve,{className:"max-w-6xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(ge,{children:[e.jsx(Ne,{children:"Manage NinjaRMM Company Mappings"}),e.jsx(be,{children:"Configure how NinjaRMM organizations map to your clients"})]}),c&&e.jsx(Os,{integrationId:c})]})}),e.jsx(ds,{open:!!t,onOpenChange:y=>{y||(d(null),C(null),P())},existingConfig:_})]})}function Ls(){return e.jsxs(W,{children:[e.jsx(Z,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(J,{children:"Webhook Management"}),e.jsx(te,{children:"Configure custom webhooks to receive data from external services"})]}),e.jsxs(v,{children:[e.jsx(ze,{className:"h-4 w-4 mr-2"}),"Add Webhook"]})]})}),e.jsx(H,{children:e.jsxs("div",{className:"text-center py-12",children:[e.jsx("p",{className:"text-muted-foreground mb-4",children:"No webhooks configured"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Create your first webhook to start receiving data from external services"})]})})]})}function Gs(){const{data:c,isLoading:j}=he({queryKey:["integration-logs"],queryFn:async()=>{const{data:d,error:_}=await g.from("integration_logs").select(` 5 *, 6 integration:integrations(name) 7 `).order("created_at",{ascending:!1}).limit(50);if(_)throw _;return d}}),t=d=>{switch(d){case"success":return e.jsx(Y,{className:"bg-success text-success-foreground",children:"Success"});case"error":return e.jsx(Y,{variant:"destructive",children:"Error"});case"warning":return e.jsx(Y,{variant:"secondary",children:"Warning"});case"info":return e.jsx(Y,{variant:"outline",children:"Info"});default:return e.jsx(Y,{children:d})}};return e.jsxs(W,{children:[e.jsxs(Z,{children:[e.jsx(J,{children:"Integration Activity Logs"}),e.jsx(te,{children:"View recent integration activity and troubleshoot issues"})]}),e.jsx(H,{children:j?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"Loading logs..."}):c&&c.length>0?e.jsxs(Ce,{children:[e.jsx(ke,{children:e.jsxs(re,{children:[e.jsx(D,{children:"Timestamp"}),e.jsx(D,{children:"Integration"}),e.jsx(D,{children:"Action"}),e.jsx(D,{children:"Status"}),e.jsx(D,{children:"Duration"}),e.jsx(D,{children:"Details"})]})}),e.jsx(Ae,{children:c.map(d=>{var _;return e.jsxs(re,{children:[e.jsx(z,{className:"text-muted-foreground text-sm",children:Xe(new Date(d.created_at),{addSuffix:!0})}),e.jsx(z,{className:"font-medium",children:((_=d.integration)==null?void 0:_.name)||"Unknown"}),e.jsx(z,{className:"text-sm",children:d.action}),e.jsx(z,{children:t(d.event_type)}),e.jsx(z,{className:"text-sm text-muted-foreground",children:d.execution_time_ms?`${d.execution_time_ms}ms`:"-"}),e.jsx(z,{className:"text-sm text-muted-foreground",children:d.error_message||d.status_code||"-"})]},d.id)})})]}):e.jsxs("div",{className:"text-center py-12",children:[e.jsx("p",{className:"text-muted-foreground mb-4",children:"No activity logs yet"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Integration activity will appear here once you configure and use integrations"})]})})]})}function Vs(){const c=$e(),[j,t]=l.useState(""),[d,_]=l.useState(""),[C,M]=l.useState(""),{data:n,isLoading:P}=he({queryKey:["staff-microsoft365-config"],queryFn:async()=>{const{data:r,error:p}=await g.from("staff_microsoft365_config").select("*").single();if(p&&p.code!=="PGRST116")throw p;return r}}),k=(n==null?void 0:n.tenant_id)&&(n==null?void 0:n.client_id_azure)&&(n==null?void 0:n.client_secret_encrypted);l.useEffect(()=>{n&&(t(n.tenant_id||""),_(n.client_id_azure||""),M(n.client_secret_encrypted||""))},[n]);const S=ue({mutationFn:async r=>{if(n){const{error:p}=await g.from("staff_microsoft365_config").update(r).eq("id",n.id);if(p)throw p}else{const{error:p}=await g.from("staff_microsoft365_config").insert([r]);if(p)throw p}},onSuccess:()=>{c.invalidateQueries({queryKey:["staff-microsoft365-config"]}),xe.success("Azure AD credentials saved successfully")},onError:r=>{xe.error(r.message||"Failed to save credentials")}}),y=ue({mutationFn:async r=>{if(r.is_sso_enabled&&!k)throw new Error("Cannot enable SSO without saving Azure AD credentials first");
7if(n){const{error:p}=await g.from("staff_microsoft365_config").update(r).eq("id",n.id);if(p)throw p}else{if(!r.tenant_id||!r.client_id_azure||!r.client_secret_encrypted)throw new Error("Cannot save configuration without all required credentials");const{error:p}=await g.from("staff_microsoft365_config").insert([r]);if(p)throw p}},onSuccess:()=>{c.invalidateQueries({queryKey:["staff-microsoft365-config"]}),xe.success("Staff SSO configuration saved")},onError:r=>{xe.error(r.message||"Failed to save configuration")}}),I=()=>{if(!(n!=null&&n.client_id_azure)||!(n!=null&&n.tenant_id)){xe.error("Please save Azure credentials first");return}const r=`${Re}/auth/callback`,p=["User.Read","openid","profile","email"].join(" "),A=`https://login.microsoftonline.com/${n.tenant_id}/oauth2/v2.0/authorize?client_id=${n.client_id_azure}&response_type=code&redirect_uri=${encodeURIComponent(r)}&response_mode=query&scope=${encodeURIComponent(p)}&state=test_staff_sso`;window.open(A,"_blank","width=600,height=700")};return P?e.jsx("div",{className:"flex items-center justify-center p-8",children:e.jsx(G,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs(W,{children:[e.jsxs(Z,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ve,{className:"h-5 w-5"}),e.jsx(J,{children:"Staff Microsoft 365 SSO"})]}),e.jsx(te,{children:"Configure Single Sign-On for technicians and administrators"})]}
7),e.jsxs(H,{className:"space-y-6",children:[!k&&e.jsxs(Ue,{variant:"default",className:"border-amber-500/50 bg-amber-500/10",children:[e.jsx(Pe,{className:"h-4 w-4 text-amber-600"}),e.jsx(Le,{className:"text-amber-900 dark:text-amber-100",children:"Please save all Azure AD credentials before enabling SSO"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsx("h3",{className:"text-sm font-medium",children:"Azure AD Application"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(b,{htmlFor:"staff-tenant-id",children:"Tenant ID *"}),(n==null?void 0:n.tenant_id)&&e.jsx(Se,{className:"h-3 w-3 text-green-600"})]}),e.jsx(B,{id:"staff-tenant-id",value:j,onChange:r=>t(r.target.value),placeholder:"00000000-0000-0000-0000-000000000000"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(b,{htmlFor:"staff-client-id",children:"Client ID *"}),(n==null?void 0:n.client_id_azure)&&e.jsx(Se,{className:"h-3 w-3 text-green-600"})]}),e.jsx(B,{id:"staff-client-id",value:d,onChange:r=>_(r.target.value),placeholder:"00000000-0000-0000-0000-000000000000"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(b,{htmlFor:"staff-client-secret",children:"Client Secret *"}),(n==null?void 0:n.client_secret_encrypted)&&e.jsx(Se,{className:"h-3 w-3 text-green-600"})]}),e.jsx(B,{id:"staff-client-secret",type:"password",value:C,onChange:r=>M(r.target.value),placeholder:"Enter client secret"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Create a separate Azure AD App Registration for staff with redirect URI:"," ",e.jsxs("code",{className:"bg-muted px-1 py-0.5 rounded text-xs",children:[Re,"/auth/callback"]})]})]}),e.jsx(v,{onClick:()=>{if(!j||!d||!C){xe.error("Please fill in all Azure AD credential fields");return}S.mutate({tenant_id:j,client_id_azure:d,client_secret_encrypted:C})},disabled:!j||!d||!C||S.isPending,className:"w-full",children:S.isPending?e.jsxs(e.Fragment,{children:[e.jsx(G,{className:"h-4 w-4 mr-2 animate-spin"}),"Saving..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Se,{className:"h-4 w-4 mr-2"}),"Save Azure AD Credentials"]})}),k&&e.jsxs(v,{onClick:I,variant:"outline",className:"w-full",children:[e.jsx(Ss,{className:"h-4 w-4 mr-2"}),"Test SSO Connection"]})]}),e.jsxs("div",{className:"space-y-4 pt-4 border-t",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(b,{htmlFor:"staff-sso-enabled",children:"Enable Staff SSO"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Allow staff to sign in with Microsoft 365"})]}),e.jsx($,{id:"staff-sso-enabled",checked:(n==null?void 0:n.is_sso_enabled)||!1,disabled:!k,onCheckedChange:r=>{if(!k){xe.error("Please save Azure AD credentials first");return}y.mutate({is_sso_enabled:r})}})]}),(n==null?void 0:n.is_sso_enabled)&&e.jsxs("div",{className:"p-3 bg-muted/50 rounded-lg space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(Se,{className:"h-4 w-4 text-green-600"}),e.jsx("span",{children:"Staff SSO is enabled"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:'Staff can sign in using "Sign in with Microsoft (Staff)" button'})]})]}),(n==null?void 0:n.is_sso_enabled)&&e.jsxs("div",{className:"space-y-2 pt-4 border-t",children:[e.jsx(b,{htmlFor:"default-staff-role",children:"Default Role for New Staff"}),e.jsxs(ce,{value:(n==null?void 0:n.default_staff_role)||"technician",onValueChange:r=>{y.mutate({default_staff_role:r})},children:[e.jsx(le,{id:"default-staff-role",children:e.jsx(oe,{})}),e.jsxs(de,{children:[e.jsx(ne,{value:"technician",children:"Technician"}),e.jsx(ne,{value:"co_managed_technician",children:"Co-Managed Technician"}),e.jsx(ne,{value:"project_manager",children:"Project Manager"}),e.jsx(ne,{value:"admin",children:"Administrator"})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"New users signing in via SSO will be assigned this role by default"})]})]})]}),e.jsxs(W,{children:[e.jsx(Z,{children:e.jsx(J,{className:"text-sm",children:"Setup Instru
7ctions"})}),e.jsx(H,{children:e.jsxs("ol",{className:"list-decimal list-inside space-y-2 text-sm text-muted-foreground",children:[e.jsx("li",{children:"Create an Azure AD App Registration for your organization"}),e.jsxs("li",{children:["Add the redirect URI: ",Re,"/auth/callback"]}),e.jsx("li",{children:"Grant delegated permissions: User.Read, openid, profile, email"}),e.jsx("li",{children:"Generate a client secret and enter it above"}),e.jsx("li",{children:"Enable Staff SSO using the toggle"}),e.jsx("li",{children:'Test the connection using the "Test SSO Connection" button'})]})})]})]})}function $s(){const c=new Uint8Array(32);return crypto.getRandomValues(c),Array.from(c,j=>j.toString(16).padStart(2,"0")).join("")}function Bs(){const c=$e(),[j,t]=l.useState(!1),[d,_]=l.useState(""),[C,M]=l.useState(""),[n,P]=l.useState(null),{data:k,isLoading:S}=he({queryKey:["external-api-keys"],queryFn:async()=>{const{data:x,error:o}=await g.from("external_api_keys").select("*").order("created_at",{ascending:!1});if(o)throw o;return x}}),y=ue({mutationFn:async({productName:x,description:o})=>{const{data:{user:i}}=await g.auth.getUser();if(!i)throw new Error("Not authenticated");const{data:w,error:N}=await g.from("profiles").select("organization_id").eq("id",i.id).maybeSingle();if(N)throw N;if(!(w!=null&&w.organization_id))throw new Error("Your profile has no organization â cannot create an API key.");const s=$s(),{error:a}=await g.from("external_api_keys").insert({api_key:s,product_name:x,description:o,created_by:i.id,organization_id:w.organization_id});if(a)throw a;return s},onSuccess:x=>{P(x),c.invalidateQueries({queryKey:["external-api-keys"]}),ae({title:"API key created",description:"Copy the key now â it won't be shown again."})},onError:x=>{ae({title:"Error creating API key",description:x.message,variant:"destructive"})}}),I=ue({mutationFn:async({id:x,isActive:o})=>{const{error:i}=await g.from("external_api_keys").update({is_active:o}).eq("id",x);if(i)throw i},onSuccess:()=>{c.invalidateQueries({queryKey:["external-api-keys"]})}}),r=ue({mutationFn:async x=>{const{error:o}=await g.from("external_api_keys").delete().eq("id",x);if(o)throw o},onSuccess:()=>{c.invalidateQueries({queryKey:["external-api-keys"]}),ae({title:"API key deleted"})}}),p=()=>{if(!d.trim()){ae({title:"Product name is required",variant:"destructive"});return}y.mutate({productName:d.trim(),description:C.trim()})},A=()=>{t(!1),_(""),M(""),P(null)},T=x=>{navigator.clipboard.writeText(x),ae({title:"Copied to clipboard"})};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold",children:"External API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage API keys for external applications (e.g. CyberGen sites) to submit and sync tickets."})]}),e.jsxs(ye,{open:j,onOpenChange:x=>{x?t(!0):A()},children:[e.jsx(js,{asChild:!0,children:e.jsxs(v,{children:[e.jsx(ze,{className:"h-4 w-4 mr-2"}),"Create API Key"]})}),e.jsxs(ve,{children:[e.jsxs(ge,{children:[e.jsx(Ne,{children:n?"API Key Created":"Create External API Key"}),e.jsx(be,{children:n?"Copy this key now. It will not be shown again.":"Generate a new API key for an external application to integrate with Grit."})]}),n?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(B,{value:n,readOnly:!0,className:"font-mono text-xs"}),e.jsx(v,{variant:"outline",size:"icon",onClick:()=>T(n),children:e.jsx(Cs,{className:"h-4 w-4"})})]}),e.jsx(fe,{children:e.jsx(v,{onClick:A,children:"Done"})})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{children:"Product Name"}),e.jsx(B,{placeholder:"e.g. cybergen-ai",value:d,onChange:x=>_(x.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"This identifies the source platform. Tickets will be tagged with this name."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(b,{children:"Description (optional)"}),e.jsx(B,{placeholder:"e.g. CyberGen main website support form",value:C,onChange:x=>M(x.target.value)})]}),e.jsxs(fe,{children:[e.jsx(v,{variant:"outline",onClick:A,children:"Cancel"}),e.jsxs(v,{onClick:p,disabled:y.isPending,children:[y.isPending&&e.jsx(G,{className:"h-4 w-4 mr-2 animate-spin"}),"Generate Key"]})]})]})]})]})]}),S?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(G,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):k!=null&&k.length?e.jsx("div",{className:"space-y-3",children:k.map(x=>e.jsxs(W,{children:[e.jsxs(Z,{className:"pb-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(J,{className:"text-base",children:x.product_name}),e.jsx(Y,{variant:x.is_active?"default":"secondary",children:x.is_active?"Active":"Inactive"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx($,{checked:x.is_active,onCheckedChange:o=>I.mutate({id:x.id,isActive:o})}),e.jsxs(es,{children:[e.jsx(ss,{asChild:!0,children:e.jsx(v,{variant:"ghost",size:"icon",className:"text-destructive",children:e.jsx(qe,{className:"h-4 w-4"})})}),e.jsxs(ts,{children:[e.jsxs(as,{children:[e.jsx(ns,{children:"Delete API Key"}),e.jsxs(is,{children:['This will permanently revoke access for "',x.product_name,'". Any external applications using this key will stop working immediately.']})]}),e.jsxs(rs,{children:[e.jsx(cs,{children:"Cancel"}),e.jsx(ls,{onClick:()=>r.mutate(x.id),className:"bg-destructive text-destructive-foreground",children:"Delete"})]})]})]})]})]}),x.description&&e.jsx(te,{children:x.description})]}),e.jsx(H,{className:"pt-0",children:e.jsxs("div",{className:"flex gap-6 text-xs text-muted-foreground",children:[e.jsxs("span",{children:["Key: â¢â¢â¢â¢",x.api_key.slice(-8)]}
7),e.jsxs("span",{children:["Created: ",Ee(new Date(x.created_at),"MMM d, yyyy")]}),x.last_used_at&&e.jsxs("span",{children:["Last used: ",Ee(new Date(x.last_used_at),"MMM d, yyyy HH:mm")]})]})})]},x.id))}):e.jsx(W,{children:e.jsxs(H,{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(ks,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h4",{className:"font-semibold mb-1",children:"No API keys yet"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:"Create an API key to allow external applications to submit tickets to Grit."})]})}),e.jsxs(W,{className:"bg-muted/50",children:[e.jsx(Z,{children:e.jsx(J,{className:"text-sm",children:"Integration Guide"})}),e.jsxs(H,{className:"text-xs text-muted-foreground space-y-2",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Submit a ticket:"})," ",e.jsx("code",{children:"POST /functions/v1/receive-external-ticket"})]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Sync tickets:"})," ",e.jsx("code",{children:"POST /functions/v1/sync-external-tickets"})]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Auth:"})," Include ",e.jsx("code",{children:"x-api-key: <your-key>"})," header"]})]})]})]})}const we=g,ms="cybergen-ai";function Ye(c=32){const j=new Uint8Array(c);return crypto.getRandomValues(j),Array.from(j,t=>t.toString(16).padStart(2,"0")).join("")}function hs(c){return c.parent_name?`${c.parent_name} â ${c.name}`:c.name}function Ws(){const c=$e(),{currentOrganization:j}=fs(),t=(j==null?void 0:j.id)??null,d=(j==null?void 0:j.name)??"Master",[_,C]=l.useState(!1),[M,n]=l.useState(null),[P,k]=l.useState(null),{data:S,isLoading:y}=he({queryKey:["cybergen-mappings",t],enabled:!!t,queryFn:async()=>{const{data:s,error:a}=await we.from("cybergen_grit_mappings").select("*").eq("master_organization_id",t).order("created_at",{ascending:!1});if(a)throw a;return s??[]}}),{data:I,isLoading:r}=he({queryKey:["cybergen-mapping-api-keys",t],enabled:!!t,queryFn:async()=>{const{data:s,error:a}=await g.from("external_api_keys").select("id, product_name, is_active, organization_id").eq("is_active",!0).eq("organization_id",t).order("product_name");if(a)throw a;return s??[]}}),{data:p}=he({queryKey:["mapping-org-options",t],enabled:!!t,queryFn:async()=>{const{data:s,error:a}=await g.from("organizations").select("id, name, parent_organization_id").eq("id",t).maybeSingle();if(a)throw a;const{data:u,error:m}=await g.from("organizations").select("id, name, parent_organization_id").eq("parent_organization_id",t).order("name");if(m)throw m;const E=(s==null?void 0:s.name)??d,F=[];s&&F.push({id:s.id,name:s.name,parent_organization_id:null,parent_name:null,isMaster:!0});for(const h of u??[])F.push({id:h.id,name:h.name,parent_organization_id:h.parent_organization_id,parent_name:E,isMaster:!1});return F}}),A=he({queryKey:["cybergen-recent-events",t,(S??[]).map(s=>s.id).join(",")],enabled:!!t,queryFn:async()=>{const s=(S??[]).map(m=>m.id);if(s.length===0)return[];const{data:a,error:u}=await we.from("integration_events").select("id, event_id, event_type, mapping_id, delivery_status, attempts, last_error, created_at, delivered_at").in("mapping_id",s).order("created_at",{ascending:!1}).limit(20);if(u)throw u;return a??[]}}),T=ue({mutationFn:async s=>{if(s.id){const{id:a,...u}=s,{error:m}=await we.from("cybergen_grit_mappings").update(u).eq("id",a);if(m)throw m}else{const{error:a}=await we.from("cybergen_grit_mappings").insert(s);if(a)throw a}},onSuccess:()=>{c.invalidateQueries({queryKey:["cybergen-mappings"]}),C(!1),n(null),ae({title:"Configuration saved"})},onError:s=>ae({title:"Save failed",description:s.message,variant:"destructive"})}),x=ue({mutationFn:async s=>{const{error:a}=await we.from("cybergen_grit_mappings").update({is_active:!s.is_active}).eq("id",s.id);if(a)throw a},onSuccess:()=>c.invalidateQueries({queryKey:["cybergen-mappings"]})}),o=ue({mutationFn:async s=>{const{error:a}=await we.from("cybergen_grit_mappings").delete().eq("id",s);if(a)throw a},onSuccess:()=>{c.invalidateQueries({queryKey:["cybergen-mappings"]}),ae({title:"Configuration deleted"})},onError:s=>ae({title:"Delete failed",description:s.message,variant:"destructive"})}),i=s=>{const a=p==null?void 0:p.find(u=>u.id===s);return a?hs(a):s.slice(0,8)},w=l.useMemo(()=>(S??[]).find(s=>s.cybergen_tenant_id===ms)??null,[S]),N=()=>{n(w),C(!0)};return e.jsxs("div",{className:"space-y-6",children:[e.jsx(W,{className:"border-primary/30 bg-primary/5",children:e.jsxs(H,{
7className:"flex items-start gap-3 py-4",children:[e.jsx(Is,{className:"h-5 w-5 text-primary mt-0.5 shrink-0"}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"font-semibold",children:"CyberGen Integration"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["This integration uses a single organization-wide mapping. All clients and tickets are automatically included. Client routing is handled dynamically using"," ",e.jsx("code",{className:"text-xs",children:"cybergen_account_id"}),"."]})]})]})}),e.jsxs(W,{children:[e.jsxs(Z,{className:"flex flex-row items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs(J,{className:"flex items-center gap-2",children:[e.jsx(Be,{className:"h-5 w-5"})," CyberGen Configuration"]}),e.jsx(te,{children:"One organization-wide mapping connecting CyberGen AI to your GRIT master organization. Covers every child organization and client automatically."})]}),w?e.jsxs(v,{onClick:N,children:[e.jsx(Ts,{className:"h-4 w-4 mr-2"})," Edit Configuration"]}):e.jsxs(v,{onClick:()=>{n(null),C(!0)},children:[e.jsx(ze,{className:"h-4 w-4 mr-2"})," Add Configuration"]})]}),e.jsx(H,{children:y?e.jsxs("div",{className:"flex items-center justify-center py-8 text-muted-foreground",children:[e.jsx(G,{className:"h-5 w-5 animate-spin mr-2"})," Loadingâ¦"]}):(S??[]).length===0?e.jsx("div",{className:"text-sm text-muted-foreground py-8 text-center",children:"No configuration yet. Add one to start sending and receiving CyberGen tickets."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(Ce,{children:[e.jsx(ke,{children:e.jsxs(re,{children:[e.jsx(D,{children:"Tenant"}),e.jsx(D,{children:"GRIT Organization"}),e.jsx(D,{children:"Webhook URL"}),e.jsx(D,{children:"Status"}),e.jsx(D,{children:"Last Updated"}),e.jsx(D,{className:"text-right",children:"Actions"})]})}),e.jsx(Ae,{children:S.map(s=>e.jsxs(re,{children:[e.jsx(z,{className:"font-mono text-xs break-all",children:s.cybergen_tenant_id}),e.jsxs(z,{className:"text-sm",children:[e.jsx("div",{children:i(s.grit_organization_id)}),e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"Includes all child organizations and clients"})]}),e.jsxs(z,{className:"text-xs max-w-[260px]",children:[e.jsx("div",{className:"truncate break-words overflow-hidden",title:s.webhook_url??"",children:s.webhook_url||e.jsx("span",{className:"text-muted-foreground italic",children:"not set"})}),s.webhook_secret&&e.jsxs("div",{className:"flex items-center gap-1 mt-1 font-mono",children:[P===s.id?e.jsx("span",{className:"break-all",children:s.webhook_secret}):e.jsx("span",{children:"â¢â¢â¢â¢â¢â¢â¢â¢"}),e.jsx(v,{size:"icon",variant:"ghost",className:"h-5 w-5",onClick:()=>k(P===s.id?null:s.id),children:P===s.id?e.jsx(Fe,{className:"h-3 w-3"}):e.jsx(De,{className:"h-3 w-3"})})]})]}),e.jsx(z,{children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx($,{checked:s.is_active,onCheckedChange:()=>x.mutate(s)}),e.jsx(Y,{variant:s.is_active?"default":"secondary",children:s.is_active?"Active":"Disabled"})]})}),e.jsx(z,{className:"text-xs whitespace-nowrap text-muted-foreground",children:Ee(new Date(s.updated_at),"PPp")}),e.jsxs(z,{className:"text-right",children:[e.jsx(v,{size:"icon",variant:"ghost",onClick:()=>{n(s),C(!0)},children:e.jsx(Ms,{className:"h-4 w-4"})}),e.jsxs(es,{children:[e.jsx(ss,{asChild:!0,children:e.jsx(v,{size:"icon",variant:"ghost",children:e.jsx(qe,{className:"h-4 w-4 text-destructive"})})}),e.jsxs(ts,{children:[e.jsxs(as,{children:[e.jsx(ns,{children:"Delete this configuration?"}),e.jsx(is,{children:"CyberGen requests will be rejected until a new configuration is added. Tickets already created stay. Prefer disabling with the Active toggle if you only need to pause the integration."})]}),e.jsxs(rs,{children:[e.jsx(cs,{children:"Cancel"}),e.jsx(ls,{onClick:()=>o.mutate(s.id),children:"Delete"})]})]})]})]})]},s.id))})]})})})]}),e.jsxs(W,{children:[e.jsxs(Z,{children:[e.jsxs(J,{className:"flex items-center gap-2",children:[e.jsx(Je,{className:"h-5 w-5"})," Recent Webhook Deliveries"]}),e.jsx(te,{children:"Last 20 outbound events to CyberGen."})]}),e.jsx(H,{children:(A.data??[]).length===0?e.jsx("div",{className:"text-sm text-muted-foreground py-4 text-center",children:"No events yet."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(Ce,{children:[e.jsx(ke,{children:e.jsxs(re,{children:[e.jsx(D,{children:"When"}),e.jsx(D,{children:"Event"}),e.jsx(D,{children:"Status"}),e.jsx(D,{children:"Attempts"}),e.jsx(D,{children:"Last Error"})]})}),e.jsx(Ae,{children:A.data.map(s=>e.jsxs(re,{children:[e.jsx(z,{className:"text-xs whitespace-nowrap",children:Ee(new Date(s.created_at),"PPp")}),e.jsx(z,{className:"text-sm font-mono",children:s.event_type}),e.jsx(z,{children:e.jsx(Y,{variant:s.delivery_status==="success"?"default":s.delivery_status==="dead"||s.delivery_status==="failed"?"destructive":"secondary",children:s.delivery_status})}),e.jsx(z,{children:s.attempts}),e.jsx(z,{className:"text-xs text-muted-foreground max-w-[400px] break-words overflow-hidden",children:s.last_error??"â"})]},s.id))})]})})})]}),e.jsx(Hs,{open:_,onOpenChange:C,editing:M,masterOrgId:t,apiKeys:I??[],apiKeysLoading:r,orgOptions:p??[],existingMappings:S??[],onSave:s=>T.mutate(s),saving:T.isPending})]})}function Hs({open:c,onOpenChange:j,editing:t,masterOrgId:d,apiKeys:_,apiKeysLoading:C,orgOptions:M,existingMappings:n,onSave:P,saving:k}){const[S]=l.useState(ms),[y,I]=l.useState(""),[r,p]=l.useState(""),[A,T]=l.useState(""),[x,o]=l.useState(""),[i,w]=l.useState(!0);l.useEffect(()=>{c&&(t?(I(t.api_key_id),p(t.grit_organization_id),T(t.webhook_url??""),o(t.webhook_secret??""),w(t.is_active)):(I(""),p(""),T(""),o(Ye()),w(!0)))},[c,t]);const N=()=>
7{if(d){if(!y||!r||!A.trim()||!x.trim()){ae({title:"Missing fields",description:"API key, GRIT organization, webhook URL, and webhook secret are all required.",variant:"destructive"});return}if(!M.some(s=>s.id===r)){ae({title:"Invalid organization",description:"Pick the master org or one of its child organizations.",variant:"destructive"});return}if(!t&&n.find(a=>a.cybergen_tenant_id===S)){ae({title:"Configuration already exists",description:"Use Edit Configuration instead â only one mapping is allowed.",variant:"destructive"});return}P({id:t==null?void 0:t.id,cybergen_tenant_id:S,cybergen_account_id:null,api_key_id:y,master_organization_id:d,grit_organization_id:r,grit_client_id:null,default_client_id:null,webhook_url:A.trim(),webhook_secret:x.trim(),is_active:i})}};return e.jsx(ye,{open:c,onOpenChange:j,children:e.jsxs(ve,{className:"max-w-2xl",children:[e.jsxs(ge,{children:[e.jsx(Ne,{children:t?"Edit Configuration":"New CyberGen Configuration"}),e.jsx(be,{children:"One organization-wide mapping for CyberGen AI. All clients and child organizations are included automatically."})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2 col-span-2",children:[e.jsx(b,{children:"CyberGen Tenant ID"}),e.jsx(B,{value:S,readOnly:!0,disabled:!0,className:"font-mono"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Fixed identifier for the CyberGen tenant. Cannot be changed."})]}),e.jsxs("div",{className:"space-y-2 col-span-2",children:[e.jsx(b,{children:"Master API Key *"}),e.jsxs(ce,{value:y,onValueChange:I,children:[e.jsx(le,{children:e.jsx(oe,{placeholder:"Select API key"})}),e.jsx(de,{children:C?e.jsx("div",{className:"px-2 py-1.5 text-sm text-muted-foreground",children:"Loadingâ¦"}):_.length===0?e.jsx("div",{className:"px-2 py-1.5 text-sm text-muted-foreground",children:"No active API keys found."}):_.map(s=>e.jsx(ne,{value:s.id,children:s.product_name},s.id))})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[_.length," active key",_.length===1?"":"s"," available. Create one under the ",e.jsx("strong",{children:"External API"})," tab if none appears."]})]}),e.jsxs("div",{className:"space-y-2 col-span-2",children:[e.jsx(b,{children:"GRIT Organization *"}),e.jsxs(ce,{value:r,onValueChange:p,children:[e.jsx(le,{children:e.jsx(oe,{placeholder:"Select organization"})}),e.jsx(de,{children:M.map(s=>e.jsx(ne,{value:s.id,children:hs(s)},s.id))})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["This mapping covers all clients and child organizations automatically. Client routing is handled dynamically using ",e.jsx("code",{className:"text-xs",children:"cybergen_account_id"}),"."]})]}),e.jsxs("div",{className:"space-y-2 col-span-2",children:[e.jsx(b,{children:"Webhook URL *"}),e.jsx(B,{value:A,onChange:s=>T(s.target.value),placeholder:"https://cybergen.ai/api/grit/webhook"})]}),e.jsxs("div",{className:"space-y-2 col-span-2",children:[e.jsx(b,{children:"Webhook Secret * (HMAC-SHA256)"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(B,{value:x,onChange:s=>o(s.target.value),className:"font-mono text-xs",placeholder:"32-byte hex secret"}),e.jsxs(v,{type:"button",variant:"outline",onClick:()=>o(Ye()),children:[e.jsx(Ps,{className:"h-4 w-4 mr-1"})," Generate"]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Outbound webhooks will be signed as ",e.jsx("code",{children:"x-cybergen-signature"})," using this secret. Share it with CyberGen so they can verify the signature."]})]}),e.jsxs("div",{className:"flex items-center gap-3 col-span-2",children:[e.jsx($,{checked:i,onCheckedChange:w,id:"active"}),e.jsx(b,{htmlFor:"active",children:"Active"})]})]}),e.jsxs(fe,{children:[e.jsx(v,{variant:"outline",onClick:()=>j(!1),children:"Cancel"}),e.jsxs(v,{onClick:N,disabled:k,children:[k&&e.jsx(G,{className:"h-4 w-4 mr-2 animate-spin"}),t?"Save changes":"Create configuration"]})]})]})})}function Qs(){return e.jsxs(gs,{defaultValue:"available",className:"w-full",children:[e.jsxs(Ns,{className:"grid w-full grid-cols-7",children:[e.jsxs(pe,{value:"available",children:[e.jsx(ys,{className:"h-4 w-4 mr-2"}),"Available"]}),e.jsxs(pe,{value:"active",children:[e.jsx(Es,{className:"h-4 w-4 mr-2"}),"Active"]}),e.jsxs(pe,{value:"staff-sso",children:[e.jsx(Ve,{className:"h-4 w-4 mr-2"}),"Staff SSO"]}),e.jsxs(pe,{value:"external-api",children:[e.jsx(Fs,{className:"h-4 w-4 mr-2"}),"External API"]}),e.jsxs(pe,{value:"cybergen",children:[e.jsx(As,{className:"h-4 w-4 mr-2"}),"CyberGen"]}),e.jsxs(pe,{value:"webhooks",children:[e.jsx(Be,{className:"h-4 w-4 mr-2"}),"Webhooks"]}),e.jsxs(pe,{value:"logs",children:[e.jsx(vs,{className:"h-4 w-4 mr-2"}),"Logs"]})]}),e.jsx(je,{value:"available",className:"mt-6",children:e.jsx(Ks,{})}),e.jsx(je,{value:"active",className:"mt-6",children:e.jsx(Us,{})}),e.jsx(je,{value:"staff-sso",className:"mt-6",children:e.jsx(Vs,{})}),e.jsx(je,{value:"external-api",className:"mt-6",children:e.jsx(Bs,{})}),e.jsx(je,{value:"cybergen",className:"mt-6",children:e.jsx(Ws,{})}),e.jsx(je,{value:"webhooks",className:"mt-6",children:e.jsx(Ls,{})}),e.jsx(je,{value:"logs",className:"mt-6",children:e.jsx(Gs,{})})]})}const Dt=()=>e.jsx("div",{className:"p-6",children:e.jsx(Qs,{})});
7export{Dt 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.