PageSourceSearch

https://app.knockknockapp.ai/assets/KnoxKnowledge-DgBj76uF.js

js knockknockapp.ai collected 2026-09-24 13:19:58 UTC 32,907 bytes, 1 lines download raw bytes

1import{w as be,l as o,y as de,B as m,z as M,m as n,Y as q,q as e,u as x,D as Q,F as T,J as z,K as d,v as P,p as k,C as ve,W as ce,X as ke,r as _,e as A,b as he,aa as ne,ac as ie,a6 as je}from"./vue-vendor-B52ivs5F.js";import{u as we,b as me}from"./query-vendor-Ab0nfCYP.js";import{_ as Be}from"./ConfirmDialog-CguVS9_-.js";import{g as Pe,a as _e,c as $e,s as Re,d as Ue,e as Ie}from"./knox-BBPew7c8.js";import{_ as Le,t as F}from"./index-NM9cAr_v.js";import{_ as Me}from"./KnoxAdminTabs-eC8apC-I.js";import{X as Z,d2 as qe,d3 as Ce,d4 as Ae,bJ as Qe,aO as Ee,a5 as Ve,b as xe,j as Oe,ak as We,c3 as Ye,W as Je}from"./ui-vendor-D-1UBobO.js";import"./date-vendor-HBGOQ70J.js";import"./twilio-DAuME2Y9.js";import"./charts-D4hDxUnJ.js";import"./socket-CzTGKfeH.js";const Xe={class:"flex max-h-[92vh] w-full max-w-2xl flex-col overflow-hidden rounded-t-2xl border border-gray-200 bg-white shadow-xl sm:rounded-xl dark:border-gray-700 dark:bg-gray-800",role:"dialog","aria-modal":"true","aria-labelledby":"bulk-import-title"},Ge={class:"flex items-center justify-between border-b border-gray-200 px-5 py-4 dark:border-gray-700"},He=["disabled"],Ze={class:"flex-1 overflow-y-auto px-5 py-4"},et={key:0,class:"space-y-4"},tt={class:"text-sm font-medium text-gray-700 dark:text-gray-200"},rt={class:"mt-2 cursor-pointer text-xs text-teal-600 underline-offset-2 hover:underline dark:text-teal-400"},at={key:1,class:"space-y-4"},st={class:"grid grid-cols-3 gap-3 text-center"},ot={class:"rounded-lg bg-gray-50 px-3 py-3 dark:bg-gray-700/40"},lt={class:"text-2xl font-bold text-gray-900 dark:text-white"},nt={class:"rounded-lg bg-gray-50 px-3 py-3 dark:bg-gray-700/40"},it={class:"text-2xl font-bold text-gray-900 dark:text-white"},dt={class:"rounded-lg bg-gray-50 px-3 py-3 dark:bg-gray-700/40"},ct={class:"text-2xl font-bold text-gray-900 dark:text-white"},ut={class:"space-y-1 rounded-lg border border-gray-200 dark:border-gray-700"},gt={class:"flex min-w-0 items-center gap-2"},pt={class:"truncate font-medium text-gray-800 dark:text-gray-200"},yt={class:"shrink-0 text-xs text-gray-500 dark:text-gray-400"},mt={class:"flex items-center justify-between rounded-lg border border-gray-200 px-3 py-2 text-xs dark:border-gray-700"},xt={class:"text-gray-600 dark:text-gray-400"},ft={class:"font-semibold text-gray-800 dark:text-gray-200"},bt={key:0,class:"text-gray-500 dark:text-gray-500"},vt={class:"font-semibold text-amber-700 dark:text-amber-400"},kt={key:0,class:"rounded-lg border border-amber-200 bg-amber-50/50 px-3 py-2 text-xs dark:border-amber-900/40 dark:bg-amber-900/10"},ht={class:"cursor-pointer text-amber-800 dark:text-amber-300"},wt={class:"mt-2 space-y-1 text-amber-700 dark:text-amber-400"},_t={class:"font-mono"},$t={class:"text-amber-600 dark:text-amber-500"},Ct={key:1,class:"rounded-lg border border-gray-200 px-3 py-2 text-xs dark:border-gray-700"},Dt={class:"cursor-pointer text-gray-600 dark:text-gray-400"},St={class:"mt-2 space-y-0.5 text-gray-500 dark:text-gray-500"},zt={key:2,class:"space-y-3"},Tt={class:"flex items-center justify-between text-sm"},Ft={class:"font-medium text-gray-800 dark:text-gray-200"},Kt={class:"flex items-center gap-3 text-xs"},Nt={class:"text-emerald-600 dark:text-emerald-400"},jt={key:0,class:"text-red-600 dark:text-red-400"},Bt={class:"h-1.5 w-full overflow-hidden rounded-full bg-gray-100 dark:bg-gray-700"},Pt={class:"max-h-72 space-y-0.5 overflow-y-auto rounded-lg border border-gray-200 px-2 py-2 text-xs dark:border-gray-700"},Rt={class:"mt-0.5 w-3 shrink-0 text-center"},Ut={key:0,class:"text-gray-300"},It={key:1,class:"text-emerald-500"},Lt={key:2,class:"text-red-500"},Mt={key:3,class:"text-amber-500"},qt={class:"min-w-0 flex-1"},At={class:"truncate font-mono text-gray-700 dark:text-gray-300"},Qt={key:0,class:"text-red-500 dark:text-red-400"},Et={class:"flex flex-col-reverse gap-2 border-t border-gray-200 px-5 py-4 sm:flex-row sm:justify-end dark:border-gray-700"},Vt=["disabled"],fe=1100,Ot={__name:"KnoxBulkImportModal",props:{open:{type:Boolean,required:!0}},emits:["close"],setup(ee,{emit:E}){const $=ee,j=E,B=we(),y=_("pick"),f=_([]),w=_([]),b=_([]),c=he({done:0,succeeded:0,failed:0}),D=_(!1),S=_(!1);let K=0;const C=A(()=>{let l=0,t=0;const a=[];for(const s of f.value)l+=s.related_urls?.length||0,s.dropped_urls?.length&&(t+=s.dropped_urls.length,a.push({path:s.path,urls:s.dropped_urls}));return{kept:l,dropped:t,droppedDetails:a}});be(()=>$.open,l=>{l&&(y.value="pick",f.value=[],w.value=[],b.value=[],c.done=0,c.succeeded=0,c.failed=0,L.clear(),D.value=!1,K=0,S.value=!1)});function I(){y.value!=="importing"&&j("close")}function te(){y.value!=="importing"&&I()}function V(){y.value="pick",f.value=[],w.value=[],b.value=[]}function re(l){const t=l.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);if(!t)return{title:null,related_urls:[],body:l};const a=t[1],s=t[2],u=a.match(/^title:\s*(.+)$/m);return{title:u?u[1].trim().replace(/^["']|["']$/g,""):null,related_urls:R(a),body:s.trimStart()}}function R(l){const t=l.match(/^related_urls:\s*\[([^\]]*)\]/m);if(t)return t[1].split(",").map(s=>
1s.trim().replace(/^["']|["']$/g,"")).filter(Boolean);const a=l.match(/^related_urls:\s*\n((?:[ \t]+-[ \t]+.+\r?\n?)+)/m);return a?a[1].split(/\r?\n/).map(s=>s.match(/^\s*-\s+(.+?)\s*$/)).filter(Boolean).map(s=>s[1].replace(/^["']|["']$/g,"")).filter(Boolean):[]}const ae=new Set(["ai","api","crm","url","sms","ui","ux","kb"]);function O(l){return l.split("-").filter(Boolean).map(t=>ae.has(t)?t.toUpperCase():t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function W(l){const t=l.replace(/\.md$/i,"");return O(t)}function Y(l){return new Promise(t=>setTimeout(t,l))}async function G(l,{maxAttempts:t=5}={}){let a=0;for(;;)try{return await l()}catch(s){if(s?.response?.status!==429||a>=t-1)throw s;a++;const g=s?.response?.headers?.["retry-after"],U=Number(g),X=Number.isFinite(U)&&U>0?U*1e3:Math.min(15e3,1e3*2**a+Math.random()*500);await Y(X)}}async function se(l){return new Promise((t,a)=>{const s=new FileReader;s.onload=()=>t(String(s.result||"")),s.onerror=()=>a(s.error),s.readAsText(l)})}function v(){K++,D.value=!0}function r(l){l.dataTransfer&&(l.dataTransfer.dropEffect="copy")}function J(){K=Math.max(0,K-1),K===0&&(D.value=!1)}async function i(l){if(K=0,D.value=!1,S.value)return;const t=Array.from(l.dataTransfer?.items||[]);if(!t.length)return;const a=t.map(s=>s.webkitGetAsEntry?.()).filter(Boolean);if(!a.length){F.error('Drag-and-drop folders are not supported in this browser. Use "choose a folder" instead.');return}S.value=!0;try{const s=[];for(const u of a){const g=u.isDirectory?`${u.name}/`:"";await oe(u,g,s)}await ue(s)}catch(s){F.error(`Failed to read folder: ${s?.message||s}`)}finally{S.value=!1}}async function oe(l,t,a){if(l.isFile){const s=await new Promise((u,g)=>l.file(u,g));a.push({file:s,relPath:t+l.name});return}if(l.isDirectory){const s=l.createReader();for(;;){const u=await new Promise((g,U)=>s.readEntries(g,U));if(!u.length)break;for(const g of u)await oe(g,t+l.name+"/",a)}}}async function De(l){const t=Array.from(l.target.files||[]);if(l.target.value="",!t.length)return;const a=t.map(s=>({file:s,relPath:s.webkitRelativePath||s.name}));await ue(a)}async function ue(l){if(!l.length)return;const t=[],a=[];for(const{file:p,relPath:h}of l){if(!h.toLowerCase().endsWith(".md")){a.push(h);continue}const N=h.split("/");if(N.length<3){a.push(h);continue}const H=N[N.length-2];t.push({file:p,path:h,collectionSlug:H})}if(!t.length){F.error("No importable .md files found (need at least one subfolder)"),b.value=a;return}let s=new Set;try{const p=await Pe()||[];s=new Set(p.map(h=>h.url_pattern))}catch(p){F.error(`Couldn't load page registry: ${p?.message||p}`);return}const u=[];for(const p of t)try{const h=await se(p.file),{title:N,related_urls:H,body:Fe}=re(h),Ke=H.filter(le=>s.has(le)),Ne=H.filter(le=>!s.has(le));u.push({path:p.path,collectionSlug:p.collectionSlug,title:N||W(p.file.name),markdown_content:Fe,related_urls:Ke,dropped_urls:Ne,status:"pending",error:null})}catch(h){u.push({path:p.path,collectionSlug:p.collectionSlug,title:W(p.file.name),markdown_content:"",related_urls:[],dropped_urls:[],status:"failed",error:`Failed to read file: ${h?.message||h}`})}let g=[];try{g=await _e()||[]}catch{F.error("Failed to load existing collections");return}const U=new Map(g.map(p=>[p.slug,p])),X=new Map;for(const p of u)X.set(p.collectionSlug,(X.get(p.collectionSlug)||0)+1);const Te=Array.from(X.entries()).sort(([p],[h])=>p.localeCompare(h)).map(([p,h])=>{const N=U.get(p);return{slug:p,name:N?.name||O(p),willCreate:!N,fileCount:h,id:N?.id||null}});f.value=u,w.value=Te,b.value=a,y.value="preview"}const L=new Map;async function ge(l){for(const t of l)if(!L.has(t.slug)){if(t.id){L.set(t.slug,t.id);continue}try{const a=await G(()=>$e({name:t.name,slug:t.slug,description:void 0}));L.set(t.slug,a.id),t.id=a.id,t.willCreate=!1,await Y(fe)}catch(a){const s=a?.response?.data?.message||a?.message||"Failed to create collection";for(const u of f.value)u.collectionSlug===t.slug&&u.status!=="success"&&(u.status="failed",u.error=`Collection "${t.name}" failed: ${s}`,c.done++,c.failed++)}}}async function pe(l){for(const t of l){t.status="uploading",t.error=null;const a=L.get(t.collectionSlug);if(!a){t.status="failed",t.error="No collection id (collection creation failed earlier)",c.done++,c.failed++;continue}try{await G(()=>Re({title:t.title,markdown_content:t.markdown_content,collection_id:a,related_urls:t.related_urls||[]})),t.status="success",c.succeeded++}catch(s){const u=s?.response?.data;let g=u?.message||s?.message||"Failed to save";Array.isArray(u?.unknown)&&u.unknown.length&&(g=`Unknown portal URL(s): ${u.unknown.join(", ")}`),t.status="failed",t.error=String(g),c.failed++}finally{c.done++}await Y(fe)}}async function Se(){y.value="importing",c.done=0,c.succeeded=0,c.failed=0,await ge(w.value),B.invalidateQueries({queryKey:["admin","knox","collections"]});const l=f.value.filter(t=>t.status!=="failed");await pe(l),B.invalidateQueries({queryKey:["admin","knox"]}),y.value="done",ye()}async function ze(){const l=f.value.filter(g=>g.status==="failed");if(!l.length)return;const t=l.length;c.done=f.value.length-t,c.failed=0,c.succeeded=f.value.filter(g=>g.status==="success").length,y.value="importing";const a=new Set(l.map(g=>g.collectionSlug)),s=w.value.filter(g=>a.has(g.slug)&&!L.has(g.slug));s.length&&(await ge(s),B.invalidateQueries({queryKey:["admin","knox","collections"]}));const u=f.value.filter(g=>g.status==="failed");for(const g of u)g.status="pending";await pe(u),B.invalidateQueries({queryKey:["admin","knox"]}),y.value="done",ye()}function ye(){c.failed===0?F.success(`Imported ${c.succeeded} document${c.succeeded===1?"":"s"}`):F.error(`Imported ${c.succeeded} of ${f.value.length} — ${c.failed} failed`)}return(l,t)=>(o(),de(ke,{to:"body"},[m(ce,{name:"fade"},{default:M(()=>[ee.open?(o(),n("div",{key:0,class:"fixed inset-0 z-50 flex items-end justify-center bg-black/40 p-0 sm:items-center sm:p-4",onClick:q(te,["self"])},[e("div",Xe,[e("div",Ge,[t[0]||(t[0]=e("div",null,[e("h3",{id:"bulk-import-title",class:"text-base font-semibold text-gray-900 dark:text-white"}," Bulk Import Documents "),e("p",{class:"mt-0.5 text-xs text-gray-500 dark:text-gray-400"}," Pick a folder of markdown. Subfolders become collections, files become documents. ")],-1)),e("button",{onClick:I,disabled:y.value==="importing",class:"rounded-lg p-1.5 text-gray-400 transition-colors hover:bg-gray-100 hover:text-gray-600 disabled:opacity-40 dark:hover:bg-gray-700","aria-label":"Close"},[m(x(Z),{size:16})],8,He)]),e("div",Ze,[y.value==="pick"?(o(),n("div",et,[e("div",{class:Q(["flex w-full flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed px-6 py-10 text-center transition-colors",D.value?"border-teal-500 bg-teal-50/60 dark:border-teal-400 dark:bg-teal-900/20":"border-gray-300 hover:border-teal-400 hover:bg-teal-50/30 dark:border-gray-600 dark:hover:border-teal-500 dark:hover:bg-teal-900/10",S.value?"pointer-events-none opacity-70":""]),onDragenter:q(v,["prevent"]),onDragover:q(r,["prevent"]),onDragleave:q(J,["prevent"]),onDrop:q(i,["prevent"])},[m(x(qe),{size:32,class:"text-gray-400 dark:text-gray-500"}),e("span",tt,[S.value?(o(),n(T,{key:0},[z("Scanning folder…")],64)):D.value?(o(),n(T,{key:1},[z("Drop to import")],64)):(o(),n(T,{key:2},[z("Drag a folder here")],64))]),t[2]||(t[2]=e("span",{class:"text-xs text-gray-500 dark:text-gray-400"}," Only `.md` files are imported. Top-level files are skipped. ",-1)),e("label",rt,[t[1]||(t[1]=z(" …or choose a folder ",-1)),e("input",{type:"file",webkitdirectory:"",directory:"",multiple:"",class:"hidden",onChange:De},null,32)])],34),t[3]||(t[3]=e("div",{class:"rounded-lg border border-gray-200 bg-gray-50 px-3 py-2 text-xs text-gray-600 dark:border-gray-700 dark:bg-gray-900/40 dark:text-gray-400"}," `related_urls` from each file's frontmatter is preserved automatically. URLs not found in the page registry are dropped so the import doesn't 400 — you'll see a count in the preview. ",-1))])):y.value==="preview"?(o(),n("div",at,[e("div",st,[e("div",ot,[e("div",lt,d(f.value.length),1),t[4]||(t[4]=e("div",{class:"text-[10px] tracking-wide text-gray-500 uppercase dark:text-gray-400"}," Documents ",-1))]),e("div",nt,[e("div",it,d(w.value.length),1),t[5]||(t[5]=e("div",{class:"text-[10px] tracking-wide text-gray-500 uppercase dark:text-gray-400"}," Collections ",-1))]),e("div",dt,[e("div",ct,d(b.value.length),1),t[6]||(t[6]=e("div",{class:"text-[10px] tracking-wide text-gray-500 uppercase dark:text-gray-400"}," Skipped ",-1))])]),e("div",null,[t[7]||(t[7]=e("h4",{class:"mb-2 text-xs font-semibold tracking-wide text-gray-600 uppercase dark:text-gray-400"}," Collections ",-1)),e("ul",ut,[(o(!0),n(T,null,P(w.value,a=>(o(),n("li",{key:a.slug,class:"flex items-center justify-between px-3 py-2 text-sm odd:bg-gray-50/60 dark:odd:bg-gray-700/30"},[e("div",gt,[m(x(Ce),{size:14,class:"shrink-0 text-gray-400"}),e("span",pt,d(a.name),1),e("span",{class:Q(["shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium tracking-wide uppercase",a.willCreate?"bg-teal-50 text-teal-700 dark:bg-teal-900/30 dark:text-teal-400":"bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400"])},d(a.willCreate?"new":"existing"),3)]),e("span",yt,d(a.fileCount)+" doc"+d(a.fileCount===1?"":"s"),1)]))),128))])]),e("div",mt,[e("span",xt,[e("span",ft,d(C.value.kept),1),z(" related URL"+d(C.value.kept===1?"":"s")+" preserved ",1),C.value.dropped>0?(o(),n("span",bt,[t[8]||(t[8]=z(" · ",-1)),e("span",vt,d(C.value.dropped),1),t[9]||(t[9]=z(" not in registry ",-1))])):k("",!0)])]),C.value.dropped>0?(o(),n("details",kt,[e("summary",ht,d(C.value.dropped)+" URL(s) will be dropped (not in `knox_page_registry`) ",1),e("ul",wt,[(o(!0),n(T,null,P(C.value.droppedDetails,a=>(o(),n("li",{key:a.path},[e("span",_t,d(a.path),1),t[10]||(t[10]=z(": ",-1)),e("span",$t,d(a.urls.join(", ")),1)]))),128))])])):k("",!0),b.value.length?(o(),n("details",Ct,[e("summary",Dt,d(b.value.length)+" file(s) skipped (top-level or non-markdown) ",1),e("ul",St,[(o(!0),n(T,null,P(b.value,a=>(o(),n("li",{key:a,class:"font-mono"},d(a),1))),128))])])):k("",!0)])):y.value==="importing"||y.value==="done"?(o(),n("div",zt,[e("div",Tt,[e("div",Ft,d(c.done)+" / "+d(f.value.length),1),e("div",Kt,[e("span",Nt," ✓ "+d(c.succeeded),1),c.failed?(o(),n("span",jt," ✕ "+d(c.failed),1)):k("",!0)])]),e("div",Bt,[e("div",{class:"h-full bg-teal-500 transition-all",style:ve({width:`${c.done/Math.max(f.value.length,1)*100}%`})},null,4)]),e("ul",Pt,[(o(!0),n(T,null,P(f.value,a=>(o(),n("li",{key:a.path,class:"flex items-start gap-2 px-1 py-0.5"},[e("span",Rt,[a.status==="pending"?(o(),n("span",Ut,"·")):a.status==="success"?(o(),n("span",It,"✓")):a.status==="failed"?(o(),n("span",Lt,"✕")):(o(),n("span",Mt,"…"))]),e("div",qt,[e("div",At,d(a.path),1),a.error?(o(),n("div",Qt,d(a.error),1)):k("",!0)])]))),128))])])):k("",!0)]),e("div",Et,[y.value==="preview"?(o(),n("button",{key:0,onClick:V,class:"rounded-lg border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700"}," Back ")):k("",!0),y.value==="pick"||y.value==="preview"?(o(),n("button",{key:1,onClick:I,class:"rounded-lg border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700"}
1," Cancel ")):k("",!0),y.value==="preview"?(o(),n("button",{key:2,onClick:Se,disabled:!f.value.length,class:"rounded-lg bg-teal-600 px-4 py-2 text-sm font-medium text-white shadow-sm transition-colors hover:bg-teal-700 disabled:cursor-not-allowed disabled:opacity-50"}," Import "+d(f.value.length)+" document"+d(f.value.length===1?"":"s"),9,Vt)):k("",!0),y.value==="done"&&c.failed>0?(o(),n("button",{key:3,onClick:ze,class:"rounded-lg border border-amber-300 bg-amber-50 px-4 py-2 text-sm font-medium text-amber-800 shadow-sm transition-colors hover:bg-amber-100 dark:border-amber-700 dark:bg-amber-900/30 dark:text-amber-200 dark:hover:bg-amber-900/50"}," Retry "+d(c.failed)+" failed ",1)):k("",!0),y.value==="done"?(o(),n("button",{key:4,onClick:I,class:"rounded-lg bg-teal-600 px-4 py-2 text-sm font-medium text-white shadow-sm transition-colors hover:bg-teal-700"}," Done ")):k("",!0)])])])):k("",!0)]),_:1})]))}},Wt=Le(Ot,[["__scopeId","data-v-f0d88e2d"]]),Yt={class:"flex h-full flex-col bg-gray-50 dark:bg-gray-900"},Jt={class:"relative flex flex-1 overflow-hidden"},Xt={class:"flex items-center justify-between border-b border-gray-200 px-4 py-3 dark:border-gray-700"},Gt={class:"px-3 pt-2"},Ht={class:"flex-1 overflow-y-auto py-2",role:"list"},Zt={class:"ml-auto rounded bg-gray-100 px-1.5 py-0.5 text-[11px] font-medium text-gray-500 dark:bg-gray-700 dark:text-gray-400"},er={key:0,class:"space-y-2 px-4 py-3"},tr=["onClick"],rr={class:"truncate"},ar={class:"ml-auto rounded bg-gray-100 px-1.5 py-0.5 text-[11px] font-medium text-gray-500 dark:bg-gray-700 dark:text-gray-400"},sr={key:0,class:"px-4 py-3 text-xs text-gray-400 italic dark:text-gray-500"},or={class:"flex min-w-0 flex-1 flex-col overflow-hidden"},lr={class:"sticky top-0 z-10 flex flex-col gap-3 border-b border-gray-200 bg-white px-4 py-3 sm:px-6 sm:py-4 lg:flex-row lg:items-center lg:gap-4 dark:border-gray-700 dark:bg-gray-800"},nr={class:"flex items-center gap-2 lg:min-w-0 lg:flex-1"},ir={class:"min-w-0 flex-1"},dr={class:"truncate text-base font-bold text-gray-900 sm:text-lg dark:text-white"},cr={class:"mt-0.5 truncate text-xs text-gray-500 dark:text-gray-400"},ur={class:"flex flex-col gap-2 sm:flex-row sm:items-center"},gr={class:"relative flex-1 sm:w-64 sm:flex-none"},pr={class:"flex-1 overflow-y-auto px-4 py-4 sm:px-6 sm:py-6"},yr={key:0,class:"space-y-3"},mr={key:1,class:"flex flex-col items-center justify-center py-16 text-center sm:py-20"},xr={class:"mb-1 text-base font-semibold text-gray-700 dark:text-gray-300"},fr={key:2,class:"flex flex-col items-center justify-center py-16 text-center sm:py-20"},br={key:3,class:"space-y-2 sm:space-y-3"},vr={class:"min-w-0 flex-1"},kr={class:"flex flex-wrap items-center gap-x-2 gap-y-1"},hr={class:"truncate text-sm font-semibold text-gray-900 dark:text-white"},wr={class:"mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-gray-500 dark:text-gray-400"},_r={key:0,class:"rounded bg-gray-100 px-1.5 py-0.5 dark:bg-gray-700"},$r={key:1,class:"hidden sm:inline"},Cr={class:"hidden sm:inline"},Dr={class:"hidden md:inline"},Sr={class:"w-full max-w-md overflow-hidden rounded-t-2xl border border-gray-200 bg-white shadow-xl sm:rounded-xl dark:border-gray-700 dark:bg-gray-800",role:"dialog","aria-modal":"true","aria-labelledby":"new-collection-title"},zr={class:"flex items-center justify-between border-b border-gray-200 px-5 py-4 dark:border-gray-700"},Tr={class:"space-y-3 px-5 py-4"},Fr={class:"block"},Kr={class:"block"},Nr=["value"],jr={class:"block"},Br={class:"flex flex-col-reverse gap-2 border-t border-gray-200 px-5 py-4 sm:flex-row sm:justify-end dark:border-gray-700"},Pr=["disabled"],Wr={__name:"KnoxKnowledge",setup(ee){const E=we(),$=_(null),j=_(!1),B=_(!1),y=_(!1),f=_(!1),w=_(!1),b=he({name:"",description:""}),c=A(()=>b.name.toLowerCase().trim().replace(/[^a-z0-9\s-]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").slice(0,64)),D=_(""),S=_("");let K=null;be(D,v=>{K&&clearTimeout(K),K=setTimeout(()=>{S.value=v},250)});const{data:C,isLoading:I}=me({queryKey:["admin","knox","collections"],queryFn:_e}),te=A(()=>["admin","knox","documents",$.value,S.value]),{data:V,isLoading:re}=me({queryKey:te,queryFn:()=>Ie($.value,S.value),keepPreviousData:!0}),R=A(()=>C.value?.find(v=>v.id===$.value)),ae=A(()=>C.value?C.value.reduce((v,r)=>v+(r.document_count||0),0):0),O=A(()=>{const v="/admin/knox/doc/new";return $.value?`${v}?collection=${$.value}
1`:v});function W(v){$.value=v,w.value=!1}function Y(v){return v?new Date(v).toLocaleDateString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):""}async function G(){if(!(!b.name.trim()||!c.value))try{await $e({name:b.name.trim(),slug:c.value,description:b.description.trim()||void 0}),F.success("Collection created"),E.invalidateQueries({queryKey:["admin","knox","collections"]}),j.value=!1,b.name="",b.description=""}catch(v){F.error(v?.response?.data?.message||"Failed to create collection")}}async function se(){if($.value){f.value=!0;try{await Ue($.value),F.success("Collection deleted"),y.value=!1,$.value=null,E.invalidateQueries({queryKey:["admin","knox","collections"]}),E.invalidateQueries({queryKey:["admin","knox","documents"]})}catch(v){F.error(v?.response?.data?.message||"Failed to delete collection")}finally{f.value=!1}}}return(v,r)=>{const J=je("router-link");return o(),n("div",Yt,[m(Me),e("div",Jt,[m(ce,{"enter-active-class":"transition-opacity duration-150","leave-active-class":"transition-opacity duration-150","enter-from-class":"opacity-0","leave-to-class":"opacity-0"},{default:M(()=>[w.value?(o(),n("div",{key:0,class:"absolute inset-0 z-30 bg-black/40 lg:hidden",onClick:r[0]||(r[0]=i=>w.value=!1),"aria-hidden":"true"})):k("",!0)]),_:1}),e("aside",{class:Q(["absolute inset-y-0 left-0 z-40 flex w-64 max-w-[85vw] shrink-0 transform flex-col border-r border-gray-200 bg-white shadow-xl transition-transform duration-200 ease-out lg:static lg:z-auto lg:max-w-none lg:shadow-none dark:border-gray-700 dark:bg-gray-800",w.value?"translate-x-0":"-translate-x-full lg:translate-x-0"]),"aria-label":"Collections"},[e("div",Xt,[r[16]||(r[16]=e("h2",{class:"text-sm font-bold text-gray-900 dark:text-white"},"Collections",-1)),e("button",{onClick:r[1]||(r[1]=i=>w.value=!1),class:"rounded-lg p-1.5 text-gray-400 transition-colors hover:bg-gray-100 hover:text-gray-600 lg:hidden dark:hover:bg-gray-700","aria-label":"Close collections"},[m(x(Z),{size:16})])]),e("div",Gt,[e("button",{onClick:r[2]||(r[2]=i=>j.value=!0),class:"flex w-full items-center justify-center gap-1.5 rounded-lg border border-dashed border-gray-300 px-3 py-2 text-xs font-medium text-gray-500 transition-colors hover:border-teal-400 hover:text-teal-600 focus:outline-none focus-visible:border-teal-500 focus-visible:ring-2 focus-visible:ring-teal-500/40 dark:border-gray-600 dark:text-gray-400 dark:hover:border-teal-500 dark:hover:text-teal-400"},[m(x(Ae),{size:14}),r[17]||(r[17]=z(" New Collection ",-1))])]),e("div",Ht,[e("button",{onClick:r[3]||(r[3]=i=>W(null)),class:Q(["flex w-full items-center gap-2 px-4 py-2 text-left text-sm transition-colors",$.value===null?"bg-teal-50 font-medium text-teal-700 dark:bg-teal-900/30 dark:text-teal-300":"text-gray-600 hover:bg-gray-50 dark:text-gray-400 dark:hover:bg-gray-700/60"]),role:"listitem"},[m(x(Qe),{size:15,class:"shrink-0"}),r[18]||(r[18]=e("span",{class:"truncate"},"All Documents",-1)),e("span",Zt,d(ae.value),1)],2),x(I)?(o(),n("div",er,[(o(),n(T,null,P(4,i=>e("div",{key:i,class:"h-4 animate-pulse rounded bg-gray-200 dark:bg-gray-700",style:ve({width:`${50+i*13%40}%`})},null,4)),64))])):(o(),n(T,{key:1},[(o(!0),n(T,null,P(x(C),i=>(o(),n("button",{key:i.id,onClick:oe=>W(i.id),class:Q(["flex w-full items-center gap-2 px-4 py-2 text-left text-sm transition-colors",$.value===i.id?"bg-teal-50 font-medium text-teal-700 dark:bg-teal-900/30 dark:text-teal-300":"text-gray-600 hover:bg-gray-50 dark:text-gray-400 dark:hover:bg-gray-700/60"]),role:"listitem"},[m(x(Ce),{size:15,class:"shrink-0"}),e("span",rr,d(i.name),1),e("span",ar,d(i.document_count),1)],10,tr))),128)),x(C)?.length?k("",!0):(o(),n("p",sr," No collections yet. "))],64))])],2),e("div",or,[e("div",lr,[e("div",nr,[e("button",{onClick:r[4]||(r[4]=i=>w.value=!0),class:"-ml-1 rounded-lg p-1.5 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 lg:hidden dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-200","aria-label":"Open collections"},[m(x(Ee),{size:18})]),e("div",ir,[e("h1",dr,d(R.value?.name||"All Documents"),1),e("p",cr,d(R.value?.description||"Knowledge documents for the Nox AI assistant."),1)]),R.value?(o(),n("button",{key:0,onClick:r[5]||
1(r[5]=i=>y.value=!0),class:"rounded-lg p-2 text-gray-400 transition-colors hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-900/30 dark:hover:text-red-400","aria-label":"Delete collection"},[m(x(Ve),{size:16})])):k("",!0)]),e("div",ur,[e("div",gr,[m(x(xe),{size:14,class:"pointer-events-none absolute top-1/2 left-2.5 -translate-y-1/2 text-gray-400"}),ne(e("input",{"onUpdate:modelValue":r[6]||(r[6]=i=>D.value=i),type:"search",placeholder:"Search titles, content, tags…",class:"w-full rounded-lg border border-gray-300 bg-white py-2 pr-8 pl-8 text-sm text-gray-900 placeholder:text-gray-400 focus:border-teal-400 focus:ring-2 focus:ring-teal-500/30 focus:outline-none dark:border-gray-600 dark:bg-gray-700 dark:text-white"},null,512),[[ie,D.value]]),D.value?(o(),n("button",{key:0,onClick:r[7]||(r[7]=i=>D.value=""),class:"absolute top-1/2 right-2 -translate-y-1/2 rounded p-1 text-gray-400 transition-colors hover:bg-gray-100 hover:text-gray-600 dark:hover:bg-gray-600","aria-label":"Clear search"},[m(x(Z),{size:12})])):k("",!0)]),e("button",{onClick:r[8]||(r[8]=i=>B.value=!0),class:"flex items-center justify-center gap-1.5 rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-teal-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:focus-visible:ring-offset-gray-800"},[m(x(Oe),{size:16}),r[19]||(r[19]=e("span",null,"Bulk Import",-1))]),m(J,{to:O.value,class:"flex items-center justify-center gap-1.5 rounded-lg bg-teal-600 px-4 py-2 text-sm font-medium text-white shadow-sm transition-colors hover:bg-teal-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-teal-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-gray-800"},{default:M(()=>[m(x(We),{size:16}),r[20]||(r[20]=e("span",null,"New Document",-1))]),_:1},8,["to"])])]),e("div",pr,[x(re)?(o(),n("div",yr,[(o(),n(T,null,P(5,i=>e("div",{key:i,class:"rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-700 dark:bg-gray-800"},[...r[21]||(r[21]=[e("div",{class:"h-4 w-1/3 animate-pulse rounded bg-gray-200 dark:bg-gray-700"},null,-1),e("div",{class:"mt-2 h-3 w-2/3 animate-pulse rounded bg-gray-100 dark:bg-gray-700/60"},null,-1)])])),64))])):!x(V)?.length&&S.value?(o(),n("div",mr,[m(x(xe),{size:36,class:"mb-3 text-gray-300 dark:text-gray-600"}),e("h3",xr,' No matches for "'+d(S.value)+'" ',1),r[22]||(r[22]=e("p",{class:"max-w-sm text-sm text-gray-500 dark:text-gray-400"}," Searched titles, body content, tags, and product area. ",-1))])):x(V)?.length?(o(),n("div",br,[(o(!0),n(T,null,P(x(V),i=>(o(),de(J,{key:i.id,to:`/admin/knox/doc/${i.id}`,class:"group flex items-center gap-3 rounded-lg border border-gray-200 bg-white p-3 transition-all hover:border-teal-300 hover:shadow-sm sm:p-4 dark:border-gray-700 dark:bg-gray-800 dark:hover:border-teal-700"},{default:M(()=>[e("div",vr,[e("div",kr,[e("h3",hr,d(i.title),1),e("span",{class:Q(["shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium tracking-wide uppercase",i.status==="published"?"bg-green-50 text-green-700 dark:bg-green-900/30 dark:text-green-400":i.status==="processing"?"bg-amber-50 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400":i.status==="failed"?"bg-red-50 text-red-700 dark:bg-red-900/30 dark:text-red-400":"bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400"])},d(i.status),3)]),e("div",wr,[i.product_area?(o(),n("span",_r,d(i.product_area),1)):k("",!0),i.content_type?(o(),n("span",$r,d(i.content_type),1)):k("",!0),e("span",Cr,d(i.chunk_count)+" chunks",1),e("span",Dr,"v"+d(i.version),1),e("span",null,d(Y(i.updated_at)),1)])]),m(x(Je),{size:16,class:"shrink-0 text-gray-400 transition-transform group-hover:translate-x-0.5"})]),_:2},1032,["to"]))),128))])):(o(),n("div",fr,[m(x(Ye),{size:48,class:"mb-4 text-gray-300 dark:text-gray-600"}),r[24]||(r[24]=e("h3",{class:"mb-1 text-base font-semibold text-gray-700 dark:text-gray-300"}," No documents yet ",-1)),r[25]||(r[25]=e("p",{class:"mb-4 max-w-sm text-sm text-gray-500 dark:text-gray-400"}," Write knowledge in markdown. Nox will auto-chunk, enrich with context, and embed it for retrieval. ",-1)),m(J,{to:O.value,class:"rounded-lg bg-teal-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-teal-700"},{default:M(()=>[...r[23]||(r[23]=[z(" Write First Document ",-1)])]),_:1},8,["to"])]))])])]),m(Wt,{open:B.value,onClose:r[9]||(r[9]=i=>B.value=!1)},null,8,["open"]),m(Be,{modelValue:y.value,"onUpdate:modelValue":r[10]||(r[10]=i=>y.value=i),title:"Delete Collection",message:`Delete “${R.value?.name}” and its ${R.value?.document_count||0} document(s)? Their knowledge chunks are removed and Nox stops answering from them immediately.`,"confirm-text":"Delete",loading:f.value,onConfirm:se},null,8,["modelValue","message","loading"]),(o(),de(ke,{to:"body"},[m(ce,{name:"fade"},{default:M(()=>[j.value?(o(),n("div",{key:0,class:"fixed inset-0 z-50 flex items-end justify-center bg-black/40 p-0 sm:items-center sm:p-4",onClick:r[15]||(r[15]=q(i=>j.value=!1,["self"]))},[e("div",Sr,[e("div",zr,[r[26]||(r[26]=e("h3",{id:"new-collection-title",class:"text-base font-semibold text-gray-900 dark:text-white"}
1," New Collection ",-1)),e("button",{onClick:r[11]||(r[11]=i=>j.value=!1),class:"rounded-lg p-1.5 text-gray-400 transition-colors hover:bg-gray-100 hover:text-gray-600 dark:hover:bg-gray-700","aria-label":"Close"},[m(x(Z),{size:16})])]),e("div",Tr,[e("label",Fr,[r[27]||(r[27]=e("span",{class:"mb-1 block text-[11px] font-medium tracking-wide text-gray-600 uppercase dark:text-gray-400"}," Name ",-1)),ne(e("input",{"onUpdate:modelValue":r[12]||(r[12]=i=>b.name=i),placeholder:"e.g. Integrations",class:"w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 outline-none focus:border-teal-400 focus:ring-2 focus:ring-teal-500/30 dark:border-gray-600 dark:bg-gray-700 dark:text-white"},null,512),[[ie,b.name]])]),e("label",Kr,[r[28]||(r[28]=e("span",{class:"mb-1 flex items-center gap-1.5 text-[11px] font-medium tracking-wide text-gray-600 uppercase dark:text-gray-400"},[z(" Slug "),e("span",{class:"text-[10px] font-normal tracking-normal text-gray-400 normal-case"}," URL-safe id, auto-generated ")],-1)),e("input",{value:c.value,readonly:"",class:"w-full cursor-not-allowed rounded-lg border border-gray-200 bg-gray-50 px-3 py-2 font-mono text-sm text-gray-500 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-400"},null,8,Nr)]),e("label",jr,[r[29]||(r[29]=e("span",{class:"mb-1 block text-[11px] font-medium tracking-wide text-gray-600 uppercase dark:text-gray-400"},[z(" Description "),e("span",{class:"font-normal tracking-normal text-gray-400 normal-case"},"(optional)")],-1)),ne(e("input",{"onUpdate:modelValue":r[13]||(r[13]=i=>b.description=i),placeholder:"Short description shown on the collection page",class:"w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 outline-none focus:border-teal-400 focus:ring-2 focus:ring-teal-500/30 dark:border-gray-600 dark:bg-gray-700 dark:text-white"},null,512),[[ie,b.description]])])]),e("div",Br,[e("button",{onClick:r[14]||(r[14]=i=>j.value=!1),class:"rounded-lg border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700"}," Cancel "),e("button",{onClick:G,disabled:!b.name||!c.value,class:"rounded-lg bg-teal-600 px-4 py-2 text-sm font-medium text-white shadow-sm transition-colors hover:bg-teal-700 disabled:cursor-not-allowed disabled:opacity-50"}," Create ",8,Pr)])])])):k("",!0)]),_:1})]))])}}};export{Wr 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.