@xenon-device-management/xenon 1.29.0 → 2.0.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/README.md +11 -2
- package/lib/package.json +1 -1
- package/lib/public/assets/{AnnotationOverlay-Ne9IA8t9.js → AnnotationOverlay-BmTPCAds.js} +1 -1
- package/lib/public/assets/{ApiKeyGate-CwXbDjtR.js → ApiKeyGate-B5eB7f8B.js} +1 -1
- package/lib/public/assets/{BugReportButton-D8694Ndn.js → BugReportButton-DKYsOdGV.js} +1 -1
- package/lib/public/assets/{DeviceMosaicView-vqKa_a7b.js → DeviceMosaicView-9DUoZnQi.js} +1 -1
- package/lib/public/assets/{EmptyState-DqbEejWx.js → EmptyState-lvyNiXev.js} +1 -1
- package/lib/public/assets/{FieldGroup-BNKuUsHt.js → FieldGroup-BduMPM9K.js} +1 -1
- package/lib/public/assets/{FilterMenu-CLqoSOsz.js → FilterMenu-BSqX6I94.js} +1 -1
- package/lib/public/assets/{Menu-CU57vgsd.js → Menu-Ba5cT7jZ.js} +1 -1
- package/lib/public/assets/{Modal-Dt2whV22.js → Modal-CceoMY7D.js} +1 -1
- package/lib/public/assets/{RecordingPage-BipS3IoG.js → RecordingPage-6T9dOidc.js} +1 -1
- package/lib/public/assets/{RecordingsPage-DORtXeH5.js → RecordingsPage-qj6FdZXR.js} +1 -1
- package/lib/public/assets/{SegmentedControl-IX6aSFFO.js → SegmentedControl-CSRuZ8TR.js} +1 -1
- package/lib/public/assets/{SettingCard-DDp2N5zA.js → SettingCard-Bp1kz4By.js} +1 -1
- package/lib/public/assets/{Table-CiaA4Dni.js → Table-LV7zFyZg.js} +1 -1
- package/lib/public/assets/{activity-DzhwJvJO.js → activity-D17TUloi.js} +1 -1
- package/lib/public/assets/{ai-settings-BllB4M52.js → ai-settings-qvbhY89P.js} +1 -1
- package/lib/public/assets/api-keys-BfpvdG7G.js +1 -0
- package/lib/public/assets/apps-DMhpZuKd.css +1 -0
- package/lib/public/assets/apps-Dbnzd0fW.js +26 -0
- package/lib/public/assets/{arrow-left-poHDsOnw.js → arrow-left-DD1VjtC7.js} +1 -1
- package/lib/public/assets/{arrow-right-Bt8ka8uH.js → arrow-right-D0pnM3ma.js} +1 -1
- package/lib/public/assets/{arrow-up-right-C7zjEfIX.js → arrow-up-right-BIC8JOV6.js} +1 -1
- package/lib/public/assets/{auth-shell-DqNP66nv.js → auth-shell-DWHPXSnI.js} +2 -2
- package/lib/public/assets/{builds-page-BmoSSMe1.js → builds-page-ClCNBUv_.js} +1 -1
- package/lib/public/assets/{button-DujkWRKD.js → button-xtAhYR-f.js} +1 -1
- package/lib/public/assets/{calendar-3xj_SfAt.js → calendar-CupwJ7Bm.js} +1 -1
- package/lib/public/assets/{check-DAtcemi7.js → check-CyuEoKkd.js} +1 -1
- package/lib/public/assets/{chevron-left-BODVavmZ.js → chevron-left-DgX-F9xK.js} +1 -1
- package/lib/public/assets/{chevron-right-BtzJa9CV.js → chevron-right-BKJgJnU9.js} +1 -1
- package/lib/public/assets/{circle-check-CNLy00dn.js → circle-check-CZdg8mMa.js} +1 -1
- package/lib/public/assets/{circle-x-DwlxOXJV.js → circle-x-CZH6t9z-.js} +1 -1
- package/lib/public/assets/{clock-CthJSgmT.js → clock-Cd-t7xpe.js} +1 -1
- package/lib/public/assets/{copy-o_vwnvDl.js → copy-C6zerX3I.js} +1 -1
- package/lib/public/assets/{device-explorer-BGwZQSit.js → device-explorer-B1pI6b_M.js} +2 -2
- package/lib/public/assets/device-explorer-DV8rWRxL.css +1 -0
- package/lib/public/assets/{download-CH7KYHQ6.js → download-x9WP7mcL.js} +1 -1
- package/lib/public/assets/{forgot-password-Fo0NoMuQ.js → forgot-password-B0TEH4N-.js} +1 -1
- package/lib/public/assets/{funnel-DLq7lVeF.js → funnel-Cb40MfFN.js} +1 -1
- package/lib/public/assets/{index-SVMaJ9rC.js → index-BR1wTIPC.js} +9 -9
- package/lib/public/assets/{index-tbOE1tW_.js → index-BvH_ekRy.js} +1 -1
- package/lib/public/assets/{index-Fa91L6sA.css → index-hymrhlEZ.css} +1 -1
- package/lib/public/assets/{input-Cn9aCi1V.js → input-DejcCiTI.js} +1 -1
- package/lib/public/assets/{keycodes-DVNcuy4F.js → keycodes-Mavx5iGg.js} +1 -1
- package/lib/public/assets/{layers-DFA4vIXT.js → layers-BKqYLiHE.js} +1 -1
- package/lib/public/assets/{lock-DbVuQMlE.js → lock-LFsFhc17.js} +1 -1
- package/lib/public/assets/{login-kvBEtLEI.js → login-x2pkzt-t.js} +1 -1
- package/lib/public/assets/{maintenance-settings-9MSQd7-h.js → maintenance-settings-CYafcoV-.js} +1 -1
- package/lib/public/assets/{monitor-C2wiQCzm.js → monitor-_7_uJ8d9.js} +1 -1
- package/lib/public/assets/{mouse-pointer-2-BxOt4PTR.js → mouse-pointer-2-BfLuURKN.js} +1 -1
- package/lib/public/assets/{network-VOsv-B1C.js → network-Z_zBhpsD.js} +1 -1
- package/lib/public/assets/{overview-BxRv07jX.js → overview-BY5uv08S.js} +1 -1
- package/lib/public/assets/{page-header-DRYmsZ55.js → page-header-CP2UkykG.js} +1 -1
- package/lib/public/assets/{plus-BY8JP9c5.js → plus-BTD0dnQ0.js} +1 -1
- package/lib/public/assets/{profile-page-C0IMKJRO.js → profile-page-BhJZuCS7.js} +1 -1
- package/lib/public/assets/{reset-password-2OxcQdve.js → reset-password-CMN0SO81.js} +1 -1
- package/lib/public/assets/{runbook-page-ChzDYLnk.js → runbook-page-CBpPX9_5.js} +1 -1
- package/lib/public/assets/{select-DkLtE2T3.js → select-Uc9E5pye.js} +1 -1
- package/lib/public/assets/{selector-detail-page-9XKCgLLk.js → selector-detail-page-BSyBnRuU.js} +1 -1
- package/lib/public/assets/{selector-health-CZb7lL82.js → selector-health-DzqxNkzm.js} +1 -1
- package/lib/public/assets/{selector-health-page-CgNkXERq.js → selector-health-page-CyPLjoD1.js} +1 -1
- package/lib/public/assets/{session-detail-page-V68omLzd.js → session-detail-page-BZQZN1P-.js} +1 -1
- package/lib/public/assets/{settings-BTO5_h8Z.js → settings-CkSWiZq8.js} +1 -1
- package/lib/public/assets/{status-pill-outline-DteJiQpj.js → status-pill-outline-BFYni2qo.js} +1 -1
- package/lib/public/assets/{tablet-BvW2cqBO.js → tablet-BSd-xSZK.js} +1 -1
- package/lib/public/assets/teams-PpoEQz31.js +1 -0
- package/lib/public/assets/{trash-2-Ck4Hj9AT.js → trash-2-BorJv5_u.js} +1 -1
- package/lib/public/assets/{upload-DOZwUk1H.js → upload-C3i7sAZl.js} +1 -1
- package/lib/public/assets/{use-password-reset-mode-BkBlX2qd.js → use-password-reset-mode-CeZQ3EsH.js} +1 -1
- package/lib/public/assets/{users-yoXht7X_.js → users-CEJ3fC78.js} +1 -1
- package/lib/public/assets/{users-CkggsUeX.js → users-Drd7ifJx.js} +1 -1
- package/lib/public/assets/{video-off-DZG2o_Gl.js → video-off-CNzn6bPE.js} +1 -1
- package/lib/public/assets/{webhook-settings-D31jQ3yC.js → webhook-settings-BFqX6QXV.js} +1 -1
- package/lib/public/assets/{zap-nAiJWOGv.js → zap-4yN8Jdfw.js} +1 -1
- package/lib/public/index.html +2 -2
- package/lib/schema.json +1 -1
- package/lib/src/XenonCapabilityManager.js +21 -50
- package/lib/src/app/index.js +14 -9
- package/lib/src/app/insertBeforeRoutes.js +57 -0
- package/lib/src/app/registerCommandAuth.js +67 -0
- package/lib/src/app/routers/apps.js +83 -5
- package/lib/src/app/routers/auth.js +1 -1
- package/lib/src/app/routers/bug-report.js +12 -0
- package/lib/src/app/routers/capabilities.js +4 -0
- package/lib/src/app/routers/control.js +6 -1
- package/lib/src/app/routers/dashboard.js +116 -66
- package/lib/src/app/routers/grid.js +38 -57
- package/lib/src/app/routers/recordings.js +3 -1
- package/lib/src/app/swagger-docs.js +7 -4
- package/lib/src/app/swagger.js +3 -0
- package/lib/src/dashboard/event-manager.js +18 -21
- package/lib/src/dashboard/services/app-service.js +24 -2
- package/lib/src/data-service/device-service.js +2 -1
- package/lib/src/data-service/queue-service.js +4 -3
- package/lib/src/device-utils.js +1 -1
- package/lib/src/generated/client/edge.js +5 -4
- package/lib/src/generated/client/index-browser.js +2 -1
- package/lib/src/generated/client/index.d.ts +413 -7
- package/lib/src/generated/client/index.js +5 -4
- package/lib/src/generated/client/package.json +1 -1
- package/lib/src/generated/client/schema.prisma +7 -0
- package/lib/src/generated/client/wasm.js +2 -1
- package/lib/src/interceptors/CommandInterceptor.js +5 -5
- package/lib/src/middleware/authMiddleware.js +44 -36
- package/lib/src/middleware/commandAuth.js +146 -0
- package/lib/src/middleware/commandCaller.js +142 -0
- package/lib/src/middleware/verifyCredential.js +124 -0
- package/lib/src/services/ServerManager.js +7 -0
- package/lib/src/services/SessionLifecycleService.js +143 -73
- package/lib/src/services/TeamService.js +6 -3
- package/lib/src/services/device-access/appVisibility.js +27 -0
- package/lib/src/services/device-access/queueVisibility.js +118 -0
- package/lib/src/services/device-access/sessionVisibility.js +65 -0
- package/lib/src/services/healing/HealingOrchestrator.js +11 -3
- package/lib/src/services/lease/LeaseService.js +13 -4
- package/lib/src/services/lease/buildCapabilityBag.js +4 -1
- package/lib/src/services/lease/leaseSessionCaps.js +13 -69
- package/lib/src/services/recording/annotation-render.js +33 -1
- package/lib/src/services/recording/recordingSummary.js +6 -5
- package/lib/src/services/recording/recordingTiming.js +19 -5
- package/lib/src/services/session/appCapability.js +50 -0
- package/lib/src/services/session/sessionCredentials.js +105 -0
- package/lib/src/services/session/xenonOptions.js +71 -0
- package/lib/src/services/sessionTokenGate.js +19 -9
- package/lib/src/services/token/AppDownloadTicketService.js +73 -0
- package/lib/src/services/token/StreamTicketService.js +7 -17
- package/lib/src/services/token/singleUseLedger.js +41 -0
- package/lib/src/sessions/XenonSession.js +2 -2
- package/lib/test/helpers/loopbackServer.js +48 -0
- package/lib/test/integration/sdk-leases-router.spec.js +1 -1
- package/lib/test/integration/team-visibility-apps.spec.js +181 -0
- package/lib/test/integration/team-visibility-recordings.spec.js +4 -0
- package/lib/test/integration/team-visibility-sessions.spec.js +274 -0
- package/lib/test/unit/AppDownloadTicketService.spec.js +101 -0
- package/lib/test/unit/CapabilitiesRouter.spec.js +10 -0
- package/lib/test/unit/SessionTokenGate.spec.js +7 -2
- package/lib/test/unit/TeamService.test.js +22 -0
- package/lib/test/unit/XenonCapabilityManager.spec.js +11 -1
- package/lib/test/unit/aggregate-hotspots-session-scope.spec.js +202 -0
- package/lib/test/unit/annotation-render.spec.js +90 -0
- package/lib/test/unit/apps-team-visibility.spec.js +305 -0
- package/lib/test/unit/authMiddleware.appTicket.spec.js +201 -0
- package/lib/test/unit/bug-report/route.spec.js +49 -2
- package/lib/test/unit/cliargs-admin-only.spec.js +182 -0
- package/lib/test/unit/command-auth-appium-server.spec.js +184 -0
- package/lib/test/unit/command-auth.spec.js +410 -0
- package/lib/test/unit/command-caller.spec.js +254 -0
- package/lib/test/unit/event-manager-regression-hook.spec.js +7 -1
- package/lib/test/unit/extract-access-key-token-pair.test.js +47 -4
- package/lib/test/unit/grid-admin-only.spec.js +55 -0
- package/lib/test/unit/healing-tier-gate.spec.js +24 -1
- package/lib/test/unit/insert-before-routes.spec.js +167 -0
- package/lib/test/unit/install-repository-app-team.spec.js +116 -0
- package/lib/test/unit/lease/LeaseService.spec.js +3 -1
- package/lib/test/unit/lease/allocate-lease-branch.spec.js +2 -2
- package/lib/test/unit/lease/buildCapabilityBag.spec.js +3 -2
- package/lib/test/unit/lease/lease-override.spec.js +1 -1
- package/lib/test/unit/lease/lease-session-ownership.spec.js +4 -4
- package/lib/test/unit/lease/lease-team-visibility.spec.js +1 -1
- package/lib/test/unit/lease/lease-token-log-filter.spec.js +1 -1
- package/lib/test/unit/lease/lease-token-oracle.spec.js +207 -0
- package/lib/test/unit/lease/session-lease-proof.spec.js +42 -26
- package/lib/test/unit/logcat-ws.spec.js +7 -4
- package/lib/test/unit/queue-requester.spec.js +211 -0
- package/lib/test/unit/queue-team-scope-routes.spec.js +209 -0
- package/lib/test/unit/queue-visibility.spec.js +179 -0
- package/lib/test/unit/recording-summary.spec.js +22 -0
- package/lib/test/unit/recording-timing.spec.js +27 -0
- package/lib/test/unit/recordings-library-routes.spec.js +25 -0
- package/lib/test/unit/session-app-resolution.spec.js +331 -0
- package/lib/test/unit/session-assets.spec.js +167 -0
- package/lib/test/unit/session-attribution-wiring.spec.js +134 -24
- package/lib/test/unit/session-credential-strip.spec.js +277 -0
- package/lib/test/unit/session-credentials.spec.js +149 -0
- package/lib/test/unit/session-identity.spec.js +2 -2
- package/lib/test/unit/session-visibility.spec.js +109 -0
- package/lib/test/unit/stored-session-capabilities.spec.js +54 -0
- package/lib/test/unit/verify-credential.spec.js +138 -0
- package/lib/test/unit/xenon-options.spec.js +95 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/prisma/migrations/20260928120000_app_team/migration.sql +26 -0
- package/prisma/schema.prisma +7 -0
- package/schema.json +1 -1
- package/lib/public/assets/api-keys-bjXg97iu.js +0 -1
- package/lib/public/assets/apps-CQEjt22I.js +0 -21
- package/lib/public/assets/apps-DJMD5JOy.css +0 -1
- package/lib/public/assets/device-explorer-DTH5oU54.css +0 -1
- package/lib/public/assets/teams-8Qo7HmUv.js +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as V,E as Y,r as l,j as n,Y as z,A as G,e as q}from"./index-
|
|
1
|
+
import{u as V,E as Y,r as l,j as n,Y as z,A as G,e as q}from"./index-BR1wTIPC.js";import{P as Q}from"./page-header-CP2UkykG.js";import{T as Z,a as J,b as T,c as h,d as X,e as m}from"./Table-LV7zFyZg.js";import{B as v}from"./button-xtAhYR-f.js";import{E as y}from"./EmptyState-lvyNiXev.js";import{I as ee}from"./input-DejcCiTI.js";import{F as f}from"./FilterMenu-BSqX6I94.js";import{l as A}from"./recordings-BWe1ydXm.js";import{f as ne,a as te}from"./recordings-n-GTW3aT.js";import"./utils-CDN07tui.js";import"./Menu-Ba5cT7jZ.js";import"./index-BvH_ekRy.js";import"./check-CyuEoKkd.js";import"./plus-BTD0dnQ0.js";const re={phone:"",by:"",when:"any",q:""},oe=["any","24h","7d","30d"],R=864e5,se={"24h":R,"7d":7*R,"30d":30*R},ae={any:"Any time","24h":"Last 24 hours","7d":"Last 7 days","30d":"Last 30 days"};function ce(t){const r=t.get("when");return{phone:t.get("phone")??"",by:t.get("by")??"",when:r&&oe.includes(r)?r:"any",q:t.get("q")??""}}function F(t){const r=new URLSearchParams;return t.phone&&r.set("phone",t.phone),t.by&&r.set("by",t.by),t.when!=="any"&&r.set("when",t.when),t.q.trim()&&r.set("q",t.q),r}function ie(t){return!!(t.phone||t.by||t.when!=="any"||t.q.trim())}function P(t,r){return{udid:t.phone||void 0,startedBy:t.by||void 0,since:t.when==="any"?void 0:new Date(r-se[t.when]).toISOString(),q:t.q.trim()||void 0}}const B=50,le=250;function de(t){const r=t.phones.map(g=>g.name);return{text:r.length>2?`${r.slice(0,2).join(", ")} +${r.length-2}`:r.join(", "),title:r.join(`
|
|
2
2
|
`)}}const ue=t=>t.status==="recording"?"/devices/live":`/recordings/${encodeURIComponent(t.groupId)}`;function Ne(){const t=V(),[r,g]=Y(),a=ce(r),x=F(a).toString(),[s,S]=l.useState(null),[I,D]=l.useState(null),[j,C]=l.useState([]),[N,w]=l.useState(null),[M,k]=l.useState(!1),[H,O]=l.useState(0),u=l.useRef(0),d=l.useRef(!0),p=e=>g(F(e),{replace:!0});l.useEffect(()=>{d.current=!0;const e=++u.current,c=window.setTimeout(()=>{A({...P(a,Date.now()),limit:B}).then(i=>{!d.current||e!==u.current||(S(i),C(i.recordings),w(null),D(x))}).catch(i=>{!d.current||e!==u.current||w(i instanceof Error?i.message:String(i))})},le);return()=>{window.clearTimeout(c),d.current=!1}},[x,H]);const b=I===x?(s==null?void 0:s.nextCursor)??null:null,_=async()=>{if(!b)return;const e=u.current;k(!0);try{const c=await A({...P(a,Date.now()),limit:B,cursor:b});if(!d.current||e!==u.current)return;S(c),C(i=>i.concat(c.recordings))}catch(c){if(!d.current||e!==u.current)return;w(c instanceof Error?c.message:String(c))}finally{d.current&&k(!1)}},o=s==null?void 0:s.facets,W=[{value:"",label:"Any phone",count:(o==null?void 0:o.when.any)??0},...((o==null?void 0:o.phones)??[]).map(e=>({value:e.udid,label:e.name,count:e.count}))],K=[{value:"",label:"Anyone",count:(o==null?void 0:o.when.any)??0},...((o==null?void 0:o.people)??[]).map(e=>({value:e.id,label:e.name,count:e.count})),...o&&o.unknownCount>0?[{value:"unknown",label:"Unknown",count:o.unknownCount}]:[]],U=["any","24h","7d","30d"].map(e=>({value:e,label:ae[e],count:(o==null?void 0:o.when[e])??0})),E=(s==null?void 0:s.total)??0;return n.jsxs("div",{className:"rec-page",children:[n.jsx(Q,{icon:z,title:"Recordings",subtitle:s?`${E} recording${E===1?"":"s"}`:void 0}),n.jsxs("div",{className:"rec-toolbar",children:[n.jsx(ee,{type:"text",className:"rec-search","aria-label":"Search recordings",placeholder:"Search phones and bookmarks",value:a.q,onChange:e=>p({...a,q:e.target.value})}),n.jsx(f,{name:"Phone",value:a.phone,anyValue:"",options:W,onChange:e=>p({...a,phone:e})}),n.jsx(f,{name:"Recorded by",value:a.by,anyValue:"",options:K,onChange:e=>p({...a,by:e})}),n.jsx(f,{name:"When",value:a.when,anyValue:"any",options:U,onChange:e=>p({...a,when:e})})]}),N?n.jsx(y,{title:"Couldn't load recordings",description:N,action:n.jsxs(v,{variant:"secondary",onClick:()=>O(e=>e+1),children:[n.jsx(G,{size:14,"aria-hidden":"true"}),"Retry"]})}):s?j.length===0?ie(a)?n.jsx(y,{title:"No recordings match",action:n.jsx(v,{variant:"secondary",onClick:()=>p(re),children:"Clear filters"})}):n.jsx(y,{title:"No recordings yet",description:"Record phones from Live devices.",action:n.jsx(q,{className:"rec-link",to:"/devices/live",children:"Open Live devices"})}):n.jsxs(n.Fragment,{children:[n.jsxs(Z,{className:"rec-table",children:[n.jsxs("caption",{className:"sr-only",children:["Recordings, ",j.length," shown"]}),n.jsx(J,{children:n.jsxs(T,{children:[n.jsx(h,{scope:"col",children:"When"}),n.jsx(h,{scope:"col",children:"Phones"}),n.jsx(h,{scope:"col",children:"Length"}),n.jsx(h,{scope:"col",children:"Recorded by"}),n.jsx(h,{scope:"col",children:"Bookmarks"}),n.jsx(h,{scope:"col",children:"Status"})]})}),n.jsx(X,{children:j.map(e=>{var L;const c=de(e),i=ue(e);return n.jsxs(T,{className:"rec-row",onClick:$=>{$.target.closest("a")||t(i)},children:[n.jsx(m,{children:n.jsx(q,{to:i,className:"rec-link",children:ne(e.startedAt)})}),n.jsx(m,{title:c.title,children:c.text}),n.jsx(m,{className:"rec-num",children:e.durationMs===null?"—":te(e.durationMs)}),n.jsx(m,{children:((L=e.startedBy)==null?void 0:L.name)??"Unknown"}),n.jsx(m,{className:"rec-num",children:e.bookmarkCount}),n.jsx(m,{children:e.status==="recording"?"Recording…":e.status==="failed"?"Failed":""})]},e.groupId)})})]}),b&&n.jsx("div",{className:"rec-more",children:n.jsx(v,{variant:"secondary",onClick:_,disabled:M,children:"Load more"})})]}):n.jsx(y,{title:"Loading recordings…"}),s&&n.jsxs("p",{className:"rec-footnote",children:["Recordings are kept for ",s.retention.days," days, up to the newest"," ",s.retention.maxCount,"."]})]})}export{Ne as default,de as phoneNames};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./index-
|
|
1
|
+
import{j as e}from"./index-BR1wTIPC.js";const s=({kind:n,size:a=6,className:l})=>e.jsx("span",{className:`status-dot status-dot-${n}${l?" "+l:""}`,style:{width:a,height:a},"aria-hidden":!0});function d({segments:n,value:a,onChange:l,size:o="md",label:i}){return e.jsx("div",{className:`seg seg-${o}`,role:"tablist","aria-label":i,children:n.map(t=>e.jsxs("button",{role:"tab","aria-selected":t.value===a,"aria-label":t.title&&typeof t.label=="string"?t.label:void 0,"aria-keyshortcuts":t.keyShortcuts,title:t.title,disabled:t.disabled,className:`seg-btn${t.value===a?" seg-btn-active":""}`,onClick:()=>{t.disabled||l(t.value)},type:"button",children:[t.tone&&e.jsx(s,{kind:t.tone}),e.jsx("span",{children:t.label}),typeof t.count=="number"&&e.jsx("span",{className:`seg-count${t.count===0?" seg-count-zero":""}`,children:t.count})]},t.value))})}export{s as S,d as a};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as n,j as s,A as h}from"./index-
|
|
1
|
+
import{c as n,j as s,A as h}from"./index-BR1wTIPC.js";import{B as r}from"./button-xtAhYR-f.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{j as t}from"./index-
|
|
1
|
+
import{j as t}from"./index-BR1wTIPC.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-BR1wTIPC.js";/* empty css */import{S,A as F}from"./SettingCard-Bp1kz4By.js";import{P as B}from"./page-header-CP2UkykG.js";import{L as T}from"./lock-LFsFhc17.js";import{C as b}from"./circle-check-CZdg8mMa.js";import{A as E}from"./activity-D17TUloi.js";import"./button-xtAhYR-f.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.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as le,r as a,j as e,A as $,V as g,y as oe}from"./index-BR1wTIPC.js";/* empty css */import{a as L}from"./time-B8FIgwPE.js";import{T as ce,a as de,b as z,c as l,d as me,e as o}from"./Table-LV7zFyZg.js";import{F as m}from"./FieldGroup-BduMPM9K.js";import{P as O}from"./page-header-CP2UkykG.js";import{M as B}from"./Modal-CceoMY7D.js";import{B as u}from"./button-xtAhYR-f.js";import{I as H}from"./input-DejcCiTI.js";import{S as M}from"./select-Uc9E5pye.js";import{P as v}from"./plus-BTD0dnQ0.js";import{T as pe}from"./trash-2-BorJv5_u.js";import{C as he}from"./check-CyuEoKkd.js";import{C as xe}from"./copy-C6zerX3I.js";import"./index-BvH_ekRy.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:"xenon: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)}.deployment-flyout{position:absolute;top:50%;padding:6px;right:180px;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)}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
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,v as ge}from"./index-BR1wTIPC.js";import{f as Ne}from"./time-B8FIgwPE.js";import{c as be,B as x}from"./button-xtAhYR-f.js";import{c as ke}from"./utils-CDN07tui.js";import{P as we}from"./page-header-CP2UkykG.js";import{S as Z}from"./select-Uc9E5pye.js";import{M as J}from"./Modal-CceoMY7D.js";import{F as Q}from"./FieldGroup-BduMPM9K.js";import{U as ee,T as H}from"./upload-C3i7sAZl.js";import{C as Ce}from"./check-CyuEoKkd.js";import{C as Ae}from"./copy-C6zerX3I.js";import{Z as Se}from"./zap-4yN8Jdfw.js";import{D as ze}from"./download-x9WP7mcL.js";import{T as Me}from"./trash-2-BorJv5_u.js";import"./index-BvH_ekRy.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 Te=[["path",{d:"M12 6.528V3a1 1 0 0 1 1-1h0",key:"11qiee"}],["path",{d:"M18.237 21A15 15 0 0 0 22 11a6 6 0 0 0-10-4.472A6 6 0 0 0 2 11a15.1 15.1 0 0 0 3.763 10 3 3 0 0 0 3.648.648 5.5 5.5 0 0 1 5.178 0A3 3 0 0 0 18.237 21",key:"110c12"}]],q=k("apple",Te);/**
|
|
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 De=[["path",{d:"m3 16 4 4 4-4",key:"1co6wj"}],["path",{d:"M7 20V4",key:"1yoxec"}],["path",{d:"M11 4h10",key:"1w87gc"}],["path",{d:"M11 8h7",key:"djye34"}],["path",{d:"M11 12h4",key:"q8tih4"}]],Ie=k("arrow-down-wide-narrow",De);/**
|
|
12
|
+
* @license lucide-react v0.555.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const Ee=[["path",{d:"m16 3 4 4-4 4",key:"1x1c3m"}],["path",{d:"M20 7H4",key:"zbl0bi"}],["path",{d:"m8 21-4-4 4-4",key:"h9nckh"}],["path",{d:"M4 17h16",key:"g4d7ey"}]],se=k("arrow-right-left",Ee);/**
|
|
17
|
+
* @license lucide-react v0.555.0 - ISC
|
|
18
|
+
*
|
|
19
|
+
* This source code is licensed under the ISC license.
|
|
20
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
21
|
+
*/const Fe=[["path",{d:"m3 8 4-4 4 4",key:"11wl7u"}],["path",{d:"M7 4v16",key:"1glfcx"}],["path",{d:"M11 12h4",key:"q8tih4"}],["path",{d:"M11 16h7",key:"uosisv"}],["path",{d:"M11 20h10",key:"jvxblo"}]],$e=k("arrow-up-narrow-wide",Fe);/**
|
|
22
|
+
* @license lucide-react v0.555.0 - ISC
|
|
23
|
+
*
|
|
24
|
+
* This source code is licensed under the ISC license.
|
|
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};
|
|
@@ -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-BR1wTIPC.js";import{N as l}from"./network-Z_zBhpsD.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","
|
|
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.0.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 z,j as e,z as R,R as y,T as H,q as X,r as v,u as q,i as Q,t as V,M as G,X as J}from"./index-
|
|
1
|
+
import{c as z,j as e,z as R,R as y,T as H,q as X,r as v,u as q,i as Q,t as V,M as G,X as J}from"./index-BR1wTIPC.js";import{f as E,s as $,b as T,a as A,d as K,p as W,o as Y,S as Z,h as ee,c as te,e as D,u as se}from"./status-pill-outline-BFYni2qo.js";import{A as ae}from"./activity-D17TUloi.js";import{C as re}from"./circle-x-CZH6t9z-.js";import{C as ne}from"./circle-check-CZdg8mMa.js";import{I as P}from"./input-DejcCiTI.js";import{S as le}from"./select-Uc9E5pye.js";import{C as oe}from"./clock-Cd-t7xpe.js";import{B as I}from"./button-xtAhYR-f.js";import{D as ie}from"./download-x9WP7mcL.js";import{s as ce}from"./labels-C21SA4JG.js";import{C as de}from"./chevron-right-BKJgJnU9.js";import{T as xe}from"./tablet-BSd-xSZK.js";import{M as ue}from"./monitor-_7_uJ8d9.js";import{P as me}from"./page-header-CP2UkykG.js";import"./time-B8FIgwPE.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-BR1wTIPC.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 P,j as e,r as c,C as Ms,U as Hn,X as M,t as Ve,v as sn,b as Wn,u as mt,a as Mt,T as qn,q as ns,R as Fe,w as Kn,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 Xn,D as Gn,E as Yn,p as Zn}from"./index-
|
|
1
|
+
import{c as P,j as e,r as c,C as Ms,U as Hn,X as M,t as Ve,v as sn,b as Wn,u as mt,a as Mt,T as qn,q as ns,R as Fe,w as Kn,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 Xn,D as Gn,E as Yn,p as Zn}from"./index-BR1wTIPC.js";import{P as Jn}from"./page-header-CP2UkykG.js";import{P as Ct,B as Qn}from"./BugReportButton-DKYsOdGV.js";import{A as ea}from"./activity-D17TUloi.js";import{p as _t}from"./labels-C21SA4JG.js";import{B as Y}from"./button-xtAhYR-f.js";import{S as ms}from"./select-Uc9E5pye.js";import{P as rn,M as on,a as pe,b as ta}from"./Menu-Ba5cT7jZ.js";import{M as ps}from"./Modal-CceoMY7D.js";import{F as $t}from"./FieldGroup-BduMPM9K.js";import{C as sa}from"./clock-Cd-t7xpe.js";import{P as na}from"./plus-BTD0dnQ0.js";import{C as Te}from"./copy-C6zerX3I.js";import{T as aa}from"./tablet-BSd-xSZK.js";import{S as ia,a as zs}from"./SegmentedControl-CSRuZ8TR.js";import{T as ra,a as oa,b as cn,c as At,d as ca,e as Oe}from"./Table-LV7zFyZg.js";import{f as la}from"./time-B8FIgwPE.js";import{L as ln}from"./layers-BKqYLiHE.js";import{C as da}from"./chevron-right-BKJgJnU9.js";import{M as Ls}from"./mouse-pointer-2-BfLuURKN.js";import{Z as dn}from"./zap-4yN8Jdfw.js";import{C as dt}from"./check-CyuEoKkd.js";import{C as un}from"./circle-check-CZdg8mMa.js";import{C as hn}from"./circle-x-CZH6t9z-.js";import{S as mn,C as ua,H as ha,a as Gt,A as ot,I as Yt}from"./keycodes-Mavx5iGg.js";import{D as ma}from"./download-x9WP7mcL.js";import{T as as}from"./trash-2-BorJv5_u.js";import{U as pa,T as fa}from"./upload-C3i7sAZl.js";import{A as ya}from"./arrow-left-DD1VjtC7.js";import{A as xa}from"./arrow-right-D0pnM3ma.js";import{C as Os}from"./chevron-left-DgX-F9xK.js";import{L as va}from"./lock-LFsFhc17.js";import{F as Ps}from"./FilterMenu-BSqX6I94.js";import"./utils-CDN07tui.js";import"./index-BvH_ekRy.js";/**
|
|
2
2
|
* @license lucide-react v0.555.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -215,7 +215,7 @@ import{c as P,j as e,r as c,C as Ms,U as Hn,X as M,t as Ve,v as sn,b as Wn,u as
|
|
|
215
215
|
* See the LICENSE file in the root directory of this source tree.
|
|
216
216
|
*/const Ui=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]],Bi=P("wifi",Ui);function Vi(t){return t>=50?"ready":t>=20?"warning":"error"}function Hi(t){return t>=50?e.jsx(Ca,{size:10}):t>=20?e.jsx(Na,{size:10}):e.jsx(wa,{size:10})}function Wi(t){return t==="Normal"?"ready":t==="Critical"?"error":"warning"}const qi=({device:t})=>{if(t.deviceType==="emulator"||t.deviceType==="simulator"||t.offline)return null;const n=typeof t.batteryLevel=="number",a=typeof t.thermalStatus=="string"&&t.thermalStatus.length>0&&t.thermalStatus!=="Unknown";return!n&&!a?e.jsx("div",{className:"dc2-health",children:e.jsxs(Ct,{tone:"neutral",title:"Device does not report battery or thermal data",children:[e.jsx(ea,{size:10}),"No telemetry"]})}):e.jsxs("div",{className:"dc2-health",children:[n&&e.jsxs(Ct,{tone:Vi(t.batteryLevel),title:`Battery ${t.batteryLevel}%`,children:[Hi(t.batteryLevel),t.batteryLevel,"%"]}),a&&e.jsxs(Ct,{tone:Wi(t.thermalStatus),title:`Thermal: ${t.thermalStatus}`,children:[e.jsx(Ei,{size:10}),t.thermalStatus]})]})};function Ki(t){if(typeof t!="number")throw new TypeError("Expected a number");const s=t>0?Math.floor:Math.ceil;return{days:s(t/864e5),hours:s(t/36e5)%24,minutes:s(t/6e4)%60,seconds:s(t/1e3)%60,milliseconds:s(t)%1e3,microseconds:s(t*1e3)%1e3,nanoseconds:s(t*1e6)%1e3}}const Xi=(t,s)=>s===1?t:`${t}s`,Gi=1e-7;function fn(t,s={}){if(!Number.isFinite(t))throw new TypeError("Expected a finite number");s.colonNotation&&(s.compact=!1,s.formatSubMilliseconds=!1,s.separateMilliseconds=!1,s.verbose=!1),s.compact&&(s.secondsDecimalDigits=0,s.millisecondsDecimalDigits=0);const n=[],a=(l,u)=>{const d=Math.floor(l*10**u+Gi);return(Math.round(d)/10**u).toFixed(u)},o=(l,u,d,i)=>{if((n.length===0||!s.colonNotation)&&l===0&&!(s.colonNotation&&d==="m"))return;i=(i||l||"0").toString();let m,x;if(s.colonNotation){m=n.length>0?":":"",x="";const k=i.includes(".")?i.split(".")[0].length:i.length,f=n.length>0?2:1;i="0".repeat(Math.max(0,f-k))+i}else m="",x=s.verbose?" "+Xi(u,l):d;n.push(m+i+x)},r=Ki(t);if(o(Math.trunc(r.days/365),"year","y"),o(r.days%365,"day","d"),o(r.hours,"hour","h"),o(r.minutes,"minute","m"),s.separateMilliseconds||s.formatSubMilliseconds||!s.colonNotation&&t<1e3)if(o(r.seconds,"second","s"),s.formatSubMilliseconds)o(r.milliseconds,"millisecond","ms"),o(r.microseconds,"microsecond","µs"),o(r.nanoseconds,"nanosecond","ns");else{const l=r.milliseconds+r.microseconds/1e3+r.nanoseconds/1e6,u=typeof s.millisecondsDecimalDigits=="number"?s.millisecondsDecimalDigits:0,d=l>=1?Math.round(l):Math.ceil(l),i=u?l.toFixed(u):d;o(Number.parseFloat(i),"millisecond","ms",i)}else{const l=t/1e3%60,u=typeof s.secondsDecimalDigits=="number"?s.secondsDecimalDigits:1,d=a(l,u),i=s.keepDecimalsOnWholeSeconds?d:d.replace(/\.0+$/,"");o(Number.parseFloat(i),"second","s",i)}if(n.length===0)return"0"+(s.verbose?" milliseconds":"ms");if(s.compact)return n[0];if(typeof s.unitCount=="number"){const l=s.colonNotation?"":" ";return n.slice(0,Math.max(s.unitCount,1)).join(l)}return s.colonNotation?n.join(""):n.join(" ")}const Jt=6e4;function Yi(t){return!Number.isFinite(t)||t<=0?"expiring":t<Jt?"under 1m":fn(Math.floor(t/Jt)*Jt,{unitCount:2})}const is=["ready","busy","reserved","maintenance","offline"],yn={ready:"Ready",busy:"Busy",reserved:"Reserved",maintenance:"Maintenance",offline:"Offline"};function ut(t,s){return t.offline?"offline":t.userBlocked?"maintenance":t.busy?"busy":t.reservedUntil&&s<t.reservedUntil?"reserved":"ready"}function xn(t,s){if(!t.busy||!t.session_id)return null;const n=String(t.session_id);return n.startsWith("manual_")?s!=null&&s.userId&&n===`manual_${s.userId}_${t.udid}`?"self":"other":"session"}const Bs=t=>(t==null?void 0:t.role)==="ADMIN"||(t==null?void 0:t.role)==="SUPER_ADMIN";function Zi(t,s,n){switch(xn(t,s)){case"session":return t.sessionStartTime&&t.sessionStartTime>0&&n>t.sessionStartTime?`Test session · ${fn(n-t.sessionStartTime,{compact:!0})}`:"Test session running";case"self":return"Live control by you";case"other":return"Live control by another user"}if(t.reservedUntil&&n<t.reservedUntil){const o=!!t.reservedBy&&(t.reservedBy===(s==null?void 0:s.email)||t.reservedBy===(s==null?void 0:s.name))?"you":t.reservedBy||"another user";return`${Yi(t.reservedUntil-n)} left · by ${o}`}return null}function Ji(t,s){if(t.offline)return{enabled:!1,reason:"Device is offline"};if(t.userBlocked&&!Bs(s))return{enabled:!1,reason:"In maintenance"};const n=xn(t,s);return n==="session"?{enabled:!1,reason:"A test is running"}:n==="other"&&!Bs(s)?{enabled:!1,reason:"Another user has control"}:{enabled:!0}}function Me(t){var s;return((s=t.marketingName)==null?void 0:s.trim())||t.name}function vn(t){const s=[_t(t.platform),t.sdk].filter(Boolean).join(" ");if(t.deviceType==="emulator")return`Emulator · ${s}`;if(t.deviceType==="simulator")return`Simulator · ${s}`;const a=[t.manufacturer?t.manufacturer.charAt(0).toUpperCase()+t.manufacturer.slice(1):"",t.model].filter(Boolean).join(" ");return a?`${a} · ${s}`:s}function Qi(t){return t.formFactor==="tablet"||t.formFactor==="tv"?t.formFactor:"phone"}function Qe(t,s){return t.teamId?(s==null?void 0:s.get(t.teamId))??t.teamName??`Team ${t.teamId.slice(0,6)}`:null}const er=[{label:"1 Hour",value:"1h"},{label:"2 Hours",value:"2h"},{label:"4 Hours",value:"4h"},{label:"8 Hours",value:"8h"}],tr=({device:t,onClose:s,onReserved:n})=>{const[a,o]=c.useState(""),[r,l]=c.useState("1h"),[u,d]=c.useState(""),[i,m]=c.useState(!1),[x,k]=c.useState(null),[f,y]=c.useState(null),S=async()=>{if(!a.trim()){k("Please enter your name/ID");return}m(!0),k(null),y(null);try{const C=await M.reserveDevice(t.udid,t.host,a,r,u);C.success?(n(),s()):y(C.error||"Failed to reserve device")}catch(C){y(C.message||"An unexpected error occurred")}finally{m(!1)}};return e.jsx(ps,{open:!0,onClose:s,width:520,title:e.jsxs(e.Fragment,{children:[e.jsx(Aa,{size:16,className:"title-icon"}),"Reserve device"]}),footer:e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"btn-cancel",onClick:s,disabled:i,children:"Cancel"}),e.jsx("button",{className:"btn-reserve",onClick:S,disabled:i||!a.trim(),children:i?"Reserving...":"Confirm Reservation"})]}),children:e.jsxs("div",{className:"reservation-modal-body",children:[e.jsxs("div",{className:"device-id-badge",children:[e.jsx("span",{className:"label",children:"Device:"}),e.jsx("span",{className:"value",children:t.udid})]}),e.jsxs("p",{children:["Reserve ",e.jsx("strong",{children:t.name||t.udid})," for exclusive use. This will prevent CI sessions from using this device."]}),e.jsx($t,{label:e.jsxs(e.Fragment,{children:[e.jsx(Hn,{size:14,style:{marginRight:6,verticalAlign:"middle",color:"var(--color-accent)"}}),"Reserved by"]}),htmlFor:"reservation-reserved-by",error:x?e.jsxs(e.Fragment,{children:[e.jsx(Ms,{size:14,style:{marginRight:6,verticalAlign:"middle"}}),x]}):void 0,children:e.jsx("input",{id:"reservation-reserved-by",type:"text",className:"reservation-input",placeholder:"Enter your name or ID",value:a,onChange:C=>{o(C.target.value),x&&k(null)},disabled:i})}),e.jsx($t,{label:e.jsxs(e.Fragment,{children:[e.jsx(sa,{size:14,style:{marginRight:6,verticalAlign:"middle",color:"var(--color-accent)"}}),"Duration"]}),children:e.jsx("div",{className:"duration-selector",children:er.map(C=>e.jsx("div",{className:`duration-option ${r===C.value?"active":""}`,onClick:()=>l(C.value),children:C.label},C.value))})}),e.jsx($t,{label:e.jsxs(e.Fragment,{children:[e.jsx(ii,{size:14,style:{marginRight:6,verticalAlign:"middle",color:"var(--color-accent)"}}),"Reason (optional)"]}),htmlFor:"reservation-reason",error:f?e.jsxs(e.Fragment,{children:[e.jsx(Ms,{size:14,style:{marginRight:6,verticalAlign:"middle"}}),f]}):void 0,children:e.jsx("input",{id:"reservation-reason",type:"text",className:"reservation-input",placeholder:"e.g., Debugging flaky login test",value:u,onChange:C=>d(C.target.value),disabled:i})})]})})},sr=({device:t,onClose:s,onUpdated:n})=>{const{toast:a}=Ve(),[o,r]=c.useState(t.tags||[]),[l,u]=c.useState(""),[d,i]=c.useState(!1),m=c.useRef(null);c.useEffect(()=>{m.current&&m.current.focus()},[]);const x=()=>{const S=l.trim();S&&!o.includes(S)&&(r([...o,S]),u(""))},k=S=>{r(o.filter(C=>C!==S))},f=S=>{S.key==="Enter"&&x()},y=async()=>{i(!0);try{await M.updateDeviceTags(t.udid,t.host,o),n(),s()}catch(S){console.error("Failed to update tags",S),a("Error saving tags. Please try again.","error")}finally{i(!1)}};return e.jsx(ps,{open:!0,onClose:s,width:520,title:e.jsxs(e.Fragment,{children:[e.jsx(wi,{size:16,className:"title-icon"}),"Manage device tags"]}),footer:e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"btn-cancel",onClick:s,children:"Cancel"}),e.jsx("button",{className:"btn-save",onClick:y,disabled:d,children:d?"Saving...":"Apply Changes"})]}),children:e.jsxs("div",{className:"tag-modal-body",children:[e.jsxs("div",{className:"device-id-badge",children:[e.jsx("span",{className:"label",children:"Device:"}),e.jsx("span",{className:"value",children:t.udid})]}),e.jsx($t,{label:"Add new tag",description:"Press Enter to add multiple tags",htmlFor:"tag-input",children:e.jsxs("div",{className:"input-with-button",children:[e.jsx("input",{ref:m,id:"tag-input",type:"text",placeholder:"e.g. stable, team-a, ios-17",value:l,onChange:S=>u(S.target.value),onKeyDown:f}),e.jsx("button",{className:"add-inline-btn",onClick:x,disabled:!l.trim(),children:e.jsx(na,{size:16})})]})}),e.jsxs("div",{className:"tags-display-section",children:[e.jsx("label",{children:"Current Tags"}),e.jsx("div",{className:"tags-list",children:o.length>0?o.map(S=>e.jsxs("div",{className:"tag-pill-editable",children:[S,e.jsx("button",{className:"remove-tag",onClick:()=>k(S),children:e.jsx(sn,{size:12})})]},S)):e.jsx("div",{className:"empty-tags",children:"No tags assigned to this device."})})]})]})})},nr="/wd/hub";function ar(t){return t==="android"?"UiAutomator2":"XCUITest"}function ir(t){return t==="android"?"Android":t==="tvos"?"tvOS":"iOS"}function rr(t,s=nr){if(!t)return"—";try{const n=new URL(t.includes("://")?t:`http://${t}`),a=s.startsWith("/")?s:`/${s}`,o=n.pathname.replace(/\/$/,"");return o===a||o.endsWith(a)?`${n.protocol}//${n.host}${o}`:`${n.protocol}//${n.host}${a}`}catch{return t}}function or(t){const s={platformName:ir(t.platform),"appium:automationName":ar(t.platform),"appium:udid":t.udid};return t.sdk&&t.sdk!=="Unknown"&&t.sdk!=="unknown"&&(s["appium:platformVersion"]=t.sdk),t.name&&(s["appium:deviceName"]=t.name),s}function cr(t){return JSON.stringify(or(t),null,2)}const lr=/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/i,dr=/^(?:\d{1,3}\.){3}\d{1,3}$/;function ur(t){const s=t.trim();return!s||lr.test(s)||!dr.test(s)?!1:s.split(".").every(n=>{const a=Number(n);return Number.isInteger(a)&&a>=0&&a<=255})}function hr(t){return t.ip&&ur(t.ip)?t.ip.trim():null}const gn=({udid:t,currentTeamId:s,teams:n,onDone:a})=>{const{toast:o}=Ve(),[r,l]=c.useState(!1);async function u(d){l(!0);try{await M.setDeviceTeam(t,d),o(d?"Device assigned":"Device returned to shared pool","success"),a(!0)}catch(i){o((i==null?void 0:i.message)||"Failed to update team","error")}finally{l(!1)}}return e.jsxs(ms,{selectSize:"sm",autoFocus:!0,"aria-label":"Team",disabled:r,defaultValue:s??"",onBlur:()=>a(!1),onChange:d=>u(d.target.value||null),children:[e.jsx("option",{value:"",children:"(Shared pool)"}),Array.from(n.entries()).map(([d,i])=>e.jsx("option",{value:d,children:i},d))]})};function bn(t,s){const[n,a]=c.useState(!1),[o,r]=c.useState(!1),[l,u]=c.useState(!1),{me:d}=Wn(),{toast:i}=Ve(),m=(d==null?void 0:d.role)==="ADMIN"||(d==null?void 0:d.role)==="SUPER_ADMIN",x=Date.now(),k=ut(t,x),f=k==="reserved",y=Zi(t,d,x),S=Ji(t,d),C=rr(t.host),L=hr(t),w=async(O,W)=>{var V;try{await((V=navigator.clipboard)==null?void 0:V.writeText(O)),i(W,"success")}catch{i("Failed to copy","error")}},j=async()=>{await M.releaseReservation(t.udid,t.host),s()},$=async()=>{await M.blockDevice(t.udid,t.host),s()},p=async()=>{await M.unblockDevice(t.udid,t.host),s()},D=async()=>{t.userBlocked?await p():await $()},A=e.jsxs(e.Fragment,{children:[n&&e.jsx(tr,{device:t,onClose:()=>a(!1),onReserved:()=>s()}),o&&e.jsx(sr,{device:t,onClose:()=>r(!1),onUpdated:()=>s()})]});return{kind:k,reserved:f,activity:y,control:S,isAdmin:m,editingTeam:l,setEditingTeam:u,openReservation:()=>a(!0),openTagManager:()=>r(!0),release:j,toggleMaintenance:D,copy:w,serverUrl:C,ip:L,dialogs:A}}const jn=({device:t,actions:s,navigate:n,reasonId:a})=>{const{kind:o,reserved:r,control:l}=s;return e.jsxs(e.Fragment,{children:[e.jsx(Y,{variant:"tonal",size:"sm",disabled:!l.enabled,"aria-describedby":l.enabled?void 0:a,onClick:()=>{l.enabled&&n(`/devices/${t.udid}/control`)},children:"Control"}),r?e.jsx(Y,{variant:"secondary",size:"sm",onClick:s.release,children:"Release"}):o==="ready"?e.jsx(Y,{variant:"secondary",size:"sm",onClick:s.openReservation,children:"Reserve"}):null]})},Nn=({device:t,actions:s})=>{const[n,a]=c.useState(!1),o=c.useRef(null),{isAdmin:r,serverUrl:l,ip:u,copy:d}=s;return e.jsxs(e.Fragment,{children:[e.jsx("button",{ref:o,type:"button",className:"dc2-more",onClick:()=>a(i=>!i),"aria-label":"More actions",children:e.jsx(Va,{size:14})}),e.jsx(rn,{open:n,onClose:()=>a(!1),anchorRef:o,children:e.jsxs(on,{children:[e.jsx(pe,{icon:e.jsx(Te,{size:12}),onClick:()=>{a(!1),d(t.udid,"UDID copied")},children:"Copy UDID"}),l!=="—"&&e.jsx(pe,{icon:e.jsx(Te,{size:12}),onClick:()=>{a(!1),d(l,"Server URL copied")},children:"Copy server URL"}),u&&e.jsx(pe,{icon:e.jsx(Te,{size:12}),onClick:()=>{a(!1),d(u,"IP address copied")},children:"Copy IP address"}),e.jsx(pe,{icon:e.jsx(Te,{size:12}),onClick:()=>{a(!1),d(cr(t),"Session capabilities copied")},children:"Copy capabilities"}),r&&e.jsxs(e.Fragment,{children:[e.jsx(ta,{}),e.jsx(pe,{onClick:()=>{a(!1),s.openTagManager()},children:"Manage tags…"}),e.jsx(pe,{onClick:()=>{a(!1),s.setEditingTeam(!0)},children:"Assign team…"}),e.jsx(pe,{onClick:()=>{a(!1),s.toggleMaintenance()},children:t.userBlocked?"Exit maintenance":"Enter maintenance"})]})]})})]})},mr=({device:t})=>{const s={phone:ns,tablet:aa,tv:qn}[Qi(t)],n=t.deviceType==="emulator"||t.deviceType==="simulator";return e.jsx(s,{size:26,strokeWidth:1.5,strokeDasharray:n?"3 2":void 0})},pr=({device:t,reloadDevices:s,navigate:n,teams:a})=>{var x,k,f;const o=bn(t,s),{kind:r,activity:l,control:u}=o,d=`dc2-reason-${t.udid}`,i=Me(t),m=Qe(t,a);return e.jsxs("div",{className:`dc2 dc2-${r}`,children:[e.jsxs("div",{className:`dc2-band dc2-band-${r}`,children:[e.jsxs("span",{className:"dc2-band-label",children:[e.jsx("span",{className:"dc2-band-dot","aria-hidden":!0}),yn[r]]}),l&&e.jsx("span",{className:"dc2-band-activity",title:l,children:l})]}),e.jsxs("div",{className:`dc2-body${r==="offline"?" dc2-dim":""}`,children:[e.jsxs("div",{className:"dc2-head",children:[e.jsx("div",{className:"dc2-icon","aria-hidden":!0,children:e.jsx(mr,{device:t})}),e.jsxs("div",{className:"dc2-id",children:[e.jsx("div",{className:"dc2-title",title:`${i}
|
|
217
217
|
${t.udid}`,children:i}),e.jsx("div",{className:"dc2-subtitle",children:vn(t)})]})]}),e.jsxs("div",{className:"dc2-meta",children:[e.jsx(qi,{device:t}),o.editingTeam?e.jsx(gn,{udid:t.udid,currentTeamId:t.teamId??null,teams:a??new Map,onDone:y=>{o.setEditingTeam(!1),y&&s()}}):m&&e.jsx(Ct,{tone:"accent",title:`Team: ${m}`,children:m}),(x=t.tags)==null?void 0:x.slice(0,2).map(y=>e.jsxs("span",{className:"dc2-tag",title:y,children:["#",y]},y)),(((k=t.tags)==null?void 0:k.length)||0)>2&&e.jsxs("span",{className:"dc2-tag",children:["+",(((f=t.tags)==null?void 0:f.length)||0)-2]})]})]}),e.jsxs("div",{className:"dc2-foot",children:[e.jsx(jn,{device:t,actions:o,navigate:n,reasonId:d}),!u.enabled&&e.jsx("span",{id:d,className:"dc2-unavailable",title:u.reason,children:u.reason}),e.jsx("span",{className:"dc2-spacer"}),e.jsx(Nn,{device:t,actions:o})]}),o.dialogs]})};function fr(t){const s=mt(),{search:n}=Mt();return e.jsx(pr,{device:t.device,reloadDevices:t.reloadDevices,navigate:a=>s(`${a}${n}`),teams:t.teams})}class yr extends Fe.Component{constructor(){super(...arguments),this.state={teamsMap:new Map}}componentDidMount(){M.listTeams().then(s=>{this.setState({teamsMap:new Map(s.map(n=>[n.id,n.name]))})}).catch(()=>{})}render(){return e.jsx("div",{className:"device-explorer-card-container",children:Fe.Children.toArray(this.props.devices.map(s=>e.jsx(fr,{device:s,reloadDevices:this.props.reloadDevices,teams:this.state.teamsMap})))})}}const xr={status:"all",platform:"all",type:"all",q:""},kn=["all",...is],wn=["all","android","ios","tvos"],Sn=["all","real","virtual"];function Qt(t,s){return s.includes(t)?t:s[0]}function vr(t){const s=t.get("q")??"";return{status:Qt(t.get("status"),kn),platform:Qt(t.get("platform"),wn),type:Qt(t.get("type"),Sn),q:s.trim()?s:""}}function gr(t){const s=new URLSearchParams;return t.status!=="all"&&s.set("status",t.status),t.platform!=="all"&&s.set("platform",t.platform),t.type!=="all"&&s.set("type",t.type),t.q.trim()&&s.set("q",t.q),s}function ht(t){return t.deviceType==="simulator"||t.deviceType==="emulator"?!0:!t.deviceType&&t.realDevice===!1}function xs(t){const s=(t.platform||"").toLowerCase();return s==="android"||s==="ios"||s==="tvos"?s:null}function br(t){const s=t.deviceType==="emulator"?"Emulator":t.deviceType==="simulator"?"Simulator":"";return[Me(t),t.name,t.manufacturer,t.model,_t(t.platform),t.sdk,s,t.teamName,t.udid].filter(Boolean).join(" ").toLowerCase()}function Tt(t,s,n,a){if(a!=="status"&&s.status!=="all"&&ut(t,n)!==s.status||a!=="platform"&&s.platform!=="all"&&xs(t)!==s.platform||a!=="type"&&s.type!=="all"&&s.type==="virtual"!==ht(t))return!1;const o=s.q.toLowerCase().split(/\s+/).filter(Boolean);if(o.length===0)return!0;const r=br(t);return o.every(l=>r.includes(l))}const es=t=>Object.fromEntries(t.map(s=>[s,0]));function jr(t,s,n){const a=es(kn),o=es(wn),r=es(Sn);for(const l of t){if(Tt(l,s,n,"status")&&(a.all+=1,a[ut(l,n)]+=1),Tt(l,s,n,"platform")){o.all+=1;const u=xs(l);u&&(o[u]+=1)}Tt(l,s,n,"type")&&(r.all+=1,r[ht(l)?"virtual":"real"]+=1)}return{status:a,platform:o,type:r}}function Nr(t){return t.some(s=>xs(s)==="tvos")}function kr(t){return t.status!=="all"||t.platform!=="all"||t.type!=="all"||t.q.trim()!==""}function wr(t,s){const n=a=>a===1?"device":"devices";return t===s?`${s} ${n(s)}`:`${t} of ${s} ${n(s)}`}const rs={key:"status",dir:"asc"},Sr=["status","device","platform","type","team","host"],Cr=new Intl.Collator(void 0,{sensitivity:"base",numeric:!0}),Pe=(t,s)=>Cr.compare(t,s);function $r(t,s,n,a){switch(n){case"status":return is.indexOf(ut(t,a.now))-is.indexOf(ut(s,a.now));case"device":return Pe(Me(t),Me(s));case"platform":return Pe(t.platform||"",s.platform||"")||Pe(t.sdk||"",s.sdk||"");case"type":return Number(ht(t))-Number(ht(s));case"team":return Pe(Qe(t,a.teams)??"",Qe(s,a.teams)??"");case"host":return Pe(t.host||"",s.host||"")}}function Tr(t,s,n){const a=s.dir==="desc"?-1:1;return t.slice().sort((o,r)=>{if(s.key==="team"){const l=Qe(o,n.teams)===null,u=Qe(r,n.teams)===null;if(l!==u)return l?1:-1}return a*$r(o,r,s.key,n)||Pe(Me(o),Me(r))||Pe(o.udid,r.udid)})}function Rr(t){const s=t.get("sort");return!s||!Sr.includes(s)?rs:{key:s,dir:t.get("dir")==="desc"?"desc":"asc"}}function Ar(t,s){t.delete("sort"),t.delete("dir"),!(s.key===rs.key&&s.dir===rs.dir)&&(t.set("sort",s.key),s.dir==="desc"&&t.set("dir","desc"))}const Je=({sortKey:t,label:s,sort:n,onSortChange:a})=>{const o=n.key===t,r=o?n.dir:"asc";return e.jsx(At,{scope:"col","aria-sort":o?r==="asc"?"ascending":"descending":"none",children:e.jsxs("button",{type:"button",className:"devtable-sort",onClick:()=>a(o?{key:t,dir:r==="asc"?"desc":"asc"}:{key:t,dir:"asc"}),children:[s,o&&(r==="asc"?e.jsx(ys,{size:12,"aria-hidden":"true"}):e.jsx(fs,{size:12,"aria-hidden":"true"}))]})})},Er=({device:t,reloadDevices:s,navigate:n,teams:a,showHost:o})=>{const r=bn(t,s),{kind:l,activity:u,control:d}=r,i=Me(t),m=vn(t),x=Qe(t,a),k=`${_t(t.platform)} ${t.sdk??""}`,f=t.tags??[],y=`devtable-reason-${t.udid}`;return e.jsxs(cn,{className:`devtable-row${l==="offline"?" is-offline":""}`,children:[e.jsxs(Oe,{children:[e.jsxs("div",{className:"devtable-line",children:[e.jsx(ia,{kind:l,className:"devtable-status-dot"})," ",yn[l]]}),u&&e.jsx("div",{className:"devtable-muted devtable-line",title:u,children:u})]}),e.jsxs(At,{scope:"row",className:"devtable-rowheader",title:`${i}
|
|
218
|
-
${t.udid}`,children:[e.jsx("div",{className:"devtable-title devtable-line",children:i}),e.jsx("div",{className:"devtable-muted devtable-line",title:m,children:m})]}),e.jsx(Oe,{title:k,children:k}),e.jsx(Oe,{children:ht(t)?"Virtual":"Real"}),e.jsx(Oe,{title:r.editingTeam?void 0:x??"Shared",children:r.editingTeam?e.jsx(gn,{udid:t.udid,currentTeamId:t.teamId??null,teams:a,onDone:S=>{r.setEditingTeam(!1),S&&s()}}):x??"Shared"}),e.jsxs(Oe,{title:f.join(", "),children:[f.slice(0,2).map(S=>e.jsxs("span",{className:"devtable-tag",children:["#",S]},S)),f.length>2&&e.jsxs("span",{className:"devtable-tag",children:["+",f.length-2]})]}),o&&e.jsx(Oe,{title:t.host,children:t.host}),e.jsx(Oe,{className:"devtable-actions",title:d.enabled?void 0:d.reason,children:e.jsxs("div",{className:"devtable-actions-inner",children:[e.jsx(jn,{device:t,actions:r,navigate:n,reasonId:y}),!d.enabled&&e.jsx("span",{id:y,className:"sr-only",children:d.reason}),e.jsx(Nn,{device:t,actions:r})]})}),r.dialogs]})};function Dr({devices:t,reloadDevices:s,sort:n,onSortChange:a,navigate:o,teams:r}){const l=new Set(t.map(d=>d.host)).size>1,u=Tr(t,n,{now:Date.now(),teams:r});return e.jsxs(ra,{className:"devtable",children:[e.jsxs("caption",{className:"sr-only",children:["Devices, ",t.length," shown"]}),e.jsxs("colgroup",{children:[e.jsx("col",{className:"devtable-col-status"}),e.jsx("col",{}),e.jsx("col",{className:"devtable-col-platform"}),e.jsx("col",{className:"devtable-col-type"}),e.jsx("col",{className:"devtable-col-team"}),e.jsx("col",{className:"devtable-col-tags"}),l&&e.jsx("col",{className:"devtable-col-host"}),e.jsx("col",{className:"devtable-col-actions"})]}),e.jsx(oa,{children:e.jsxs(cn,{children:[e.jsx(Je,{sortKey:"status",label:"Status",sort:n,onSortChange:a}),e.jsx(Je,{sortKey:"device",label:"Device",sort:n,onSortChange:a}),e.jsx(Je,{sortKey:"platform",label:"Platform",sort:n,onSortChange:a}),e.jsx(Je,{sortKey:"type",label:"Type",sort:n,onSortChange:a}),e.jsx(Je,{sortKey:"team",label:"Team",sort:n,onSortChange:a}),e.jsx(At,{scope:"col",children:"Tags"}),l&&e.jsx(Je,{sortKey:"host",label:"Host",sort:n,onSortChange:a}),e.jsx(At,{scope:"col",children:"Actions"})]})}),e.jsx(ca,{children:u.map(d=>e.jsx(Er,{device:d,reloadDevices:s,navigate:o,teams:r,showHost:l},d.udid))})]})}function Ir(t){const s=mt(),{search:n}=Mt(),[a,o]=c.useState(new Map);return c.useEffect(()=>{M.listTeams().then(r=>o(new Map(r.map(l=>[l.id,l.name])))).catch(()=>{})},[]),e.jsx(Dr,{devices:t.devices,reloadDevices:t.reloadDevices,sort:t.sort,onSortChange:t.onSortChange,navigate:r=>s(`${r}${n}`),teams:a})}var kt,Mr=new Uint8Array(16);function _r(){if(!kt&&(kt=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||typeof msCrypto<"u"&&typeof msCrypto.getRandomValues=="function"&&msCrypto.getRandomValues.bind(msCrypto),!kt))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return kt(Mr)}const zr=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function Lr(t){return typeof t=="string"&&zr.test(t)}var re=[];for(var ts=0;ts<256;++ts)re.push((ts+256).toString(16).substr(1));function Or(t){var s=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,n=(re[t[s+0]]+re[t[s+1]]+re[t[s+2]]+re[t[s+3]]+"-"+re[t[s+4]]+re[t[s+5]]+"-"+re[t[s+6]]+re[t[s+7]]+"-"+re[t[s+8]]+re[t[s+9]]+"-"+re[t[s+10]]+re[t[s+11]]+re[t[s+12]]+re[t[s+13]]+re[t[s+14]]+re[t[s+15]]).toLowerCase();if(!Lr(n))throw TypeError("Stringified UUID is invalid");return n}function Pr(t,s,n){t=t||{};var a=t.random||(t.rng||_r)();return a[6]=a[6]&15|64,a[8]=a[8]&63|128,Or(a)}const Fr=({onCommand:t,prompt:s="$",welcomeMessage:n="Interactive Shell (Restricted Mode)",platform:a})=>{const[o,r]=c.useState([{type:"system",content:n,timestamp:Date.now()},{type:"system",content:'Type "help" for allowed commands.',timestamp:Date.now()}]),[l,u]=c.useState(""),[d,i]=c.useState([]),[m,x]=c.useState(-1),[k,f]=c.useState(!1),y=c.useRef(null),S=c.useRef(null);c.useEffect(()=>{y.current&&(y.current.scrollTop=y.current.scrollHeight)},[o]);const C=w=>{const j=w.trim();if((j.startsWith("{")||j.startsWith("["))&&(j.endsWith("}")||j.endsWith("]")))try{const $=JSON.parse(j);return JSON.stringify($,null,2)}catch{}return w},L=async w=>{if(w.key==="Enter"&&!k){const j=l.trim();if(!j)return;if(u(""),r($=>[...$,{type:"command",content:`${s} ${j}`,timestamp:Date.now()}]),i($=>[...$,j]),x(-1),f(!0),j==="clear"){r([]),f(!1);return}if(j==="help"){let $="";a==="android"?$=`
|
|
218
|
+
${t.udid}`,children:[e.jsx("div",{className:"devtable-title devtable-line",children:i}),e.jsx("div",{className:"devtable-muted devtable-line",title:m,children:m})]}),e.jsx(Oe,{title:k,children:k}),e.jsx(Oe,{children:ht(t)?"Virtual":"Real"}),e.jsx(Oe,{title:r.editingTeam?void 0:x??"Shared",children:r.editingTeam?e.jsx(gn,{udid:t.udid,currentTeamId:t.teamId??null,teams:a,onDone:S=>{r.setEditingTeam(!1),S&&s()}}):x??"Shared"}),e.jsxs(Oe,{title:f.join(", "),children:[f.slice(0,2).map(S=>e.jsxs("span",{className:"devtable-tag",children:["#",S]},S)),f.length>2&&e.jsxs("span",{className:"devtable-tag",children:["+",f.length-2]})]}),o&&e.jsx(Oe,{title:t.host,children:t.host}),e.jsx(Oe,{className:"devtable-actions",title:d.enabled?void 0:d.reason,children:e.jsxs("div",{className:"devtable-actions-inner",children:[e.jsx(jn,{device:t,actions:r,navigate:n,reasonId:y}),!d.enabled&&e.jsx("span",{id:y,className:"sr-only",children:d.reason}),e.jsx(Nn,{device:t,actions:r})]})}),r.dialogs]})};function Dr({devices:t,reloadDevices:s,sort:n,onSortChange:a,navigate:o,teams:r}){const l=new Set(t.map(d=>d.host)).size>1||n.key==="host",u=Tr(t,n,{now:Date.now(),teams:r});return e.jsxs(ra,{className:"devtable",children:[e.jsxs("caption",{className:"sr-only",children:["Devices, ",t.length," shown"]}),e.jsxs("colgroup",{children:[e.jsx("col",{className:"devtable-col-status"}),e.jsx("col",{}),e.jsx("col",{className:"devtable-col-platform"}),e.jsx("col",{className:"devtable-col-type"}),e.jsx("col",{className:"devtable-col-team"}),e.jsx("col",{className:"devtable-col-tags"}),l&&e.jsx("col",{className:"devtable-col-host"}),e.jsx("col",{className:"devtable-col-actions"})]}),e.jsx(oa,{children:e.jsxs(cn,{children:[e.jsx(Je,{sortKey:"status",label:"Status",sort:n,onSortChange:a}),e.jsx(Je,{sortKey:"device",label:"Device",sort:n,onSortChange:a}),e.jsx(Je,{sortKey:"platform",label:"Platform",sort:n,onSortChange:a}),e.jsx(Je,{sortKey:"type",label:"Type",sort:n,onSortChange:a}),e.jsx(Je,{sortKey:"team",label:"Team",sort:n,onSortChange:a}),e.jsx(At,{scope:"col",children:"Tags"}),l&&e.jsx(Je,{sortKey:"host",label:"Host",sort:n,onSortChange:a}),e.jsx(At,{scope:"col",children:"Actions"})]})}),e.jsx(ca,{children:u.map(d=>e.jsx(Er,{device:d,reloadDevices:s,navigate:o,teams:r,showHost:l},d.udid))})]})}function Ir(t){const s=mt(),{search:n}=Mt(),[a,o]=c.useState(new Map);return c.useEffect(()=>{M.listTeams().then(r=>o(new Map(r.map(l=>[l.id,l.name])))).catch(()=>{})},[]),e.jsx(Dr,{devices:t.devices,reloadDevices:t.reloadDevices,sort:t.sort,onSortChange:t.onSortChange,navigate:r=>s(`${r}${n}`),teams:a})}var kt,Mr=new Uint8Array(16);function _r(){if(!kt&&(kt=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||typeof msCrypto<"u"&&typeof msCrypto.getRandomValues=="function"&&msCrypto.getRandomValues.bind(msCrypto),!kt))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return kt(Mr)}const zr=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function Lr(t){return typeof t=="string"&&zr.test(t)}var re=[];for(var ts=0;ts<256;++ts)re.push((ts+256).toString(16).substr(1));function Or(t){var s=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,n=(re[t[s+0]]+re[t[s+1]]+re[t[s+2]]+re[t[s+3]]+"-"+re[t[s+4]]+re[t[s+5]]+"-"+re[t[s+6]]+re[t[s+7]]+"-"+re[t[s+8]]+re[t[s+9]]+"-"+re[t[s+10]]+re[t[s+11]]+re[t[s+12]]+re[t[s+13]]+re[t[s+14]]+re[t[s+15]]).toLowerCase();if(!Lr(n))throw TypeError("Stringified UUID is invalid");return n}function Pr(t,s,n){t=t||{};var a=t.random||(t.rng||_r)();return a[6]=a[6]&15|64,a[8]=a[8]&63|128,Or(a)}const Fr=({onCommand:t,prompt:s="$",welcomeMessage:n="Interactive Shell (Restricted Mode)",platform:a})=>{const[o,r]=c.useState([{type:"system",content:n,timestamp:Date.now()},{type:"system",content:'Type "help" for allowed commands.',timestamp:Date.now()}]),[l,u]=c.useState(""),[d,i]=c.useState([]),[m,x]=c.useState(-1),[k,f]=c.useState(!1),y=c.useRef(null),S=c.useRef(null);c.useEffect(()=>{y.current&&(y.current.scrollTop=y.current.scrollHeight)},[o]);const C=w=>{const j=w.trim();if((j.startsWith("{")||j.startsWith("["))&&(j.endsWith("}")||j.endsWith("]")))try{const $=JSON.parse(j);return JSON.stringify($,null,2)}catch{}return w},L=async w=>{if(w.key==="Enter"&&!k){const j=l.trim();if(!j)return;if(u(""),r($=>[...$,{type:"command",content:`${s} ${j}`,timestamp:Date.now()}]),i($=>[...$,j]),x(-1),f(!0),j==="clear"){r([]),f(!1);return}if(j==="help"){let $="";a==="android"?$=`
|
|
219
219
|
Android Allowed Commands:
|
|
220
220
|
• System Info: getprop, ip addr, date, uptime, cat /proc/meminfo, cat /proc/cpuinfo
|
|
221
221
|
• Process Mgmt: ps, top
|