@cartanova/qgrid-cli 2.6.2 → 2.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +2 -0
- package/README.md +2 -0
- package/bundle/dist/application/qgrid/expired-token-digest.js +78 -0
- package/bundle/dist/application/qgrid/qgrid.dispatcher.js +40 -6
- package/bundle/dist/application/qgrid/qgrid.frame.js +22 -7
- package/bundle/dist/application/qgrid/qgrid.types.js +13 -3
- package/bundle/dist/application/qgrid/token-death.js +29 -4
- package/bundle/dist/application/queries.generated.js +2 -1
- package/bundle/dist/application/request-log/request-log.model.js +37 -5
- package/bundle/dist/application/request-log-step/request-log-step.model.js +1 -1
- package/bundle/dist/application/sonamu.generated.js +41 -3
- package/bundle/dist/application/token/token.model.js +44 -14
- package/bundle/dist/i18n/en.js +3 -1
- package/bundle/dist/i18n/ko.js +3 -1
- package/bundle/dist/i18n/sd.generated.js +18 -1
- package/bundle/dist/migrations/20260807164057_alter_request_logs_alter1.js +13 -0
- package/bundle/dist/server-error-handler.js +5 -3
- package/bundle/dist/sonamu.config.js +8 -1
- package/bundle/dist/utils/slack-notify.js +2 -2
- package/bundle/src/application/qgrid/expired-token-digest.test.ts +49 -0
- package/bundle/src/application/qgrid/expired-token-digest.ts +93 -0
- package/bundle/src/application/qgrid/qgrid-oauth-redirect.test.ts +0 -3
- package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +30 -2
- package/bundle/src/application/qgrid/qgrid.dispatcher.ts +44 -6
- package/bundle/src/application/qgrid/qgrid.frame.ts +13 -4
- package/bundle/src/application/qgrid/qgrid.types.ts +10 -0
- package/bundle/src/application/qgrid/token-death.test.ts +33 -3
- package/bundle/src/application/qgrid/token-death.ts +32 -3
- package/bundle/src/application/queries.generated.ts +3 -0
- package/bundle/src/application/request-log/request-log.entity.json +26 -1
- package/bundle/src/application/request-log/request-log.model.ts +50 -10
- package/bundle/src/application/sonamu.generated.http +6 -0
- package/bundle/src/application/sonamu.generated.ts +42 -2
- package/bundle/src/application/token/token.model.test.ts +13 -3
- package/bundle/src/application/token/token.model.ts +34 -17
- package/bundle/src/i18n/en.ts +3 -0
- package/bundle/src/i18n/ko.ts +3 -0
- package/bundle/src/i18n/sd.generated.ts +17 -0
- package/bundle/src/migrations/20260807164057_alter_request_logs_alter1.ts +13 -0
- package/bundle/src/server-error-handler.test.ts +58 -0
- package/bundle/src/server-error-handler.ts +16 -5
- package/bundle/src/sonamu.config.ts +13 -0
- package/bundle/src/utils/slack-notify.test.ts +6 -4
- package/bundle/src/utils/slack-notify.ts +10 -3
- package/bundle/web-dist/client/assets/index-BGQSGMcK.css +1 -0
- package/bundle/web-dist/client/assets/index-DTy-s79t.js +78 -0
- package/bundle/web-dist/client/assets/logs-DYqUSqg-.js +1 -0
- package/bundle/web-dist/client/assets/{monit-BSa5lSZp.js → monit-GnFS0_Xa.js} +1 -1
- package/bundle/web-dist/client/assets/routes-CBwpn4d-.js +5 -0
- package/bundle/web-dist/client/assets/{sd.generated-CjW3rfJ8.js → sd.generated-DYdwSB2I.js} +1 -1
- package/bundle/web-dist/client/assets/{services.generated-B-dMUtEu.js → services.generated-BsAvotjG.js} +1 -1
- package/bundle/web-dist/client/assets/{show-C1jEPhuS.js → show-DDgukGuY.js} +3 -3
- package/bundle/web-dist/client/assets/{tokens-1e66MAC0.js → tokens-Co1wPrXX.js} +1 -1
- package/bundle/web-dist/client/assets/{use-update-token-mutation-DueEppqt.js → use-update-token-mutation-DqEpK7It.js} +1 -1
- package/bundle/web-dist/client/index.html +3 -3
- package/bundle/web-dist/server/assets/{lazyRouteComponent-PRxXWW3t.js → lazyRouteComponent-BaZaveNc.js} +1 -1
- package/bundle/web-dist/server/assets/{logs-CwoOsveV.js → logs-DMOw3SjD.js} +82 -40
- package/bundle/web-dist/server/assets/{monit-DIsEsDJN.js → monit-UmcqHroX.js} +2 -2
- package/bundle/web-dist/server/assets/{routes-Bts-KJ9W.js → routes-Sv_4FjtH.js} +47 -45
- package/bundle/web-dist/server/assets/{sd.generated-ek-tz-7H.js → sd.generated-B0xqnHEo.js} +21 -0
- package/bundle/web-dist/server/assets/{services.generated-Bh7Vs8Ds.js → services.generated-DqAKskAS.js} +16 -1
- package/bundle/web-dist/server/assets/{show-DJfaCNUw.js → show-C-oSdzHX.js} +31 -25
- package/bundle/web-dist/server/assets/{tokens-BA4vwDat.js → tokens-h-2A3wfD.js} +112 -109
- package/bundle/web-dist/server/assets/{use-update-token-mutation-BQRzEPy2.js → use-update-token-mutation-DHCaa7Ku.js} +1 -1
- package/bundle/web-dist/server/entry-server.generated.js +70 -29
- package/package.json +1 -1
- package/skills/qgrid/references/cli-env-and-server-boot.md +8 -0
- package/skills/qgrid/references/token-auth-quota-lifecycle.md +3 -2
- package/bundle/web-dist/client/assets/index-2cAgaLOm.css +0 -1
- package/bundle/web-dist/client/assets/index-BgWzzjvj.js +0 -78
- package/bundle/web-dist/client/assets/logs-Lyv8OfHE.js +0 -1
- package/bundle/web-dist/client/assets/routes-Cp0re-Nn.js +0 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{y as t}from"./vendor-tanstack-DJRQAbrY.js";import{i as n,r}from"./vendor-react-DH4kUfK2.js";import{i,o as a}from"./index-BgWzzjvj.js";import{a as o,n as s}from"./services.generated-B-dMUtEu.js";import{t as c}from"./use-update-token-mutation-DueEppqt.js";var l=e(n()),u=r(),d=e=>(0,u.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`1.2em`,height:`1.2em`,...e,children:(0,u.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:2,d:`M5 12h14m-7-7v14`})});function f({isPending:e,isError:t,onSubmit:n,onRestart:r}){let[a,o]=(0,l.useState)(``);return(0,u.jsxs)(`div`,{className:`space-y-2`,children:[(0,u.jsx)(`p`,{className:`text-[12px] text-sand-600 leading-relaxed`,children:`새 탭에서 Claude 로그인을 완료하면 코드가 표시됩니다. 코드 전체를 아래에 붙여넣으세요.`}),(0,u.jsx)(i,{value:a,onChange:e=>o(e.target.value),placeholder:`code#state`,className:`w-full border border-sand-200 rounded-md px-3 py-2 text-sm font-mono text-sand-900 bg-white placeholder:text-sand-300 focus:outline-none focus:border-sienna-300`}),t&&(0,u.jsx)(`p`,{className:`text-[11px] text-red-500`,children:`코드 확인에 실패했습니다 — 표시된 코드 전체를 다시 붙여넣거나 로그인을 다시 시작하세요.`}),(0,u.jsx)(`button`,{type:`button`,className:`w-full py-2.5 text-sm font-medium rounded-md bg-sand-900 text-white hover:bg-sand-800 disabled:opacity-50 transition-colors duration-150 flex items-center justify-center gap-2`,disabled:!a.trim()||e,onClick:()=>n(a),children:e?(0,u.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,u.jsx)(`span`,{className:`w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full animate-spin`}),`Verifying...`]}):`Complete login`}),(0,u.jsx)(`button`,{type:`button`,className:`w-full py-1.5 text-[12px] text-sand-500 hover:text-sand-700 transition-colors duration-150`,onClick:()=>{o(``),r()},children:`처음부터 다시 시작`})]})}var p=3e3,m=3e5;function h(e){let t=0;for(let n of e.getQueryCache().findAll({queryKey:[`Token`]})){let e=n.state.data?.rows;Array.isArray(e)&&(t=Math.max(t,e.length))}return t}function g(){let[e,n]=(0,l.useState)(null),[r,i]=(0,l.useState)(!1),a=t(),o=s.useOauthStartMutation(),c=s.useOauthStartOpenAIMutation(),u=s.useOauthCompleteMutation(),d=(0,l.useRef)({}),f=()=>{d.current.interval!==void 0&&clearInterval(d.current.interval),d.current.timeout!==void 0&&clearTimeout(d.current.timeout),d.current={}};(0,l.useEffect)(()=>f,[]);let g=()=>Promise.all([a.invalidateQueries({queryKey:[`Token`]}),a.invalidateQueries({queryKey:[`Qgrid`]})]);return{loadingProvider:e,codeEntry:r,start:async(e,t)=>{let r=t.trim();if(!r)return;let s=window.open(`about:blank`,`_blank`);n(e);try{if(e===`openai`){let{authUrl:e}=await c.mutateAsync({name:r});s?s.location.href=e:window.open(e,`_blank`);let t=h(a);f(),d.current.interval=window.setInterval(()=>{g().then(()=>{h(a)>t&&(f(),n(null))})},p),d.current.timeout=window.setTimeout(()=>{f(),n(null)},m);return}let{authUrl:t,mode:l}=await o.mutateAsync({name:r});l===`code`?(s?s.location.href=t:window.open(t,`_blank`),i(!0),n(null)):(s?.close(),window.location.href=t)}catch(e){s?.close(),console.error(`OAuth start failed:`,e),n(null)}},submitCode:async e=>{let t=e.trim();if(!t)return!1;try{await u.mutateAsync({pastedCode:t})}catch(e){return console.error(`OAuth complete failed:`,e),!1}return await g(),!0},reset:()=>{f(),n(null),i(!1),u.reset()},completeMutation:u}}function _(){let[e,t]=(0,l.useState)(!1),[n,r]=(0,l.useState)(``),o=g(),s=()=>{t(!1),r(``),o.reset()},c=async e=>{await o.submitCode(e)&&s()};return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsxs)(`button`,{type:`button`,className:`px-3.5 py-1.5 text-[12px] font-medium rounded-lg bg-sienna-500 text-white hover:bg-sienna-600 disabled:opacity-50 transition-all duration-150 active:scale-[0.97] flex items-center gap-1.5 shadow-sm`,onClick:()=>t(!0),children:[(0,u.jsx)(d,{className:`size-3.5`}),`Add Token`]}),e&&(0,u.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-start justify-center pt-[15vh]`,children:[(0,u.jsx)(`div`,{className:`absolute inset-0 bg-sand-900/8 backdrop-blur-sm`,onClick:s,onKeyDown:()=>{}}),(0,u.jsxs)(`div`,{className:`relative panel shadow-xl w-full max-w-md mx-4`,children:[(0,u.jsx)(`div`,{className:`px-5 py-4 border-b border-sand-100/50`,children:(0,u.jsx)(`h2`,{className:`text-base font-medium text-sand-900`,children:`Add Token`})}),(0,u.jsxs)(`div`,{className:`px-5 py-4 space-y-4`,children:[(0,u.jsxs)(`div`,{children:[(0,u.jsx)(`label`,{htmlFor:`token-name`,className:`text-[10px] uppercase tracking-wider text-sand-500 font-medium`,children:`Name *`}),(0,u.jsx)(i,{value:n,onChange:e=>r(e.target.value),placeholder:`e.g. your-token-name`,className:`mt-1 w-full border border-sand-200 rounded-md px-3 py-2 text-sm text-sand-900 bg-white placeholder:text-sand-300 focus:outline-none focus:border-sienna-300`})]}),o.codeEntry?(0,u.jsx)(f,{isPending:o.completeMutation.isPending,isError:o.completeMutation.isError,onSubmit:e=>void c(e),onRestart:o.reset}):(0,u.jsxs)(`div`,{className:`space-y-2`,children:[(0,u.jsx)(`button`,{type:`button`,className:`w-full py-2.5 text-sm font-medium rounded-md bg-sand-900 text-white hover:bg-sand-800 disabled:opacity-50 transition-colors duration-150 flex items-center justify-center gap-2`,disabled:!n.trim()||o.loadingProvider!==null,onClick:()=>void o.start(`openai`,n),children:o.loadingProvider===`openai`?(0,u.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,u.jsx)(`span`,{className:`w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full animate-spin`}),`Waiting for login...`]}):(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(a,{className:`size-4`}),`Login with OpenAI`]})}),(0,u.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,u.jsx)(`div`,{className:`flex-1 h-px bg-sand-200`}),(0,u.jsx)(`span`,{className:`text-[10px] text-sand-400 uppercase`,children:`or`}),(0,u.jsx)(`div`,{className:`flex-1 h-px bg-sand-200`})]}),(0,u.jsx)(`button`,{type:`button`,className:`w-full py-2.5 text-sm font-medium rounded-md border border-sand-300 text-sand-700 hover:bg-sand-100 disabled:opacity-50 transition-colors duration-150 flex items-center justify-center gap-2`,disabled:!n.trim()||o.loadingProvider!==null,onClick:()=>void o.start(`anthropic`,n),children:o.loadingProvider===`anthropic`?(0,u.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,u.jsx)(`span`,{className:`w-3.5 h-3.5 border-2 border-sand-400 border-t-transparent rounded-full animate-spin`}),`Waiting for login...`]}):(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(a,{className:`size-4`}),`Login with Claude`]})})]})]}),(0,u.jsx)(`div`,{className:`px-5 py-3 border-t border-sand-100/50 flex items-center justify-end gap-2`,children:(0,u.jsx)(`button`,{type:`button`,className:`px-3 py-1 text-xs font-medium rounded-md border border-sand-200 text-sand-600 hover:bg-sand-100 transition-colors duration-150`,onClick:s,children:`Cancel`})})]})]})]})}var v=e=>(0,u.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`1.2em`,height:`1.2em`,...e,children:(0,u.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:2,d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497zM15 5l4 4`})}),y=e=>(0,u.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`1.2em`,height:`1.2em`,...e,children:(0,u.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:2,d:`M10 11v6m4-6v6m5-11v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`})});function b(e){let t=e.credentials;return`expiresAt`in t&&typeof t.expiresAt==`number`?t.expiresAt:`accessTokenExpiresAt`in t&&typeof t.accessTokenExpiresAt==`number`?t.accessTokenExpiresAt:null}function x(e){if(!e)return{text:``,color:``};let t=e-Date.now();if(t<=0)return{text:`expired`,color:`text-red-500`};let n=Math.floor(t/36e5),r=Math.floor(t%36e5/6e4),i=n>0?`${n}h ${r}m`:`${r}m`;return t<36e5?{text:i,color:`text-amber-500`}:{text:i,color:`text-sand-400`}}function S(e){let t=e.credentials.accessToken;return t.length<=12?t:`${t.slice(0,8)}...${t.slice(-4)}`}function C({data:e,isLoading:n}){let[r,a]=(0,l.useState)(null),[o,d]=(0,l.useState)(null),[p,m]=(0,l.useState)(``),h=t(),_=s.useRemoveTokenMutation(),C=c(),w=s.useToggleTokenMutation(),T=g(),E=()=>Promise.all([h.invalidateQueries({queryKey:[`Token`]}),h.invalidateQueries({queryKey:[`Qgrid`]})]),D=async e=>{await w.mutateAsync({id:e.id}),await E()},O=async()=>{r&&(await _.mutateAsync({id:r.id}),await E(),a(null))},k=async e=>{await T.submitCode(e)&&T.reset()},A=e=>{d(e),m(e.name??``)},j=async()=>{o&&(await C.mutateAsync({id:o.id,name:p.trim()}),await E(),d(null))};if(n)return(0,u.jsx)(`div`,{className:`space-y-2`,children:Array.from({length:3}).map((e,t)=>(0,u.jsx)(`div`,{className:`h-12 bg-sand-100 rounded-md animate-pulse`},`skeleton-${t}`))});let M=e??[];return M.length===0?(0,u.jsxs)(`div`,{className:`text-sand-400 text-center py-16 text-sm`,children:[`No tokens registered. Click `,(0,u.jsx)(`strong`,{className:`text-sand-600`,children:`Add Token`}),` to get started.`]}):(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(`div`,{className:`panel overflow-hidden`,children:(0,u.jsxs)(`table`,{className:`w-full text-[13px]`,children:[(0,u.jsx)(`thead`,{children:(0,u.jsxs)(`tr`,{className:`panel-header`,children:[(0,u.jsx)(`th`,{className:`text-left px-5 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium`,children:`Provider`}),(0,u.jsx)(`th`,{className:`text-left px-5 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium`,children:`Name`}),(0,u.jsx)(`th`,{className:`text-left px-5 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium`,children:`Token`}),(0,u.jsx)(`th`,{className:`text-left px-5 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium`,children:`Status`}),(0,u.jsx)(`th`,{className:`text-left px-5 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium`,children:`Expires`}),(0,u.jsx)(`th`,{className:`w-20 px-3 py-2.5`})]})}),(0,u.jsx)(`tbody`,{className:`divide-y divide-sand-100/80`,children:M.map(e=>{let t=x(b(e));return(0,u.jsxs)(`tr`,{className:`transition-colors duration-150 hover:bg-sand-100/60 ${e.active?``:`opacity-50`}`,children:[(0,u.jsx)(`td`,{className:`px-5 py-3`,children:(0,u.jsx)(`span`,{className:`text-xs font-medium text-sand-500 uppercase`,children:e.provider})}),(0,u.jsx)(`td`,{className:`px-5 py-3`,children:e.name?(0,u.jsx)(`span`,{className:`text-sm text-sand-700`,children:e.name}):(0,u.jsx)(`span`,{className:`text-[11px] text-sand-400`,children:`—`})}),(0,u.jsx)(`td`,{className:`px-5 py-3`,children:(0,u.jsx)(`code`,{className:`text-[13px] font-mono text-sand-800`,children:S(e)})}),(0,u.jsx)(`td`,{className:`px-5 py-3`,children:(0,u.jsx)(`button`,{type:`button`,className:`relative inline-flex h-5 w-9 items-center rounded-full transition-colors duration-200 ${e.active?`bg-sage-400`:`bg-sand-300`}`,onClick:()=>D(e),disabled:w.isPending,children:(0,u.jsx)(`span`,{className:`inline-block h-3.5 w-3.5 rounded-full bg-white transition-transform duration-200 ${e.active?`translate-x-4.5`:`translate-x-0.5`}`})})}),(0,u.jsx)(`td`,{className:`px-5 py-3`,children:t.text&&(0,u.jsx)(`span`,{className:`text-xs ${t.color}`,children:t.text})}),(0,u.jsx)(`td`,{className:`px-3 py-3`,children:(0,u.jsxs)(`div`,{className:`flex items-center gap-1`,children:[!e.active&&(0,u.jsx)(`button`,{type:`button`,title:`기존 이름으로 다시 로그인`,className:`px-2 py-0.5 mr-1 text-[11px] font-medium rounded-md border border-sand-300 text-sand-600 hover:bg-sand-100 disabled:opacity-50 transition-colors duration-150 inline-flex items-center gap-1`,disabled:T.loadingProvider!==null,onClick:()=>void T.start(e.provider,e.name??``),children:T.loadingProvider===e.provider?(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(`span`,{className:`w-3 h-3 border-2 border-sand-400 border-t-transparent rounded-full animate-spin`}),`로그인 대기`]}):`재로그인`}),(0,u.jsx)(`button`,{type:`button`,className:`p-1 rounded text-sand-400 hover:text-sienna-500 transition-colors duration-150`,onClick:()=>A(e),children:(0,u.jsx)(v,{className:`size-4`})}),(0,u.jsx)(`button`,{type:`button`,className:`p-1 rounded text-sand-400 hover:text-red-500 transition-colors duration-150`,onClick:()=>a(e),children:(0,u.jsx)(y,{className:`size-4`})})]})})]},e.id)})})]})}),T.codeEntry&&(0,u.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-start justify-center pt-[15vh]`,children:[(0,u.jsx)(`div`,{className:`absolute inset-0 bg-sand-900/8 backdrop-blur-sm`,onClick:T.reset,onKeyDown:()=>{}}),(0,u.jsxs)(`div`,{className:`relative panel shadow-xl w-full max-w-md mx-4`,children:[(0,u.jsx)(`div`,{className:`px-5 py-4 border-b border-sand-100/60`,children:(0,u.jsx)(`h3`,{className:`text-base font-medium text-sand-900`,children:`재로그인`})}),(0,u.jsx)(`div`,{className:`px-5 py-4`,children:(0,u.jsx)(f,{isPending:T.completeMutation.isPending,isError:T.completeMutation.isError,onSubmit:e=>void k(e),onRestart:T.reset})})]})]}),o&&(0,u.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-start justify-center pt-[15vh]`,children:[(0,u.jsx)(`div`,{className:`absolute inset-0 bg-sand-900/8 backdrop-blur-sm`,onClick:()=>d(null),onKeyDown:()=>{}}),(0,u.jsxs)(`div`,{className:`relative panel shadow-xl w-full max-w-sm mx-4`,children:[(0,u.jsx)(`div`,{className:`px-5 py-4 border-b border-sand-100/60`,children:(0,u.jsx)(`h3`,{className:`text-base font-medium text-sand-900`,children:`Edit Token`})}),(0,u.jsx)(`div`,{className:`px-5 py-4 space-y-3`,children:(0,u.jsxs)(`div`,{children:[(0,u.jsx)(`label`,{htmlFor:`token-name`,className:`text-[10px] uppercase tracking-wider text-sand-500 font-medium`,children:`Name`}),(0,u.jsx)(i,{value:p,onChange:e=>m(e.target.value),placeholder:`e.g. prod, dev, team-a`,className:`mt-1 w-full border border-sand-200 rounded-md px-3 py-2 text-sm text-sand-900 bg-white placeholder:text-sand-300 focus:outline-none focus:border-sienna-300`})]})}),(0,u.jsxs)(`div`,{className:`px-5 py-3 border-t border-sand-100/60 flex items-center justify-end gap-2`,children:[(0,u.jsx)(`button`,{type:`button`,className:`px-3 py-1 text-xs font-medium rounded-md border border-sand-200 text-sand-600 hover:bg-sand-100 transition-colors duration-150`,onClick:()=>d(null),children:`Cancel`}),(0,u.jsx)(`button`,{type:`button`,className:`px-3 py-1 text-xs font-medium rounded-md bg-sienna-400 text-white hover:bg-sienna-500 disabled:opacity-50 transition-colors duration-150`,disabled:C.isPending,onClick:j,children:C.isPending?`Saving...`:`Save`})]})]})]}),r&&(0,u.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-start justify-center pt-[15vh]`,children:[(0,u.jsx)(`div`,{className:`absolute inset-0 bg-sand-900/8 backdrop-blur-sm`,onClick:()=>a(null),onKeyDown:()=>{}}),(0,u.jsxs)(`div`,{className:`relative panel shadow-xl w-full max-w-sm mx-4`,children:[(0,u.jsxs)(`div`,{className:`px-5 py-4`,children:[(0,u.jsx)(`h3`,{className:`text-base font-medium text-sand-900`,children:`Remove Token`}),(0,u.jsxs)(`p`,{className:`text-sm text-sand-700 mt-2`,children:[`Are you sure you want to remove`,` `,(0,u.jsx)(`code`,{className:`text-[13px] font-mono text-sand-800`,children:S(r)}),r.name&&(0,u.jsxs)(`span`,{className:`text-sand-500`,children:[` (`,r.name,`)`]}),`?`]})]}),(0,u.jsxs)(`div`,{className:`px-5 py-3 border-t border-sand-100/60 flex items-center justify-end gap-2`,children:[(0,u.jsx)(`button`,{type:`button`,className:`px-3 py-1 text-xs font-medium rounded-md border border-sand-200 text-sand-600 hover:bg-sand-100 transition-colors duration-150`,onClick:()=>a(null),children:`Cancel`}),(0,u.jsx)(`button`,{type:`button`,className:`px-3 py-1 text-xs font-medium rounded-md bg-red-500 text-white hover:bg-red-600 disabled:opacity-50 transition-colors duration-150`,disabled:_.isPending,onClick:O,children:_.isPending?`Removing...`:`Remove`})]})]})]})]})}function w(){let{data:e,isLoading:t}=o.useTokens(`A`);return(0,u.jsxs)(`div`,{className:`max-w-6xl mx-auto space-y-4`,children:[(0,u.jsx)(`div`,{className:`flex items-center justify-end`,children:(0,u.jsx)(_,{})}),(0,u.jsx)(C,{data:e?.rows,isLoading:t})]})}export{w as component};
|
|
1
|
+
import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{y as t}from"./vendor-tanstack-DJRQAbrY.js";import{i as n,r}from"./vendor-react-DH4kUfK2.js";import{i,o as a}from"./index-DTy-s79t.js";import{a as o,n as s}from"./services.generated-BsAvotjG.js";import{t as c}from"./use-update-token-mutation-DqEpK7It.js";var l=e(n()),u=r(),d=e=>(0,u.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`1.2em`,height:`1.2em`,...e,children:(0,u.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:2,d:`M5 12h14m-7-7v14`})});function f({isPending:e,isError:t,onSubmit:n,onRestart:r}){let[a,o]=(0,l.useState)(``);return(0,u.jsxs)(`div`,{className:`space-y-2`,children:[(0,u.jsx)(`p`,{className:`text-[12px] text-sand-600 leading-relaxed`,children:`새 탭에서 Claude 로그인을 완료하면 코드가 표시됩니다. 코드 전체를 아래에 붙여넣으세요.`}),(0,u.jsx)(i,{value:a,onChange:e=>o(e.target.value),placeholder:`code#state`,className:`w-full border border-sand-200 rounded-md px-3 py-2 text-sm font-mono text-sand-900 bg-white placeholder:text-sand-300 focus:outline-none focus:border-sienna-300`}),t&&(0,u.jsx)(`p`,{className:`text-[11px] text-red-500`,children:`코드 확인에 실패했습니다 — 표시된 코드 전체를 다시 붙여넣거나 로그인을 다시 시작하세요.`}),(0,u.jsx)(`button`,{type:`button`,className:`w-full py-2.5 text-sm font-medium rounded-md bg-sand-900 text-white hover:bg-sand-800 disabled:opacity-50 transition-colors duration-150 flex items-center justify-center gap-2`,disabled:!a.trim()||e,onClick:()=>n(a),children:e?(0,u.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,u.jsx)(`span`,{className:`w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full animate-spin`}),`Verifying...`]}):`Complete login`}),(0,u.jsx)(`button`,{type:`button`,className:`w-full py-1.5 text-[12px] text-sand-500 hover:text-sand-700 transition-colors duration-150`,onClick:()=>{o(``),r()},children:`처음부터 다시 시작`})]})}var p=3e3,m=3e5;function h(e){let t=0;for(let n of e.getQueryCache().findAll({queryKey:[`Token`]})){let e=n.state.data?.rows;Array.isArray(e)&&(t=Math.max(t,e.length))}return t}function g(){let[e,n]=(0,l.useState)(null),[r,i]=(0,l.useState)(!1),a=t(),o=s.useOauthStartMutation(),c=s.useOauthStartOpenAIMutation(),u=s.useOauthCompleteMutation(),d=(0,l.useRef)({}),f=()=>{d.current.interval!==void 0&&clearInterval(d.current.interval),d.current.timeout!==void 0&&clearTimeout(d.current.timeout),d.current={}};(0,l.useEffect)(()=>f,[]);let g=()=>Promise.all([a.invalidateQueries({queryKey:[`Token`]}),a.invalidateQueries({queryKey:[`Qgrid`]})]);return{loadingProvider:e,codeEntry:r,start:async(e,t)=>{let r=t.trim();if(!r)return;let s=window.open(`about:blank`,`_blank`);n(e);try{if(e===`openai`){let{authUrl:e}=await c.mutateAsync({name:r});s?s.location.href=e:window.open(e,`_blank`);let t=h(a);f(),d.current.interval=window.setInterval(()=>{g().then(()=>{h(a)>t&&(f(),n(null))})},p),d.current.timeout=window.setTimeout(()=>{f(),n(null)},m);return}let{authUrl:t,mode:l}=await o.mutateAsync({name:r});l===`code`?(s?s.location.href=t:window.open(t,`_blank`),i(!0),n(null)):(s?.close(),window.location.href=t)}catch(e){s?.close(),console.error(`OAuth start failed:`,e),n(null)}},submitCode:async e=>{let t=e.trim();if(!t)return!1;try{await u.mutateAsync({pastedCode:t})}catch(e){return console.error(`OAuth complete failed:`,e),!1}return await g(),!0},reset:()=>{f(),n(null),i(!1),u.reset()},completeMutation:u}}function _(){let[e,t]=(0,l.useState)(!1),[n,r]=(0,l.useState)(``),o=g(),s=()=>{t(!1),r(``),o.reset()},c=async e=>{await o.submitCode(e)&&s()};return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsxs)(`button`,{type:`button`,className:`px-3.5 py-1.5 text-[12px] font-medium rounded-lg bg-sienna-500 text-white hover:bg-sienna-600 disabled:opacity-50 transition-all duration-150 active:scale-[0.97] flex items-center gap-1.5 shadow-sm`,onClick:()=>t(!0),children:[(0,u.jsx)(d,{className:`size-3.5`}),`Add Token`]}),e&&(0,u.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-start justify-center pt-[15vh]`,children:[(0,u.jsx)(`div`,{className:`absolute inset-0 bg-sand-900/8 backdrop-blur-sm`,onClick:s,onKeyDown:()=>{}}),(0,u.jsxs)(`div`,{className:`relative panel shadow-xl w-full max-w-md mx-4`,children:[(0,u.jsx)(`div`,{className:`px-5 py-4 border-b border-sand-100/50`,children:(0,u.jsx)(`h2`,{className:`text-base font-medium text-sand-900`,children:`Add Token`})}),(0,u.jsxs)(`div`,{className:`px-5 py-4 space-y-4`,children:[(0,u.jsxs)(`div`,{children:[(0,u.jsx)(`label`,{htmlFor:`token-name`,className:`text-[10px] uppercase tracking-wider text-sand-500 font-medium`,children:`Name *`}),(0,u.jsx)(i,{value:n,onChange:e=>r(e.target.value),placeholder:`e.g. your-token-name`,className:`mt-1 w-full border border-sand-200 rounded-md px-3 py-2 text-sm text-sand-900 bg-white placeholder:text-sand-300 focus:outline-none focus:border-sienna-300`})]}),o.codeEntry?(0,u.jsx)(f,{isPending:o.completeMutation.isPending,isError:o.completeMutation.isError,onSubmit:e=>void c(e),onRestart:o.reset}):(0,u.jsxs)(`div`,{className:`space-y-2`,children:[(0,u.jsx)(`button`,{type:`button`,className:`w-full py-2.5 text-sm font-medium rounded-md bg-sand-900 text-white hover:bg-sand-800 disabled:opacity-50 transition-colors duration-150 flex items-center justify-center gap-2`,disabled:!n.trim()||o.loadingProvider!==null,onClick:()=>void o.start(`openai`,n),children:o.loadingProvider===`openai`?(0,u.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,u.jsx)(`span`,{className:`w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full animate-spin`}),`Waiting for login...`]}):(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(a,{className:`size-4`}),`Login with OpenAI`]})}),(0,u.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,u.jsx)(`div`,{className:`flex-1 h-px bg-sand-200`}),(0,u.jsx)(`span`,{className:`text-[10px] text-sand-400 uppercase`,children:`or`}),(0,u.jsx)(`div`,{className:`flex-1 h-px bg-sand-200`})]}),(0,u.jsx)(`button`,{type:`button`,className:`w-full py-2.5 text-sm font-medium rounded-md border border-sand-300 text-sand-700 hover:bg-sand-100 disabled:opacity-50 transition-colors duration-150 flex items-center justify-center gap-2`,disabled:!n.trim()||o.loadingProvider!==null,onClick:()=>void o.start(`anthropic`,n),children:o.loadingProvider===`anthropic`?(0,u.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,u.jsx)(`span`,{className:`w-3.5 h-3.5 border-2 border-sand-400 border-t-transparent rounded-full animate-spin`}),`Waiting for login...`]}):(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(a,{className:`size-4`}),`Login with Claude`]})})]})]}),(0,u.jsx)(`div`,{className:`px-5 py-3 border-t border-sand-100/50 flex items-center justify-end gap-2`,children:(0,u.jsx)(`button`,{type:`button`,className:`px-3 py-1 text-xs font-medium rounded-md border border-sand-200 text-sand-600 hover:bg-sand-100 transition-colors duration-150`,onClick:s,children:`Cancel`})})]})]})]})}var v=e=>(0,u.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`1.2em`,height:`1.2em`,...e,children:(0,u.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:2,d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497zM15 5l4 4`})}),y=e=>(0,u.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`1.2em`,height:`1.2em`,...e,children:(0,u.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:2,d:`M10 11v6m4-6v6m5-11v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`})});function b(e){let t=e.credentials;return`expiresAt`in t&&typeof t.expiresAt==`number`?t.expiresAt:`accessTokenExpiresAt`in t&&typeof t.accessTokenExpiresAt==`number`?t.accessTokenExpiresAt:null}function x(e){if(!e)return{text:``,color:``};let t=e-Date.now();if(t<=0)return{text:`expired`,color:`text-red-500`};let n=Math.floor(t/36e5),r=Math.floor(t%36e5/6e4),i=n>0?`${n}h ${r}m`:`${r}m`;return t<36e5?{text:i,color:`text-amber-500`}:{text:i,color:`text-sand-400`}}function S(e){let t=e.credentials.accessToken;return t.length<=12?t:`${t.slice(0,8)}...${t.slice(-4)}`}function C({data:e,isLoading:n}){let[r,a]=(0,l.useState)(null),[o,d]=(0,l.useState)(null),[p,m]=(0,l.useState)(``),h=t(),_=s.useRemoveTokenMutation(),C=c(),w=s.useToggleTokenMutation(),T=g(),E=()=>Promise.all([h.invalidateQueries({queryKey:[`Token`]}),h.invalidateQueries({queryKey:[`Qgrid`]})]),D=async e=>{await w.mutateAsync({id:e.id}),await E()},O=async()=>{r&&(await _.mutateAsync({id:r.id}),await E(),a(null))},k=async e=>{await T.submitCode(e)&&T.reset()},A=e=>{d(e),m(e.name??``)},j=async()=>{o&&(await C.mutateAsync({id:o.id,name:p.trim()}),await E(),d(null))};if(n)return(0,u.jsx)(`div`,{className:`space-y-2`,children:Array.from({length:3}).map((e,t)=>(0,u.jsx)(`div`,{className:`h-12 bg-sand-100 rounded-md animate-pulse`},`skeleton-${t}`))});let M=e??[];return M.length===0?(0,u.jsxs)(`div`,{className:`text-sand-400 text-center py-16 text-sm`,children:[`No tokens registered. Click `,(0,u.jsx)(`strong`,{className:`text-sand-600`,children:`Add Token`}),` to get started.`]}):(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(`div`,{className:`panel overflow-hidden`,children:(0,u.jsx)(`div`,{className:`overflow-x-auto`,children:(0,u.jsxs)(`table`,{className:`w-full min-w-[640px] text-[13px]`,children:[(0,u.jsx)(`thead`,{children:(0,u.jsxs)(`tr`,{className:`panel-header`,children:[(0,u.jsx)(`th`,{className:`text-left px-5 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium`,children:`Provider`}),(0,u.jsx)(`th`,{className:`text-left px-5 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium`,children:`Name`}),(0,u.jsx)(`th`,{className:`text-left px-5 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium`,children:`Token`}),(0,u.jsx)(`th`,{className:`text-left px-5 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium`,children:`Status`}),(0,u.jsx)(`th`,{className:`text-left px-5 py-2.5 text-[10px] uppercase tracking-wider text-sand-400 font-medium`,children:`Expires`}),(0,u.jsx)(`th`,{className:`w-20 px-3 py-2.5`})]})}),(0,u.jsx)(`tbody`,{className:`divide-y divide-sand-100/80`,children:M.map(e=>{let t=x(b(e));return(0,u.jsxs)(`tr`,{className:`transition-colors duration-150 hover:bg-sand-100/60 ${e.active?``:`opacity-50`}`,children:[(0,u.jsx)(`td`,{className:`px-5 py-3`,children:(0,u.jsx)(`span`,{className:`text-xs font-medium text-sand-500 uppercase`,children:e.provider})}),(0,u.jsx)(`td`,{className:`px-5 py-3`,children:e.name?(0,u.jsx)(`span`,{className:`text-sm text-sand-700`,children:e.name}):(0,u.jsx)(`span`,{className:`text-[11px] text-sand-400`,children:`—`})}),(0,u.jsx)(`td`,{className:`px-5 py-3`,children:(0,u.jsx)(`code`,{className:`text-[13px] font-mono text-sand-800`,children:S(e)})}),(0,u.jsx)(`td`,{className:`px-5 py-3`,children:(0,u.jsx)(`button`,{type:`button`,className:`relative inline-flex h-5 w-9 items-center rounded-full transition-colors duration-200 ${e.active?`bg-sage-400`:`bg-sand-300`}`,onClick:()=>D(e),disabled:w.isPending,children:(0,u.jsx)(`span`,{className:`inline-block h-3.5 w-3.5 rounded-full bg-white transition-transform duration-200 ${e.active?`translate-x-4.5`:`translate-x-0.5`}`})})}),(0,u.jsx)(`td`,{className:`px-5 py-3`,children:t.text&&(0,u.jsx)(`span`,{className:`text-xs ${t.color}`,children:t.text})}),(0,u.jsx)(`td`,{className:`px-3 py-3`,children:(0,u.jsxs)(`div`,{className:`flex items-center gap-1`,children:[!e.active&&(0,u.jsx)(`button`,{type:`button`,title:`기존 이름으로 다시 로그인`,className:`px-2 py-0.5 mr-1 text-[11px] font-medium rounded-md border border-sand-300 text-sand-600 hover:bg-sand-100 disabled:opacity-50 transition-colors duration-150 inline-flex items-center gap-1`,disabled:T.loadingProvider!==null,onClick:()=>void T.start(e.provider,e.name??``),children:T.loadingProvider===e.provider?(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(`span`,{className:`w-3 h-3 border-2 border-sand-400 border-t-transparent rounded-full animate-spin`}),`로그인 대기`]}):`재로그인`}),(0,u.jsx)(`button`,{type:`button`,className:`p-1 rounded text-sand-400 hover:text-sienna-500 transition-colors duration-150`,onClick:()=>A(e),children:(0,u.jsx)(v,{className:`size-4`})}),(0,u.jsx)(`button`,{type:`button`,className:`p-1 rounded text-sand-400 hover:text-red-500 transition-colors duration-150`,onClick:()=>a(e),children:(0,u.jsx)(y,{className:`size-4`})})]})})]},e.id)})})]})})}),T.codeEntry&&(0,u.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-start justify-center pt-[15vh]`,children:[(0,u.jsx)(`div`,{className:`absolute inset-0 bg-sand-900/8 backdrop-blur-sm`,onClick:T.reset,onKeyDown:()=>{}}),(0,u.jsxs)(`div`,{className:`relative panel shadow-xl w-full max-w-md mx-4`,children:[(0,u.jsx)(`div`,{className:`px-5 py-4 border-b border-sand-100/60`,children:(0,u.jsx)(`h3`,{className:`text-base font-medium text-sand-900`,children:`재로그인`})}),(0,u.jsx)(`div`,{className:`px-5 py-4`,children:(0,u.jsx)(f,{isPending:T.completeMutation.isPending,isError:T.completeMutation.isError,onSubmit:e=>void k(e),onRestart:T.reset})})]})]}),o&&(0,u.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-start justify-center pt-[15vh]`,children:[(0,u.jsx)(`div`,{className:`absolute inset-0 bg-sand-900/8 backdrop-blur-sm`,onClick:()=>d(null),onKeyDown:()=>{}}),(0,u.jsxs)(`div`,{className:`relative panel shadow-xl w-full max-w-sm mx-4`,children:[(0,u.jsx)(`div`,{className:`px-5 py-4 border-b border-sand-100/60`,children:(0,u.jsx)(`h3`,{className:`text-base font-medium text-sand-900`,children:`Edit Token`})}),(0,u.jsx)(`div`,{className:`px-5 py-4 space-y-3`,children:(0,u.jsxs)(`div`,{children:[(0,u.jsx)(`label`,{htmlFor:`token-name`,className:`text-[10px] uppercase tracking-wider text-sand-500 font-medium`,children:`Name`}),(0,u.jsx)(i,{value:p,onChange:e=>m(e.target.value),placeholder:`e.g. prod, dev, team-a`,className:`mt-1 w-full border border-sand-200 rounded-md px-3 py-2 text-sm text-sand-900 bg-white placeholder:text-sand-300 focus:outline-none focus:border-sienna-300`})]})}),(0,u.jsxs)(`div`,{className:`px-5 py-3 border-t border-sand-100/60 flex items-center justify-end gap-2`,children:[(0,u.jsx)(`button`,{type:`button`,className:`px-3 py-1 text-xs font-medium rounded-md border border-sand-200 text-sand-600 hover:bg-sand-100 transition-colors duration-150`,onClick:()=>d(null),children:`Cancel`}),(0,u.jsx)(`button`,{type:`button`,className:`px-3 py-1 text-xs font-medium rounded-md bg-sienna-400 text-white hover:bg-sienna-500 disabled:opacity-50 transition-colors duration-150`,disabled:C.isPending,onClick:j,children:C.isPending?`Saving...`:`Save`})]})]})]}),r&&(0,u.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-start justify-center pt-[15vh]`,children:[(0,u.jsx)(`div`,{className:`absolute inset-0 bg-sand-900/8 backdrop-blur-sm`,onClick:()=>a(null),onKeyDown:()=>{}}),(0,u.jsxs)(`div`,{className:`relative panel shadow-xl w-full max-w-sm mx-4`,children:[(0,u.jsxs)(`div`,{className:`px-5 py-4`,children:[(0,u.jsx)(`h3`,{className:`text-base font-medium text-sand-900`,children:`Remove Token`}),(0,u.jsxs)(`p`,{className:`text-sm text-sand-700 mt-2`,children:[`Are you sure you want to remove`,` `,(0,u.jsx)(`code`,{className:`text-[13px] font-mono text-sand-800`,children:S(r)}),r.name&&(0,u.jsxs)(`span`,{className:`text-sand-500`,children:[` (`,r.name,`)`]}),`?`]})]}),(0,u.jsxs)(`div`,{className:`px-5 py-3 border-t border-sand-100/60 flex items-center justify-end gap-2`,children:[(0,u.jsx)(`button`,{type:`button`,className:`px-3 py-1 text-xs font-medium rounded-md border border-sand-200 text-sand-600 hover:bg-sand-100 transition-colors duration-150`,onClick:()=>a(null),children:`Cancel`}),(0,u.jsx)(`button`,{type:`button`,className:`px-3 py-1 text-xs font-medium rounded-md bg-red-500 text-white hover:bg-red-600 disabled:opacity-50 transition-colors duration-150`,disabled:_.isPending,onClick:O,children:_.isPending?`Removing...`:`Remove`})]})]})]})]})}function w(){let{data:e,isLoading:t}=o.useTokens(`A`);return(0,u.jsxs)(`div`,{className:`max-w-6xl mx-auto space-y-4`,children:[(0,u.jsx)(`div`,{className:`flex items-center justify-end`,children:(0,u.jsx)(_,{})}),(0,u.jsx)(C,{data:e?.rows,isLoading:t})]})}export{w as component};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{m as e}from"./vendor-tanstack-DJRQAbrY.js";import{n as t}from"./services.generated-
|
|
1
|
+
import{m as e}from"./vendor-tanstack-DJRQAbrY.js";import{n as t}from"./services.generated-BsAvotjG.js";function n(){return e({mutationFn:({id:e,name:n,quotaThreshold:r,weight:i})=>t.updateToken(e,n,r,i)})}export{n as t};
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/sonamu.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Qgrid</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-DTy-s79t.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-Dw2cE7zH.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-ca-nBW7U.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-DH4kUfK2.js">
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/assets/vendor-tanstack-DJRQAbrY.js">
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/sd.generated-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/sd.generated-DYdwSB2I.js">
|
|
14
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BGQSGMcK.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
17
17
|
<div id="root"></div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { J as __commonJSMin, Z as __toESM, _ as require_jsx_runtime, m as require_shim, p as require_react_dom, v as require_react } from "./sd.generated-
|
|
1
|
+
import { J as __commonJSMin, Z as __toESM, _ as require_jsx_runtime, m as require_shim, p as require_react_dom, v as require_react } from "./sd.generated-B0xqnHEo.js";
|
|
2
2
|
//#region ../../node_modules/.pnpm/@tanstack+router-core@1.143.6/node_modules/@tanstack/router-core/dist/esm/utils.js
|
|
3
3
|
function last(arr) {
|
|
4
4
|
return arr[arr.length - 1];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { _ as require_jsx_runtime, d as string, l as number, u as object, v as require_react } from "./sd.generated-
|
|
2
|
-
import { a as TokenService, n as QgridService, r as RequestLogService } from "./services.generated-
|
|
3
|
-
import { a as Link, o as useNavigate } from "./lazyRouteComponent-
|
|
1
|
+
import { _ as require_jsx_runtime, d as string, l as number, u as object, v as require_react } from "./sd.generated-B0xqnHEo.js";
|
|
2
|
+
import { a as TokenService, n as QgridService, r as RequestLogService } from "./services.generated-DqAKskAS.js";
|
|
3
|
+
import { a as Link, o as useNavigate } from "./lazyRouteComponent-BaZaveNc.js";
|
|
4
4
|
import { n as Route } from "../entry-server.generated.js";
|
|
5
5
|
import { n as formatMicroUsd, r as formatUsd, t as cacheHitRate } from "./cost-CSH_t17I.js";
|
|
6
6
|
require_react();
|
|
@@ -82,12 +82,14 @@ var COLUMNS = [
|
|
|
82
82
|
{
|
|
83
83
|
label: "ID",
|
|
84
84
|
align: "left",
|
|
85
|
-
width: "w-12"
|
|
85
|
+
width: "w-12",
|
|
86
|
+
sortKey: "id"
|
|
86
87
|
},
|
|
87
88
|
{
|
|
88
89
|
label: "Date",
|
|
89
90
|
align: "left",
|
|
90
|
-
width: "w-20"
|
|
91
|
+
width: "w-20",
|
|
92
|
+
sortKey: "created_at"
|
|
91
93
|
},
|
|
92
94
|
{
|
|
93
95
|
label: "Project",
|
|
@@ -106,48 +108,55 @@ var COLUMNS = [
|
|
|
106
108
|
},
|
|
107
109
|
{
|
|
108
110
|
label: "TTFT",
|
|
109
|
-
align: "
|
|
110
|
-
width: "w-16"
|
|
111
|
+
align: "right",
|
|
112
|
+
width: "w-16",
|
|
113
|
+
sortKey: "ttft_ms"
|
|
111
114
|
},
|
|
112
115
|
{
|
|
113
116
|
label: "Duration",
|
|
114
|
-
align: "
|
|
115
|
-
width: "w-20"
|
|
117
|
+
align: "right",
|
|
118
|
+
width: "w-20",
|
|
119
|
+
sortKey: "duration_ms"
|
|
116
120
|
},
|
|
117
121
|
{
|
|
118
122
|
label: "In",
|
|
119
|
-
align: "
|
|
120
|
-
width: "w-16"
|
|
123
|
+
align: "right",
|
|
124
|
+
width: "w-16",
|
|
125
|
+
sortKey: "input_tokens"
|
|
121
126
|
},
|
|
122
127
|
{
|
|
123
128
|
label: "Out",
|
|
124
|
-
align: "
|
|
125
|
-
width: "w-20"
|
|
129
|
+
align: "right",
|
|
130
|
+
width: "w-20",
|
|
131
|
+
sortKey: "output_tokens"
|
|
126
132
|
},
|
|
127
133
|
{
|
|
128
134
|
label: "C.Read",
|
|
129
|
-
align: "
|
|
130
|
-
width: "w-20"
|
|
135
|
+
align: "right",
|
|
136
|
+
width: "w-20",
|
|
137
|
+
sortKey: "cache_read_tokens"
|
|
131
138
|
},
|
|
132
139
|
{
|
|
133
140
|
label: "C.Write",
|
|
134
|
-
align: "
|
|
135
|
-
width: "w-20"
|
|
141
|
+
align: "right",
|
|
142
|
+
width: "w-20",
|
|
143
|
+
sortKey: "cache_creation_tokens"
|
|
136
144
|
},
|
|
137
145
|
{
|
|
138
146
|
label: "Hit",
|
|
139
|
-
align: "
|
|
147
|
+
align: "right",
|
|
140
148
|
width: "w-14"
|
|
141
149
|
},
|
|
142
150
|
{
|
|
143
151
|
label: "Tools",
|
|
144
|
-
align: "
|
|
152
|
+
align: "right",
|
|
145
153
|
width: "w-14"
|
|
146
154
|
},
|
|
147
155
|
{
|
|
148
156
|
label: "Cost",
|
|
149
|
-
align: "
|
|
150
|
-
width: "w-20"
|
|
157
|
+
align: "right",
|
|
158
|
+
width: "w-20",
|
|
159
|
+
sortKey: "cost_usd"
|
|
151
160
|
}
|
|
152
161
|
];
|
|
153
162
|
function RequestLogTable({ search, onSearchChange }) {
|
|
@@ -155,10 +164,13 @@ function RequestLogTable({ search, onSearchChange }) {
|
|
|
155
164
|
const page = search.page ?? 1;
|
|
156
165
|
const tokenFilter = search.token ?? "";
|
|
157
166
|
const projectFilter = search.project ?? "";
|
|
167
|
+
const modelFilter = search.model ?? "";
|
|
158
168
|
const { data: tokensData } = TokenService.useTokens("A");
|
|
159
169
|
const tokenNames = (tokensData?.rows ?? []).map((t) => t.name).filter(Boolean);
|
|
160
170
|
const { data: projectData } = QgridService.useProjectNames();
|
|
161
171
|
const projectNames = projectData?.names ?? [];
|
|
172
|
+
const { data: modelData } = QgridService.useModelNames();
|
|
173
|
+
const modelNames = modelData?.names ?? [];
|
|
162
174
|
const projectFilterParam = (() => {
|
|
163
175
|
if (projectFilter === UNASSIGNED) return { project_name_is_null: true };
|
|
164
176
|
if (projectFilter) return { project_name: projectFilter };
|
|
@@ -166,12 +178,17 @@ function RequestLogTable({ search, onSearchChange }) {
|
|
|
166
178
|
})();
|
|
167
179
|
const listFilters = {
|
|
168
180
|
...tokenFilter ? { token_name: tokenFilter } : {},
|
|
169
|
-
...projectFilterParam
|
|
181
|
+
...projectFilterParam,
|
|
182
|
+
...modelFilter ? { model_name: modelFilter } : {}
|
|
170
183
|
};
|
|
184
|
+
const sort = search.sort ?? "id-desc";
|
|
185
|
+
const separator = sort.lastIndexOf("-");
|
|
186
|
+
const sortColumn = sort.slice(0, separator);
|
|
187
|
+
const sortDirection = sort.slice(separator + 1) === "asc" ? "asc" : "desc";
|
|
171
188
|
const { data, isLoading } = RequestLogService.useRequestLogs("P", {
|
|
172
189
|
num: PAGE_SIZE,
|
|
173
190
|
page,
|
|
174
|
-
orderBy:
|
|
191
|
+
orderBy: sort,
|
|
175
192
|
...listFilters
|
|
176
193
|
});
|
|
177
194
|
const { data: costData } = QgridService.useTotalCost({
|
|
@@ -192,15 +209,16 @@ function RequestLogTable({ search, onSearchChange }) {
|
|
|
192
209
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
193
210
|
className: "panel overflow-hidden",
|
|
194
211
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
195
|
-
className: "panel-header flex items-center gap-
|
|
212
|
+
className: "panel-header flex items-center gap-2 px-3 py-2.5 flex-wrap sm:gap-3 sm:px-5",
|
|
196
213
|
children: [
|
|
197
|
-
|
|
214
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
|
|
198
215
|
value: tokenFilter,
|
|
199
216
|
onChange: (e) => updateFilter({ token: e.target.value || void 0 }),
|
|
200
|
-
|
|
217
|
+
disabled: tokenNames.length === 0,
|
|
218
|
+
className: "border border-sand-200/80 rounded-lg px-2.5 py-1.5 text-[11px] text-sand-700 bg-sand-50/50 focus:outline-none focus:border-sienna-300 disabled:text-sand-300 disabled:cursor-not-allowed",
|
|
201
219
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
|
|
202
220
|
value: "",
|
|
203
|
-
children: "All Tokens"
|
|
221
|
+
children: tokenNames.length > 0 ? "All Tokens" : "Tokens —"
|
|
204
222
|
}), tokenNames.map((name) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
|
|
205
223
|
value: name,
|
|
206
224
|
children: name
|
|
@@ -225,6 +243,19 @@ function RequestLogTable({ search, onSearchChange }) {
|
|
|
225
243
|
}, name))
|
|
226
244
|
]
|
|
227
245
|
}),
|
|
246
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
|
|
247
|
+
value: modelFilter,
|
|
248
|
+
onChange: (e) => updateFilter({ model: e.target.value || void 0 }),
|
|
249
|
+
disabled: modelNames.length === 0,
|
|
250
|
+
className: "border border-sand-200/80 rounded-lg px-2.5 py-1.5 text-[11px] text-sand-700 bg-sand-50/50 focus:outline-none focus:border-sienna-300 disabled:text-sand-300 disabled:cursor-not-allowed",
|
|
251
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
|
|
252
|
+
value: "",
|
|
253
|
+
children: modelNames.length > 0 ? "All Models" : "Models —"
|
|
254
|
+
}), modelNames.map((name) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
|
|
255
|
+
value: name,
|
|
256
|
+
children: name
|
|
257
|
+
}, name))]
|
|
258
|
+
}),
|
|
228
259
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex-1" }),
|
|
229
260
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
230
261
|
className: "text-[11px] text-sand-400",
|
|
@@ -242,16 +273,25 @@ function RequestLogTable({ search, onSearchChange }) {
|
|
|
242
273
|
className: "text-sand-400 text-center py-12 text-sm",
|
|
243
274
|
children: "No requests yet."
|
|
244
275
|
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
245
|
-
className: "overflow-x-auto px-
|
|
276
|
+
className: "overflow-x-auto px-3 py-3 sm:px-5",
|
|
246
277
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", {
|
|
247
|
-
className: "w-full text-[13px]",
|
|
278
|
+
className: "w-full min-w-[900px] text-[13px]",
|
|
248
279
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", {
|
|
249
280
|
className: "border-b border-sand-100/60",
|
|
250
281
|
children: [COLUMNS.map((col) => {
|
|
251
282
|
const padX = col.label === "Duration" ? "pl-5 pr-3" : col.width ? "px-4" : "px-3";
|
|
283
|
+
const active = col.sortKey === sortColumn;
|
|
252
284
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
253
|
-
className:
|
|
254
|
-
children: col.
|
|
285
|
+
className: `${col.align === "right" ? "text-right" : "text-left"} ${col.width ?? ""} ${col.width ? "whitespace-nowrap" : ""} ${padX} py-1.5 text-[10px] uppercase font-medium ${active ? "text-sienna-600" : "text-sand-400"}`,
|
|
286
|
+
children: col.sortKey ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
287
|
+
type: "button",
|
|
288
|
+
onClick: () => updateFilter({ sort: `${col.sortKey}-${active && sortDirection === "desc" ? "asc" : "desc"}` }),
|
|
289
|
+
className: `inline-flex items-center gap-0.5 text-[10px] uppercase font-medium hover:text-sienna-500 transition-colors duration-150 ${col.align === "right" ? "justify-end w-full" : ""}`,
|
|
290
|
+
children: [col.label, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
291
|
+
className: active ? "" : "text-sand-300",
|
|
292
|
+
children: active ? sortDirection === "desc" ? "↓" : "↑" : "↕"
|
|
293
|
+
})]
|
|
294
|
+
}) : col.label
|
|
255
295
|
}, col.label);
|
|
256
296
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "w-8" })]
|
|
257
297
|
}) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", {
|
|
@@ -310,39 +350,39 @@ function RequestLogTable({ search, onSearchChange }) {
|
|
|
310
350
|
})
|
|
311
351
|
}),
|
|
312
352
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
|
|
313
|
-
className: "px-4 py-1.5 text-
|
|
353
|
+
className: "px-4 py-1.5 text-right tabular-nums text-sand-500 whitespace-nowrap",
|
|
314
354
|
children: formatTtft(row.ttft_ms)
|
|
315
355
|
}),
|
|
316
356
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
|
|
317
|
-
className: "pl-5 pr-3 py-1.5 text-
|
|
357
|
+
className: "pl-5 pr-3 py-1.5 text-right tabular-nums text-sand-500 whitespace-nowrap",
|
|
318
358
|
children: formatDuration(row.duration_ms)
|
|
319
359
|
}),
|
|
320
360
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
|
|
321
|
-
className: "px-3 py-1.5 text-
|
|
361
|
+
className: "px-3 py-1.5 text-right tabular-nums text-sand-700",
|
|
322
362
|
children: formatNum(row.input_tokens)
|
|
323
363
|
}),
|
|
324
364
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
|
|
325
|
-
className: "px-3 py-1.5 text-
|
|
365
|
+
className: "px-3 py-1.5 text-right tabular-nums text-sand-700",
|
|
326
366
|
children: formatNum(row.output_tokens)
|
|
327
367
|
}),
|
|
328
368
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
|
|
329
|
-
className: "px-3 py-1.5 text-
|
|
369
|
+
className: "px-3 py-1.5 text-right tabular-nums text-sand-700",
|
|
330
370
|
children: formatNum(row.cache_read_tokens)
|
|
331
371
|
}),
|
|
332
372
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
|
|
333
|
-
className: "px-3 py-1.5 text-
|
|
373
|
+
className: "px-3 py-1.5 text-right tabular-nums text-sand-700",
|
|
334
374
|
children: formatNum(row.cache_creation_tokens)
|
|
335
375
|
}),
|
|
336
376
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
|
|
337
|
-
className: "px-3 py-1.5 text-
|
|
377
|
+
className: "px-3 py-1.5 text-right tabular-nums text-sand-700",
|
|
338
378
|
children: cacheHitRate(row)
|
|
339
379
|
}),
|
|
340
380
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
|
|
341
|
-
className: "px-3 py-1.5 text-
|
|
381
|
+
className: "px-3 py-1.5 text-right tabular-nums text-sand-500",
|
|
342
382
|
children: row.tool_call_count > 0 ? row.tool_call_count : "—"
|
|
343
383
|
}),
|
|
344
384
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
|
|
345
|
-
className: "px-3 py-1.5 text-
|
|
385
|
+
className: "px-3 py-1.5 text-right tabular-nums text-sand-700",
|
|
346
386
|
children: row.image_cost_usd !== null ? formatMicroUsd((row.cost_usd ?? 0) + row.image_cost_usd) : row.cost_usd !== null ? formatMicroUsd(row.cost_usd) : "—"
|
|
347
387
|
}),
|
|
348
388
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
|
|
@@ -393,6 +433,8 @@ function RequestLogTable({ search, onSearchChange }) {
|
|
|
393
433
|
object({
|
|
394
434
|
token: string().optional(),
|
|
395
435
|
project: string().optional(),
|
|
436
|
+
model: string().optional(),
|
|
437
|
+
sort: string().optional(),
|
|
396
438
|
page: number().optional().default(1)
|
|
397
439
|
});
|
|
398
440
|
function LogsPage() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Z as __toESM, _ as require_jsx_runtime, c as _enum, p as require_react_dom, u as object, v as require_react } from "./sd.generated-
|
|
2
|
-
import { s as useQuery, t as MonitService } from "./services.generated-
|
|
1
|
+
import { Z as __toESM, _ as require_jsx_runtime, c as _enum, p as require_react_dom, u as object, v as require_react } from "./sd.generated-B0xqnHEo.js";
|
|
2
|
+
import { s as useQuery, t as MonitService } from "./services.generated-DqAKskAS.js";
|
|
3
3
|
import { a as clsx, r as Route } from "../entry-server.generated.js";
|
|
4
4
|
//#region ../../node_modules/.pnpm/@tanstack+virtual-core@3.17.4/node_modules/@tanstack/virtual-core/dist/esm/lazy-measurements.js
|
|
5
5
|
var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Z as __toESM, _ as require_jsx_runtime, g as useQueryClient, p as require_react_dom, v as require_react } from "./sd.generated-
|
|
2
|
-
import { a as TokenService, n as QgridService } from "./services.generated-
|
|
1
|
+
import { Z as __toESM, _ as require_jsx_runtime, g as useQueryClient, p as require_react_dom, v as require_react } from "./sd.generated-B0xqnHEo.js";
|
|
2
|
+
import { a as TokenService, n as QgridService } from "./services.generated-DqAKskAS.js";
|
|
3
3
|
import { i as Q } from "../entry-server.generated.js";
|
|
4
4
|
import { r as formatUsd } from "./cost-CSH_t17I.js";
|
|
5
|
-
import { t as useUpdateTokenMutation } from "./use-update-token-mutation-
|
|
5
|
+
import { t as useUpdateTokenMutation } from "./use-update-token-mutation-DHCaa7Ku.js";
|
|
6
6
|
//#region ../../node_modules/.pnpm/@dnd-kit+utilities@3.2.2_react@19.2.4/node_modules/@dnd-kit/utilities/dist/utilities.esm.js
|
|
7
7
|
var import_react_dom = /* @__PURE__ */ __toESM(require_react_dom());
|
|
8
8
|
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
@@ -2387,14 +2387,14 @@ function UsageRow({ label, utilization, resetsAt, windowDurationMins, theme, thr
|
|
|
2387
2387
|
const pct = utilization ?? 0;
|
|
2388
2388
|
const hasThreshold = threshold !== void 0 && threshold !== null;
|
|
2389
2389
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2390
|
-
className: "flex items-center gap-
|
|
2390
|
+
className: "flex items-center gap-2",
|
|
2391
2391
|
children: [
|
|
2392
2392
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2393
|
-
className: "text-xs text-sand-600 w-
|
|
2393
|
+
className: "text-xs text-sand-600 w-7 shrink-0",
|
|
2394
2394
|
children: formatWindowLabel(label, windowDurationMins)
|
|
2395
2395
|
}),
|
|
2396
2396
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2397
|
-
className: "relative flex-1 h-2 bg-sand-200 rounded-full overflow-hidden",
|
|
2397
|
+
className: "relative flex-1 min-w-0 h-2 bg-sand-200 rounded-full overflow-hidden",
|
|
2398
2398
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2399
2399
|
className: `h-full rounded-full transition-all duration-300 ${barColor(pct, theme)}`,
|
|
2400
2400
|
style: { width: `${Math.min(pct, 100)}%` }
|
|
@@ -2404,11 +2404,12 @@ function UsageRow({ label, utilization, resetsAt, windowDurationMins, theme, thr
|
|
|
2404
2404
|
})]
|
|
2405
2405
|
}),
|
|
2406
2406
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
2407
|
-
className: "text-xs tabular-nums text-sand-700 w-
|
|
2407
|
+
className: "text-xs tabular-nums text-sand-700 w-9 text-right shrink-0",
|
|
2408
2408
|
children: [pct, "%"]
|
|
2409
2409
|
}),
|
|
2410
2410
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2411
|
-
className: "text-[10px] text-sand-400 w-24 text-right",
|
|
2411
|
+
className: "hidden sm:inline text-[10px] text-sand-400 w-24 text-right shrink-0",
|
|
2412
|
+
title: formatResets(resetsAt),
|
|
2412
2413
|
children: formatResets(resetsAt)
|
|
2413
2414
|
})
|
|
2414
2415
|
]
|
|
@@ -2456,9 +2457,6 @@ function TokenUsage({ token, theme }) {
|
|
|
2456
2457
|
})]
|
|
2457
2458
|
});
|
|
2458
2459
|
}
|
|
2459
|
-
function stopDragPropagation(e) {
|
|
2460
|
-
e.stopPropagation();
|
|
2461
|
-
}
|
|
2462
2460
|
function ThresholdControl({ token }) {
|
|
2463
2461
|
const [pos, setPos] = (0, import_react.useState)(null);
|
|
2464
2462
|
const [value, setValue] = (0, import_react.useState)("");
|
|
@@ -2506,8 +2504,6 @@ function ThresholdControl({ token }) {
|
|
|
2506
2504
|
};
|
|
2507
2505
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2508
2506
|
className: "inline-flex",
|
|
2509
|
-
onPointerDown: stopDragPropagation,
|
|
2510
|
-
onClick: stopDragPropagation,
|
|
2511
2507
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
2512
2508
|
ref: triggerRef,
|
|
2513
2509
|
type: "button",
|
|
@@ -2623,8 +2619,6 @@ function WeightControl({ token }) {
|
|
|
2623
2619
|
};
|
|
2624
2620
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2625
2621
|
className: "inline-flex",
|
|
2626
|
-
onPointerDown: stopDragPropagation,
|
|
2627
|
-
onClick: stopDragPropagation,
|
|
2628
2622
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
2629
2623
|
ref: triggerRef,
|
|
2630
2624
|
type: "button",
|
|
@@ -2713,27 +2707,50 @@ function SortableTokenCard({ token }) {
|
|
|
2713
2707
|
opacity: isDragging ? .5 : 1,
|
|
2714
2708
|
zIndex: isDragging ? 10 : void 0
|
|
2715
2709
|
},
|
|
2716
|
-
|
|
2717
|
-
...listeners,
|
|
2718
|
-
className: "relative rounded-lg bg-white border border-sand-200/80 overflow-hidden select-none cursor-grab active:cursor-grabbing touch-none shadow-sm hover:shadow-md transition-shadow duration-200",
|
|
2710
|
+
className: "relative rounded-lg bg-white border border-sand-200/80 overflow-hidden shadow-sm hover:shadow-md transition-shadow duration-200",
|
|
2719
2711
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `absolute inset-y-0 left-0 w-1 ${theme.stripe}` }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2720
|
-
className: "pl-4 pr-
|
|
2712
|
+
className: "pl-4 pr-3 py-3",
|
|
2721
2713
|
children: [
|
|
2722
2714
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2723
|
-
className: "flex items-
|
|
2724
|
-
children: [
|
|
2725
|
-
|
|
2726
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("
|
|
2727
|
-
|
|
2715
|
+
className: "flex items-start justify-between gap-2 mb-2",
|
|
2716
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2717
|
+
className: "flex items-center gap-1.5 min-w-0",
|
|
2718
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
2719
|
+
type: "button",
|
|
2720
|
+
"aria-label": "순서 변경 핸들",
|
|
2721
|
+
...attributes,
|
|
2722
|
+
...listeners,
|
|
2723
|
+
className: "shrink-0 -m-1 p-1 text-sand-300 hover:text-sand-500 cursor-grab active:cursor-grabbing touch-none",
|
|
2724
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideGripVertical, { className: "size-3.5" })
|
|
2725
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2726
|
+
className: "text-[13px] font-medium text-sand-800 truncate select-none",
|
|
2728
2727
|
children: token.name ?? "Unnamed"
|
|
2729
|
-
})
|
|
2728
|
+
})]
|
|
2729
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2730
|
+
className: `text-[11px] tabular-nums font-medium shrink-0 ${theme.cost}`,
|
|
2731
|
+
title: "이 토큰의 누적 비용",
|
|
2732
|
+
children: formatUsd(costData?.usd ?? 0)
|
|
2733
|
+
})]
|
|
2734
|
+
}),
|
|
2735
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2736
|
+
className: "flex flex-wrap items-center gap-1 mb-2",
|
|
2737
|
+
children: [
|
|
2730
2738
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2731
|
-
className: `text-[10px] px-1.5 py-0.5 rounded-full
|
|
2739
|
+
className: `text-[10px] px-1.5 py-0.5 rounded-full uppercase ${theme.badge}`,
|
|
2732
2740
|
children: token.provider
|
|
2733
2741
|
}),
|
|
2734
2742
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2735
|
-
className: `text-[10px] px-1.5 py-0.5 rounded-full
|
|
2743
|
+
className: `text-[10px] px-1.5 py-0.5 rounded-full ${token.active ? "bg-sage-100 text-sage-600" : "bg-sand-200 text-sand-500"}`,
|
|
2736
2744
|
children: token.active ? "Active" : "Inactive"
|
|
2745
|
+
}),
|
|
2746
|
+
QUOTA_THRESHOLD_PROVIDERS.has(token.provider) && token.quota_threshold !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
2747
|
+
className: "px-1.5 py-0.5 rounded-full bg-sienna-50 text-[10px] tabular-nums font-medium text-sienna-600",
|
|
2748
|
+
title: `사용률 ${token.quota_threshold}% 이상이면 이 토큰 제외`,
|
|
2749
|
+
children: [
|
|
2750
|
+
"≤ ",
|
|
2751
|
+
token.quota_threshold,
|
|
2752
|
+
"%"
|
|
2753
|
+
]
|
|
2737
2754
|
})
|
|
2738
2755
|
]
|
|
2739
2756
|
}),
|
|
@@ -2742,23 +2759,8 @@ function SortableTokenCard({ token }) {
|
|
|
2742
2759
|
theme
|
|
2743
2760
|
}),
|
|
2744
2761
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2745
|
-
className: "mt-2 flex items-center justify-end gap-1.5",
|
|
2762
|
+
className: "mt-2 flex flex-wrap items-center justify-end gap-1.5",
|
|
2746
2763
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(WeightControl, { token }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThresholdControl, { token })]
|
|
2747
|
-
}),
|
|
2748
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2749
|
-
className: "absolute top-2.5 right-3 flex items-center gap-1.5",
|
|
2750
|
-
children: [QUOTA_THRESHOLD_PROVIDERS.has(token.provider) && token.quota_threshold !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
2751
|
-
className: "px-1.5 py-0.5 rounded-md bg-sienna-50 text-[11px] tabular-nums font-medium border border-sienna-200 text-sienna-600",
|
|
2752
|
-
title: `사용률 ${token.quota_threshold}% 이상이면 이 토큰 제외`,
|
|
2753
|
-
children: [
|
|
2754
|
-
"≤ ",
|
|
2755
|
-
token.quota_threshold,
|
|
2756
|
-
"%"
|
|
2757
|
-
]
|
|
2758
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
2759
|
-
className: `px-2 py-0.5 rounded-md bg-sand-50 text-[11px] tabular-nums font-medium border border-sand-200/80 ${theme.cost}`,
|
|
2760
|
-
children: formatUsd(costData?.usd ?? 0)
|
|
2761
|
-
})]
|
|
2762
2764
|
})
|
|
2763
2765
|
]
|
|
2764
2766
|
})]
|
|
@@ -2808,7 +2810,7 @@ function UsageCard() {
|
|
|
2808
2810
|
if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2809
2811
|
className: "panel p-5",
|
|
2810
2812
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2811
|
-
className: "grid grid-cols-2 gap-3",
|
|
2813
|
+
className: "grid grid-cols-1 sm:grid-cols-2 gap-3",
|
|
2812
2814
|
children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
2813
2815
|
className: "rounded-lg bg-sand-50 px-4 py-3 animate-pulse",
|
|
2814
2816
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-3 w-16 bg-sand-200 rounded mb-3" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-2 w-full bg-sand-200 rounded-full" })]
|
|
@@ -2850,7 +2852,7 @@ function UsageCard() {
|
|
|
2850
2852
|
items: filteredTokens.map((t) => String(t.id)),
|
|
2851
2853
|
strategy: rectSortingStrategy,
|
|
2852
2854
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
2853
|
-
className: "grid grid-cols-2 gap-3",
|
|
2855
|
+
className: "grid grid-cols-1 sm:grid-cols-2 gap-3",
|
|
2854
2856
|
children: filteredTokens.map((token) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SortableTokenCard, { token }, token.id))
|
|
2855
2857
|
})
|
|
2856
2858
|
})
|
|
@@ -22308,6 +22308,8 @@ var en_default = {
|
|
|
22308
22308
|
"error.internalServerError": "Internal server error",
|
|
22309
22309
|
"error.notFound": "Not found",
|
|
22310
22310
|
"error.serviceUnavailable": "Service unavailable",
|
|
22311
|
+
"qgrid.dispatcherFailed": (provider) => `${provider} dispatcher failed to initialize`,
|
|
22312
|
+
"qgrid.dispatcherStarting": (provider) => `${provider} dispatcher is starting up. Please retry shortly`,
|
|
22311
22313
|
"error.unauthorized": "Unauthorized",
|
|
22312
22314
|
notFound: (name, id) => `${name} ID ${id} not found`,
|
|
22313
22315
|
"validation.email": "Invalid email format",
|
|
@@ -22368,6 +22370,8 @@ var ko_default = {
|
|
|
22368
22370
|
"error.internalServerError": "서버 오류가 발생했습니다",
|
|
22369
22371
|
"error.notFound": "찾을 수 없습니다",
|
|
22370
22372
|
"error.serviceUnavailable": "서비스를 사용할 수 없습니다",
|
|
22373
|
+
"qgrid.dispatcherFailed": (provider) => `${provider} dispatcher 초기화에 실패했습니다`,
|
|
22374
|
+
"qgrid.dispatcherStarting": (provider) => `${provider} dispatcher 기동 중입니다. 잠시 후 다시 시도해주세요`,
|
|
22371
22375
|
"error.unauthorized": "인증이 필요합니다",
|
|
22372
22376
|
"error.unknownSearchField": (field) => `구현되지 않은 검색 필드 ${field}`,
|
|
22373
22377
|
notFound: (name, id) => `존재하지 않는 ${name} ID ${id}`,
|
|
@@ -22564,6 +22568,23 @@ var entityLabels = {
|
|
|
22564
22568
|
"entity.RequestLog.tool_call_count": "tool call 횟수",
|
|
22565
22569
|
"entity.RequestLog.is_image_generation": "이미지 생성 turn 여부 (quota 귀속용)",
|
|
22566
22570
|
"enum.RequestLogOrderBy.id-desc": "ID최신순",
|
|
22571
|
+
"enum.RequestLogOrderBy.id-asc": "ID오래된순",
|
|
22572
|
+
"enum.RequestLogOrderBy.created_at-desc": "등록일시최신순",
|
|
22573
|
+
"enum.RequestLogOrderBy.created_at-asc": "등록일시오래된순",
|
|
22574
|
+
"enum.RequestLogOrderBy.ttft_ms-desc": "TTFT긴순",
|
|
22575
|
+
"enum.RequestLogOrderBy.ttft_ms-asc": "TTFT짧은순",
|
|
22576
|
+
"enum.RequestLogOrderBy.duration_ms-desc": "소요시간긴순",
|
|
22577
|
+
"enum.RequestLogOrderBy.duration_ms-asc": "소요시간짧은순",
|
|
22578
|
+
"enum.RequestLogOrderBy.input_tokens-desc": "입력토큰많은순",
|
|
22579
|
+
"enum.RequestLogOrderBy.input_tokens-asc": "입력토큰적은순",
|
|
22580
|
+
"enum.RequestLogOrderBy.output_tokens-desc": "출력토큰많은순",
|
|
22581
|
+
"enum.RequestLogOrderBy.output_tokens-asc": "출력토큰적은순",
|
|
22582
|
+
"enum.RequestLogOrderBy.cache_read_tokens-desc": "캐시읽기많은순",
|
|
22583
|
+
"enum.RequestLogOrderBy.cache_read_tokens-asc": "캐시읽기적은순",
|
|
22584
|
+
"enum.RequestLogOrderBy.cache_creation_tokens-desc": "캐시생성많은순",
|
|
22585
|
+
"enum.RequestLogOrderBy.cache_creation_tokens-asc": "캐시생성적은순",
|
|
22586
|
+
"enum.RequestLogOrderBy.cost_usd-desc": "비용높은순",
|
|
22587
|
+
"enum.RequestLogOrderBy.cost_usd-asc": "비용낮은순",
|
|
22567
22588
|
"enum.RequestLogSearchField.id": "ID",
|
|
22568
22589
|
"enum.RequestLogSearchField.token_name": "토큰이름",
|
|
22569
22590
|
"enum.RequestLogSearchField.user_prompt": "사용자 프롬프트",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as resolveStaleTime, C as infiniteQueryBehavior, D as notifyManager, G as timeoutManager, H as shouldThrowError, I as noop, K as focusManager, N as isValidTimeout, O as pendingThenable, R as replaceData, S as hasPreviousPage, T as fetchState, V as shallowEqualObjects, W as timeUntilStale, Z as __toESM, _ as require_jsx_runtime, a as fetch, b as getDefaultState, f as require_lib, g as useQueryClient, i as dedupeAndFlatten, j as hashKey, k as environmentManager, o as useRefreshable, q as Subscribable, s as useSSEStream, v as require_react, x as hasNextPage, z as resolveEnabled } from "./sd.generated-
|
|
1
|
+
import { B as resolveStaleTime, C as infiniteQueryBehavior, D as notifyManager, G as timeoutManager, H as shouldThrowError, I as noop, K as focusManager, N as isValidTimeout, O as pendingThenable, R as replaceData, S as hasPreviousPage, T as fetchState, V as shallowEqualObjects, W as timeUntilStale, Z as __toESM, _ as require_jsx_runtime, a as fetch, b as getDefaultState, f as require_lib, g as useQueryClient, i as dedupeAndFlatten, j as hashKey, k as environmentManager, o as useRefreshable, q as Subscribable, s as useSSEStream, v as require_react, x as hasNextPage, z as resolveEnabled } from "./sd.generated-B0xqnHEo.js";
|
|
2
2
|
//#region ../../node_modules/.pnpm/@tanstack+query-core@5.95.2/node_modules/@tanstack/query-core/build/modern/queryObserver.js
|
|
3
3
|
var QueryObserver = class extends Subscribable {
|
|
4
4
|
constructor(client, options) {
|
|
@@ -1023,6 +1023,21 @@ var QgridService;
|
|
|
1023
1023
|
...projectNamesQueryOptions(),
|
|
1024
1024
|
...options
|
|
1025
1025
|
}));
|
|
1026
|
+
async function modelNames() {
|
|
1027
|
+
return fetch({
|
|
1028
|
+
method: "GET",
|
|
1029
|
+
url: `/api/qgrid/modelNames`
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
_QgridService.modelNames = modelNames;
|
|
1033
|
+
const modelNamesQueryOptions = _QgridService.modelNamesQueryOptions = () => queryOptions({
|
|
1034
|
+
queryKey: ["Qgrid", "modelNames"],
|
|
1035
|
+
queryFn: () => modelNames()
|
|
1036
|
+
});
|
|
1037
|
+
_QgridService.useModelNames = (options) => useRefreshable(useQuery({
|
|
1038
|
+
...modelNamesQueryOptions(),
|
|
1039
|
+
...options
|
|
1040
|
+
}));
|
|
1026
1041
|
async function addToken(provider, credentials, name) {
|
|
1027
1042
|
return fetch({
|
|
1028
1043
|
method: "POST",
|