@xenon-device-management/xenon 1.7.0 → 1.7.2
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/lib/package.json +1 -1
- package/lib/public/assets/{ApiKeyGate-BSN8crwz.js → ApiKeyGate-BousCIQZ.js} +1 -1
- package/lib/public/assets/{BugReportButton-DNja1wQ1.js → BugReportButton-Gw4lnGnV.js} +1 -1
- package/lib/public/assets/{DeviceMosaicView-DVk1IpIR.js → DeviceMosaicView-BX2hfhBf.js} +2 -2
- package/lib/public/assets/{EmptyState-CqQ21n-H.js → EmptyState-CPOfuV3O.js} +1 -1
- package/lib/public/assets/{FieldGroup-DE3u01Nu.js → FieldGroup-C5UkCHbe.js} +1 -1
- package/lib/public/assets/{Modal-BJcFdiBP.js → Modal-MMGhL8eW.js} +1 -1
- package/lib/public/assets/{SegmentedControl-CSHjmrvy.js → SegmentedControl-CZfAicws.js} +1 -1
- package/lib/public/assets/{SettingCard-M-lFn_Wm.js → SettingCard-Dp7XIdcl.js} +1 -1
- package/lib/public/assets/{Table-B3EUgBi6.js → Table-DsN_IX6J.js} +1 -1
- package/lib/public/assets/{activity-DK3R5GAb.js → activity-DCBAvxuo.js} +1 -1
- package/lib/public/assets/ai-settings-yNS_bU1m.js +21 -0
- package/lib/public/assets/api-keys-CQ9g1g1b.js +1 -0
- package/lib/public/assets/apps-Bqh1eav9.js +21 -0
- package/lib/public/assets/apps-CTrGClro.css +1 -0
- package/lib/public/assets/{arrow-left-9933DNlF.js → arrow-left-GX0vzYtn.js} +1 -1
- package/lib/public/assets/{arrow-up-right-B7q_1mXs.js → arrow-up-right-DePHHOby.js} +1 -1
- package/lib/public/assets/auth-shell-BBGlC6i3.js +1 -0
- package/lib/public/assets/builds-page-Czf7RsmD.js +6 -0
- package/lib/public/assets/{button-lkxVyarW.js → button-ybNY3GYx.js} +1 -1
- package/lib/public/assets/{check-BkT38An9.js → check-BZMx8AhR.js} +1 -1
- package/lib/public/assets/{chevron-right-WELZ1Z8v.js → chevron-right-WL_bcB02.js} +1 -1
- package/lib/public/assets/{circle-check--2DSsfaI.js → circle-check-CI2xUlDo.js} +1 -1
- package/lib/public/assets/{circle-x-x7R8vTBo.js → circle-x-De3thbcr.js} +1 -1
- package/lib/public/assets/{clock-DIpGd4Pn.js → clock-BFVLE7wW.js} +1 -1
- package/lib/public/assets/{copy-CEcFYYHm.js → copy-ve3lNhva.js} +1 -1
- package/lib/public/assets/device-explorer-elRO7T00.css +1 -0
- package/lib/public/assets/device-explorer-vzZxT4-Y.js +210 -0
- package/lib/public/assets/{download-CaKkGvKw.js → download-BDZj44ke.js} +1 -1
- package/lib/public/assets/forgot-password-BSYQX2oR.js +1 -0
- package/lib/public/assets/{funnel-D2rLIKlM.js → funnel-CptlpFZ9.js} +1 -1
- package/lib/public/assets/index-BW3kENYH.css +1 -0
- package/lib/public/assets/{index-BrVV0Kla.js → index-PtnKslHU.js} +12 -12
- package/lib/public/assets/{layers-DZwF8z_0.js → layers-DRpwoKhI.js} +1 -1
- package/lib/public/assets/{lock-CVUUnm1V.js → lock-CrQhC34I.js} +1 -1
- package/lib/public/assets/login-DaJOt8Qz.js +1 -0
- package/lib/public/assets/maintenance-settings-D629C2IC.js +6 -0
- package/lib/public/assets/{mouse-pointer-2-n4xUMxHJ.js → mouse-pointer-2-Dpcc76zN.js} +1 -1
- package/lib/public/assets/overview-CGEKYX62.js +11 -0
- package/lib/public/assets/{page-header-C0pnt4xz.js → page-header-CSvuGbSO.js} +1 -1
- package/lib/public/assets/{plus-BObE-_z6.js → plus-vJJF9g79.js} +1 -1
- package/lib/public/assets/profile-page-CF7ZQNQz.js +6 -0
- package/lib/public/assets/reset-password-BgpjbCac.js +1 -0
- package/lib/public/assets/runbook-page-Dxuzftyv.js +124 -0
- package/lib/public/assets/selector-detail-page-B_puCd9g.js +1 -0
- package/lib/public/assets/{selector-health-DraY2a4b.js → selector-health-BjMHf106.js} +1 -1
- package/lib/public/assets/selector-health-page-Du_bGD2p.js +16 -0
- package/lib/public/assets/session-detail-page-lQTe5_B1.js +13 -0
- package/lib/public/assets/settings-Cxx_aYWT.css +1 -0
- package/lib/public/assets/settings-DhxWGUzy.js +1 -0
- package/lib/public/assets/{shield-BBc4qisQ.js → shield-JGzamJo5.js} +1 -1
- package/lib/public/assets/{shield-alert-BfoPJ8q_.js → shield-alert-DzE36jcb.js} +1 -1
- package/lib/public/assets/status-pill-outline-50aN0wRU.js +1 -0
- package/lib/public/assets/{tablet-CaOqzQv_.js → tablet-DHY88mxw.js} +1 -1
- package/lib/public/assets/teams-EOAIPbZC.js +1 -0
- package/lib/public/assets/time-B8FIgwPE.js +1 -0
- package/lib/public/assets/{trash-2-CE5TRHb2.js → trash-2-BrTSfFh5.js} +1 -1
- package/lib/public/assets/{useSocket-Bkt5i-U6.js → useSocket-BRto9a5m.js} +1 -1
- package/lib/public/assets/users-Dd44jLAB.js +11 -0
- package/lib/public/assets/webhook-settings-DBYmqim_.js +1 -0
- package/lib/public/assets/{webhook-settings-DEZQtSgr.css → webhook-settings-tW1oXXrJ.css} +1 -1
- package/lib/public/assets/{zap-BzdRuL9F.js → zap-JUbOoK3o.js} +1 -1
- package/lib/public/index.html +2 -2
- package/lib/src/app/routers/auth.js +19 -2
- package/lib/src/scripts/run-migrations.js +14 -3
- package/lib/test/unit/auth-me-auth-disabled.test.js +77 -0
- package/lib/test/unit/run-migrations-fail-fast.test.js +87 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/lib/public/assets/ai-settings-AKMDh8pd.js +0 -21
- package/lib/public/assets/api-keys-B5Q1EkGN.js +0 -1
- package/lib/public/assets/apps-CWWrkTZW.js +0 -21
- package/lib/public/assets/apps-Dt5dUIag.css +0 -1
- package/lib/public/assets/builds-page-DgWXOgh5.js +0 -6
- package/lib/public/assets/device-explorer-3H1hf8ld.css +0 -1
- package/lib/public/assets/device-explorer-nV6L3w7x.js +0 -210
- package/lib/public/assets/forgot-password-CsAF11d2.js +0 -1
- package/lib/public/assets/index-Dz1K6OJU.css +0 -1
- package/lib/public/assets/login-BavGkTli.js +0 -1
- package/lib/public/assets/maintenance-settings-Vr_u8hoR.js +0 -6
- package/lib/public/assets/overview-DVgoOoYF.js +0 -11
- package/lib/public/assets/profile-page-DNKD4MS2.js +0 -1
- package/lib/public/assets/reset-password-C2gSMy8a.js +0 -1
- package/lib/public/assets/runbook-page-BRxjWJVQ.js +0 -104
- package/lib/public/assets/selector-detail-page-DcV8jQuX.js +0 -1
- package/lib/public/assets/selector-health-page-tb5e3CXy.js +0 -16
- package/lib/public/assets/session-detail-page-CEtQr37W.js +0 -13
- package/lib/public/assets/settings-CpRbubta.css +0 -1
- package/lib/public/assets/settings-Cr-YjLbX.js +0 -1
- package/lib/public/assets/status-pill-outline-Cc4PF7Mg.js +0 -1
- package/lib/public/assets/teams-B3Tt_9i2.js +0 -1
- package/lib/public/assets/users-BIvjvjM6.js +0 -11
- package/lib/public/assets/webhook-settings-dAp8wwEB.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{u as v,a as p,b as f,r as s,j as e,L as j,l as w}from"./index-PtnKslHU.js";import{A as N}from"./auth-shell-BBGlC6i3.js";function k(){const u=v(),c=p(),{refresh:m}=f(),d=new URLSearchParams(c.search).get("next")||"/overview",[a,x]=s.useState(""),[r,b]=s.useState(""),[o,n]=s.useState(!1),[l,i]=s.useState(null);async function g(t){t.preventDefault(),n(!0),i(null);try{await w(a,r),await m(),u(d,{replace:!0})}catch(h){i(h.message||"Login failed")}finally{n(!1)}}return e.jsx(N,{children:e.jsxs("form",{onSubmit:g,children:[e.jsx("h1",{className:"text-2xl font-semibold mb-1",children:"Welcome back!"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)] mb-6",children:"Sign in to your account"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Email"}),e.jsx("input",{type:"email",value:a,onChange:t=>x(t.target.value),autoFocus:!0,required:!0,className:"w-full mb-4 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Password"}),e.jsx("input",{type:"password",value:r,onChange:t=>b(t.target.value),required:!0,className:"w-full mb-2 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),e.jsx("div",{className:"text-right mb-4",children:e.jsx(j,{to:"/forgot-password",className:"text-[11px] text-[var(--text-dim)] hover:text-[var(--text)]",children:"Forgot password?"})}),l&&e.jsx("div",{className:"mt-3 text-xs text-[var(--red)]",children:l}),e.jsx("button",{type:"submit",disabled:o,className:"mt-5 w-full h-10 rounded-md bg-[var(--green)] text-black font-medium text-sm disabled:opacity-50",children:o?"Signing in…":"Sign in"})]})})}export{k as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{g as S,m as N,r as d,X as C,j as e,v as D,s as M,I as A}from"./index-PtnKslHU.js";/* empty css */import{S as o,A as B}from"./SettingCard-Dp7XIdcl.js";import{P as w}from"./page-header-CSvuGbSO.js";import{S as k,C as z}from"./shield-JGzamJo5.js";import{T as E}from"./trash-2-BrTSfFh5.js";import{C as L}from"./check-BZMx8AhR.js";/**
|
|
2
|
+
* @license lucide-react v0.555.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const I=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M12 7v5l4 2",key:"1fdv2h"}]],R=S("history",I),c={buildCleanupDays:30,buildCleanupMaxCount:100,buildCleanupSchedule:"0 0 * * *",deleteBuildAssets:!0},P=[{label:"Daily (Midnight)",value:"0 0 * * *"},{label:"Weekly (Sunday)",value:"0 0 * * 0"},{label:"Bi-Daily (12h)",value:"0 */12 * * *"}],T=(n,s)=>n.buildCleanupDays===s.buildCleanupDays&&n.buildCleanupMaxCount===s.buildCleanupMaxCount&&n.buildCleanupSchedule===s.buildCleanupSchedule&&n.deleteBuildAssets===s.deleteBuildAssets,X=()=>{const{toast:n}=N(),[s,i]=d.useState(c),[l,u]=d.useState(c),[b,p]=d.useState(!0),[h,m]=d.useState(!1);d.useEffect(()=>{y()},[]);const y=async()=>{p(!0);try{const a=await C.getGlobalConfig(),t={buildCleanupDays:a.buildCleanupDays||30,buildCleanupMaxCount:a.buildCleanupMaxCount||100,buildCleanupSchedule:a.buildCleanupSchedule||"0 0 * * *",deleteBuildAssets:a.deleteBuildAssets!==void 0?a.deleteBuildAssets:!0};i(t),u(t)}catch(a){console.error("Failed to load maintenance settings",a),n("Failed to access maintenance parameters.","error")}finally{p(!1)}},g=async a=>{const t=a??s;m(!0);try{await C.updateGlobalConfig(t),u(t),i(t),n("Maintenance parameters synchronized across fleet.","success")}catch(v){console.error("Failed to save maintenance settings",v),n("Synchronization failed. Check network integrity.","error")}finally{m(!1)}},f=async()=>{i(c),await g(c)},j=()=>{i(l)},x=!T(s,l),r={days:s.buildCleanupDays!==l.buildCleanupDays,max:s.buildCleanupMaxCount!==l.buildCleanupMaxCount,purge:s.deleteBuildAssets!==l.deleteBuildAssets,schedule:s.buildCleanupSchedule!==l.buildCleanupSchedule};return b?e.jsxs("div",{className:"settings-loading",children:[e.jsx(D,{className:"animate-spin",size:32}),e.jsx("span",{children:"Synchronizing Maintenance Parameters..."})]}):e.jsxs("div",{className:"settings-container",children:[e.jsx(w,{icon:k,title:"Maintenance",subtitle:"Manage the lifecycle of test artifacts, automated purging schedules, and storage optimization across the global registry."}),e.jsxs("div",{className:"settings-content",children:[e.jsxs("div",{className:"settings-grid settings-grid--two-equal",children:[e.jsx(o,{icon:e.jsx(R,{size:16}),title:e.jsxs("span",{className:"card-title-row",children:["Retention Window",r.days&&e.jsx("span",{className:"modified-dot","aria-label":"Modified"})]}),description:"Number of days to preserve builds and sessions before automatic purging from the system.",hint:"Standard enterprise retention is typically 30-90 days.",children:e.jsxs("div",{className:"input-group",children:[e.jsx("input",{type:"number",value:s.buildCleanupDays,onChange:a=>i({...s,buildCleanupDays:parseInt(a.target.value,10)}),min:1}),e.jsx("span",{className:"code-font",children:"DAYS"})]})}),e.jsx(o,{icon:e.jsx(E,{size:16}),title:e.jsxs("span",{className:"card-title-row",children:["Max Build Capacity",r.max&&e.jsx("span",{className:"modified-dot","aria-label":"Modified"})]}),description:"Cap the maximum number of historical builds stored in the primary database.",hint:"Protects against database bloat during high-frequency CI bursts.",children:e.jsxs("div",{className:"input-group",children:[e.jsx("input",{type:"number",value:s.buildCleanupMaxCount,onChange:a=>i({...s,buildCleanupMaxCount:parseInt(a.target.value,10)}),min:1}),e.jsx("span",{className:"code-font",children:"BUILDS"})]})}),e.jsx(o,{icon:e.jsx(M,{size:16}),title:e.jsxs("span",{className:"card-title-row",children:["Asset Purge Strategy",r.purge&&e.jsx("span",{className:"modified-dot","aria-label":"Modified"})]}),description:"Automatically remove binary artifacts (videos, screenshots) when build records are purged.",hint:"Disabling this will leave orphaned files on disk—use with caution.",children:e.jsxs("div",{className:"toggle-group",children:[e.jsxs("label",{className:"switch",children:[e.jsx("input",{type:"checkbox",checked:s.deleteBuildAssets,onChange:a=>i({...s,deleteBuildAssets:a.target.checked})}),e.jsx("span",{className:"slider round"})]}),e.jsx("span",{className:"toggle-label",children:s.deleteBuildAssets?"ENABLED":"DISABLED"})]})}),e.jsxs(o,{icon:e.jsx(z,{size:16}),title:e.jsxs("span",{className:"card-title-row",children:["Cleanup Orchestration",r.schedule&&e.jsx("span",{className:"modified-dot","aria-label":"Modified"})]}),description:"Standardized Cron syntax for scheduling the automated cleanup engine.",children:[e.jsx("div",{className:"setting-input-wrapper",children:e.jsx("input",{type:"text",placeholder:"e.g. 0 0 * * * (Midnight)",value:s.buildCleanupSchedule,onChange:a=>i({...s,buildCleanupSchedule:a.target.value})})}),e.jsx("div",{className:"cron-presets",children:e.jsx("div",{className:"presets-grid",children:P.map(a=>{const t=s.buildCleanupSchedule===a.value;return e.jsxs("button",{type:"button",className:`preset-chip ${t?"active":""}`,onClick:()=>i({...s,buildCleanupSchedule:a.value}),"aria-pressed":t,children:[t&&e.jsx(L,{size:11,className:"preset-chip__check"}),e.jsx("span",{children:a.label})]},a.label)})})})]})]}),e.jsxs("div",{className:"health-monitor-alert maintenance-notice",children:[e.jsx(A,{size:18}),e.jsxs("span",{children:[e.jsx("strong",{children:"Resource Notice:"})," Bulk purging operations are non-blocking and execute at low priority to ensure zero interference with active test execution."]})]})]}),(x||h)&&e.jsx(B,{onSave:()=>g(),onDiscard:j,onRestoreDefaults:f,isSaving:h,isDirty:x,saveLabel:"Save Configuration"})]})};export{X as MaintenanceSettings};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{g as R,r as b,X as S,j as e,u as U,T as X,S as Y}from"./index-PtnKslHU.js";import{u as z}from"./useSocket-BRto9a5m.js";import{F as V}from"./funnel-CptlpFZ9.js";import{T as W,M as K}from"./tablet-DHY88mxw.js";import{A as Q}from"./activity-DCBAvxuo.js";import{P as G}from"./plus-vJJF9g79.js";/**
|
|
2
|
+
* @license lucide-react v0.555.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const J=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]],Z=R("arrow-right",J);/**
|
|
7
|
+
* @license lucide-react v0.555.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const ee=[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]],se=R("play",ee),F=20;function te(s,n){if(!s)return!1;const t=Date.parse(s);return Number.isFinite(t)&&Date.now()-t<n}function ne(s){const t=new Date().getHours(),l=[];for(let a=0;a<24;a++){const d=(t-(23-a)+24)%24;l.push({hour:`${String(d).padStart(2,"0")}:00`,sessions:0,heals:0})}const u=Date.now()-24*60*60*1e3;let i=0;for(const a of s){const d=a.startTime?Date.parse(a.startTime):NaN;if(!Number.isFinite(d)||d<u)continue;const v=23-Math.floor((Date.now()-d)/(60*60*1e3));v>=0&&v<24&&(l[v].sessions+=1,i+=1)}return{trend:l,total:i}}function re(s){const n=new Map;for(const i of s){const a=i.platform||i.device_platform||"unknown",d=i.platformVersion||i.version||i.device_version||"",h=a==="ios"?"iOS":a==="tvos"?"tvOS":a.charAt(0).toUpperCase()+a.slice(1),v=d?`${h} ${d}`:h;n.set(v,(n.get(v)??0)+1)}const t=Array.from(n.entries()).sort((i,a)=>a[1]-i[1]);if(t.length<=6)return t.map(([i,a])=>({label:i,count:a}));const l=t.slice(0,5),u=t.slice(5).reduce((i,[,a])=>i+a,0);return[...l.map(([i,a])=>({label:i,count:a})),{label:"Other",count:u}]}function ae(s){return s.deviceName||(s.deviceUdid?s.deviceUdid.slice(0,8):"device")}function I(s){const n=s.commandName||"selector",t=ae(s);return s.tier?e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:s.tier})," healed ",e.jsx("strong",{children:n})," on ",e.jsx("strong",{children:t})]}):e.jsxs(e.Fragment,{children:["Healed ",e.jsx("strong",{children:n})," on ",e.jsx("strong",{children:t})]})}function ie(){const[s,n]=b.useState([]),[t,l]=b.useState([]),[u,i]=b.useState(0),[a,d]=b.useState([]),[h,v]=b.useState(null),{on:c}=z(),w=b.useRef(0);b.useEffect(()=>{let m=!1;return S.getDevices().then(o=>{!m&&Array.isArray(o)&&n(o)}).catch(()=>{}),S.getSessions().then(o=>{!m&&Array.isArray(o)&&l(o)}).catch(()=>{}),S.getPendingSessionsCount().then(o=>{if(m)return;const N=typeof o=="number"?o:typeof(o==null?void 0:o.count)=="number"?o.count:0;i(N)}).catch(()=>{}),S.getRecentHealingEvents().then(o=>{if(m||!o)return;v(typeof o.todayCount=="number"?o.todayCount:0);const N=Array.isArray(o.events)?o.events:[];N.length!==0&&d(y=>{const T=new Set(y.map(g=>g.id));return[...N.filter(g=>!T.has(g.id)).map(g=>({id:g.id,ts:Date.parse(g.createdAt)||Date.now(),kind:"heal",message:I(g)})),...y].sort((g,r)=>r.ts-g.ts).slice(0,F)})}).catch(()=>{}),()=>{m=!0}},[]),b.useEffect(()=>{const m=[],o=(r,x)=>{w.current+=1;const p={id:`${Date.now()}-${w.current}`,ts:Date.now(),kind:r,message:x};d(f=>[p,...f].slice(0,F))},N=r=>{var f;r&&r.session&&l(j=>j.find(C=>C.id===r.session.id)?j:[r.session,...j]);const x=((f=r==null?void 0:r.session)==null?void 0:f.id)||(r==null?void 0:r.sessionId)||"",p=x?x.slice(0,6):"";o("session",e.jsxs(e.Fragment,{children:["Session ",e.jsx("strong",{children:p||"—"})," started"]}))},y=r=>{var j,A;const x=((j=r==null?void 0:r.session)==null?void 0:j.id)||(r==null?void 0:r.sessionId)||"",p=!!((A=r==null?void 0:r.session)!=null&&A.failure_reason||r!=null&&r.failure_reason);x&&l(C=>C.map(E=>E.id===x?{...E,status:p?"failed":"finished"}:E));const f=x?x.slice(0,6):"";o(p?"session-failed":"session-end",p?e.jsxs(e.Fragment,{children:["Session ",e.jsx("strong",{children:f||"—"})," failed"]}):e.jsxs(e.Fragment,{children:["Session ",e.jsx("strong",{children:f||"—"})," ended"]}))},T=r=>{const x=(r==null?void 0:r.nodeId)||(r==null?void 0:r.id)||"node";o("node",e.jsxs(e.Fragment,{children:["Node ",e.jsx("strong",{children:String(x)})," connected"]}))},_=r=>{const x=(r==null?void 0:r.nodeId)||(r==null?void 0:r.id)||"node";o("node",e.jsxs(e.Fragment,{children:["Node ",e.jsx("strong",{children:String(x)})," disconnected"]}))},g=r=>{const x=r;if(!x||!x.id)return;v(f=>f===null?1:f+1),w.current+=1;const p={id:x.id,ts:Date.parse(x.createdAt)||Date.now(),kind:"heal",message:I(x)};d(f=>f.some(j=>j.id===p.id)?f:[p,...f].slice(0,F))};return m.push(c("session_started",N)),m.push(c("session_stopped",y)),m.push(c("node_connected",T)),m.push(c("node_disconnected",_)),m.push(c("healing_event",g)),()=>{m.forEach(r=>r&&r())}},[c]);const $=t.filter(m=>m.status==="running"),D=t.filter(m=>m.failure_reason&&te(m.endTime||m.startTime,24*60*60*1e3)).length,{trend:L,total:q}=b.useMemo(()=>ne(t),[t]),P=b.useMemo(()=>re(s),[s]);return{devices:s,activeSessions:$,queuedSessions:u,healsToday:h,failures24h:D,failuresDelta:null,activity:a,sessionTrend:L,totalSessions24h:q,osBreakdown:P}}const oe={healthy:"bg-[var(--green)]",neutral:"bg-[var(--border-strong)]",warn:"bg-[var(--amber)]",critical:"bg-[var(--red)]"},le={healthy:"bg-[var(--green)]",neutral:"bg-[var(--text-dim)]",warn:"bg-[var(--amber)]",critical:"bg-[var(--red)]"},ce={healthy:"text-[var(--green)]",neutral:"text-[var(--text-muted)]",warn:"text-[var(--amber)]",critical:"text-[var(--red)]"},k=({label:s,value:n,secondaryValue:t,subtitle:l,state:u="neutral"})=>e.jsxs("div",{className:"relative overflow-hidden rounded-lg border border-[var(--border)] bg-[var(--surface)] p-4 hover:border-[var(--border-strong)] transition-colors",children:[e.jsx("span",{className:`absolute left-0 top-0 bottom-0 w-[2px] ${oe[u]}`}),e.jsx("div",{className:"text-[10px] font-mono font-semibold uppercase tracking-widest text-[var(--text-muted)]",children:s}),e.jsxs("div",{className:"mt-3 flex items-baseline gap-2",children:[e.jsx("span",{className:"text-3xl font-semibold text-[var(--text)] tabular-nums",children:n}),t!=null&&e.jsxs("span",{className:"text-sm font-mono text-[var(--text-dim)]",children:["/ ",t]})]}),e.jsxs("div",{className:`mt-3 flex items-center gap-1.5 text-xs ${ce[u]}`,children:[e.jsx("span",{className:`h-1.5 w-1.5 rounded-full ${le[u]}`}),e.jsx("span",{children:l})]})]});function H(s){return s.offline?"offline":s.reservedBy?"reserved":s.busy?"busy":"ready"}function de(s){const n=(s.platform||"").toLowerCase();return n==="tvos"?X:/pad|tablet/i.test(s.name||"")?W:n==="ios"||n==="android"?Y:K}const xe={ready:{dot:"bg-[var(--green)]",text:"text-[var(--green)]",label:"READY"},busy:{dot:"bg-[var(--amber)]",text:"text-[var(--amber)]",label:"BUSY"},reserved:{dot:"bg-[var(--blue)]",text:"text-[var(--blue)]",label:"RESERVED"},offline:{dot:"bg-[var(--text-dim)]",text:"text-[var(--text-dim)]",label:"OFFLINE"}};function me(s){return s?s.length<=16?s:`${s.slice(0,8)}…${s.slice(-4)}`:""}const ue=({devices:s,maxRows:n=6})=>{const[t,l]=b.useState("all"),u=U(),i=(t==="all"?s:s.filter(a=>H(a)!=="ready")).slice(0,n);return e.jsxs("section",{className:"rounded-lg border border-[var(--border)] bg-[var(--surface)] flex flex-col",children:[e.jsxs("header",{className:"flex items-center justify-between px-4 py-3 border-b border-[var(--border)]",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--text)]",children:"Fleet status"}),e.jsxs("span",{className:"text-xs font-mono text-[var(--text-dim)]",children:[s.length," devices"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"flex items-center gap-0.5 bg-[var(--surface-2)] border border-[var(--border)] rounded-md p-0.5",children:[e.jsx("button",{type:"button",onClick:()=>l("all"),className:`px-2 py-1 text-[11px] rounded transition-colors ${t==="all"?"bg-[var(--border-strong)] text-[var(--text)]":"text-[var(--text-dim)] hover:text-[var(--text)]"}`,children:"All"}),e.jsxs("button",{type:"button",onClick:()=>l("issues"),className:`px-2 py-1 text-[11px] rounded transition-colors flex items-center gap-1 ${t==="issues"?"bg-[var(--border-strong)] text-[var(--text)]":"text-[var(--text-dim)] hover:text-[var(--text)]"}`,children:[e.jsx(V,{className:"h-3 w-3"}),"Non-ready"]})]}),e.jsxs("button",{type:"button",onClick:()=>u("/devices"),className:"ml-1 inline-flex items-center gap-1 text-xs text-[var(--text-muted)] hover:text-[var(--text)] transition-colors",children:["View all ",e.jsx(Z,{className:"h-3 w-3"})]})]})]}),e.jsx("div",{className:"divide-y divide-[var(--border)]",children:i.length===0?e.jsx("div",{className:"px-4 py-8 text-center text-xs text-[var(--text-dim)]",children:t==="issues"?"All devices are ready.":"No devices registered."}):i.map(a=>{const d=de(a),h=xe[H(a)];return e.jsxs("button",{type:"button",onClick:()=>a.udid&&u(`/devices/${a.udid}/control/screen`),className:"w-full flex items-center gap-3 px-4 py-2.5 hover:bg-[var(--surface-2)] transition-colors text-left",children:[e.jsx("span",{className:`h-1.5 w-1.5 rounded-full shrink-0 ${h.dot}`}),e.jsx(d,{className:"h-4 w-4 text-[var(--text-dim)] shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-0 flex items-center gap-3",children:[e.jsx("div",{className:"min-w-0 flex-1",children:e.jsx("div",{className:"text-xs text-[var(--text)] truncate",children:a.name||a.udid})}),e.jsxs("div",{className:"hidden md:block text-[11px] font-mono text-[var(--text-dim)] w-24 text-right",children:[(a.platform||"").toUpperCase()," ",a.sdk||""]}),e.jsx("div",{className:"hidden lg:block text-[11px] font-mono text-[var(--text-dim)] w-32 text-right",children:me(a.udid)})]}),e.jsx("span",{className:`font-mono text-[10px] font-semibold tracking-wider w-20 text-right ${h.text}`,children:h.label})]},a.udid||a.name)})})]})},he={session:"bg-[var(--green)]","session-end":"bg-[var(--text-dim)]","session-failed":"bg-[var(--red)]",node:"bg-[var(--blue)]",heal:"bg-[var(--amber)]"};function ve(s){const n=new Date(s);return`${String(n.getHours()).padStart(2,"0")}:${String(n.getMinutes()).padStart(2,"0")}`}const fe=[{tag:"session.start",desc:"when a new session begins"},{tag:"device.heal",desc:"when a device self-recovers"},{tag:"fleet.offline",desc:"when a device drops offline"}],ge=({events:s,live:n=!0})=>e.jsxs("section",{className:"rounded-lg border border-[var(--border)] bg-[var(--surface)] flex flex-col",children:[e.jsx("header",{className:"flex items-center justify-between px-4 py-3 border-b border-[var(--border)]",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--text)]",children:"Recent activity"}),e.jsxs("span",{className:"flex items-center gap-1 text-[10px] font-mono text-[var(--text-dim)] uppercase tracking-widest",children:[e.jsx("span",{className:`h-1.5 w-1.5 rounded-full ${n?"bg-[var(--green)] pulse-dot":"bg-[var(--text-dim)]"}`}),n?"Live":"Offline"]})]})}),s.length===0?e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-center px-6 py-10 text-center gap-2",children:[e.jsx("div",{className:"h-10 w-10 rounded-full bg-[var(--surface-2)] border border-[var(--border)] flex items-center justify-center",children:e.jsx(Q,{className:"h-5 w-5 text-[var(--text-dim)]"})}),e.jsx("div",{className:"text-sm font-medium text-[var(--text)]",children:"No activity yet"}),e.jsx("div",{className:"text-xs text-[var(--text-dim)] max-w-xs",children:"Start a session to see events stream here in real-time."}),e.jsxs("button",{type:"button",onClick:()=>window.dispatchEvent(new CustomEvent("xenon.open-command-palette")),className:"mt-2 inline-flex items-center gap-1.5 text-xs text-[var(--text)] border border-[var(--border-strong)] hover:border-[var(--green)]/50 hover:text-[var(--green)] rounded-md px-3 py-1.5 transition-colors",children:[e.jsx(se,{className:"h-3 w-3"})," Start a session"]}),e.jsxs("div",{className:"mt-4 w-full max-w-xs text-left",children:[e.jsx("div",{className:"text-[10px] font-mono uppercase tracking-widest text-[var(--text-dim)] mb-2",children:"Event types you'll see"}),e.jsx("div",{className:"space-y-1",children:fe.map(t=>e.jsxs("div",{className:"flex items-baseline gap-2 text-[11px]",children:[e.jsx("span",{className:"font-mono text-[var(--green)]",children:t.tag}),e.jsxs("span",{className:"text-[var(--text-dim)] truncate",children:["— ",t.desc]})]},t.tag))})]})]}):e.jsx("div",{className:"flex-1 overflow-y-auto divide-y divide-[var(--border)]",children:s.map(t=>e.jsxs("div",{className:"flex items-center gap-3 px-4 py-2.5",children:[e.jsx("span",{className:"font-mono text-[10px] text-[var(--text-dim)] w-10 shrink-0",children:ve(t.ts)}),e.jsx("span",{className:`h-1.5 w-1.5 rounded-full shrink-0 ${he[t.kind]}`}),e.jsx("span",{className:"text-xs text-[var(--text-muted)] truncate",children:t.message})]},t.id))})]}),be=({data:s,totalSessions:n,totalHeals:t})=>{var d,h,v;const l=Math.max(1,...s.map(c=>c.sessions)),u=s.length-1,i=Math.floor(s.length/2),a=s.every(c=>c.sessions===0&&c.heals===0);return e.jsxs("section",{className:"rounded-lg border border-[var(--border)] bg-[var(--surface)]",children:[e.jsxs("header",{className:"flex items-start justify-between px-4 py-3 border-b border-[var(--border)]",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--text)]",children:"Session activity"}),e.jsx("div",{className:"text-xs text-[var(--text-dim)] mt-0.5",children:"Last 24 hours"})]}),e.jsxs("div",{className:"flex items-center gap-4 text-right",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[10px] font-mono uppercase tracking-widest text-[var(--text-dim)]",children:"Sessions"}),e.jsx("div",{className:"text-base font-semibold text-[var(--text)] tabular-nums",children:n})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[10px] font-mono uppercase tracking-widest text-[var(--text-dim)]",children:"Heals"}),e.jsx("div",{className:"text-base font-semibold text-[var(--green)] tabular-nums",children:t})]})]})]}),e.jsxs("div",{className:"p-4",children:[a?e.jsx("div",{className:"h-32 flex items-center justify-center text-xs text-[var(--text-dim)]",children:"No sessions in the last 24 hours — activity will chart here."}):e.jsx("div",{className:"flex items-end gap-1 h-32",children:s.map((c,w)=>{const $=c.sessions/l*100,D=c.heals/l*100;return e.jsxs("div",{className:"group relative flex-1 h-full flex flex-col justify-end",children:[c.heals>0&&e.jsx("div",{className:"absolute bottom-0 left-0 right-0 rounded-sm bg-[var(--green)]/40",style:{height:`${D}%`},"aria-hidden":!0}),e.jsx("div",{className:"relative w-full rounded-sm bg-[var(--border-strong)] group-hover:bg-[var(--green)] transition-colors",style:{height:`${Math.max($,2)}%`},"aria-label":`${c.hour} — ${c.sessions} sessions, ${c.heals} heals`}),e.jsxs("div",{className:"pointer-events-none absolute -top-12 left-1/2 -translate-x-1/2 whitespace-nowrap rounded-md bg-[var(--surface-2)] border border-[var(--border-strong)] px-2 py-1 text-[10px] opacity-0 group-hover:opacity-100 transition-opacity z-10 shadow-lg",children:[e.jsx("div",{className:"font-mono text-[var(--text-dim)]",children:c.hour}),e.jsxs("div",{className:"text-[var(--text)]",children:[c.sessions," sessions · ",c.heals," heals"]})]})]},w)})}),e.jsxs("div",{className:"flex justify-between mt-2 text-[10px] font-mono text-[var(--text-dim)]",children:[e.jsx("span",{children:(d=s[0])==null?void 0:d.hour}),e.jsx("span",{children:(h=s[i])==null?void 0:h.hour}),e.jsx("span",{children:(v=s[u])==null?void 0:v.hour})]})]})]})};function O(s){const n=s.toLowerCase();return n.startsWith("tvos")?"bg-[var(--green)]":n.startsWith("ios")?"bg-[var(--blue)]":n.startsWith("android")?"bg-[var(--amber)]":n==="other"?"bg-[var(--border-strong)]":"bg-[var(--green-dim)]"}const pe=({rows:s})=>{const n=s.reduce((t,l)=>t+l.count,0);return e.jsxs("section",{className:"rounded-lg border border-[var(--border)] bg-[var(--surface)]",children:[e.jsxs("header",{className:"px-4 py-3 border-b border-[var(--border)]",children:[e.jsx("h2",{className:"text-sm font-semibold text-[var(--text)]",children:"Fleet composition"}),e.jsxs("div",{className:"text-xs text-[var(--text-dim)] mt-0.5",children:["By operating system · ",n," ",n===1?"device":"devices"]})]}),n===0?e.jsx("div",{className:"px-4 py-8 text-center text-xs text-[var(--text-dim)]",children:"No devices to break down."}):e.jsxs("div",{className:"p-4 space-y-3",children:[e.jsx("div",{className:"h-2 w-full rounded-full overflow-hidden flex bg-[var(--surface-2)]",children:s.map(t=>e.jsx("div",{className:`${O(t.label)} h-full`,style:{width:`${t.count/n*100}%`},title:`${t.label}: ${t.count}`},t.label))}),e.jsx("div",{className:"space-y-1.5",children:s.map(t=>e.jsxs("div",{className:"flex items-center justify-between text-xs",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:`h-2 w-2 rounded-sm ${O(t.label)}`}),e.jsx("span",{className:"font-mono text-[var(--text)]",children:t.label})]}),e.jsxs("div",{className:"flex items-center gap-3 font-mono text-[var(--text-dim)]",children:[e.jsx("span",{className:"tabular-nums",children:t.count}),e.jsxs("span",{className:"tabular-nums w-10 text-right",children:[Math.round(t.count/n*100),"%"]})]})]},t.label))})]})]})},B="—",M="Xenon",$e=()=>{const s=ie(),n=s.devices.length,t=s.devices.filter(v=>!v.offline).length,l=n?Math.round(t/n*100):null,u=n===0?"neutral":t===n?"healthy":"warn",i=s.activeSessions.length>0?"healthy":s.queuedSessions>0?"warn":"neutral",a=s.failures24h>0?"critical":"healthy",d=()=>window.dispatchEvent(new CustomEvent("xenon.open-command-palette")),h=new Date().getFullYear();return e.jsx("div",{className:"flex-1 min-w-0 overflow-y-auto",children:e.jsxs("div",{className:"max-w-7xl mx-auto px-6 py-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 mb-6",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2 text-[10px] font-mono uppercase tracking-widest text-[var(--text-dim)] mb-1.5",children:[e.jsx("span",{children:M}),e.jsx("span",{children:"/"}),e.jsx("span",{className:"text-[var(--text-muted)]",children:"Overview"})]}),e.jsx("h1",{className:"text-2xl font-semibold tracking-tight text-[var(--text)]",children:"Overview"}),e.jsx("p",{className:"text-sm text-[var(--text-muted)] mt-1",children:"Real-time fleet health and session activity."})]}),e.jsxs("button",{type:"button",onClick:d,className:"inline-flex items-center gap-1.5 h-9 px-3.5 rounded-md bg-[var(--green)] hover:bg-[var(--green-dim)] text-black text-sm font-medium transition-colors shadow-sm",children:[e.jsx(G,{className:"h-4 w-4"}),"New session"]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 mb-6",children:[e.jsx(k,{label:"Devices online",value:n===0?B:t,secondaryValue:n===0?void 0:n,subtitle:n===0?"No devices registered":l===100?"100% fleet uptime":`${l}% fleet uptime`,state:u}),e.jsx(k,{label:"Active sessions",value:s.activeSessions.length,subtitle:s.queuedSessions>0?`${s.queuedSessions} queued`:"No queue",state:i}),e.jsx(k,{label:"Heals today",value:s.healsToday===null?B:s.healsToday,subtitle:s.healsToday===null?"Loading…":s.healsToday===0?"No heals needed":`${s.healsToday} selector${s.healsToday===1?"":"s"} recovered`,state:s.healsToday&&s.healsToday>0?"warn":"neutral"}),e.jsx(k,{label:"Failures (24h)",value:s.failures24h,subtitle:s.failures24h===0?"No failures":`${s.failures24h} session${s.failures24h===1?"":"s"} failed`,state:a})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-3 mb-3",children:[e.jsx(ue,{devices:s.devices}),e.jsx(ge,{events:s.activity,live:!0})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-3",children:[e.jsx("div",{className:"lg:col-span-2",children:e.jsx(be,{data:s.sessionTrend,totalSessions:s.totalSessions24h,totalHeals:s.healsToday??0})}),e.jsx(pe,{rows:s.osBreakdown})]}),e.jsxs("footer",{className:"mt-12 pt-6 pb-8 border-t border-[var(--border)] flex flex-col sm:flex-row items-center justify-between gap-4 text-xs text-[var(--text-dim)]",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"font-medium text-[var(--text)]",children:[M," Device Ops"]}),e.jsx("span",{className:"hidden sm:inline-block h-3 w-px bg-[var(--border)]"}),e.jsx("span",{className:"hidden sm:inline-block",children:"Intelligent Fleet Management"})]}),e.jsxs("div",{className:"flex items-center gap-6",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-[var(--green)] opacity-75"}),e.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-[var(--green)]"})]}),e.jsx("span",{children:"Systems operational"})]}),e.jsxs("span",{className:"font-mono",children:["© ",h," ",M]})]})]})]})})};export{$e as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./index-
|
|
1
|
+
import{j as e}from"./index-PtnKslHU.js";const m=({icon:s,eyebrow:t,title:x,subtitle:a,action:r})=>e.jsx("header",{className:"px-6 pt-6 pb-4 border-b border-[var(--border)]",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[t&&e.jsx("div",{className:"text-[10px] font-mono font-semibold uppercase tracking-widest text-[var(--text-dim)] mb-1.5",children:t}),e.jsxs("h1",{className:"flex items-center gap-2 text-xl font-semibold tracking-tight text-[var(--text)]",children:[s&&e.jsx(s,{className:"h-5 w-5 text-[var(--green)] shrink-0"}),e.jsx("span",{className:"truncate",children:x})]}),a&&e.jsx("p",{className:"mt-1.5 text-sm text-[var(--text-muted)] max-w-3xl",children:a})]}),r&&e.jsx("div",{className:"flex items-center gap-2 shrink-0",children:r})]})});export{m as P};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{g as T,b as k,r as o,j as e,D as S,v as E}from"./index-PtnKslHU.js";import{P as C}from"./page-header-CSvuGbSO.js";import{a as y,f as w}from"./time-B8FIgwPE.js";import{C as A}from"./copy-ve3lNhva.js";import{T as $}from"./trash-2-BrTSfFh5.js";/**
|
|
2
|
+
* @license lucide-react v0.555.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const D=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"10",r:"3",key:"ilqhr7"}],["path",{d:"M7 20.662V19a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v1.662",key:"154egf"}]],K=T("circle-user",D);function R(){const{me:t}=k(),[n,d]=o.useState(""),[r,c]=o.useState(""),[f,p]=o.useState(""),[m,i]=o.useState(!1),[u,b]=o.useState(null);async function l(a){if(a.preventDefault(),b(null),r!==f){b({kind:"err",text:"Passwords do not match."});return}i(!0);try{await S(n,r),b({kind:"ok",text:"Password updated. Other sessions for your account were signed out."}),d(""),c(""),p("")}catch(x){b({kind:"err",text:x.message})}finally{i(!1)}}return e.jsxs("div",{className:"max-w-md",children:[(t==null?void 0:t.role)==="MEMBER"&&(t.teams.length>0?e.jsxs("div",{className:"mb-6",children:[e.jsx("div",{className:"text-xs text-[var(--text-dim)] uppercase tracking-wide mb-2",children:"Your Teams"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:t.teams.map(a=>e.jsx("span",{className:"inline-block px-2 py-1 rounded bg-[var(--surface)] border border-[var(--border)] text-xs",children:a.name},a.id))})]}):e.jsx("div",{className:"mb-6 text-xs text-[var(--text-dim)]",children:"You're not on any team — ask an admin to add you so you can see team-scoped devices."})),e.jsxs("form",{onSubmit:l,children:[e.jsx("h2",{className:"text-xl font-semibold mb-4",children:"Update Password"}),["oldPassword","newPassword","confirm"].map(a=>e.jsxs("div",{className:"mb-3",children:[e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:a==="oldPassword"?"Current password":a==="newPassword"?"New password":"Confirm new password"}),e.jsx("input",{type:"password",value:a==="oldPassword"?n:a==="newPassword"?r:f,onChange:x=>{a==="oldPassword"?d(x.target.value):a==="newPassword"?c(x.target.value):p(x.target.value)},className:"w-full h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm"})]},a)),u&&e.jsx("div",{className:`text-xs mb-3 ${u.kind==="ok"?"text-[var(--green)]":"text-[var(--red)]"}`,children:u.text}),e.jsx("button",{type:"submit",disabled:m||r.length<8,className:"h-10 px-4 rounded-md bg-[var(--green)] text-black font-medium text-sm disabled:opacity-50",children:m?"Updating…":"Update Password"})]})]})}const v="/xenon/api/profile";async function I(){const t=await fetch(`${v}/tokens`,{credentials:"include"});if(!t.ok)throw new Error(`listTokens failed (${t.status})`);return t.json()}async function O(t,n,d){const r=await fetch(`${v}/tokens`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:t,scopes:n,expiresAt:d??void 0})});if(!r.ok){const c=await r.json().catch(()=>({}));throw new Error(c.error||`createToken failed (${r.status})`)}return r.json()}async function L(t){const n=await fetch(`${v}/tokens/${t}`,{method:"DELETE",credentials:"include"});if(!n.ok&&n.status!==204)throw new Error(`deleteToken failed (${n.status})`)}async function M(){const t=await fetch(`${v}/access-key`,{credentials:"include"});if(!t.ok)throw new Error(`getAccessKey failed (${t.status})`);return(await t.json()).accessKey}async function U(){const t=await fetch(`${v}/access-key/rotate`,{method:"POST",credentials:"include"});if(!t.ok)throw new Error(`rotateAccessKey failed (${t.status})`);return(await t.json()).accessKey}const j={"7d":"7 days","30d":"30 days","90d":"90 days","1y":"1 year",never:"No expiry"},B={"7d":7,"30d":30,"90d":90,"1y":365};function g(t){if(t==="never")return null;const n=B[t]*24*60*60*1e3;return new Date(Date.now()+n).toISOString()}function z({onClose:t,onCreated:n}){const[d,r]=o.useState(""),[c,f]=o.useState("30d"),[p,m]=o.useState(!1),[i,u]=o.useState(null);async function b(l){l.preventDefault(),m(!0),u(null);try{const a=g(c),x=await O(d,void 0,a);n({name:d,token:x.token,expiresAt:x.expiresAt})}catch(a){u(a.message)}finally{m(!1)}}return e.jsx("div",{className:"fixed inset-0 z-30 bg-black/50 flex items-center justify-center",role:"dialog","aria-modal":"true",children:e.jsxs("form",{onSubmit:b,className:"bg-[var(--bg)] border border-[var(--border)] rounded-lg w-full max-w-md p-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"Generate Identity Token"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Description"}),e.jsx("input",{autoFocus:!0,value:d,onChange:l=>r(l.target.value),placeholder:"e.g. mac, CI, etc.",required:!0,className:"w-full mb-4 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Expires after"}),e.jsx("select",{value:c,onChange:l=>f(l.target.value),className:"w-full mb-1 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm",children:Object.keys(j).map(l=>e.jsx("option",{value:l,children:j[l]},l))}),e.jsx("p",{className:"text-[11px] text-[var(--text-dim)] mb-4",children:c==="never"?"Token never expires. Rotate manually when needed.":`Token will stop working on ${y(g(c))}.`}),i&&e.jsx("div",{className:"text-xs text-[var(--red)] mb-2",children:i}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:t,className:"h-9 px-3 rounded-md border border-[var(--border)] text-sm",children:"Cancel"}),e.jsx("button",{type:"submit",disabled:p||!d,className:"h-9 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium disabled:opacity-50",children:p?"Creating…":"Create"})]})]})})}function F(){const[t,n]=o.useState(""),[d,r]=o.useState([]),[c,f]=o.useState(!0),[p,m]=o.useState(!1),[i,u]=o.useState(null),[b,l]=o.useState(null);async function a(){f(!0),l(null);try{const[s,h]=await Promise.all([M(),I()]);n(s),r(h)}catch(s){l(s instanceof Error?s.message:"Failed to load tokens")}finally{f(!1)}}o.useEffect(()=>{a()},[]);async function x(){if(confirm("Rotate access key? Existing tokens stay valid but the old accessKey will stop working immediately."))try{n(await U())}catch(s){l(s instanceof Error?s.message:"Failed to rotate access key")}}async function N(s){if(confirm("Delete this token? It will stop working immediately."))try{await L(s),r(h=>h.filter(P=>P.id!==s))}catch(h){l(h instanceof Error?h.message:"Failed to delete token")}}return e.jsxs("div",{className:"max-w-3xl",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx("span",{className:"text-xs text-[var(--text-dim)]",children:"Access Key"}),e.jsx("code",{className:"px-2 py-1 rounded bg-[var(--surface)] border border-[var(--border)] text-xs",children:t||"…"}),e.jsx("button",{onClick:()=>navigator.clipboard.writeText(t),"aria-label":"Copy access key",className:"text-[var(--text-dim)] hover:text-[var(--text)]",children:e.jsx(A,{size:14})}),e.jsx("button",{onClick:x,"aria-label":"Rotate access key",className:"text-[var(--text-dim)] hover:text-[var(--text)]",children:e.jsx(E,{size:14})}),e.jsx("span",{className:"text-[10px] text-[var(--text-dim)] ml-2",children:"Public — paired with a token below"})]}),e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-base font-semibold",children:"Identity Tokens"}),e.jsx("button",{onClick:()=>m(!0),className:"h-9 px-4 rounded-md bg-[var(--green)] text-black font-medium text-sm",children:"Generate New Token"})]}),c?e.jsx("div",{className:"text-sm text-[var(--text-dim)]",children:"Loading…"}):b?e.jsxs("div",{className:"text-sm text-[var(--red)] py-6 text-center border border-dashed border-[var(--border)] rounded-md",children:[b," ",e.jsx("button",{className:"underline text-[var(--text)]",onClick:a,children:"Retry"})]}):d.length===0?e.jsx("div",{className:"text-sm text-[var(--text-dim)] py-6 text-center border border-dashed border-[var(--border)] rounded-md",children:"No tokens yet — generate one to use programmatically."}):e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"text-[11px] text-[var(--text-dim)] uppercase tracking-wide",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left py-2",children:"Name"}),e.jsx("th",{className:"text-left py-2",children:"Issued"}),e.jsx("th",{className:"text-left py-2",children:"Last Used"}),e.jsx("th",{className:"text-left py-2",children:"Expires"}),e.jsx("th",{className:"w-px"})]})}),e.jsx("tbody",{children:d.map(s=>{const h=s.expiresAt?new Date(s.expiresAt).getTime()<=Date.now():!1;return e.jsxs("tr",{className:"border-t border-[var(--border)]",children:[e.jsx("td",{className:"py-2",children:s.name}),e.jsx("td",{className:"py-2 text-[var(--text-muted)]",children:w(s.createdAt)}),e.jsx("td",{className:"py-2 text-[var(--text-muted)]",children:s.lastUsedAt?w(s.lastUsedAt):"—"}),e.jsx("td",{className:`py-2 ${h?"text-[var(--red)]":"text-[var(--text-muted)]"}`,children:s.expiresAt?`${y(s.expiresAt)}${h?" (expired)":""}`:"Never"}),e.jsx("td",{className:"py-2 text-right",children:e.jsx("button",{onClick:()=>N(s.id),"aria-label":"Delete token",className:"text-[var(--red)] hover:opacity-80",children:e.jsx($,{size:14})})})]},s.id)})})]}),p&&e.jsx(z,{onClose:()=>m(!1),onCreated:s=>{m(!1),u(s),a()}}),i&&e.jsx("div",{className:"fixed inset-0 z-30 bg-black/50 flex items-center justify-center",role:"dialog",children:e.jsxs("div",{className:"bg-[var(--bg)] border border-[var(--border)] rounded-lg w-full max-w-md p-6",children:[e.jsx("h3",{className:"text-base font-semibold mb-2",children:"Token created"}),e.jsx("p",{className:"text-xs text-[var(--text-dim)] mb-3",children:"Copy this now — it will not be shown again."}),e.jsx("code",{className:"block break-all px-3 py-2 rounded bg-[var(--surface)] border border-[var(--border)] text-xs mb-3",children:i.token}),e.jsx("p",{className:"text-[11px] text-[var(--text-dim)] mb-4",children:i.expiresAt?`Expires ${y(i.expiresAt)}`:"No expiry — rotate manually."}),e.jsx("div",{className:"flex justify-end",children:e.jsx("button",{onClick:()=>u(null),className:"h-9 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium",children:"Done"})})]})})]})}function J(){const{me:t}=k(),[n,d]=o.useState("password");return e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx(C,{icon:K,title:"Profile",subtitle:t?[t.name||t.email,t.role].filter(Boolean).join(" — "):"Your account settings."}),e.jsxs("div",{className:"flex flex-1 min-h-0",children:[e.jsxs("nav",{className:"w-56 shrink-0 border-r border-[var(--border)] py-6 px-3",children:[e.jsx("div",{className:"text-sm font-semibold mb-4 px-2",children:"Profile Settings"}),[{id:"password",label:"Password & Authentication"},{id:"tokens",label:"API Tokens"}].map(r=>e.jsx("button",{onClick:()=>d(r.id),className:`block w-full text-left px-3 py-2 text-sm rounded-md mb-1 ${n===r.id?"bg-[var(--green)]/10 text-[var(--green)]":"text-[var(--text)] hover:bg-[var(--surface)]"}`,children:r.label},r.id))]}),e.jsx("section",{className:"flex-1 px-8 py-6",children:n==="password"?e.jsx(R,{}):e.jsx(F,{})})]})]})}export{J as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as f,u as g,r as n,d as p,j as e,L as v,e as w}from"./index-PtnKslHU.js";import{A as o}from"./auth-shell-BBGlC6i3.js";function k(){const{token:i}=f(),m=g(),[s,r]=n.useState("checking"),[a,u]=n.useState(""),[l,x]=n.useState(""),[c,d]=n.useState(null);n.useEffect(()=>{if(!i){r("invalid");return}p(i).then(t=>r(t?"ready":"invalid"))},[i]);async function h(t){if(t.preventDefault(),d(null),a!==l){d("Passwords do not match.");return}if(a.length<8){d("Password must be at least 8 characters.");return}r("submitting");try{await w(i,a),r("done"),setTimeout(()=>m("/login",{replace:!0}),1500)}catch(b){d(b.message||"Reset failed"),r("ready")}}return s==="checking"?e.jsx(o,{children:e.jsx("div",{className:"text-sm text-[var(--text-dim)] text-center",children:"Checking link…"})}):s==="invalid"?e.jsx(o,{children:e.jsxs("div",{className:"text-center",children:[e.jsx("h1",{className:"text-xl font-semibold mb-3",children:"This link is invalid or expired"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)] mb-6",children:"Reset links are good for 1 hour and single-use. Request a new one."}),e.jsx(v,{to:"/forgot-password",className:"inline-block h-10 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium leading-10",children:"Request a new link"})]})}):s==="done"?e.jsx(o,{children:e.jsxs("div",{className:"text-center",children:[e.jsx("h1",{className:"text-xl font-semibold mb-3",children:"Password updated"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)]",children:"Redirecting to sign in…"})]})}):e.jsx(o,{children:e.jsxs("form",{onSubmit:h,children:[e.jsx("h1",{className:"text-2xl font-semibold mb-1",children:"Reset your password"}),e.jsx("p",{className:"text-sm text-[var(--text-dim)] mb-6",children:"Choose a new password to sign in with."}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"New password"}),e.jsx("input",{type:"password",value:a,onChange:t=>u(t.target.value),autoFocus:!0,required:!0,className:"w-full mb-3 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Confirm new password"}),e.jsx("input",{type:"password",value:l,onChange:t=>x(t.target.value),required:!0,className:"w-full mb-3 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm focus:border-[var(--green)] outline-none"}),c&&e.jsx("div",{className:"text-xs text-[var(--red)] mb-3",children:c}),e.jsx("button",{type:"submit",disabled:s==="submitting"||a.length<8,className:"mt-5 w-full h-10 rounded-md bg-[var(--green)] text-black font-medium text-sm disabled:opacity-50",children:s==="submitting"?"Updating…":"Update password"})]})})}export{k as default};
|