@xenon-device-management/xenon 2.10.0 → 2.11.0
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/{AnnotationOverlay-LzfXiiZJ.js → AnnotationOverlay-BQPQ5bPF.js} +1 -1
- package/lib/public/assets/{ApiKeyGate-BzFDp4mK.js → ApiKeyGate-Bd7Pumwv.js} +1 -1
- package/lib/public/assets/{BugReportButton-BpgWvmZo.js → BugReportButton-iC7fxPxl.js} +1 -1
- package/lib/public/assets/{DeviceMosaicView-CCB-egSH.js → DeviceMosaicView-CNdES7nm.js} +1 -1
- package/lib/public/assets/{EmptyState-DkUVmANo.js → EmptyState-wZeJbGhN.js} +1 -1
- package/lib/public/assets/{FieldGroup-mbfnfTql.js → FieldGroup-tpRfmhlE.js} +1 -1
- package/lib/public/assets/{FilterMenu-BH5usz4Y.js → FilterMenu-BZwOppId.js} +1 -1
- package/lib/public/assets/{Menu-Cbo9mdTk.js → Menu-CahoAx8L.js} +1 -1
- package/lib/public/assets/{Modal-D6XfQHPr.js → Modal-mcM5W_Ji.js} +1 -1
- package/lib/public/assets/{RecordingPage-CmFPkWqH.js → RecordingPage-B4dFBndn.js} +1 -1
- package/lib/public/assets/{RecordingsPage-CSlKk2qC.js → RecordingsPage-BOez3f_9.js} +1 -1
- package/lib/public/assets/{SegmentedControl-BFW9Dlqd.js → SegmentedControl-qMSiMN1d.js} +1 -1
- package/lib/public/assets/{SettingCard-C4DioTTi.js → SettingCard-rcPtJ7HG.js} +1 -1
- package/lib/public/assets/{Table-DrKjlL00.js → Table-J3uognu0.js} +1 -1
- package/lib/public/assets/{activity-C9bE7Jm8.js → activity-_5pNSfKT.js} +1 -1
- package/lib/public/assets/{ai-settings-DRYic4oO.js → ai-settings-DTPRbkei.js} +1 -1
- package/lib/public/assets/{api-keys-CaQU0g7c.js → api-keys-CxkIUo76.js} +1 -1
- package/lib/public/assets/apps-BQKfuN3J.css +1 -0
- package/lib/public/assets/{apps-c1gUFmmK.js → apps-Bv0pAfxz.js} +2 -2
- package/lib/public/assets/{arrow-left-DMvAWA8r.js → arrow-left-uY7F6z1K.js} +1 -1
- package/lib/public/assets/{arrow-right-BEQgxmKT.js → arrow-right-BbAm_2Wa.js} +1 -1
- package/lib/public/assets/{arrow-up-right-Ba0e2GeU.js → arrow-up-right-x4H5NuvE.js} +1 -1
- package/lib/public/assets/{auth-shell-COODQnc7.js → auth-shell-CtMFhbnC.js} +2 -2
- package/lib/public/assets/{builds-page-DZQgWBUs.js → builds-page-B_O5uBSZ.js} +1 -1
- package/lib/public/assets/{button-WW9j43wR.js → button-CQoMQEj_.js} +1 -1
- package/lib/public/assets/{calendar-COUs9VxF.js → calendar-BZkpCqlL.js} +1 -1
- package/lib/public/assets/{check-D8ifHIJR.js → check-CAB6RYuc.js} +1 -1
- package/lib/public/assets/{chevron-right-BjKVUlB_.js → chevron-right-ec0unu3u.js} +1 -1
- package/lib/public/assets/{circle-check-CfP79QE2.js → circle-check-Dfg-gpjg.js} +1 -1
- package/lib/public/assets/{circle-x-BZbFCixZ.js → circle-x-cbPq6Btp.js} +1 -1
- package/lib/public/assets/{clock-BuTm35Qg.js → clock-DU9cBLi8.js} +1 -1
- package/lib/public/assets/{copy-W00zUBwN.js → copy-VM9kWPpE.js} +1 -1
- package/lib/public/assets/{device-explorer-BEpS-Y-_.js → device-explorer-ai0usQ8m.js} +1 -1
- package/lib/public/assets/{download-CGz-MS3y.js → download-WgW4AVid.js} +1 -1
- package/lib/public/assets/{forgot-password-DG7SqVgU.js → forgot-password-BGRpjTtt.js} +1 -1
- package/lib/public/assets/{index-EkaQM1DK.js → index-C33GjwPr.js} +2 -2
- package/lib/public/assets/{index-DWHTp1YP.js → index-DNDdHt3h.js} +1 -1
- package/lib/public/assets/{input-ChaTXeCq.js → input-DwiVcO3Q.js} +1 -1
- package/lib/public/assets/{keycodes-BhbgeW_r.js → keycodes-CvCtpVJD.js} +1 -1
- package/lib/public/assets/{line-chart-9P3RxScy.js → line-chart-PE5e9PeN.js} +1 -1
- package/lib/public/assets/{list-checks-_23IIEEL.js → list-checks-Bgn9GEEO.js} +1 -1
- package/lib/public/assets/{lock-B2JaqqRI.js → lock-Cb7My6hc.js} +1 -1
- package/lib/public/assets/{login-BEWIfLfC.js → login-CDmyzSpl.js} +1 -1
- package/lib/public/assets/{maintenance-settings-BGJIJQ-k.js → maintenance-settings-Bq6pKoBt.js} +1 -1
- package/lib/public/assets/{monitor-BrwMY4G0.js → monitor-BZSwrnPV.js} +1 -1
- package/lib/public/assets/{mouse-pointer-2-DsWDMyrY.js → mouse-pointer-2-BbFj8y8i.js} +1 -1
- package/lib/public/assets/{network-DfIhNVJv.js → network-DpwYGB0-.js} +1 -1
- package/lib/public/assets/{overview-B1mePY2_.js → overview-B4_IO-X8.js} +1 -1
- package/lib/public/assets/{page-header-DoD3TOzZ.js → page-header-BpLEuo7i.js} +1 -1
- package/lib/public/assets/{plus-BGvWvpBB.js → plus-DHZS0EGU.js} +1 -1
- package/lib/public/assets/{profile-page-CvV5aWvl.js → profile-page-DsHDIq-Y.js} +1 -1
- package/lib/public/assets/{reset-password-CGVd31LR.js → reset-password-DuUjhw_l.js} +1 -1
- package/lib/public/assets/{runbook-page-Bq2cvwb5.js → runbook-page-BI_ayvLd.js} +1 -1
- package/lib/public/assets/{select-CTcD4jWR.js → select-xiba9PSx.js} +1 -1
- package/lib/public/assets/selector-detail-redirect-Emz2obK_.js +1 -0
- package/lib/public/assets/selector-health-page-zpwrgalC.js +11 -0
- package/lib/public/assets/session-detail-page-BhlTJ1Oq.js +4 -0
- package/lib/public/assets/{settings-C-EnGIqs.js → settings-B-mabJFm.js} +1 -1
- package/lib/public/assets/{stat-tile-BY0RDTRm.js → stat-tile-lT8WcPgu.js} +1 -1
- package/lib/public/assets/{tablet-B4cFM-5B.js → tablet-DM8dp75P.js} +1 -1
- package/lib/public/assets/{teams-BFe-RpYd.js → teams-CRkb5-Fe.js} +1 -1
- package/lib/public/assets/{trash-2-CJCKBOP9.js → trash-2-Dxgryn4o.js} +1 -1
- package/lib/public/assets/{upload-DidWkbld.js → upload-Ci0vz0BP.js} +1 -1
- package/lib/public/assets/{use-builds-data-fnfxatOd.js → use-builds-data-DaaqMjjL.js} +1 -1
- package/lib/public/assets/{use-password-reset-mode-iPen3tmC.js → use-password-reset-mode-BvIyZtaF.js} +1 -1
- package/lib/public/assets/{users-CrcjmRdf.js → users-BT8qx3ea.js} +1 -1
- package/lib/public/assets/{users-DBUv0CJx.js → users-CWYHk75q.js} +1 -1
- package/lib/public/assets/{video-off-eh69-FKB.js → video-off-BvY08g6I.js} +1 -1
- package/lib/public/assets/view-state-83Z1gFME.js +1 -0
- package/lib/public/assets/{webhook-settings-CQoSshBn.js → webhook-settings-aHIlSJFP.js} +1 -1
- package/lib/public/assets/{zap-CICtWiLn.js → zap-qG2Li6rI.js} +1 -1
- package/lib/public/index.html +1 -1
- package/lib/src/app/index.js +2 -0
- package/lib/src/dashboard/event-manager.js +4 -6
- package/lib/src/gateway/nodeSessionMetrics.js +39 -0
- package/lib/src/gateway/nodeSessionStatus.js +32 -23
- package/lib/src/generated/client/edge.js +2 -2
- package/lib/src/generated/client/index.js +2 -2
- package/lib/src/generated/client/package.json +1 -1
- package/lib/src/generated/client/schema.prisma +6 -0
- package/lib/src/plugin.js +3 -0
- package/lib/src/services/SelectorVerificationJob.js +50 -5
- package/lib/src/services/SessionLifecycleService.js +16 -0
- package/lib/src/services/metrics/NodeMetricsCollector.js +114 -0
- package/lib/src/services/metrics/NodeMetricsStore.js +76 -0
- package/lib/src/services/metrics/SessionMetricsService.js +71 -14
- package/lib/src/services/metrics/nodeMetrics.js +92 -0
- package/lib/src/services/selector-health/selectorDetail.js +36 -20
- package/lib/src/sessions/RemoteSession.js +32 -0
- package/lib/src/sessions/SessionManager.js +63 -0
- package/lib/test/helpers/scratch-database.js +17 -3
- package/lib/test/unit/dashboard-events-metrics.spec.js +10 -0
- package/lib/test/unit/hub-node-session-metrics.spec.js +330 -0
- package/lib/test/unit/node-metrics-collector.spec.js +226 -0
- package/lib/test/unit/node-metrics-store.spec.js +70 -0
- package/lib/test/unit/node-session-metrics-route.spec.js +97 -0
- package/lib/test/unit/selector-health-detail.spec.js +57 -0
- package/lib/test/unit/selector-verification-job.spec.js +3 -0
- package/lib/test/unit/selector-verification-missed-regression.spec.js +132 -0
- package/lib/test/unit/session-log-indexes.spec.js +147 -0
- package/lib/test/unit/session-metrics-lifecycle.spec.js +55 -0
- package/lib/test/unit/session-metrics-service.spec.js +97 -0
- package/lib/test/unit/session-recovery-metrics.spec.js +94 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/prisma/migrations/20261002180000_session_log_indexes/migration.sql +5 -0
- package/prisma/migrations/20261002190000_log_profiling_session_indexes/migration.sql +5 -0
- package/prisma/schema.prisma +6 -0
- package/lib/public/assets/apps-DMhpZuKd.css +0 -1
- package/lib/public/assets/selector-detail-redirect-19odlD4B.js +0 -1
- package/lib/public/assets/selector-health-page-LqIsLrjW.js +0 -11
- package/lib/public/assets/session-detail-page-DQzb8_fq.js +0 -4
- package/lib/public/assets/view-state-CP9dE1UI.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as t}from"./index-
|
|
1
|
+
import{j as t}from"./index-C33GjwPr.js";const x=({className:s,...a})=>t.jsx("table",{className:`tbl${s?" "+s:""}`,...a}),j=s=>t.jsx("thead",{...s}),c=s=>t.jsx("tbody",{...s}),e=s=>t.jsx("tr",{...s}),n=s=>t.jsx("th",{...s}),T=s=>t.jsx("td",{...s});export{x as T,j as a,e as b,n as c,c as d,T as e};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as p,t as z,r as c,X as m,j as e,S as k,A as N,P as I,Q as $}from"./index-
|
|
1
|
+
import{c as p,t as z,r as c,X as m,j as e,S as k,A as N,P as I,Q as $}from"./index-C33GjwPr.js";/* empty css */import{S,A as F}from"./SettingCard-rcPtJ7HG.js";import{P as B}from"./page-header-BpLEuo7i.js";import{L as T}from"./lock-Cb7My6hc.js";import{C as b}from"./circle-check-Dfg-gpjg.js";import{A as E}from"./activity-_5pNSfKT.js";import"./button-CQoMQEj_.js";import"./utils-CDN07tui.js";/**
|
|
2
2
|
* @license lucide-react v0.555.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as le,r as a,j as e,A as $,V as g,y as oe}from"./index-EkaQM1DK.js";/* empty css */import{a as L}from"./time-D-gjmE1o.js";import{T as ce,a as de,b as z,c as l,d as me,e as o}from"./Table-DrKjlL00.js";import{F as m}from"./FieldGroup-mbfnfTql.js";import{P as O}from"./page-header-DoD3TOzZ.js";import{M as B}from"./Modal-D6XfQHPr.js";import{B as u}from"./button-WW9j43wR.js";import{I as H}from"./input-ChaTXeCq.js";import{S as M}from"./select-CTcD4jWR.js";import{P as v}from"./plus-BGvWvpBB.js";import{T as pe}from"./trash-2-CJCKBOP9.js";import{C as he}from"./check-D8ifHIJR.js";import{C as xe}from"./copy-W00zUBwN.js";import"./index-DWHTp1YP.js";import"./utils-CDN07tui.js";const U=["read","sessions","devices","admin"],W={"7d":"7 days","30d":"30 days","90d":"90 days","1y":"1 year",never:"No expiry"},ue={"7d":7,"30d":30,"90d":90,"1y":365};function Y(i){return i==="never"?null:new Date(Date.now()+ue[i]*864e5).toISOString()}function q(i){if(!i)return"Never";const n=Date.now()-new Date(i).getTime();return n<6e4?"Just now":n<36e5?`${Math.floor(n/6e4)}m ago`:n<864e5?`${Math.floor(n/36e5)}h ago`:`${Math.floor(n/864e5)}d ago`}const Ee=()=>{const{toast:i}=le(),[n,w]=a.useState([]),[b,J]=a.useState([]),[X,N]=a.useState(!0),[G,k]=a.useState(!1),[V,d]=a.useState(!1),[r,y]=a.useState(null),[C,S]=a.useState(null),[T,_]=a.useState(!1),[p,A]=a.useState(""),[j,I]=a.useState({read:!0,sessions:!0,devices:!1,admin:!1}),[R,P]=a.useState(300),[E,D]=a.useState(""),[h,F]=a.useState("30d"),[x,K]=a.useState(!1),Q=s=>{var t;return s?((t=b.find(c=>c.id===s))==null?void 0:t.name)||s.slice(0,8):"Shared"},f=async()=>{N(!0);try{const[s,t]=await Promise.all([fetch("/xenon/api/apikeys",{credentials:"include"}),fetch("/xenon/api/teams",{credentials:"include"})]);if(s.status===403){k(!0),w([]);return}if(!s.ok)throw new Error(`HTTP ${s.status}`);w(await s.json()),t.ok&&J(await t.json()),k(!1)}catch(s){i(`Failed to load API keys: ${s.message}`,"error")}finally{N(!1)}};a.useEffect(()=>{f()},[]);const Z=()=>{A(""),I({read:!0,sessions:!0,devices:!1,admin:!1}),P(300),D(""),F("30d")},ee=async()=>{const s=U.filter(t=>j[t]);if(!p.trim()){i("Key name is required","error");return}if(s.length===0){i("Select at least one scope","error");return}K(!0);try{const t=await fetch("/xenon/api/apikeys",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:p.trim(),scopes:s,rateLimit:R,teamId:E||null,expiresAt:Y(h)})});if(!t.ok)throw new Error(`HTTP ${t.status}`);const c=await t.json();d(!1),Z(),y({name:p.trim(),raw:c.key}),await f()}catch(t){i(`Create failed: ${t.message}`,"error")}finally{K(!1)}},se=async s=>{S(s);try{const t=await fetch(`/xenon/api/apikeys/${s}`,{method:"DELETE",credentials:"include"});if(!t.ok)throw new Error(`HTTP ${t.status}`);i("Key revoked","success"),await f()}catch(t){i(`Revoke failed: ${t.message}`,"error")}finally{S(null)}},te=async s=>{try{await navigator.clipboard.writeText(s),_(!0),setTimeout(()=>_(!1),1500)}catch{i("Copy failed — select the text manually","error")}};if(X)return e.jsxs("div",{className:"settings-loading",children:[e.jsx($,{className:"animate-spin",size:32}),e.jsx("span",{children:"Loading API keys…"})]});if(G)return e.jsx("div",{className:"settings-container",children:e.jsx(O,{icon:g,title:"API keys",subtitle:e.jsxs(e.Fragment,{children:["Your key lacks the ",e.jsx("code",{children:"admin"})," scope. Ask an administrator to issue an admin key so you can manage access for other users."]})})});const ae=n.length,ie=n.filter(s=>s.scopes.includes("admin")).length,ne=n.filter(s=>s.lastUsedAt&&Date.now()-new Date(s.lastUsedAt).getTime()<864e5).length;return e.jsxs("div",{className:"settings-container",children:[e.jsx(O,{icon:g,title:"API keys",subtitle:e.jsxs(e.Fragment,{children:["Issue scoped credentials for humans (dashboard login) and machines (CI, WebDriver clients via ",e.jsx("code",{children:"xe:options.accessKey"})," + ",e.jsx("code",{children:"xe:options.token"}),"). Keys are shown only once at creation — copy the value before closing the dialog."]}),action:e.jsxs("button",{type:"button",className:"page-header-action",onClick:()=>d(!0),children:[e.jsx(v,{size:16}),e.jsx("span",{children:"Create new key"})]})}),e.jsxs("div",{className:"settings-content",children:[n.length>0&&e.jsxs("div",{className:"stat-strip",children:[e.jsxs("div",{className:"stat-strip__cell",children:[e.jsx("div",{className:"stat-strip__value",children:ae}),e.jsx("div",{className:"stat-strip__label",children:"Total keys"})]}),e.jsxs("div",{className:"stat-strip__cell",children:[e.jsx("div",{className:"stat-strip__value stat-strip__value--accent",children:ie}),e.jsx("div",{className:"stat-strip__label",children:"Admin scope"})]}),e.jsxs("div",{className:"stat-strip__cell",children:[e.jsx("div",{className:"stat-strip__value",children:ne}),e.jsx("div",{className:"stat-strip__label",children:"Active in last 24h"})]})]}),n.length===0?e.jsxs("div",{className:"empty-state",children:[e.jsx("div",{className:"empty-state__icon",children:e.jsx(g,{size:28})}),e.jsx("h3",{className:"empty-state__title",children:"No API keys yet"}),e.jsx("p",{className:"empty-state__copy",children:"Issue your first key to authenticate WebDriver clients or CI pipelines. Keys are shown only once at creation — copy the value before closing the dialog."}),e.jsxs("button",{type:"button",className:"page-header-action empty-state__action",onClick:()=>d(!0),children:[e.jsx(v,{size:16}),e.jsx("span",{children:"Create your first key"})]})]}):e.jsx("div",{className:"data-card",children:e.jsxs(ce,{children:[e.jsx(de,{children:e.jsxs(z,{children:[e.jsx(l,{children:"Name"}),e.jsx(l,{children:"Team"}),e.jsx(l,{children:"Scopes"}),e.jsx(l,{children:"Rate limit"}),e.jsx(l,{children:"Last used"}),e.jsx(l,{children:"Created"}),e.jsx(l,{children:"Expires"}),e.jsx(l,{style:{textAlign:"right"},children:"Actions"})]})}),e.jsx(me,{children:n.map(s=>e.jsxs(z,{children:[e.jsxs(o,{children:[e.jsx("strong",{children:s.name}),e.jsx("div",{className:"row-meta-mono",children:s.id.slice(0,8)})]}),e.jsx(o,{children:e.jsx("span",{className:`pill-chip ${s.teamId?"pill-chip--team":"pill-chip--shared"}`,children:Q(s.teamId)})}),e.jsx(o,{children:e.jsx("div",{className:"scope-chips",children:s.scopes.split(",").map(t=>{const c=t.trim(),re=c==="admin";return e.jsx("span",{className:`pill-chip ${re?"pill-chip--admin":"pill-chip--scope"}`,children:c},t)})})}),e.jsxs(o,{className:"row-mono",children:[s.rateLimit,"/min"]}),e.jsx(o,{className:"row-mono",children:q(s.lastUsedAt)}),e.jsx(o,{className:"row-mono",children:q(s.createdAt)}),e.jsx(o,{className:"row-mono",children:s.expiresAt?new Date(s.expiresAt).getTime()<=Date.now()?e.jsx("span",{style:{color:"var(--red)"},children:"expired"}):L(s.expiresAt):"Never"}),e.jsx(o,{style:{textAlign:"right"},children:e.jsxs("button",{type:"button",className:"row-action row-action--danger",disabled:C===s.id,onClick:()=>{window.confirm(`Revoke "${s.name}"? Any client using this key will immediately fail.`)&&se(s.id)},children:[e.jsx(pe,{size:13}),C===s.id?"Revoking…":"Revoke"]})})]},s.id))})]})})]}),e.jsx(B,{open:V,title:"Create API key",width:520,onClose:()=>d(!1),footer:e.jsxs(e.Fragment,{children:[e.jsx(u,{variant:"secondary",onClick:()=>d(!1),disabled:x,children:"Cancel"}),e.jsxs(u,{variant:"primary",onClick:ee,disabled:x,children:[x?e.jsx($,{className:"animate-spin",size:18}):e.jsx(v,{size:18}),x?"Creating…":"Create key"]})]}),children:e.jsxs("div",{style:{display:"flex",flexDirection:"column"},children:[e.jsx(m,{label:"Name",htmlFor:"apikey-name",children:e.jsx(H,{id:"apikey-name",type:"text",value:p,onChange:s=>A(s.target.value),placeholder:"alice-laptop, ci-main, etc.",className:"w-full",autoFocus:!0})}),e.jsx(m,{label:"Scopes",description:e.jsxs(e.Fragment,{children:[e.jsx("code",{children:"admin"})," grants full access including API-key management."," ",e.jsx("code",{children:"sessions"})," is required for WebDriver sessions (",e.jsx("code",{children:"xe:options.accessKey"})," + ",e.jsx("code",{children:"xe:options.token"}),")."]}),children:e.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:8},children:U.map(s=>e.jsxs("label",{style:ye,children:[e.jsx("input",{type:"checkbox",checked:j[s],onChange:t=>I({...j,[s]:t.target.checked})}),e.jsx("span",{children:s})]},s))})}),e.jsx(m,{label:"Rate limit (requests/min)",htmlFor:"apikey-ratelimit",children:e.jsx(H,{id:"apikey-ratelimit",type:"number",min:10,step:10,value:R,onChange:s=>P(parseInt(s.target.value)||300),className:"w-full"})}),e.jsx(m,{label:"Default team",description:e.jsxs(e.Fragment,{children:["Keys without a team can only reach shared-pool devices. Admins can override at session time via ",e.jsx("code",{children:"xe:options.team"}),"."]}),htmlFor:"apikey-team",children:e.jsxs(M,{id:"apikey-team",value:E,onChange:s=>D(s.target.value),className:"w-full",children:[e.jsx("option",{value:"",children:"No team (shared pool only)"}),b.map(s=>e.jsx("option",{value:s.id,children:s.name},s.id))]})}),e.jsx(m,{label:"Expires after",description:h==="never"?"Key never expires. Rotate manually when needed.":`Key will stop working on ${L(Y(h))}.`,htmlFor:"apikey-expiry",children:e.jsx(M,{id:"apikey-expiry",value:h,onChange:s=>F(s.target.value),className:"w-full",children:Object.keys(W).map(s=>e.jsx("option",{value:s,children:W[s]},s))})})]})}),e.jsx(B,{open:!!r,title:r?`Key created: ${r.name}`:"",width:560,onClose:()=>y(null),closeOnOverlayClick:!1,footer:e.jsxs(e.Fragment,{children:[e.jsxs(u,{variant:"primary",onClick:()=>r&&te(r.raw),disabled:!r,children:[T?e.jsx(he,{size:18}):e.jsx(xe,{size:18}),T?"Copied":"Copy to clipboard"]}),e.jsx(u,{variant:"secondary",onClick:()=>y(null),children:"I've saved it"})]}),children:r&&e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:16},children:[e.jsxs("div",{style:{background:"var(--status-busy-bg)",border:"1px solid var(--status-busy-border)",borderRadius:6,padding:12,display:"flex",gap:8,alignItems:"flex-start"},children:[e.jsx(oe,{size:18,style:{flexShrink:0,marginTop:2}}),e.jsxs("div",{children:[e.jsx("strong",{children:"This key will not be shown again."})," Copy it now and store it in your password manager, CI secret store, or client config."]})]}),e.jsx("div",{style:{fontFamily:"monospace",padding:12,background:"rgb(var(--rgb-black) / 0.3)",borderRadius:6,wordBreak:"break-all",fontSize:"0.9em"},children:r.raw})]})})]})},ye={display:"flex",alignItems:"center",gap:6,padding:"6px 12px",background:"rgb(var(--rgb-white) / 0.04)",borderRadius:6,cursor:"pointer",fontFamily:"monospace",fontSize:"0.9em"};export{Ee as ApiKeys};
|
|
1
|
+
import{t as le,r as a,j as e,A as $,V as g,y as oe}from"./index-C33GjwPr.js";/* empty css */import{a as L}from"./time-D-gjmE1o.js";import{T as ce,a as de,b as z,c as l,d as me,e as o}from"./Table-J3uognu0.js";import{F as m}from"./FieldGroup-tpRfmhlE.js";import{P as O}from"./page-header-BpLEuo7i.js";import{M as B}from"./Modal-mcM5W_Ji.js";import{B as u}from"./button-CQoMQEj_.js";import{I as H}from"./input-DwiVcO3Q.js";import{S as M}from"./select-xiba9PSx.js";import{P as v}from"./plus-DHZS0EGU.js";import{T as pe}from"./trash-2-Dxgryn4o.js";import{C as he}from"./check-CAB6RYuc.js";import{C as xe}from"./copy-VM9kWPpE.js";import"./index-DNDdHt3h.js";import"./utils-CDN07tui.js";const U=["read","sessions","devices","admin"],W={"7d":"7 days","30d":"30 days","90d":"90 days","1y":"1 year",never:"No expiry"},ue={"7d":7,"30d":30,"90d":90,"1y":365};function Y(i){return i==="never"?null:new Date(Date.now()+ue[i]*864e5).toISOString()}function q(i){if(!i)return"Never";const n=Date.now()-new Date(i).getTime();return n<6e4?"Just now":n<36e5?`${Math.floor(n/6e4)}m ago`:n<864e5?`${Math.floor(n/36e5)}h ago`:`${Math.floor(n/864e5)}d ago`}const Ee=()=>{const{toast:i}=le(),[n,w]=a.useState([]),[b,J]=a.useState([]),[X,N]=a.useState(!0),[G,k]=a.useState(!1),[V,d]=a.useState(!1),[r,y]=a.useState(null),[C,S]=a.useState(null),[T,_]=a.useState(!1),[p,A]=a.useState(""),[j,I]=a.useState({read:!0,sessions:!0,devices:!1,admin:!1}),[R,P]=a.useState(300),[E,D]=a.useState(""),[h,F]=a.useState("30d"),[x,K]=a.useState(!1),Q=s=>{var t;return s?((t=b.find(c=>c.id===s))==null?void 0:t.name)||s.slice(0,8):"Shared"},f=async()=>{N(!0);try{const[s,t]=await Promise.all([fetch("/xenon/api/apikeys",{credentials:"include"}),fetch("/xenon/api/teams",{credentials:"include"})]);if(s.status===403){k(!0),w([]);return}if(!s.ok)throw new Error(`HTTP ${s.status}`);w(await s.json()),t.ok&&J(await t.json()),k(!1)}catch(s){i(`Failed to load API keys: ${s.message}`,"error")}finally{N(!1)}};a.useEffect(()=>{f()},[]);const Z=()=>{A(""),I({read:!0,sessions:!0,devices:!1,admin:!1}),P(300),D(""),F("30d")},ee=async()=>{const s=U.filter(t=>j[t]);if(!p.trim()){i("Key name is required","error");return}if(s.length===0){i("Select at least one scope","error");return}K(!0);try{const t=await fetch("/xenon/api/apikeys",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:p.trim(),scopes:s,rateLimit:R,teamId:E||null,expiresAt:Y(h)})});if(!t.ok)throw new Error(`HTTP ${t.status}`);const c=await t.json();d(!1),Z(),y({name:p.trim(),raw:c.key}),await f()}catch(t){i(`Create failed: ${t.message}`,"error")}finally{K(!1)}},se=async s=>{S(s);try{const t=await fetch(`/xenon/api/apikeys/${s}`,{method:"DELETE",credentials:"include"});if(!t.ok)throw new Error(`HTTP ${t.status}`);i("Key revoked","success"),await f()}catch(t){i(`Revoke failed: ${t.message}`,"error")}finally{S(null)}},te=async s=>{try{await navigator.clipboard.writeText(s),_(!0),setTimeout(()=>_(!1),1500)}catch{i("Copy failed — select the text manually","error")}};if(X)return e.jsxs("div",{className:"settings-loading",children:[e.jsx($,{className:"animate-spin",size:32}),e.jsx("span",{children:"Loading API keys…"})]});if(G)return e.jsx("div",{className:"settings-container",children:e.jsx(O,{icon:g,title:"API keys",subtitle:e.jsxs(e.Fragment,{children:["Your key lacks the ",e.jsx("code",{children:"admin"})," scope. Ask an administrator to issue an admin key so you can manage access for other users."]})})});const ae=n.length,ie=n.filter(s=>s.scopes.includes("admin")).length,ne=n.filter(s=>s.lastUsedAt&&Date.now()-new Date(s.lastUsedAt).getTime()<864e5).length;return e.jsxs("div",{className:"settings-container",children:[e.jsx(O,{icon:g,title:"API keys",subtitle:e.jsxs(e.Fragment,{children:["Issue scoped credentials for humans (dashboard login) and machines (CI, WebDriver clients via ",e.jsx("code",{children:"xe:options.accessKey"})," + ",e.jsx("code",{children:"xe:options.token"}),"). Keys are shown only once at creation — copy the value before closing the dialog."]}),action:e.jsxs("button",{type:"button",className:"page-header-action",onClick:()=>d(!0),children:[e.jsx(v,{size:16}),e.jsx("span",{children:"Create new key"})]})}),e.jsxs("div",{className:"settings-content",children:[n.length>0&&e.jsxs("div",{className:"stat-strip",children:[e.jsxs("div",{className:"stat-strip__cell",children:[e.jsx("div",{className:"stat-strip__value",children:ae}),e.jsx("div",{className:"stat-strip__label",children:"Total keys"})]}),e.jsxs("div",{className:"stat-strip__cell",children:[e.jsx("div",{className:"stat-strip__value stat-strip__value--accent",children:ie}),e.jsx("div",{className:"stat-strip__label",children:"Admin scope"})]}),e.jsxs("div",{className:"stat-strip__cell",children:[e.jsx("div",{className:"stat-strip__value",children:ne}),e.jsx("div",{className:"stat-strip__label",children:"Active in last 24h"})]})]}),n.length===0?e.jsxs("div",{className:"empty-state",children:[e.jsx("div",{className:"empty-state__icon",children:e.jsx(g,{size:28})}),e.jsx("h3",{className:"empty-state__title",children:"No API keys yet"}),e.jsx("p",{className:"empty-state__copy",children:"Issue your first key to authenticate WebDriver clients or CI pipelines. Keys are shown only once at creation — copy the value before closing the dialog."}),e.jsxs("button",{type:"button",className:"page-header-action empty-state__action",onClick:()=>d(!0),children:[e.jsx(v,{size:16}),e.jsx("span",{children:"Create your first key"})]})]}):e.jsx("div",{className:"data-card",children:e.jsxs(ce,{children:[e.jsx(de,{children:e.jsxs(z,{children:[e.jsx(l,{children:"Name"}),e.jsx(l,{children:"Team"}),e.jsx(l,{children:"Scopes"}),e.jsx(l,{children:"Rate limit"}),e.jsx(l,{children:"Last used"}),e.jsx(l,{children:"Created"}),e.jsx(l,{children:"Expires"}),e.jsx(l,{style:{textAlign:"right"},children:"Actions"})]})}),e.jsx(me,{children:n.map(s=>e.jsxs(z,{children:[e.jsxs(o,{children:[e.jsx("strong",{children:s.name}),e.jsx("div",{className:"row-meta-mono",children:s.id.slice(0,8)})]}),e.jsx(o,{children:e.jsx("span",{className:`pill-chip ${s.teamId?"pill-chip--team":"pill-chip--shared"}`,children:Q(s.teamId)})}),e.jsx(o,{children:e.jsx("div",{className:"scope-chips",children:s.scopes.split(",").map(t=>{const c=t.trim(),re=c==="admin";return e.jsx("span",{className:`pill-chip ${re?"pill-chip--admin":"pill-chip--scope"}`,children:c},t)})})}),e.jsxs(o,{className:"row-mono",children:[s.rateLimit,"/min"]}),e.jsx(o,{className:"row-mono",children:q(s.lastUsedAt)}),e.jsx(o,{className:"row-mono",children:q(s.createdAt)}),e.jsx(o,{className:"row-mono",children:s.expiresAt?new Date(s.expiresAt).getTime()<=Date.now()?e.jsx("span",{style:{color:"var(--red)"},children:"expired"}):L(s.expiresAt):"Never"}),e.jsx(o,{style:{textAlign:"right"},children:e.jsxs("button",{type:"button",className:"row-action row-action--danger",disabled:C===s.id,onClick:()=>{window.confirm(`Revoke "${s.name}"? Any client using this key will immediately fail.`)&&se(s.id)},children:[e.jsx(pe,{size:13}),C===s.id?"Revoking…":"Revoke"]})})]},s.id))})]})})]}),e.jsx(B,{open:V,title:"Create API key",width:520,onClose:()=>d(!1),footer:e.jsxs(e.Fragment,{children:[e.jsx(u,{variant:"secondary",onClick:()=>d(!1),disabled:x,children:"Cancel"}),e.jsxs(u,{variant:"primary",onClick:ee,disabled:x,children:[x?e.jsx($,{className:"animate-spin",size:18}):e.jsx(v,{size:18}),x?"Creating…":"Create key"]})]}),children:e.jsxs("div",{style:{display:"flex",flexDirection:"column"},children:[e.jsx(m,{label:"Name",htmlFor:"apikey-name",children:e.jsx(H,{id:"apikey-name",type:"text",value:p,onChange:s=>A(s.target.value),placeholder:"alice-laptop, ci-main, etc.",className:"w-full",autoFocus:!0})}),e.jsx(m,{label:"Scopes",description:e.jsxs(e.Fragment,{children:[e.jsx("code",{children:"admin"})," grants full access including API-key management."," ",e.jsx("code",{children:"sessions"})," is required for WebDriver sessions (",e.jsx("code",{children:"xe:options.accessKey"})," + ",e.jsx("code",{children:"xe:options.token"}),")."]}),children:e.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:8},children:U.map(s=>e.jsxs("label",{style:ye,children:[e.jsx("input",{type:"checkbox",checked:j[s],onChange:t=>I({...j,[s]:t.target.checked})}),e.jsx("span",{children:s})]},s))})}),e.jsx(m,{label:"Rate limit (requests/min)",htmlFor:"apikey-ratelimit",children:e.jsx(H,{id:"apikey-ratelimit",type:"number",min:10,step:10,value:R,onChange:s=>P(parseInt(s.target.value)||300),className:"w-full"})}),e.jsx(m,{label:"Default team",description:e.jsxs(e.Fragment,{children:["Keys without a team can only reach shared-pool devices. Admins can override at session time via ",e.jsx("code",{children:"xe:options.team"}),"."]}),htmlFor:"apikey-team",children:e.jsxs(M,{id:"apikey-team",value:E,onChange:s=>D(s.target.value),className:"w-full",children:[e.jsx("option",{value:"",children:"No team (shared pool only)"}),b.map(s=>e.jsx("option",{value:s.id,children:s.name},s.id))]})}),e.jsx(m,{label:"Expires after",description:h==="never"?"Key never expires. Rotate manually when needed.":`Key will stop working on ${L(Y(h))}.`,htmlFor:"apikey-expiry",children:e.jsx(M,{id:"apikey-expiry",value:h,onChange:s=>F(s.target.value),className:"w-full",children:Object.keys(W).map(s=>e.jsx("option",{value:s,children:W[s]},s))})})]})}),e.jsx(B,{open:!!r,title:r?`Key created: ${r.name}`:"",width:560,onClose:()=>y(null),closeOnOverlayClick:!1,footer:e.jsxs(e.Fragment,{children:[e.jsxs(u,{variant:"primary",onClick:()=>r&&te(r.raw),disabled:!r,children:[T?e.jsx(he,{size:18}):e.jsx(xe,{size:18}),T?"Copied":"Copy to clipboard"]}),e.jsx(u,{variant:"secondary",onClick:()=>y(null),children:"I've saved it"})]}),children:r&&e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:16},children:[e.jsxs("div",{style:{background:"var(--status-busy-bg)",border:"1px solid var(--status-busy-border)",borderRadius:6,padding:12,display:"flex",gap:8,alignItems:"flex-start"},children:[e.jsx(oe,{size:18,style:{flexShrink:0,marginTop:2}}),e.jsxs("div",{children:[e.jsx("strong",{children:"This key will not be shown again."})," Copy it now and store it in your password manager, CI secret store, or client config."]})]}),e.jsx("div",{style:{fontFamily:"monospace",padding:12,background:"rgb(var(--rgb-black) / 0.3)",borderRadius:6,wordBreak:"break-all",fontSize:"0.9em"},children:r.raw})]})})]})},ye={display:"flex",alignItems:"center",gap:6,padding:"6px 12px",background:"rgb(var(--rgb-white) / 0.04)",borderRadius:6,cursor:"pointer",fontFamily:"monospace",fontSize:"0.9em"};export{Ee as ApiKeys};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.apps-container{display:flex;flex-direction:column;height:100%;width:100%}.apps-registry-content{flex:1;overflow-y:auto;padding:var(--space-4) 24px;background:var(--bg)}.registry-table-header{display:grid;grid-template-columns:3fr 1fr 1fr 1fr 1.5fr 2fr;padding:12px 24px;border-bottom:2px solid var(--border);color:var(--text-dim);font-size:11px;font-weight:700;background:rgb(var(--rgb-well) / calc(.2 * var(--well-k)))}.registry-list{display:flex;flex-direction:column}.artifact-row{display:grid;grid-template-columns:3fr 1fr 1fr 1fr 1.5fr 2fr;align-items:center;padding:12px 24px;background:rgb(var(--rgb-well) / calc(.1 * var(--well-k)));border-bottom:1px solid var(--border);transition:all .2s ease;position:relative}.artifact-row:hover{background:rgb(var(--rgb-fg) / .02)}.artifact-row.active{background:rgb(var(--rgb-accent) / .05);border-left:3px solid var(--color-accent)}.col-app-info{display:flex;align-items:center;gap:16px;min-width:0}.app-platform-badge{width:32px;height:32px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border:1px solid var(--border);border-radius:6px;display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--text-dim)}.artifact-row.android .app-platform-badge{color:var(--color-accent);border-color:rgb(var(--rgb-accent) / .2)}.artifact-row.ios .app-platform-badge{color:var(--text);border-color:var(--border)}.app-text-block{display:flex;flex-direction:column;min-width:0}.app-display-name{font-size:13px;font-weight:700;color:var(--text);font-family:Outfit,sans-serif;margin-bottom:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.app-package-id{font-family:JetBrains Mono,monospace;font-size:11px;color:var(--text-dim);opacity:.8;display:flex;align-items:center;gap:6px}.col-version{font-family:JetBrains Mono,monospace;font-size:11px;color:var(--color-accent);font-weight:600}.col-size{font-family:JetBrains Mono,monospace;font-size:11px;color:var(--text-muted)}.col-timestamp{font-size:11px;color:var(--text-dim)}.col-team{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px;color:var(--text-muted)}.app-move-name{margin:0 0 var(--space-3);font-weight:700;color:var(--text);overflow-wrap:anywhere}.col-actions{display:flex;align-items:center;justify-content:flex-end;gap:12px}.instant-deploy-trigger{height:28px;background:rgb(var(--rgb-accent) / .05);border:1px solid var(--color-accent);border-radius:6px;padding:0 12px;display:flex;align-items:center;gap:8px;color:var(--color-accent);font-size:11px;font-weight:700;transition:all .2s;cursor:pointer}.instant-deploy-trigger:hover:not(:disabled){background:var(--color-accent);color:var(--bg);box-shadow:none}.utility-icon-btn{width:28px;height:28px;background:rgb(var(--rgb-well) / calc(.3 * var(--well-k)));border:1px solid var(--border);border-radius:6px;display:flex;align-items:center;justify-content:center;color:var(--text-dim);transition:all .2s}.utility-icon-btn:hover{border-color:var(--border);color:var(--text)}.utility-icon-btn.danger:hover{color:var(--status-error-fg)}.device-explorer-header-container{display:flex;justify-content:space-between;align-items:center;padding:12px 24px;background:#0f0f1a66;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border-bottom:1px solid var(--border);z-index:15;gap:16px;flex-wrap:wrap}.device-explorer-header-left-container{display:flex;align-items:center;gap:24px;flex:1;min-width:0;flex-wrap:wrap}.device-explorer-header-right-container{display:flex;align-items:center;gap:12px}.device-explorer-header-filter-count{margin-left:8px}@media (max-width: 900px){.device-explorer-header-container{flex-direction:column;align-items:stretch;padding:12px 16px}.device-explorer-header-left-container{flex-direction:column;align-items:stretch;gap:12px}.device-explorer-header-left-container>*{width:100%;min-width:0}.device-explorer-header-right-container{justify-content:flex-end;flex-wrap:wrap}}.icon-btn-secondary{width:32px;height:32px;background:rgb(var(--rgb-fg) / .03);border:1px solid var(--border);border-radius:6px;display:flex;align-items:center;justify-content:center;color:var(--text-dim);cursor:pointer;transition:all .2s ease}.icon-btn-secondary:hover{background:rgb(var(--rgb-fg) / .08);color:var(--text);border-color:var(--border)}.deploy-anchor{position:relative;display:flex}.deployment-flyout{position:absolute;top:50%;padding:6px;right:calc(100% + 8px);transform:translateY(-50%);background:var(--surface);border:1px solid var(--color-accent);border-radius:8px;box-shadow:0 10px 40px rgb(var(--rgb-black) / calc(.6 * var(--shadow-k)));z-index:110;display:flex;gap:4px;animation:slideInRight .2s cubic-bezier(.16,1,.3,1)}@keyframes slideInRight{0%{opacity:0;transform:translateY(-50%) translate(10px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.target-device-select{height:32px;background:rgb(var(--rgb-well) / calc(.25 * var(--well-k)));border:1px solid var(--border);border-radius:6px;color:var(--text);font-size:11px;font-weight:600;padding:0 12px;min-width:280px;outline:none;cursor:pointer;transition:all .2s ease;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center}.target-device-select:hover{border-color:var(--color-accent);background-color:rgb(var(--rgb-well) / calc(.4 * var(--well-k)))}.target-device-select option{background:var(--surface);color:var(--text);padding:8px}.target-device-select.empty{display:flex;align-items:center;justify-content:center;padding:0 20px;height:32px;font-style:italic;opacity:.5;font-size:11px}.deploy-actions-group{display:flex;align-items:center;gap:6px}.confirm-deploy-btn{width:32px;height:32px;background:var(--color-accent);border:none;border-radius:6px;display:flex;align-items:center;justify-content:center;color:var(--color-on-accent);cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1)}.confirm-deploy-btn:hover:not(:disabled){background:var(--color-accent-strong);transform:scale(1.05);box-shadow:none}.confirm-deploy-btn:disabled{background:rgb(var(--rgb-fg) / .1);color:rgb(var(--rgb-fg) / .2);cursor:not-allowed}.upload-overlay-technical{position:fixed;top:0;right:0;bottom:0;left:0;background:#020617d9;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:2000;display:flex;align-items:center;justify-content:center}.upload-card-technical{width:420px;background:var(--surface);border:1px solid var(--border);border-radius:16px;padding:40px;text-align:center;box-shadow:0 30px 60px rgb(var(--rgb-black) / calc(.6 * var(--shadow-k)))}.processing-loader{width:40px;height:40px;border:2px solid rgb(var(--rgb-accent) / .1);border-top-color:var(--color-accent);border-radius:50%;margin:0 auto 20px;animation:spin 1s linear infinite}.empty-registry-technical{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:100px 20px;text-align:center;max-width:600px;margin:0 auto}.empty-icon-container{width:100px;height:100px;background:radial-gradient(circle,rgb(var(--rgb-blue) / .1) 0%,transparent 70%);display:flex;align-items:center;justify-content:center;border-radius:50%;margin-bottom:24px}.empty-title{font-size:28px;font-weight:800;color:var(--text);margin-bottom:16px;letter-spacing:-.02em}.empty-description{font-size:14px;line-height:1.6;color:var(--text-muted);margin-bottom:40px}.empty-description code{background:rgb(var(--rgb-blue) / .1);padding:2px 6px;border-radius:4px;font-weight:600}.upload-trigger-massive{cursor:pointer;display:block;border-radius:8px}.upload-trigger-massive:focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:4px}.massive-upload-content{display:flex;flex-direction:column;align-items:center;padding:30px 60px;background:var(--surface);border:1px solid var(--color-accent);box-shadow:none;border-radius:8px;color:var(--color-accent);font-weight:700;font-size:16px;transition:all .3s cubic-bezier(.4,0,.2,1);box-shadow:0 0 0 transparent}.massive-upload-content:hover{background:rgb(var(--rgb-blue) / .05);transform:translateY(-4px);box-shadow:none;border-style:solid}.massive-upload-content svg{transition:transform .3s ease}.massive-upload-content:hover svg{transform:translateY(-4px) scale(1.1)}.copy-hint{cursor:pointer;opacity:.4;transition:opacity .2s}.copy-hint:hover{opacity:1}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (min-width: 1401px){.apps-registry-content{padding:0 24px 24px}}.device-explorer-container{display:flex;flex-direction:column;width:100%;gap:var(--space-4)}.device-explorer-header-entry{display:flex;flex-direction:column;gap:4px;min-width:0}.device-explorer-header-value{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.device-explorer-header-value>.device-explorer-header__platform-btn+.device-explorer-header__platform-btn{margin-left:4px}.device-explorer-header__platform-btn{display:flex;align-items:center;gap:6px;padding:6px 12px;border-radius:6px;background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));border:1px solid var(--border);color:var(--text-muted);font-size:12px;font-weight:600;cursor:pointer;transition:all .2s ease}.device-explorer-header__platform-btn:hover{background:rgb(var(--rgb-fg) / .03);color:var(--text);border-color:var(--border)}.device-explorer-header__platform-btn.selected{background:rgb(var(--rgb-accent) / .05);color:var(--color-accent);border-color:rgb(var(--rgb-accent) / .3);box-shadow:none}.device-explorer-search-wrapper{position:relative;width:320px}.device-explorer-search-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);pointer-events:none;opacity:.5}.device-explorer-header-text-filter{width:100%;height:32px;padding:0 12px 0 36px;border-radius:6px;border:1px solid var(--border);background:rgb(var(--rgb-well) / calc(.4 * var(--well-k)));font-family:JetBrains Mono,monospace;font-size:12px;color:var(--text);transition:all .2s ease}.device-explorer-header-text-filter:focus{outline:none;border-color:var(--color-accent);background:rgb(var(--rgb-well) / calc(.6 * var(--well-k)));box-shadow:none}.device-explorer-header-text-filter::placeholder{color:var(--text-dim);font-size:11px}:root[data-theme=light] .device-explorer-header-container{background:rgb(var(--rgb-white) / .7)}.badge-base{display:inline-flex;align-items:center;gap:6px;border-radius:6px;border:1px solid transparent;padding:2px 8px;font-size:11px;font-weight:800;transition:all .2s ease;white-space:nowrap}.badge-variant-default{background:rgb(var(--rgb-well) / calc(.3 * var(--well-k)));color:var(--text-dim);border-color:var(--border)}.badge-variant-success{background:rgb(var(--rgb-success) / .05);color:var(--color-success);border-color:rgb(var(--rgb-success) / .2)}.badge-variant-warning{background:#ffc1070d;color:#ffc107;border-color:#ffc10733}.badge-variant-error{background:rgb(var(--rgb-red-alt) / .05);color:var(--red-alt);border-color:rgb(var(--rgb-red-alt) / .2)}.badge-variant-secondary{background:var(--surface);color:var(--text);border-color:var(--border)}.badge-variant-outline{background:transparent;color:var(--text-dim);border:1px solid var(--border)}.badge-variant-outline:hover{color:var(--text);border-color:var(--text-muted)}:root[data-theme=light] .badge-variant-warning{background:rgb(var(--rgb-amber) / .08);color:var(--amber);border-color:rgb(var(--rgb-amber) / .3)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as k,j as e,r as i,A as K,t as ve,b as
|
|
1
|
+
import{c as k,j as e,r as i,A as K,t as ve,b as je,X as p,H as fe,q as V,z as ye,v as ge}from"./index-C33GjwPr.js";import{f as Ne}from"./time-D-gjmE1o.js";import{c as be,B as x}from"./button-CQoMQEj_.js";import{c as ke}from"./utils-CDN07tui.js";import{P as we}from"./page-header-BpLEuo7i.js";import{S as Z}from"./select-xiba9PSx.js";import{M as J}from"./Modal-mcM5W_Ji.js";import{F as Q}from"./FieldGroup-tpRfmhlE.js";import{U as ee,T as H}from"./upload-Ci0vz0BP.js";import{C as Ce}from"./check-CAB6RYuc.js";import{C as Ae}from"./copy-VM9kWPpE.js";import{Z as Se}from"./zap-qG2Li6rI.js";import{D as ze}from"./download-WgW4AVid.js";import{T as Me}from"./trash-2-Dxgryn4o.js";import"./index-DNDdHt3h.js";/**
|
|
2
2
|
* @license lucide-react v0.555.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -23,4 +23,4 @@ import{c as k,j as e,r as i,A as K,t as ve,b as fe,X as p,H as je,q as V,z as ye
|
|
|
23
23
|
*
|
|
24
24
|
* This source code is licensed under the ISC license.
|
|
25
25
|
* See the LICENSE file in the root directory of this source tree.
|
|
26
|
-
*/const Ue=[["path",{d:"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z",key:"m3kijz"}],["path",{d:"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z",key:"1fmvmk"}],["path",{d:"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0",key:"1f8sc4"}],["path",{d:"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5",key:"qeys4"}]],W=k("rocket",Ue),Re=be("badge-base",{variants:{variant:{default:"badge-variant-default",success:"badge-variant-success",warning:"badge-variant-warning",error:"badge-variant-error",outline:"badge-variant-outline",secondary:"badge-variant-secondary"}},defaultVariants:{variant:"default"}});function Y({className:r,variant:c,...n}){return e.jsx("div",{className:ke(Re({variant:c}),r),...n})}const ae=({id:r,value:c,teams:n,onChange:m,disabled:h})=>e.jsxs(Z,{id:r,value:c,disabled:h,className:"w-full",onChange:l=>m(l.target.value),children:[e.jsx("option",{value:"",children:"Shared"}),n.map(l=>e.jsx("option",{value:l.id,children:l.name},l.id))]}),te="Members of the team can see and run it. Shared apps are open to everyone.",_e=({open:r,teams:c,teamId:n,onTeamChange:m,onChooseFile:h,onClose:l})=>e.jsx(J,{open:r,onClose:l,title:"Upload app",footer:e.jsxs(e.Fragment,{children:[e.jsx(x,{variant:"secondary",onClick:l,children:"Cancel"}),e.jsxs(x,{variant:"primary",onClick:h,children:[e.jsx(ee,{size:14,className:"mr-1"}),"Choose file…"]})]}),children:e.jsx(Q,{label:"Team",htmlFor:"upload-app-team",description:te,children:e.jsx(ae,{id:"upload-app-team",value:n,teams:c,onChange:m})})}),Le=({app:r,teams:c,onMove:n,onClose:m})=>{const[h,l]=i.useState(""),[d,j]=i.useState(!1),[y,u]=i.useState(null);i.useEffect(()=>{l((r==null?void 0:r.teamId)??""),u(null)},[r]);const g=async()=>{j(!0),u(null);try{await n(h||null)}catch(v){u((v==null?void 0:v.message)||"Could not move the app")}finally{j(!1)}};return e.jsxs(J,{open:!!r,onClose:m,title:"Move to team",footer:e.jsxs(e.Fragment,{children:[e.jsx(x,{variant:"secondary",onClick:m,disabled:d,children:"Cancel"}),e.jsxs(x,{variant:"primary",onClick:g,disabled:d,children:[d?e.jsx(K,{size:14,className:"mr-1 animate-spin"}):e.jsx(se,{size:14,className:"mr-1"}),"Move"]})]}),children:[e.jsx("p",{className:"app-move-name",children:r==null?void 0:r.name}),e.jsx(Q,{label:"Team",htmlFor:"move-app-team",description:te,error:y??void 0,children:e.jsx(ae,{id:"move-app-team",value:h,teams:c,onChange:l,disabled:d})})]})},X=r=>{var c;return((c=r.team)==null?void 0:c.name)??(r.teamId?String(r.teamId).slice(0,8):"Shared")},ss=()=>{const{toast:r,removeToast:c}=ve(),[n,m]=i.useState([]),[h,l]=i.useState([]),[d,j]=i.useState(!1),[y,u]=i.useState(""),[g,v]=i.useState(!1),[re,R]=i.useState(null),[w,_]=i.useState({android:!0,ios:!0}),[S,ie]=i.useState("desc"),[C,z]=i.useState(null),[M,T]=i.useState(""),D=i.useRef(null),{me:f}=fe(),N=(f==null?void 0:f.role)==="ADMIN"||(f==null?void 0:f.role)==="SUPER_ADMIN",[L,B]=i.useState([]),[ne,I]=i.useState(!1),[E,G]=i.useState(""),[F,$]=i.useState(null),b=i.useCallback(async()=>{j(!0);try{const s=await p.getApps();m(Array.isArray(s)?s:[])}catch(s){console.error("Failed to fetch apps",s)}finally{j(!1)}},[]),U=i.useCallback(async()=>{try{const s=await p.getDevices();l(Array.isArray(s)?s:[])}catch(s){console.error("Failed to fetch devices",s)}},[]);i.useEffect(()=>{b(),U();const s=setInterval(U,1e4);return()=>clearInterval(s)},[b,U]),i.useEffect(()=>{N&&p.listTeams().then(B).catch(()=>B([]))},[N]);const O=()=>{var s;N?(G(""),I(!0)):(s=D.current)==null||s.click()},le=async s=>{F&&(await p.setAppTeam(F.id,s),r(s?"App moved to team":"App shared with everyone","success"),$(null),await b())},ce=async s=>{var o;const a=(o=s.target.files)==null?void 0:o[0];if(!a)return;const t=N&&E?E:null;I(!1),v(!0);try{await p.uploadApp(a,t),await b()}catch(ue){console.error("Upload failed",ue)}finally{v(!1),s.target&&(s.target.value="")}},oe=async(s,a)=>{if(window.confirm(`Permanently remove artifact "${a}"?`))try{await p.deleteApp(s),m(t=>t.filter(o=>o.id!==s))}catch(t){console.error("Delete failed",t)}},de=(s,a)=>{navigator.clipboard.writeText(s),R(`${a}-${s}`),setTimeout(()=>R(null),2e3)},me=async(s,a)=>{const t=r(`Deploying app to ${a}...`,"loading",0);try{const o=await p.installRepositoryApp(a,s);o.success?(r("App deployed successfully","success"),z(null),T("")):r(`Deployment failed: ${o.error}`,"error")}catch(o){r(`Execution Error: ${o.message}`,"error")}finally{c(t)}},A=n.filter(s=>{const a=s.name.toLowerCase().includes(y.toLowerCase())||s.packageName&&s.packageName.toLowerCase().includes(y.toLowerCase()),t=w.android&&s.platform==="android"||w.ios&&s.platform==="ios";return a&&t}).sort((s,a)=>{const t=new Date(s.createdAt).getTime(),o=new Date(a.createdAt).getTime();return S==="desc"?o-t:t-o}),he=s=>{if(!s)return"0 B";const a=1024,t=Math.floor(Math.log(s)/Math.log(a));return parseFloat((s/Math.pow(a,t)).toFixed(1))+" "+["B","KB","MB","GB"][t]},pe=s=>Ne(s),P=s=>{_(a=>({...a,[s]:!a[s]}))},xe=s=>{const a=s.toLowerCase();return a.includes("wda-signed")||a.includes("wda-resign")||a.includes("webdriveragent")};return e.jsxs("div",{className:"apps-container device-explorer-container",children:[e.jsx("div",{className:"scanline",style:{position:"absolute",inset:0,pointerEvents:"none",opacity:.05,zIndex:1001}}),e.jsx(we,{icon:je,title:"Apps",subtitle:"Signed builds available for installation across your device fleet."}),e.jsxs("div",{className:"device-explorer-header-container",children:[e.jsxs("div",{className:"device-explorer-header-left-container",children:[e.jsx("div",{className:"device-explorer-header-entry",children:e.jsxs("div",{className:"device-explorer-header-value",children:[e.jsxs("button",{className:`device-explorer-header__platform-btn ${w.android&&"selected"}`,onClick:()=>P("android"),children:[e.jsx(V,{size:18,color:"currentColor"})," Android"]}),e.jsxs("button",{className:`device-explorer-header__platform-btn ${w.ios&&"selected"}`,onClick:()=>P("ios"),children:[e.jsx(q,{size:18,color:"currentColor"})," iOS"]})]})}),e.jsx("div",{className:"device-explorer-header-entry",children:e.jsx("div",{className:"device-explorer-header-value",children:e.jsxs("div",{className:"device-explorer-search-wrapper",children:[e.jsx(ye,{size:16,color:"#94a3b8",className:"device-explorer-search-icon"}),e.jsx("input",{type:"text",className:"device-explorer-header-text-filter",placeholder:"Filter by bundle or name...",value:y,onChange:s=>u(s.target.value)})]})})}),e.jsx("div",{className:"device-explorer-header-filter-count",children:e.jsxs(Y,{variant:"secondary",children:[e.jsx("span",{className:"font-bold",children:A.length})," of"," ",e.jsx("span",{className:"font-bold",children:n.length})," ",n.length===1?"artifact":"artifacts"]})})]}),e.jsxs("div",{className:"device-explorer-header-right-container",children:[e.jsx("button",{className:"icon-btn-secondary sort-btn",onClick:()=>ie(s=>s==="desc"?"asc":"desc"),title:S==="desc"?"Newest First":"Oldest First",children:S==="desc"?e.jsx(Ie,{size:18}):e.jsx($e,{size:18})}),e.jsxs(x,{size:"sm",variant:"secondary",onClick:()=>b(),disabled:d,children:[e.jsx(K,{size:14,className:`mr-1 ${d&&"animate-spin"}`}),"Refresh"]}),e.jsx("input",{ref:D,type:"file",accept:".apk,.ipa",onChange:ce,hidden:!0}),e.jsxs(x,{size:"sm",variant:"primary",onClick:O,disabled:g,children:[e.jsx(ee,{size:14,className:"mr-1"}),"Upload app"]})]})]}),e.jsx("main",{className:"apps-registry-content",children:d&&n.length===0?e.jsxs("div",{className:"empty-data-vignette",children:[e.jsx("div",{className:"processing-loader"}),e.jsx("p",{className:"text-muted text-xs font-bold tracking-widest",children:"SYNCING REGISTRY..."})]}):e.jsxs(e.Fragment,{children:[A.length>0&&e.jsxs("div",{className:"registry-table-header",children:[e.jsx("div",{children:"Artifact bundle"}),e.jsx("div",{children:"Version"}),e.jsx("div",{children:"Size"}),e.jsx("div",{children:"Team"}),e.jsx("div",{children:"Registry date"}),e.jsx("div",{style:{textAlign:"right"},children:"Management"})]}),e.jsx("div",{className:"registry-list",children:A.map(s=>{const a=h.filter(t=>t.platform===s.platform&&!t.busy&&!t.offline);return e.jsxs("div",{className:`artifact-row ${s.platform}`,children:[e.jsxs("div",{className:"col-app-info",children:[e.jsx("div",{className:"app-platform-badge",children:s.platform==="android"?e.jsx(V,{size:18}):e.jsx(q,{size:18})}),e.jsxs("div",{className:"app-text-block",children:[e.jsxs("div",{className:"app-display-name",title:s.name,children:[s.name,xe(s.name)&&e.jsx(Y,{variant:"outline",className:"ml-2 text-[10px] h-4 py-0 border-primary text-primary",children:"WDA"})]}),e.jsxs("div",{className:"app-package-id",children:[e.jsx("code",{children:s.packageName||"internal.bundle"}),s.packageName&&e.jsx("div",{className:"copy-hint",title:`Copy ${s.packageName}`,onClick:()=>de(s.packageName,"pkg"),children:re===`pkg-${s.packageName}`?e.jsx(Ce,{size:10,className:"text-primary"}):e.jsx(Ae,{size:10})})]})]})]}),e.jsx("div",{className:"col-version",children:s.version||"v1.0.0"}),e.jsx("div",{className:"col-size",children:he(s.size)}),e.jsx("div",{className:"col-team",title:X(s),children:X(s)}),e.jsx("div",{className:"col-timestamp",children:pe(s.createdAt)}),e.jsxs("div",{className:"col-actions",children:[e.jsx("button",{className:`instant-deploy-trigger ${C===s.id&&"active"}`,onClick:()=>{C===s.id?(z(null),T("")):z(s.id)},children:C===s.id?e.jsxs(e.Fragment,{children:[e.jsx(ge,{size:12})," CANCEL"]}):e.jsxs(e.Fragment,{children:[e.jsx(Se,{size:12})," Deploy"]})}),C===s.id&&e.jsx("div",{className:"deployment-flyout",children:a.length>0?e.jsxs("div",{className:"deploy-actions-group",children:[e.jsxs(Z,{selectSize:"sm",className:"min-w-[280px]",autoFocus:!0,value:M,onChange:t=>T(t.target.value),children:[e.jsx("option",{value:"",children:"SELECT TARGET..."}),a.map(t=>e.jsxs("option",{value:t.udid,children:[t.name," (",t.udid,")"]},t.udid))]}),e.jsx("button",{className:"confirm-deploy-btn",disabled:!M,onClick:()=>me(s.id,M),title:"Confirm deployment",children:e.jsx(W,{size:14})})]}):e.jsx("div",{className:"target-device-select empty",children:"NO TARGETS"})}),e.jsx("button",{className:"utility-icon-btn",onClick:()=>window.open(`/xenon/api/apps/${s.id}/download`,"_blank"),children:e.jsx(ze,{size:14})}),N&&e.jsx("button",{className:"utility-icon-btn","aria-label":`Move ${s.name} to team`,title:"Move to team",onClick:()=>$(s),children:e.jsx(se,{size:14})}),e.jsx("button",{className:"utility-icon-btn danger",onClick:()=>oe(s.id,s.name),children:e.jsx(Me,{size:14})})]})]},s.id)})}),A.length===0&&n.length>0&&!d&&e.jsxs("div",{className:"empty-registry-technical",children:[e.jsx("div",{className:"empty-icon-container",children:e.jsx(H,{size:48,className:"text-primary opacity-40"})}),e.jsx("h2",{className:"empty-title brand-font",children:"No matching artifacts"}),e.jsxs("p",{className:"empty-description",children:[n.length," ",n.length===1?"artifact is":"artifacts are"," registered, but none match the current filter."]}),e.jsx("div",{className:"empty-actions",children:e.jsx(x,{size:"sm",variant:"default",onClick:()=>{u(""),_({android:!0,ios:!0})},children:"Clear filters"})})]}),n.length===0&&!d&&e.jsxs("div",{className:"empty-registry-technical",children:[e.jsx("div",{className:"empty-icon-container",children:e.jsx(H,{size:48,className:"text-primary opacity-40 animate-pulse"})}),e.jsx("h2",{className:"empty-title brand-font",children:"No apps yet"}),e.jsxs("p",{className:"empty-description",children:["Upload ",e.jsx("code",{className:"text-primary",children:".apk"})," or"," ",e.jsx("code",{className:"text-primary",children:".ipa"})," artifacts to enable versioned installs across your device fleet."]}),e.jsx("div",{className:"empty-actions",children:e.jsx("button",{type:"button",className:"upload-trigger-massive",onClick:O,disabled:g,children:e.jsxs("span",{className:"massive-upload-content",children:[e.jsx(W,{size:24,className:"mb-2"}),e.jsx("span",{children:"Upload your first app"})]})})})]})]})}),e.jsx(_e,{open:ne,teams:L,teamId:E,onTeamChange:G,onChooseFile:()=>{var s;return(s=D.current)==null?void 0:s.click()},onClose:()=>I(!1)}),e.jsx(Le,{app:F,teams:L,onMove:le,onClose:()=>$(null)}),g&&e.jsx("div",{className:"upload-overlay-technical",children:e.jsxs("div",{className:"upload-card-technical",children:[e.jsx("div",{className:"processing-loader"}),e.jsx("h2",{className:"brand-font",style:{fontSize:"20px",marginBottom:"8px"},children:"Artifact ingestion"}),e.jsx("p",{className:"text-muted text-xs",children:"VERIFYING CHECKSUM & DEPLOYING TO REGISTRY..."})]})})]})};export{ss as default};
|
|
26
|
+
*/const Ue=[["path",{d:"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z",key:"m3kijz"}],["path",{d:"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z",key:"1fmvmk"}],["path",{d:"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0",key:"1f8sc4"}],["path",{d:"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5",key:"qeys4"}]],W=k("rocket",Ue),Re=be("badge-base",{variants:{variant:{default:"badge-variant-default",success:"badge-variant-success",warning:"badge-variant-warning",error:"badge-variant-error",outline:"badge-variant-outline",secondary:"badge-variant-secondary"}},defaultVariants:{variant:"default"}});function Y({className:r,variant:c,...n}){return e.jsx("div",{className:ke(Re({variant:c}),r),...n})}const ae=({id:r,value:c,teams:n,onChange:m,disabled:h})=>e.jsxs(Z,{id:r,value:c,disabled:h,className:"w-full",onChange:l=>m(l.target.value),children:[e.jsx("option",{value:"",children:"Shared"}),n.map(l=>e.jsx("option",{value:l.id,children:l.name},l.id))]}),te="Members of the team can see and run it. Shared apps are open to everyone.",_e=({open:r,teams:c,teamId:n,onTeamChange:m,onChooseFile:h,onClose:l})=>e.jsx(J,{open:r,onClose:l,title:"Upload app",footer:e.jsxs(e.Fragment,{children:[e.jsx(x,{variant:"secondary",onClick:l,children:"Cancel"}),e.jsxs(x,{variant:"primary",onClick:h,children:[e.jsx(ee,{size:14,className:"mr-1"}),"Choose file…"]})]}),children:e.jsx(Q,{label:"Team",htmlFor:"upload-app-team",description:te,children:e.jsx(ae,{id:"upload-app-team",value:n,teams:c,onChange:m})})}),Le=({app:r,teams:c,onMove:n,onClose:m})=>{const[h,l]=i.useState(""),[d,f]=i.useState(!1),[y,u]=i.useState(null);i.useEffect(()=>{l((r==null?void 0:r.teamId)??""),u(null)},[r]);const g=async()=>{f(!0),u(null);try{await n(h||null)}catch(v){u((v==null?void 0:v.message)||"Could not move the app")}finally{f(!1)}};return e.jsxs(J,{open:!!r,onClose:m,title:"Move to team",footer:e.jsxs(e.Fragment,{children:[e.jsx(x,{variant:"secondary",onClick:m,disabled:d,children:"Cancel"}),e.jsxs(x,{variant:"primary",onClick:g,disabled:d,children:[d?e.jsx(K,{size:14,className:"mr-1 animate-spin"}):e.jsx(se,{size:14,className:"mr-1"}),"Move"]})]}),children:[e.jsx("p",{className:"app-move-name",children:r==null?void 0:r.name}),e.jsx(Q,{label:"Team",htmlFor:"move-app-team",description:te,error:y??void 0,children:e.jsx(ae,{id:"move-app-team",value:h,teams:c,onChange:l,disabled:d})})]})},X=r=>{var c;return((c=r.team)==null?void 0:c.name)??(r.teamId?String(r.teamId).slice(0,8):"Shared")},ss=()=>{const{toast:r,removeToast:c}=ve(),[n,m]=i.useState([]),[h,l]=i.useState([]),[d,f]=i.useState(!1),[y,u]=i.useState(""),[g,v]=i.useState(!1),[re,R]=i.useState(null),[w,_]=i.useState({android:!0,ios:!0}),[S,ie]=i.useState("desc"),[C,z]=i.useState(null),[M,T]=i.useState(""),D=i.useRef(null),{me:j}=je(),N=(j==null?void 0:j.role)==="ADMIN"||(j==null?void 0:j.role)==="SUPER_ADMIN",[L,B]=i.useState([]),[ne,I]=i.useState(!1),[E,G]=i.useState(""),[F,$]=i.useState(null),b=i.useCallback(async()=>{f(!0);try{const s=await p.getApps();m(Array.isArray(s)?s:[])}catch(s){console.error("Failed to fetch apps",s)}finally{f(!1)}},[]),U=i.useCallback(async()=>{try{const s=await p.getDevices();l(Array.isArray(s)?s:[])}catch(s){console.error("Failed to fetch devices",s)}},[]);i.useEffect(()=>{b(),U();const s=setInterval(U,1e4);return()=>clearInterval(s)},[b,U]),i.useEffect(()=>{N&&p.listTeams().then(B).catch(()=>B([]))},[N]);const O=()=>{var s;N?(G(""),I(!0)):(s=D.current)==null||s.click()},le=async s=>{F&&(await p.setAppTeam(F.id,s),r(s?"App moved to team":"App shared with everyone","success"),$(null),await b())},ce=async s=>{var o;const a=(o=s.target.files)==null?void 0:o[0];if(!a)return;const t=N&&E?E:null;I(!1),v(!0);try{await p.uploadApp(a,t),await b()}catch(ue){console.error("Upload failed",ue)}finally{v(!1),s.target&&(s.target.value="")}},oe=async(s,a)=>{if(window.confirm(`Permanently remove artifact "${a}"?`))try{await p.deleteApp(s),m(t=>t.filter(o=>o.id!==s))}catch(t){console.error("Delete failed",t)}},de=(s,a)=>{navigator.clipboard.writeText(s),R(`${a}-${s}`),setTimeout(()=>R(null),2e3)},me=async(s,a)=>{const t=r(`Deploying app to ${a}...`,"loading",0);try{const o=await p.installRepositoryApp(a,s);o.success?(r("App deployed successfully","success"),z(null),T("")):r(`Deployment failed: ${o.error}`,"error")}catch(o){r(`Execution Error: ${o.message}`,"error")}finally{c(t)}},A=n.filter(s=>{const a=s.name.toLowerCase().includes(y.toLowerCase())||s.packageName&&s.packageName.toLowerCase().includes(y.toLowerCase()),t=w.android&&s.platform==="android"||w.ios&&s.platform==="ios";return a&&t}).sort((s,a)=>{const t=new Date(s.createdAt).getTime(),o=new Date(a.createdAt).getTime();return S==="desc"?o-t:t-o}),he=s=>{if(!s)return"0 B";const a=1024,t=Math.floor(Math.log(s)/Math.log(a));return parseFloat((s/Math.pow(a,t)).toFixed(1))+" "+["B","KB","MB","GB"][t]},pe=s=>Ne(s),P=s=>{_(a=>({...a,[s]:!a[s]}))},xe=s=>{const a=s.toLowerCase();return a.includes("wda-signed")||a.includes("wda-resign")||a.includes("webdriveragent")};return e.jsxs("div",{className:"apps-container device-explorer-container",children:[e.jsx("div",{className:"scanline",style:{position:"absolute",inset:0,pointerEvents:"none",opacity:.05,zIndex:1001}}),e.jsx(we,{icon:fe,title:"Apps",subtitle:"Signed builds available for installation across your device fleet."}),e.jsxs("div",{className:"device-explorer-header-container",children:[e.jsxs("div",{className:"device-explorer-header-left-container",children:[e.jsx("div",{className:"device-explorer-header-entry",children:e.jsxs("div",{className:"device-explorer-header-value",children:[e.jsxs("button",{className:`device-explorer-header__platform-btn ${w.android&&"selected"}`,onClick:()=>P("android"),children:[e.jsx(V,{size:18,color:"currentColor"})," Android"]}),e.jsxs("button",{className:`device-explorer-header__platform-btn ${w.ios&&"selected"}`,onClick:()=>P("ios"),children:[e.jsx(q,{size:18,color:"currentColor"})," iOS"]})]})}),e.jsx("div",{className:"device-explorer-header-entry",children:e.jsx("div",{className:"device-explorer-header-value",children:e.jsxs("div",{className:"device-explorer-search-wrapper",children:[e.jsx(ye,{size:16,color:"#94a3b8",className:"device-explorer-search-icon"}),e.jsx("input",{type:"text",className:"device-explorer-header-text-filter",placeholder:"Filter by bundle or name...",value:y,onChange:s=>u(s.target.value)})]})})}),e.jsx("div",{className:"device-explorer-header-filter-count",children:e.jsxs(Y,{variant:"secondary",children:[e.jsx("span",{className:"font-bold",children:A.length})," of"," ",e.jsx("span",{className:"font-bold",children:n.length})," ",n.length===1?"artifact":"artifacts"]})})]}),e.jsxs("div",{className:"device-explorer-header-right-container",children:[e.jsx("button",{className:"icon-btn-secondary sort-btn",onClick:()=>ie(s=>s==="desc"?"asc":"desc"),title:S==="desc"?"Newest First":"Oldest First",children:S==="desc"?e.jsx(Ie,{size:18}):e.jsx($e,{size:18})}),e.jsxs(x,{size:"sm",variant:"secondary",onClick:()=>b(),disabled:d,children:[e.jsx(K,{size:14,className:`mr-1 ${d&&"animate-spin"}`}),"Refresh"]}),e.jsx("input",{ref:D,type:"file",accept:".apk,.ipa",onChange:ce,hidden:!0}),e.jsxs(x,{size:"sm",variant:"primary",onClick:O,disabled:g,children:[e.jsx(ee,{size:14,className:"mr-1"}),"Upload app"]})]})]}),e.jsx("main",{className:"apps-registry-content",children:d&&n.length===0?e.jsxs("div",{className:"empty-data-vignette",children:[e.jsx("div",{className:"processing-loader"}),e.jsx("p",{className:"text-muted text-xs font-bold tracking-widest",children:"SYNCING REGISTRY..."})]}):e.jsxs(e.Fragment,{children:[A.length>0&&e.jsxs("div",{className:"registry-table-header",children:[e.jsx("div",{children:"Artifact bundle"}),e.jsx("div",{children:"Version"}),e.jsx("div",{children:"Size"}),e.jsx("div",{children:"Team"}),e.jsx("div",{children:"Registry date"}),e.jsx("div",{style:{textAlign:"right"},children:"Management"})]}),e.jsx("div",{className:"registry-list",children:A.map(s=>{const a=h.filter(t=>t.platform===s.platform&&!t.busy&&!t.offline);return e.jsxs("div",{className:`artifact-row ${s.platform}`,children:[e.jsxs("div",{className:"col-app-info",children:[e.jsx("div",{className:"app-platform-badge",children:s.platform==="android"?e.jsx(V,{size:18}):e.jsx(q,{size:18})}),e.jsxs("div",{className:"app-text-block",children:[e.jsxs("div",{className:"app-display-name",title:s.name,children:[s.name,xe(s.name)&&e.jsx(Y,{variant:"outline",className:"ml-2 text-[10px] h-4 py-0 border-primary text-primary",children:"WDA"})]}),e.jsxs("div",{className:"app-package-id",children:[e.jsx("code",{children:s.packageName||"internal.bundle"}),s.packageName&&e.jsx("div",{className:"copy-hint",title:`Copy ${s.packageName}`,onClick:()=>de(s.packageName,"pkg"),children:re===`pkg-${s.packageName}`?e.jsx(Ce,{size:10,className:"text-primary"}):e.jsx(Ae,{size:10})})]})]})]}),e.jsx("div",{className:"col-version",children:s.version||"v1.0.0"}),e.jsx("div",{className:"col-size",children:he(s.size)}),e.jsx("div",{className:"col-team",title:X(s),children:X(s)}),e.jsx("div",{className:"col-timestamp",children:pe(s.createdAt)}),e.jsxs("div",{className:"col-actions",children:[e.jsxs("div",{className:"deploy-anchor",children:[e.jsx("button",{className:`instant-deploy-trigger ${C===s.id&&"active"}`,onClick:()=>{C===s.id?(z(null),T("")):z(s.id)},children:C===s.id?e.jsxs(e.Fragment,{children:[e.jsx(ge,{size:12})," CANCEL"]}):e.jsxs(e.Fragment,{children:[e.jsx(Se,{size:12})," Deploy"]})}),C===s.id&&e.jsx("div",{className:"deployment-flyout",children:a.length>0?e.jsxs("div",{className:"deploy-actions-group",children:[e.jsxs(Z,{selectSize:"sm",className:"min-w-[280px]",autoFocus:!0,value:M,onChange:t=>T(t.target.value),children:[e.jsx("option",{value:"",children:"SELECT TARGET..."}),a.map(t=>e.jsxs("option",{value:t.udid,children:[t.name," (",t.udid,")"]},t.udid))]}),e.jsx("button",{className:"confirm-deploy-btn",disabled:!M,onClick:()=>me(s.id,M),title:"Confirm deployment",children:e.jsx(W,{size:14})})]}):e.jsx("div",{className:"target-device-select empty",children:"NO TARGETS"})})]}),e.jsx("button",{className:"utility-icon-btn",onClick:()=>window.open(`/xenon/api/apps/${s.id}/download`,"_blank"),children:e.jsx(ze,{size:14})}),N&&e.jsx("button",{className:"utility-icon-btn","aria-label":`Move ${s.name} to team`,title:"Move to team",onClick:()=>$(s),children:e.jsx(se,{size:14})}),e.jsx("button",{className:"utility-icon-btn danger",onClick:()=>oe(s.id,s.name),children:e.jsx(Me,{size:14})})]})]},s.id)})}),A.length===0&&n.length>0&&!d&&e.jsxs("div",{className:"empty-registry-technical",children:[e.jsx("div",{className:"empty-icon-container",children:e.jsx(H,{size:48,className:"text-primary opacity-40"})}),e.jsx("h2",{className:"empty-title brand-font",children:"No matching artifacts"}),e.jsxs("p",{className:"empty-description",children:[n.length," ",n.length===1?"artifact is":"artifacts are"," registered, but none match the current filter."]}),e.jsx("div",{className:"empty-actions",children:e.jsx(x,{size:"sm",variant:"default",onClick:()=>{u(""),_({android:!0,ios:!0})},children:"Clear filters"})})]}),n.length===0&&!d&&e.jsxs("div",{className:"empty-registry-technical",children:[e.jsx("div",{className:"empty-icon-container",children:e.jsx(H,{size:48,className:"text-primary opacity-40 animate-pulse"})}),e.jsx("h2",{className:"empty-title brand-font",children:"No apps yet"}),e.jsxs("p",{className:"empty-description",children:["Upload ",e.jsx("code",{className:"text-primary",children:".apk"})," or"," ",e.jsx("code",{className:"text-primary",children:".ipa"})," artifacts to enable versioned installs across your device fleet."]}),e.jsx("div",{className:"empty-actions",children:e.jsx("button",{type:"button",className:"upload-trigger-massive",onClick:O,disabled:g,children:e.jsxs("span",{className:"massive-upload-content",children:[e.jsx(W,{size:24,className:"mb-2"}),e.jsx("span",{children:"Upload your first app"})]})})})]})]})}),e.jsx(_e,{open:ne,teams:L,teamId:E,onTeamChange:G,onChooseFile:()=>{var s;return(s=D.current)==null?void 0:s.click()},onClose:()=>I(!1)}),e.jsx(Le,{app:F,teams:L,onMove:le,onClose:()=>$(null)}),g&&e.jsx("div",{className:"upload-overlay-technical",children:e.jsxs("div",{className:"upload-card-technical",children:[e.jsx("div",{className:"processing-loader"}),e.jsx("h2",{className:"brand-font",style:{fontSize:"20px",marginBottom:"8px"},children:"Artifact ingestion"}),e.jsx("p",{className:"text-muted text-xs",children:"VERIFYING CHECKSUM & DEPLOYING TO REGISTRY..."})]})})]})};export{ss as default};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{c as i,j as e,n,S as o}from"./index-
|
|
1
|
+
import{c as i,j as e,n,S as o}from"./index-C33GjwPr.js";import{N as l}from"./network-DpwYGB0-.js";/**
|
|
2
2
|
* @license lucide-react v0.555.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const d=[["path",{d:"M18 8V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h8",key:"10dyio"}],["path",{d:"M10 19v-3.96 3.15",key:"1irgej"}],["path",{d:"M7 19h5",key:"qswx4l"}],["rect",{width:"6",height:"10",x:"16",y:"12",rx:"2",key:"1egngj"}]],c=i("monitor-smartphone",d),x=[{icon:o,title:"Self-healing selectors",body:"Broken locators recover through six escalating tiers before a test fails."},{icon:c,title:"Live Android & iOS devices",body:"Watch, drive and record real devices from the browser."},{icon:l,title:"Hub–node scaling",body:"One hub orchestrates device labs across machines."}];function b({children:t}){return e.jsxs("div",{className:"grid min-h-screen w-full grid-cols-1 bg-[var(--bg)] text-[var(--text)] md:grid-cols-[minmax(0,5fr)_minmax(0,7fr)]",children:[e.jsxs("aside",{className:"relative hidden overflow-hidden border-r border-[rgb(var(--rgb-fg)/0.06)] bg-[var(--surface-sunken)] md:flex md:flex-col",children:[e.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_90%_60%_at_0%_0%,rgb(var(--rgb-accent)/0.14),transparent_60%)]"}),e.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 bg-[linear-gradient(to_right,rgb(var(--rgb-white)/0.03)_1px,transparent_1px),linear-gradient(to_bottom,rgb(var(--rgb-white)/0.03)_1px,transparent_1px)] bg-[size:48px_48px] [mask-image:linear-gradient(to_bottom,black,transparent_85%)]"}),e.jsxs("div",{className:"relative flex flex-1 flex-col justify-between px-12 py-10",children:[e.jsx(n,{className:"h-8 w-auto self-start object-contain"}),e.jsxs("div",{className:"max-w-md",children:[e.jsxs("h2",{className:"text-4xl font-semibold leading-tight tracking-tight",children:["Your device lab,",e.jsx("br",{}),e.jsx("span",{className:"text-[var(--color-accent)]",children:"under control."})]}),e.jsx("p",{className:"mt-4 text-sm leading-relaxed text-[var(--text-muted)]",children:"Appium orchestration for the devices you own — with self-healing tests, live streaming and recordable proof of what ran."}),e.jsx("ul",{className:"mt-10 space-y-6",children:x.map(({icon:a,title:r,body:s})=>e.jsxs("li",{className:"flex gap-4",children:[e.jsx("span",{className:"grid h-9 w-9 shrink-0 place-items-center rounded-lg border border-[var(--accent-border)] bg-[var(--accent-subtle)]",children:e.jsx(a,{className:"h-4 w-4 text-[var(--color-accent)]","aria-hidden":"true"})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-[var(--text)]",children:r}),e.jsx("div",{className:"mt-0.5 text-sm text-[var(--text-muted)]",children:s})]})]},r))})]}),e.jsxs("footer",{className:"flex items-center justify-between border-t border-[rgb(var(--rgb-fg)/0.06)] pt-5 text-xs text-[var(--text-muted)]",children:[e.jsxs("span",{children:["Xenon v","2.
|
|
6
|
+
*/const d=[["path",{d:"M18 8V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h8",key:"10dyio"}],["path",{d:"M10 19v-3.96 3.15",key:"1irgej"}],["path",{d:"M7 19h5",key:"qswx4l"}],["rect",{width:"6",height:"10",x:"16",y:"12",rx:"2",key:"1egngj"}]],c=i("monitor-smartphone",d),x=[{icon:o,title:"Self-healing selectors",body:"Broken locators recover through six escalating tiers before a test fails."},{icon:c,title:"Live Android & iOS devices",body:"Watch, drive and record real devices from the browser."},{icon:l,title:"Hub–node scaling",body:"One hub orchestrates device labs across machines."}];function b({children:t}){return e.jsxs("div",{className:"grid min-h-screen w-full grid-cols-1 bg-[var(--bg)] text-[var(--text)] md:grid-cols-[minmax(0,5fr)_minmax(0,7fr)]",children:[e.jsxs("aside",{className:"relative hidden overflow-hidden border-r border-[rgb(var(--rgb-fg)/0.06)] bg-[var(--surface-sunken)] md:flex md:flex-col",children:[e.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_90%_60%_at_0%_0%,rgb(var(--rgb-accent)/0.14),transparent_60%)]"}),e.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 bg-[linear-gradient(to_right,rgb(var(--rgb-white)/0.03)_1px,transparent_1px),linear-gradient(to_bottom,rgb(var(--rgb-white)/0.03)_1px,transparent_1px)] bg-[size:48px_48px] [mask-image:linear-gradient(to_bottom,black,transparent_85%)]"}),e.jsxs("div",{className:"relative flex flex-1 flex-col justify-between px-12 py-10",children:[e.jsx(n,{className:"h-8 w-auto self-start object-contain"}),e.jsxs("div",{className:"max-w-md",children:[e.jsxs("h2",{className:"text-4xl font-semibold leading-tight tracking-tight",children:["Your device lab,",e.jsx("br",{}),e.jsx("span",{className:"text-[var(--color-accent)]",children:"under control."})]}),e.jsx("p",{className:"mt-4 text-sm leading-relaxed text-[var(--text-muted)]",children:"Appium orchestration for the devices you own — with self-healing tests, live streaming and recordable proof of what ran."}),e.jsx("ul",{className:"mt-10 space-y-6",children:x.map(({icon:a,title:r,body:s})=>e.jsxs("li",{className:"flex gap-4",children:[e.jsx("span",{className:"grid h-9 w-9 shrink-0 place-items-center rounded-lg border border-[var(--accent-border)] bg-[var(--accent-subtle)]",children:e.jsx(a,{className:"h-4 w-4 text-[var(--color-accent)]","aria-hidden":"true"})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-[var(--text)]",children:r}),e.jsx("div",{className:"mt-0.5 text-sm text-[var(--text-muted)]",children:s})]})]},r))})]}),e.jsxs("footer",{className:"flex items-center justify-between border-t border-[rgb(var(--rgb-fg)/0.06)] pt-5 text-xs text-[var(--text-muted)]",children:[e.jsxs("span",{children:["Xenon v","2.11.0"," · Self-hosted device lab"]}),e.jsx("a",{href:"/xenon/api-docs",target:"_blank",rel:"noreferrer",className:"text-[var(--text-muted)] underline-offset-4 hover:text-[var(--text)] hover:underline",children:"API docs"})]})]})]}),e.jsx("main",{className:"flex items-center justify-center px-6 py-10",children:e.jsx("div",{className:"w-full max-w-[400px] rounded-xl border border-[var(--border)] bg-[var(--surface)] px-8 py-9 shadow-[var(--shadow-lg)]",children:t})})]})}export{b as A};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as ee,r as h,p as te,X,j as e,z as V,R as _,f as se,T as ae,q as re,u as ne,i as le,t as oe,M as ie}from"./index-
|
|
1
|
+
import{c as ee,r as h,p as te,X,j as e,z as V,R as _,f as se,T as ae,q as re,u as ne,i as le,t as oe,M as ie}from"./index-C33GjwPr.js";import{s as ce,b as L,P as de,T as B,i as xe,f as q,a as ue,c as me,d as pe,p as he,e as fe,r as ve,C as be,g as ge,h as je,j as A,k as Ne,l as W,S as we,m as ye,n as Se,u as Ce,o as $e}from"./use-builds-data-DaaqMjjL.js";import{I as J}from"./input-DwiVcO3Q.js";import{L as ke,a as Me}from"./list-checks-Bgn9GEEO.js";import{B as O}from"./button-CQoMQEj_.js";import{D as Ee}from"./download-WgW4AVid.js";import{s as Te}from"./labels-C21SA4JG.js";import{C as Re}from"./circle-x-cbPq6Btp.js";import{C as Be}from"./circle-check-Dfg-gpjg.js";import{C as Le}from"./chevron-right-ec0unu3u.js";import{T as Ie}from"./tablet-DM8dp75P.js";import{M as _e}from"./monitor-BZSwrnPV.js";import{S}from"./stat-tile-lT8WcPgu.js";import{P as De}from"./page-header-BpLEuo7i.js";import{S as Ae}from"./select-xiba9PSx.js";import{E as F}from"./EmptyState-wZeJbGhN.js";import"./time-D-gjmE1o.js";import"./utils-CDN07tui.js";/**
|
|
2
2
|
* @license lucide-react v0.555.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as x,j as z}from"./index-
|
|
1
|
+
import{r as x,j as z}from"./index-C33GjwPr.js";import{a as j,c as g}from"./utils-CDN07tui.js";const v=a=>typeof a=="boolean"?`${a}`:a===0?"0":a,b=j,k=(a,e)=>t=>{var l;if((e==null?void 0:e.variants)==null)return b(a,t==null?void 0:t.class,t==null?void 0:t.className);const{variants:d,defaultVariants:r}=e,y=Object.keys(d).map(n=>{const s=t==null?void 0:t[n],o=r==null?void 0:r[n];if(s===null)return null;const i=v(s)||v(o);return d[n][i]}),c=t&&Object.entries(t).reduce((n,s)=>{let[o,i]=s;return i===void 0||(n[o]=i),n},{}),f=e==null||(l=e.compoundVariants)===null||l===void 0?void 0:l.reduce((n,s)=>{let{class:o,className:i,...V}=s;return Object.entries(V).every(N=>{let[m,u]=N;return Array.isArray(u)?u.includes({...r,...c}[m]):{...r,...c}[m]===u})?[...n,o,i]:n},[]);return b(a,y,f,t==null?void 0:t.class,t==null?void 0:t.className)},C=k("btn-base",{variants:{variant:{default:"btn-primary",primary:"btn-primary",secondary:"btn-secondary",outline:"btn-secondary",ghost:"btn-ghost",tonal:"btn-tonal",link:"btn-link",destructive:"btn-danger",danger:"btn-danger"},size:{default:"btn-size-md",md:"btn-size-md",sm:"btn-size-sm",lg:"btn-size-lg",icon:"btn-size-icon"}},defaultVariants:{variant:"primary",size:"md"}}),O=x.forwardRef(({className:a,variant:e,size:t,...l},d)=>z.jsx("button",{className:g(C({variant:e,size:t,className:a})),ref:d,...l}));O.displayName="Button";export{O as B,k as c};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as U,j as e,r as c,C as Ms,U as Wn,X as M,t as Ve,v as sn,b as qn,u as mt,a as Mt,T as Kn,q as ns,R as Fe,w as Xn,x as _s,y as $e,z as hs,I as nn,S as Nt,f as ct,A as St,i as an,B as Gn,D as Yn,E as Zn,p as Jn}from"./index-
|
|
1
|
+
import{c as U,j as e,r as c,C as Ms,U as Wn,X as M,t as Ve,v as sn,b as qn,u as mt,a as Mt,T as Kn,q as ns,R as Fe,w as Xn,x as _s,y as $e,z as hs,I as nn,S as Nt,f as ct,A as St,i as an,B as Gn,D as Yn,E as Zn,p as Jn}from"./index-C33GjwPr.js";import{P as Qn}from"./page-header-BpLEuo7i.js";import{P as Ct,S as ea,B as ta}from"./BugReportButton-iC7fxPxl.js";import{A as sa}from"./activity-_5pNSfKT.js";import{h as na,M as rn,S as on,C as aa,a as zs,H as ia,b as Gt,A as ot,I as Yt}from"./keycodes-CvCtpVJD.js";import{p as _t}from"./labels-C21SA4JG.js";import{B as Y}from"./button-CQoMQEj_.js";import{S as ms}from"./select-xiba9PSx.js";import{P as cn,M as ln,a as pe,b as ra}from"./Menu-CahoAx8L.js";import{M as ps}from"./Modal-mcM5W_Ji.js";import{F as $t}from"./FieldGroup-tpRfmhlE.js";import{C as oa}from"./clock-DU9cBLi8.js";import{P as ca}from"./plus-DHZS0EGU.js";import{C as Te}from"./copy-VM9kWPpE.js";import{T as la}from"./tablet-DM8dp75P.js";import{S as da,a as Ls}from"./SegmentedControl-qMSiMN1d.js";import{T as ua,a as ha,b as dn,c as At,d as ma,e as Oe}from"./Table-J3uognu0.js";import{f as pa}from"./time-D-gjmE1o.js";import{L as un,a as fa}from"./list-checks-Bgn9GEEO.js";import{C as ya}from"./chevron-right-ec0unu3u.js";import{M as Os}from"./mouse-pointer-2-BbFj8y8i.js";import{Z as hn}from"./zap-qG2Li6rI.js";import{C as dt}from"./check-CAB6RYuc.js";import{C as mn}from"./circle-check-Dfg-gpjg.js";import{C as pn}from"./circle-x-cbPq6Btp.js";import{D as xa}from"./download-WgW4AVid.js";import{T as as}from"./trash-2-Dxgryn4o.js";import{U as va,T as ga}from"./upload-Ci0vz0BP.js";import{A as ba}from"./arrow-left-uY7F6z1K.js";import{A as ja}from"./arrow-right-BbAm_2Wa.js";import{L as Na}from"./lock-Cb7My6hc.js";import{F as Ps}from"./FilterMenu-BZwOppId.js";import"./utils-CDN07tui.js";import"./index-DNDdHt3h.js";/**
|
|
2
2
|
* @license lucide-react v0.555.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as t,j as e,e as m,g as b}from"./index-
|
|
1
|
+
import{r as t,j as e,e as m,g as b}from"./index-C33GjwPr.js";import{u as g}from"./use-password-reset-mode-BvIyZtaF.js";import{A as c}from"./auth-shell-CtMFhbnC.js";import"./network-DpwYGB0-.js";function N(){const[s,d]=t.useState(""),[a,o]=t.useState(!1),[u,x]=t.useState(!1),[n,l]=t.useState(null),i=g();async function f(r){r.preventDefault(),o(!0),l(null);try{await b(s),x(!0)}catch(h){l(h.message||"Request failed")}finally{o(!1)}}return i!=="email"?e.jsxs(c,{children:[e.jsx("h1",{className:"text-2xl font-semibold mb-1",children:"Forgot password?"}),i==="admin"&&e.jsx("p",{className:"text-sm text-[var(--text-muted)] mb-6",children:"This Xenon server can't send email, so passwords are reset by an administrator. Ask a Xenon admin to send you a reset link from the Users page."}),e.jsx("div",{className:"mt-6 text-center",children:e.jsx(m,{to:"/login",className:"text-sm text-[var(--color-accent)] underline-offset-4 hover:underline",children:"Back to sign in"})})]}):e.jsx(c,{children:e.jsxs("form",{onSubmit:f,children:[e.jsx("h1",{className:"text-2xl font-semibold mb-1",children:"Forgot password?"}),e.jsx("p",{className:"text-sm text-[var(--text-muted)] mb-6",children:"Enter your email and we'll send you a reset link if your account exists."}),u?e.jsx("div",{className:"text-sm text-[var(--text)] mb-6",children:"If your email is registered, you'll receive a reset link shortly. Check your spam folder if you don't see it within a minute."}):e.jsxs(e.Fragment,{children:[e.jsx("label",{htmlFor:"forgot-email",className:"block text-sm font-medium text-[var(--text)] mb-1.5",children:"Email"}),e.jsx("input",{id:"forgot-email",type:"email",autoComplete:"username",value:s,onChange:r=>d(r.target.value),autoFocus:!0,required:!0,className:"w-full mb-4 h-10 px-3 rounded-lg bg-[var(--bg)] border border-[var(--border-strong)] text-sm text-[var(--text)] outline-none focus:border-[var(--color-accent)] focus:shadow-[0_0_0_3px_var(--accent-subtle)]"}),n&&e.jsx("div",{role:"alert",className:"text-sm text-[var(--red)] mb-3",children:n}),e.jsx("button",{type:"submit",disabled:a||!s,className:"mt-5 w-full h-10 rounded-md bg-[var(--color-accent)] text-[var(--color-on-accent)] font-medium text-sm disabled:opacity-50",children:a?"Sending…":"Send reset link"})]}),e.jsx("div",{className:"mt-6 text-center",children:e.jsx(m,{to:"/login",className:"text-sm text-[var(--color-accent)] underline-offset-4 hover:underline",children:"Back to sign in"})})]})})}export{N as default};
|