@xenon-device-management/xenon 2.12.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/package.json +2 -2
- package/lib/public/assets/{AnnotationOverlay-Crkn72_3.js → AnnotationOverlay-CzbFYtPI.js} +1 -1
- package/lib/public/assets/{ApiKeyGate-BThVlj_j.js → ApiKeyGate-CA5KFHHJ.js} +1 -1
- package/lib/public/assets/{BugReportButton-Dwa0GnBh.js → BugReportButton-D-DSGg8C.js} +1 -1
- package/lib/public/assets/{DeviceMosaicView-Ccc-pOls.js → DeviceMosaicView-paDEFU4B.js} +1 -1
- package/lib/public/assets/{EmptyState-BeuTrlN_.js → EmptyState-BE_5f8Vw.js} +1 -1
- package/lib/public/assets/{FieldGroup-DBIaNxl1.js → FieldGroup-DqMf7Rf3.js} +1 -1
- package/lib/public/assets/{FilterMenu-BgSAS6iT.js → FilterMenu-BQY75Su3.js} +1 -1
- package/lib/public/assets/{Menu-GCbP6gYN.js → Menu-BiW3os9u.js} +1 -1
- package/lib/public/assets/{Modal-ByESeBRC.js → Modal-DfawTxih.js} +1 -1
- package/lib/public/assets/{RecordingPage-Bwyf3WMl.js → RecordingPage-BvemyRiy.js} +1 -1
- package/lib/public/assets/{RecordingsPage-7kM1rB3i.js → RecordingsPage-CXfw7wpd.js} +1 -1
- package/lib/public/assets/{SegmentedControl-B8tTU8kD.js → SegmentedControl-B7m9kpom.js} +1 -1
- package/lib/public/assets/{SettingCard-Clg_Ijbc.js → SettingCard-Cw6lDD0l.js} +1 -1
- package/lib/public/assets/{Table-CIaR0QWV.js → Table-DlEuFgv-.js} +1 -1
- package/lib/public/assets/{activity-Bengh9SD.js → activity-CnLvNwae.js} +1 -1
- package/lib/public/assets/{ai-settings-G9SymiPH.js → ai-settings-D7Te8o-a.js} +1 -1
- package/lib/public/assets/{api-keys-CrGlbfn-.js → api-keys-DphSVzBr.js} +1 -1
- package/lib/public/assets/{apps-DIbcGVlU.js → apps-vUfu15lX.js} +1 -1
- package/lib/public/assets/{arrow-left-BtJIXXMY.js → arrow-left-CLQWAiCY.js} +1 -1
- package/lib/public/assets/{arrow-right-zm-NagQh.js → arrow-right-K6A5e_Ee.js} +1 -1
- package/lib/public/assets/{arrow-up-right-DdU8YEYp.js → arrow-up-right-DUA_lq6f.js} +1 -1
- package/lib/public/assets/{auth-shell-CHmBFmOz.js → auth-shell-BYRHcZd6.js} +2 -2
- package/lib/public/assets/{builds-page-JkzWKRpU.js → builds-page-C0fTvIG8.js} +1 -1
- package/lib/public/assets/{button-CqhPBGRj.js → button-BxnHCCsX.js} +1 -1
- package/lib/public/assets/{calendar-C7eYYJTo.js → calendar-CqVsn28A.js} +1 -1
- package/lib/public/assets/{check-DpbIM4E0.js → check-R6V3bot0.js} +1 -1
- package/lib/public/assets/{chevron-right-Dl4X1PRz.js → chevron-right-BA2Fntu-.js} +1 -1
- package/lib/public/assets/{circle-check-Du3sjbfV.js → circle-check-D4EzyGzs.js} +1 -1
- package/lib/public/assets/{circle-x-BSSqhpXi.js → circle-x-Cf6AF2B2.js} +1 -1
- package/lib/public/assets/{clock-DMT60v1C.js → clock-EZfet0sS.js} +1 -1
- package/lib/public/assets/{copy-BKNyOehd.js → copy-Bc6P8v9V.js} +1 -1
- package/lib/public/assets/{device-explorer-CoPR8DW3.js → device-explorer-BFXpRq6d.js} +1 -1
- package/lib/public/assets/{download-BM6Xn22t.js → download-Bd8OGLzi.js} +1 -1
- package/lib/public/assets/{forgot-password-B8WqMqBT.js → forgot-password-CoE7Ugtx.js} +1 -1
- package/lib/public/assets/{index-DauQh6ie.js → index-BiL0Enl_.js} +1 -1
- package/lib/public/assets/{index-ClrpAMAT.js → index-CHOr4JCs.js} +2 -2
- package/lib/public/assets/{input-CyKdLnEx.js → input-CJ8z3IO5.js} +1 -1
- package/lib/public/assets/{line-chart-EIBXwYGo.js → line-chart-CPK0ObjV.js} +1 -1
- package/lib/public/assets/{list-checks-fWsgD9bI.js → list-checks-mXGHUVbB.js} +1 -1
- package/lib/public/assets/{lock-CVCe56TH.js → lock-BSXM1xvq.js} +1 -1
- package/lib/public/assets/{login-BJ8a7yVD.js → login-Ct2iW066.js} +1 -1
- package/lib/public/assets/{maintenance-settings-DcRmTLS6.js → maintenance-settings-DaOs00P6.js} +1 -1
- package/lib/public/assets/{monitor-Bw1YQZnL.js → monitor-D8WQK8md.js} +1 -1
- package/lib/public/assets/{mouse-pointer-2-C01jbqkO.js → mouse-pointer-2-Cw2tWzDX.js} +1 -1
- package/lib/public/assets/{network-CBGUjJDJ.js → network-Ba_uFxWo.js} +1 -1
- package/lib/public/assets/{overview-Cxe8aQ7C.js → overview-CxrZ7_6k.js} +1 -1
- package/lib/public/assets/{page-header-B92DKLiq.js → page-header-Cm1XL49f.js} +1 -1
- package/lib/public/assets/{play-Ck0L-0_m.js → play-C0CuKLXj.js} +1 -1
- package/lib/public/assets/{plus-Dq3tCy2N.js → plus-CIIvR_6Z.js} +1 -1
- package/lib/public/assets/{profile-page--dkDiKbr.js → profile-page-BZ_e-Bgw.js} +1 -1
- package/lib/public/assets/{recording-group-store-5BYIFFN9.js → recording-group-store-BWeeNs2_.js} +1 -1
- package/lib/public/assets/{reset-password-KYWlfjia.js → reset-password-lfNz8Rm1.js} +1 -1
- package/lib/public/assets/{runbook-page-mnsxgS1d.js → runbook-page-Cnec3VSx.js} +1 -1
- package/lib/public/assets/{select-BBOIZTYm.js → select-CZuCnold.js} +1 -1
- package/lib/public/assets/{selector-detail-redirect-CcI2j_Su.js → selector-detail-redirect-BG3pxFLw.js} +1 -1
- package/lib/public/assets/{selector-health-page-BdJb_x5L.js → selector-health-page-DsyL58tb.js} +1 -1
- package/lib/public/assets/{session-detail-page-BjLaJy8z.js → session-detail-page-ZZyGM413.js} +1 -1
- package/lib/public/assets/{settings-B6cpMhsx.js → settings-DGZ7B_AR.js} +1 -1
- package/lib/public/assets/{stat-tile-BU9e4s36.js → stat-tile-DFhv8JoI.js} +1 -1
- package/lib/public/assets/{tablet-hgbEwrWq.js → tablet-68J5f6zh.js} +1 -1
- package/lib/public/assets/{teams-uiiG4hZM.js → teams-eHSyEpbD.js} +1 -1
- package/lib/public/assets/{trash-2-NK_Iazmg.js → trash-2-CcSsv4fS.js} +1 -1
- package/lib/public/assets/{upload-BUX8TNFi.js → upload-BYf26K71.js} +1 -1
- package/lib/public/assets/{use-builds-data-DZszmFyl.js → use-builds-data-CHW-MhaP.js} +1 -1
- package/lib/public/assets/{use-password-reset-mode-BK4B9kRC.js → use-password-reset-mode-DozShXkk.js} +1 -1
- package/lib/public/assets/{users-BU4XBbMT.js → users-BpYnpOl2.js} +1 -1
- package/lib/public/assets/{users-BDh1xjad.js → users-CcSQRoK9.js} +1 -1
- package/lib/public/assets/{video-off-BOjNwT4R.js → video-off-dFKgps73.js} +1 -1
- package/lib/public/assets/{webhook-settings-BMzyUcx5.js → webhook-settings-DD1XjiOD.js} +1 -1
- package/lib/public/assets/{zap-DTWwVMUg.js → zap-COC2tZaH.js} +1 -1
- package/lib/public/index.html +1 -1
- package/lib/src/app/apiErrors.js +118 -0
- package/lib/src/app/index.js +6 -1
- package/lib/src/app/openapi/control.yaml +3129 -0
- package/lib/src/app/openapi/grid.yaml +2295 -0
- package/lib/src/app/openapi/identity.yaml +2168 -0
- package/lib/src/app/openapi/platform.yaml +2885 -0
- package/lib/src/app/openapi/sessions.yaml +3784 -0
- package/lib/src/app/routers/bug-report.js +4 -1
- package/lib/src/app/routers/config.js +6 -107
- package/lib/src/app/routers/control.js +117 -59
- package/lib/src/app/routers/dashboard.js +13 -7
- package/lib/src/app/routers/grid.js +54 -14
- package/lib/src/app/routers/profile.js +27 -13
- package/lib/src/app/routers/recordings.js +11 -5
- package/lib/src/app/routers/reservation.js +63 -15
- package/lib/src/app/routers/users.js +4 -0
- package/lib/src/app/routers/webhook.js +17 -8
- package/lib/src/app/swagger.js +259 -177
- package/lib/src/data-service/device-service.js +4 -1
- package/lib/src/data-service/deviceFieldOwners.js +1 -0
- package/lib/src/device-managers/AndroidDeviceManager.js +5 -2
- package/lib/src/device-managers/ios/WDAClient.js +32 -32
- package/lib/src/generated/client/edge.js +4 -3
- package/lib/src/generated/client/index-browser.js +1 -0
- package/lib/src/generated/client/index.d.ts +38 -0
- package/lib/src/generated/client/index.js +4 -3
- package/lib/src/generated/client/package.json +1 -1
- package/lib/src/generated/client/schema.prisma +2 -0
- package/lib/src/generated/client/wasm.js +1 -0
- package/lib/src/middleware/csrfMiddleware.js +13 -5
- package/lib/src/middleware/rateLimitMiddleware.js +19 -5
- package/lib/src/middleware/roleGuard.js +20 -0
- package/lib/src/services/AIService.js +13 -3
- package/lib/src/services/NotificationService.js +28 -28
- package/lib/src/services/bug-report/BugReportService.js +8 -2
- package/lib/src/services/lease/LeaseService.js +71 -20
- package/lib/src/services/omni-vision/OmniVisionService.js +14 -5
- package/lib/src/services/recording/RecordingOrchestrator.js +16 -2
- package/lib/test/helpers/expressRoutes.js +41 -0
- package/lib/test/integration/team-visibility-control.spec.js +2 -2
- package/lib/test/unit/access-scopes.spec.js +227 -0
- package/lib/test/unit/api-error-handling.spec.js +179 -0
- package/lib/test/unit/bug-report/route.spec.js +29 -0
- package/lib/test/unit/bug-report/service.spec.js +30 -0
- package/lib/test/unit/control-honest-answers.spec.js +134 -0
- package/lib/test/unit/device-allocation-routes.spec.js +232 -0
- package/lib/test/unit/healing-state-endpoints.spec.js +8 -5
- package/lib/test/unit/install-repository-app-team.spec.js +4 -1
- package/lib/test/unit/lease/LeaseService.spec.js +5 -4
- package/lib/test/unit/lease/lease-device-match.spec.js +161 -0
- package/lib/test/unit/lease/lease-session-ownership.spec.js +10 -9
- package/lib/test/unit/omni-vision-failures.spec.js +81 -0
- package/lib/test/unit/openapi-coverage.spec.js +114 -0
- package/lib/test/unit/profile-router.test.js +42 -0
- package/lib/test/unit/rateLimitMiddleware.test.js +49 -0
- package/lib/test/unit/recording-orchestrator.spec.js +80 -0
- package/lib/test/unit/recordings-library-routes.spec.js +37 -0
- package/lib/test/unit/reservation-team-visibility.spec.js +4 -3
- package/lib/test/unit/reset-link.test.js +2 -1
- package/lib/test/unit/stream-ticket-identity.spec.js +1 -1
- package/lib/test/unit/users-router.test.js +14 -1
- package/lib/test/unit/wda-client-failures.spec.js +90 -0
- package/lib/test/unit/webhook-delivery.spec.js +142 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/prisma/migrations/20261004120000_reservation_holder/migration.sql +2 -0
- package/prisma/schema.prisma +2 -0
- package/lib/src/app/swagger-docs.js +0 -1701
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as c,i as J,u as Q,b as X,t as ee,j as e,e as B,A as te,Z as ne}from"./index-ClrpAMAT.js";import{f as Z,a as re,c as se,h as ae,i as q,j as ie,k as oe,m as ce}from"./recordings-BWe1ydXm.js";import{P as le}from"./page-header-B92DKLiq.js";import{B as I}from"./button-CqhPBGRj.js";import{E as L}from"./EmptyState-BeuTrlN_.js";import{M as ue}from"./Modal-ByESeBRC.js";import{P as de,M as fe,a as me}from"./Menu-GCbP6gYN.js";import{A as ge}from"./AnnotationOverlay-Crkn72_3.js";import{t as O,v as pe,R as he,P as be,n as ye,c as U,o as ve,a as R,f as ke,p as xe,S as V,b as je,d as Me}from"./recordings-n-GTW3aT.js";import{A as we}from"./arrow-left-BtJIXXMY.js";import{T as Re}from"./trash-2-NK_Iazmg.js";import{P as Se,a as Ne}from"./play-Ck0L-0_m.js";import{D as Ee}from"./download-BM6Xn22t.js";import"./utils-CDN07tui.js";import"./index-DauQh6ie.js";import"./check-DpbIM4E0.js";function Ce(n){const t=[{key:"zip",label:"All videos (zip)",url:re(n.groupId)}];return n.hasComposite&&t.push({key:"composite",label:"Side-by-side video",url:se(n.groupId)}),t.push({key:"bundle",label:"Proof bundle",url:ae(n.groupId)}),n.phones.filter(l=>l.status!=="FAILED"&&l.status!=="DISCARDED").forEach(l=>{t.push({key:`video-${l.recordingId}`,label:`${l.name}: video`,url:q(n.groupId,l.recordingId,!0)}),l.annotationCount>0&&t.push({key:`annotated-${l.recordingId}`,label:`${l.name}: video with annotations`,url:ie(n.groupId,l.recordingId)})}),t}function Ie(n,t){return t?t.role==="ADMIN"||t.role==="SUPER_ADMIN"?!0:!!n.startedBy&&!!t.userId&&n.startedBy.id===t.userId:!1}function De(n){if(n instanceof Z){if(n.code==="not_owner")return"Only the person who recorded it, or an admin, can delete it.";if(n.code==="recording_in_progress")return"It’s still recording. Stop it on Live devices first.";if(n.status===404)return"It was already deleted, or it’s on phones you can’t see."}return`Couldn’t delete the recording: ${n instanceof Error?n.message:String(n)}`}function Ae(n){const t=document.createElement("a");t.href=n,t.download="",document.body.appendChild(t),t.click(),document.body.removeChild(t)}const Te={now:()=>performance.now(),schedule:n=>window.requestAnimationFrame(()=>n()),cancel:n=>window.cancelAnimationFrame(n)},Pe=100,_e=3,Fe=.05;function W(n){return n.ended||Number.isFinite(n.duration)&&n.currentTime>=n.duration-Fe}function Le(n,t=Te){const l=c.useRef(new Map),v=c.useRef(new Map),u=c.useRef(new Map),d=c.useRef({baseMs:0,since:null,running:!1,waiting:!1}),p=c.useRef(null),S=c.useRef(-1/0),k=c.useRef(n);k.current=n;const[D,w]=c.useState({timeMs:0,playing:!1,waiting:!1}),x=()=>d.current.since===null?d.current.baseMs:d.current.baseMs+(t.now()-d.current.since),h=(s,a)=>{l.current.forEach((i,M)=>{var _;const m=v.current.get(M);if(!m||i.error)return;const T=O(s,m.offsetMs,m.durationMs);let C=T==="before"?0:T==="after"?m.durationMs:pe(s,m.offsetMs);Number.isFinite(i.duration)&&(C=Math.min(C,i.duration*1e3));const $=d.current.running?he:be;ye(i.currentTime*1e3,C,$)&&(i.currentTime=C/1e3),a&&T==="playing"?i.paused&&!W(i)&&((_=i.play())==null||_.catch(()=>{})):i.paused||i.pause()})},j=s=>Array.from(l.current.entries()).some(([a,i])=>{const M=v.current.get(a);return!!M&&!i.error&&!W(i)&&O(s,M.offsetMs,M.durationMs)==="playing"&&i.readyState<_e}),g=s=>{const a=t.now();!s&&a-S.current<Pe||(S.current=a,w({timeMs:x(),playing:d.current.running,waiting:d.current.waiting}))},b=()=>{p.current!==null&&t.cancel(p.current),p.current=null},A=()=>{p.current=null;const s=d.current;if(!s.running)return;const a=x();if(a>=k.current){Object.assign(s,{baseMs:k.current,since:null,running:!1,waiting:!1}),h(k.current,!1),g(!0);return}const i=j(a);i!==s.waiting?(s.baseMs=a,s.since=i?null:t.now(),s.waiting=i,h(a,!i),g(!0)):(h(a,!i),g(!1)),p.current=t.schedule(A)},N=()=>{const s=d.current;x()>=k.current?s.baseMs=0:s.baseMs=x(),Object.assign(s,{since:t.now(),running:!0,waiting:!1}),h(s.baseMs,!0),g(!0),b(),p.current=t.schedule(A)},y=()=>{const s=d.current;Object.assign(s,{baseMs:x(),since:null,running:!1,waiting:!1}),b(),h(s.baseMs,!1),g(!0)},f=s=>{const a=d.current,i=U(s,k.current);a.baseMs=i,a.since=a.running&&!a.waiting?t.now():null,h(i,a.running&&!a.waiting),g(!0)},P=c.useCallback((s,a)=>{v.current.set(s,a);let i=u.current.get(s);return i||(i=M=>{if(M){l.current.set(s,M);const m=d.current;h(x(),m.running&&!m.waiting)}else l.current.delete(s)},u.current.set(s,i)),i},[]);return c.useEffect(()=>b,[]),{...D,play:N,pause:y,toggle:()=>d.current.running?y():N(),seek:f,bind:P}}const $e=()=>{},Y="Stop the recording on Live devices first.",Be=1e3;function Oe(n){const t=n;return!t||!t.closest?!1:!!t.closest('input:not([type="range"]):not([type="checkbox"]), select, textarea, [contenteditable="true"], [role="dialog"], [role="menu"]')}function Ue({groupId:n,phone:t,timeMs:l,marks:v,showMarks:u,bind:d}){const[p,S]=c.useState(!1),[k,D]=c.useState(void 0),w=t.status==="FAILED"||t.status==="DISCARDED",x=O(l,t.offsetMs,t.durationMs),h=je(v,l).map(Me).filter(g=>g!==null);let j=null;return w?j=`Recording failed: ${t.failReason??"unknown reason"}`:p?j="Video no longer available":x==="before"&&t.offsetMs>=Be&&(j=`Starts at ${R(t.offsetMs)}`),e.jsxs("figure",{className:"rec-tile theme-dark","aria-label":t.name,children:[e.jsx("figcaption",{className:"rec-tile-name",title:t.name,children:t.name}),e.jsxs("div",{className:"rec-tile-screen",children:[!w&&e.jsx("video",{className:"rec-tile-video",muted:!0,playsInline:!0,preload:"auto",src:q(n,t.recordingId),ref:d(t.recordingId,{offsetMs:t.offsetMs,durationMs:t.durationMs}),onError:()=>S(!0),onLoadedMetadata:g=>{const b=g.currentTarget;b.videoWidth>0&&b.videoHeight>0&&D(b.videoWidth/b.videoHeight)}}),!w&&u&&e.jsx(ge,{enabled:!1,shape:"RECT",color:"currentColor",onCommit:$e,committed:h,mediaAspect:k}),j&&e.jsx("div",{className:"rec-tile-note",children:j})]})]})}function ze({detail:n}){const[t,l]=c.useState(!1),v=c.useRef(null);return e.jsxs(e.Fragment,{children:[e.jsxs(I,{ref:v,variant:"secondary","aria-haspopup":"menu","aria-expanded":t,onClick:()=>l(u=>!u),children:[e.jsx(Ee,{size:14,"aria-hidden":"true"}),"Download"]}),e.jsx(de,{open:t,onClose:()=>l(!1),anchorRef:v,children:e.jsx(fe,{children:Ce(n.summary).map(u=>e.jsx(me,{onClick:()=>{l(!1),Ae(u.url)},children:u.label},u.key))})})]})}function at(){var K;const{groupId:n=""}=J(),t=Q(),{me:l}=X(),{toast:v}=ee(),[u,d]=c.useState(null),[p,S]=c.useState(null),[k,D]=c.useState(0),[w,x]=c.useState(!0),[h,j]=c.useState(!1),[g,b]=c.useState(!1),[A,N]=c.useState(null);c.useEffect(()=>{let r=!0;return S(null),d(null),oe(n).then(o=>r&&d(ve(o))).catch(o=>{r&&S({missing:o instanceof Z&&o.status===404,message:o instanceof Error?o.message:String(o)})}),()=>{r=!1}},[n,k]);const y=(u==null?void 0:u.summary.durationMs)??0,f=Le(y),P=c.useRef(f);P.current=f;const s=c.useRef(!0);if(c.useEffect(()=>(s.current=!0,()=>{s.current=!1}),[]),c.useEffect(()=>{if(!u||u.summary.status==="recording")return;const r=o=>{var F,H;if(o.metaKey||o.ctrlKey||o.altKey||Oe(o.target)||o.key===" "&&((H=(F=o.target)==null?void 0:F.closest)!=null&&H.call(F,"button, a, label")))return;if(o.key===" "&&o.repeat){o.preventDefault();return}const E=P.current;o.key===" "?(o.preventDefault(),E.toggle()):o.key==="ArrowRight"?(o.preventDefault(),E.seek(U(E.timeMs+V,y))):o.key==="ArrowLeft"&&(o.preventDefault(),E.seek(U(E.timeMs-V,y)))};return document.addEventListener("keydown",r),()=>document.removeEventListener("keydown",r)},[u,y]),p)return p.missing?e.jsx(L,{title:"This recording isn't available",description:"It may have been deleted, or it's on phones you can't see.",action:e.jsx(B,{className:"rec-link",to:"/recordings",children:"Back to Recordings"})}):e.jsx(L,{title:"Couldn't load this recording",description:p.message,action:e.jsxs(I,{variant:"secondary",onClick:()=>D(r=>r+1),children:[e.jsx(te,{size:14,"aria-hidden":"true"}),"Retry"]})});if(!u)return e.jsx(L,{title:"Loading recording…"});const{summary:a,bookmarks:i,annotations:M}=u,m=a.status==="recording",T=a.phones.map(r=>r.name).join(", "),C=r=>{var o;return((o=a.phones.find(E=>E.recordingId===r))==null?void 0:o.name)??""},$=[T,a.durationMs===null?null:`Length ${R(a.durationMs)}`,`Recorded by ${((K=a.startedBy)==null?void 0:K.name)??"Unknown"}`].filter(Boolean).join(" · "),_=Ie(a,l),z=()=>{j(!1),N(null)},G=async()=>{b(!0),N(null);try{await ce(n)}catch(r){s.current&&(b(!1),N(De(r)));return}v("Recording deleted","success"),s.current&&t("/recordings")};return e.jsxs("div",{className:"rec-page",children:[e.jsx("nav",{className:"rec-backbar",children:e.jsxs(B,{className:"rec-link",to:"/recordings",children:[e.jsx(we,{size:14,"aria-hidden":"true"})," Recordings"]})}),e.jsx(le,{icon:ne,title:ke(a.startedAt),subtitle:$,action:e.jsxs(e.Fragment,{children:[!m&&a.status!=="failed"&&e.jsx(ze,{detail:u}),_&&e.jsxs(e.Fragment,{children:[e.jsxs(I,{variant:"danger",disabled:m,"aria-describedby":m?"rec-delete-reason":void 0,title:m?Y:void 0,onClick:()=>{N(null),j(!0)},children:[e.jsx(Re,{size:14,"aria-hidden":"true"}),"Delete"]}),m&&e.jsx("span",{id:"rec-delete-reason",className:"sr-only",children:Y})]})]})}),m?e.jsx(L,{title:"Still recording",description:"Stop it on Live devices to play it here.",action:e.jsx(B,{className:"rec-link",to:"/devices/live",children:"Open Live devices"})}):e.jsxs("div",{className:`rec-body${i.length>0?" rec-body--with-list":""}`,children:[e.jsxs("div",{className:"rec-player",children:[e.jsx("div",{className:"rec-grid",children:a.phones.map(r=>e.jsx(Ue,{groupId:n,phone:r,timeMs:f.timeMs,marks:M.filter(o=>o.recordingId===r.recordingId),showMarks:w,bind:f.bind},r.recordingId))}),e.jsxs("div",{className:"rec-transport",children:[e.jsx(I,{variant:"secondary",size:"icon","aria-label":f.playing?"Pause":"Play",onClick:f.toggle,children:f.playing?e.jsx(Se,{size:14,"aria-hidden":"true"}):e.jsx(Ne,{size:14,"aria-hidden":"true"})}),e.jsxs("span",{className:"rec-num rec-clock",children:[R(f.timeMs)," / ",R(y)]}),e.jsxs("div",{className:"rec-timeline",children:[e.jsx("input",{type:"range",className:"rec-range","aria-label":"Timeline","aria-valuetext":`${R(f.timeMs)} of ${R(y)}`,min:0,max:y,step:100,value:f.timeMs,onChange:r=>f.seek(Number(r.target.value))}),i.map(r=>e.jsx("button",{type:"button",className:"rec-mark",style:{left:`${xe(r.timecodeMs,y)}%`},title:r.label,"aria-label":`Bookmark: ${r.label}, ${R(r.timecodeMs)}`,onClick:()=>f.seek(r.timecodeMs)},r.id))]}),e.jsx("span",{role:"status",className:"rec-waiting",children:f.waiting?"Buffering…":""}),a.annotationCount>0&&e.jsxs("label",{className:"rec-toggle",children:[e.jsx("input",{type:"checkbox",checked:w,onChange:r=>x(r.target.checked)}),"Annotations"]})]})]}),i.length>0&&e.jsxs("section",{className:"rec-bookmarks","aria-labelledby":"rec-bookmarks-title",children:[e.jsx("h2",{id:"rec-bookmarks-title",className:"rec-bookmarks-title",children:"Bookmarks"}),e.jsx("ol",{className:"rec-bookmark-list",children:i.map(r=>e.jsx("li",{children:e.jsxs("button",{type:"button",className:"rec-bookmark",onClick:()=>f.seek(r.timecodeMs),children:[e.jsx("span",{className:"rec-bookmark-label",children:r.label}),e.jsxs("span",{className:"rec-num rec-bookmark-meta",children:[R(r.timecodeMs)," · ",C(r.recordingId)]})]})},r.id))})]})]}),e.jsxs(ue,{open:h,title:"Delete this recording?",onClose:()=>{g||z()},footer:e.jsxs(e.Fragment,{children:[e.jsx(I,{variant:"secondary",onClick:z,disabled:g,children:"Cancel"}),e.jsx(I,{variant:"danger",onClick:G,disabled:g,children:"Delete"})]}),children:[e.jsx("p",{children:"Its videos, bookmarks and annotations are removed for everyone."}),A&&e.jsx("p",{role:"alert",className:"rec-error",children:A})]})]})}export{at as default};
|
|
1
|
+
import{r as c,i as J,u as Q,b as X,t as ee,j as e,e as B,A as te,Z as ne}from"./index-CHOr4JCs.js";import{f as Z,a as re,c as se,h as ae,i as q,j as ie,k as oe,m as ce}from"./recordings-BWe1ydXm.js";import{P as le}from"./page-header-Cm1XL49f.js";import{B as I}from"./button-BxnHCCsX.js";import{E as L}from"./EmptyState-BE_5f8Vw.js";import{M as ue}from"./Modal-DfawTxih.js";import{P as de,M as fe,a as me}from"./Menu-BiW3os9u.js";import{A as ge}from"./AnnotationOverlay-CzbFYtPI.js";import{t as O,v as pe,R as he,P as be,n as ye,c as U,o as ve,a as R,f as ke,p as xe,S as V,b as je,d as Me}from"./recordings-n-GTW3aT.js";import{A as we}from"./arrow-left-CLQWAiCY.js";import{T as Re}from"./trash-2-CcSsv4fS.js";import{P as Se,a as Ne}from"./play-C0CuKLXj.js";import{D as Ee}from"./download-Bd8OGLzi.js";import"./utils-CDN07tui.js";import"./index-BiL0Enl_.js";import"./check-R6V3bot0.js";function Ce(n){const t=[{key:"zip",label:"All videos (zip)",url:re(n.groupId)}];return n.hasComposite&&t.push({key:"composite",label:"Side-by-side video",url:se(n.groupId)}),t.push({key:"bundle",label:"Proof bundle",url:ae(n.groupId)}),n.phones.filter(l=>l.status!=="FAILED"&&l.status!=="DISCARDED").forEach(l=>{t.push({key:`video-${l.recordingId}`,label:`${l.name}: video`,url:q(n.groupId,l.recordingId,!0)}),l.annotationCount>0&&t.push({key:`annotated-${l.recordingId}`,label:`${l.name}: video with annotations`,url:ie(n.groupId,l.recordingId)})}),t}function Ie(n,t){return t?t.role==="ADMIN"||t.role==="SUPER_ADMIN"?!0:!!n.startedBy&&!!t.userId&&n.startedBy.id===t.userId:!1}function De(n){if(n instanceof Z){if(n.code==="not_owner")return"Only the person who recorded it, or an admin, can delete it.";if(n.code==="recording_in_progress")return"It’s still recording. Stop it on Live devices first.";if(n.status===404)return"It was already deleted, or it’s on phones you can’t see."}return`Couldn’t delete the recording: ${n instanceof Error?n.message:String(n)}`}function Ae(n){const t=document.createElement("a");t.href=n,t.download="",document.body.appendChild(t),t.click(),document.body.removeChild(t)}const Te={now:()=>performance.now(),schedule:n=>window.requestAnimationFrame(()=>n()),cancel:n=>window.cancelAnimationFrame(n)},Pe=100,_e=3,Fe=.05;function W(n){return n.ended||Number.isFinite(n.duration)&&n.currentTime>=n.duration-Fe}function Le(n,t=Te){const l=c.useRef(new Map),v=c.useRef(new Map),u=c.useRef(new Map),d=c.useRef({baseMs:0,since:null,running:!1,waiting:!1}),p=c.useRef(null),S=c.useRef(-1/0),k=c.useRef(n);k.current=n;const[D,w]=c.useState({timeMs:0,playing:!1,waiting:!1}),x=()=>d.current.since===null?d.current.baseMs:d.current.baseMs+(t.now()-d.current.since),h=(s,a)=>{l.current.forEach((i,M)=>{var _;const m=v.current.get(M);if(!m||i.error)return;const T=O(s,m.offsetMs,m.durationMs);let C=T==="before"?0:T==="after"?m.durationMs:pe(s,m.offsetMs);Number.isFinite(i.duration)&&(C=Math.min(C,i.duration*1e3));const $=d.current.running?he:be;ye(i.currentTime*1e3,C,$)&&(i.currentTime=C/1e3),a&&T==="playing"?i.paused&&!W(i)&&((_=i.play())==null||_.catch(()=>{})):i.paused||i.pause()})},j=s=>Array.from(l.current.entries()).some(([a,i])=>{const M=v.current.get(a);return!!M&&!i.error&&!W(i)&&O(s,M.offsetMs,M.durationMs)==="playing"&&i.readyState<_e}),g=s=>{const a=t.now();!s&&a-S.current<Pe||(S.current=a,w({timeMs:x(),playing:d.current.running,waiting:d.current.waiting}))},b=()=>{p.current!==null&&t.cancel(p.current),p.current=null},A=()=>{p.current=null;const s=d.current;if(!s.running)return;const a=x();if(a>=k.current){Object.assign(s,{baseMs:k.current,since:null,running:!1,waiting:!1}),h(k.current,!1),g(!0);return}const i=j(a);i!==s.waiting?(s.baseMs=a,s.since=i?null:t.now(),s.waiting=i,h(a,!i),g(!0)):(h(a,!i),g(!1)),p.current=t.schedule(A)},N=()=>{const s=d.current;x()>=k.current?s.baseMs=0:s.baseMs=x(),Object.assign(s,{since:t.now(),running:!0,waiting:!1}),h(s.baseMs,!0),g(!0),b(),p.current=t.schedule(A)},y=()=>{const s=d.current;Object.assign(s,{baseMs:x(),since:null,running:!1,waiting:!1}),b(),h(s.baseMs,!1),g(!0)},f=s=>{const a=d.current,i=U(s,k.current);a.baseMs=i,a.since=a.running&&!a.waiting?t.now():null,h(i,a.running&&!a.waiting),g(!0)},P=c.useCallback((s,a)=>{v.current.set(s,a);let i=u.current.get(s);return i||(i=M=>{if(M){l.current.set(s,M);const m=d.current;h(x(),m.running&&!m.waiting)}else l.current.delete(s)},u.current.set(s,i)),i},[]);return c.useEffect(()=>b,[]),{...D,play:N,pause:y,toggle:()=>d.current.running?y():N(),seek:f,bind:P}}const $e=()=>{},Y="Stop the recording on Live devices first.",Be=1e3;function Oe(n){const t=n;return!t||!t.closest?!1:!!t.closest('input:not([type="range"]):not([type="checkbox"]), select, textarea, [contenteditable="true"], [role="dialog"], [role="menu"]')}function Ue({groupId:n,phone:t,timeMs:l,marks:v,showMarks:u,bind:d}){const[p,S]=c.useState(!1),[k,D]=c.useState(void 0),w=t.status==="FAILED"||t.status==="DISCARDED",x=O(l,t.offsetMs,t.durationMs),h=je(v,l).map(Me).filter(g=>g!==null);let j=null;return w?j=`Recording failed: ${t.failReason??"unknown reason"}`:p?j="Video no longer available":x==="before"&&t.offsetMs>=Be&&(j=`Starts at ${R(t.offsetMs)}`),e.jsxs("figure",{className:"rec-tile theme-dark","aria-label":t.name,children:[e.jsx("figcaption",{className:"rec-tile-name",title:t.name,children:t.name}),e.jsxs("div",{className:"rec-tile-screen",children:[!w&&e.jsx("video",{className:"rec-tile-video",muted:!0,playsInline:!0,preload:"auto",src:q(n,t.recordingId),ref:d(t.recordingId,{offsetMs:t.offsetMs,durationMs:t.durationMs}),onError:()=>S(!0),onLoadedMetadata:g=>{const b=g.currentTarget;b.videoWidth>0&&b.videoHeight>0&&D(b.videoWidth/b.videoHeight)}}),!w&&u&&e.jsx(ge,{enabled:!1,shape:"RECT",color:"currentColor",onCommit:$e,committed:h,mediaAspect:k}),j&&e.jsx("div",{className:"rec-tile-note",children:j})]})]})}function ze({detail:n}){const[t,l]=c.useState(!1),v=c.useRef(null);return e.jsxs(e.Fragment,{children:[e.jsxs(I,{ref:v,variant:"secondary","aria-haspopup":"menu","aria-expanded":t,onClick:()=>l(u=>!u),children:[e.jsx(Ee,{size:14,"aria-hidden":"true"}),"Download"]}),e.jsx(de,{open:t,onClose:()=>l(!1),anchorRef:v,children:e.jsx(fe,{children:Ce(n.summary).map(u=>e.jsx(me,{onClick:()=>{l(!1),Ae(u.url)},children:u.label},u.key))})})]})}function at(){var K;const{groupId:n=""}=J(),t=Q(),{me:l}=X(),{toast:v}=ee(),[u,d]=c.useState(null),[p,S]=c.useState(null),[k,D]=c.useState(0),[w,x]=c.useState(!0),[h,j]=c.useState(!1),[g,b]=c.useState(!1),[A,N]=c.useState(null);c.useEffect(()=>{let r=!0;return S(null),d(null),oe(n).then(o=>r&&d(ve(o))).catch(o=>{r&&S({missing:o instanceof Z&&o.status===404,message:o instanceof Error?o.message:String(o)})}),()=>{r=!1}},[n,k]);const y=(u==null?void 0:u.summary.durationMs)??0,f=Le(y),P=c.useRef(f);P.current=f;const s=c.useRef(!0);if(c.useEffect(()=>(s.current=!0,()=>{s.current=!1}),[]),c.useEffect(()=>{if(!u||u.summary.status==="recording")return;const r=o=>{var F,H;if(o.metaKey||o.ctrlKey||o.altKey||Oe(o.target)||o.key===" "&&((H=(F=o.target)==null?void 0:F.closest)!=null&&H.call(F,"button, a, label")))return;if(o.key===" "&&o.repeat){o.preventDefault();return}const E=P.current;o.key===" "?(o.preventDefault(),E.toggle()):o.key==="ArrowRight"?(o.preventDefault(),E.seek(U(E.timeMs+V,y))):o.key==="ArrowLeft"&&(o.preventDefault(),E.seek(U(E.timeMs-V,y)))};return document.addEventListener("keydown",r),()=>document.removeEventListener("keydown",r)},[u,y]),p)return p.missing?e.jsx(L,{title:"This recording isn't available",description:"It may have been deleted, or it's on phones you can't see.",action:e.jsx(B,{className:"rec-link",to:"/recordings",children:"Back to Recordings"})}):e.jsx(L,{title:"Couldn't load this recording",description:p.message,action:e.jsxs(I,{variant:"secondary",onClick:()=>D(r=>r+1),children:[e.jsx(te,{size:14,"aria-hidden":"true"}),"Retry"]})});if(!u)return e.jsx(L,{title:"Loading recording…"});const{summary:a,bookmarks:i,annotations:M}=u,m=a.status==="recording",T=a.phones.map(r=>r.name).join(", "),C=r=>{var o;return((o=a.phones.find(E=>E.recordingId===r))==null?void 0:o.name)??""},$=[T,a.durationMs===null?null:`Length ${R(a.durationMs)}`,`Recorded by ${((K=a.startedBy)==null?void 0:K.name)??"Unknown"}`].filter(Boolean).join(" · "),_=Ie(a,l),z=()=>{j(!1),N(null)},G=async()=>{b(!0),N(null);try{await ce(n)}catch(r){s.current&&(b(!1),N(De(r)));return}v("Recording deleted","success"),s.current&&t("/recordings")};return e.jsxs("div",{className:"rec-page",children:[e.jsx("nav",{className:"rec-backbar",children:e.jsxs(B,{className:"rec-link",to:"/recordings",children:[e.jsx(we,{size:14,"aria-hidden":"true"})," Recordings"]})}),e.jsx(le,{icon:ne,title:ke(a.startedAt),subtitle:$,action:e.jsxs(e.Fragment,{children:[!m&&a.status!=="failed"&&e.jsx(ze,{detail:u}),_&&e.jsxs(e.Fragment,{children:[e.jsxs(I,{variant:"danger",disabled:m,"aria-describedby":m?"rec-delete-reason":void 0,title:m?Y:void 0,onClick:()=>{N(null),j(!0)},children:[e.jsx(Re,{size:14,"aria-hidden":"true"}),"Delete"]}),m&&e.jsx("span",{id:"rec-delete-reason",className:"sr-only",children:Y})]})]})}),m?e.jsx(L,{title:"Still recording",description:"Stop it on Live devices to play it here.",action:e.jsx(B,{className:"rec-link",to:"/devices/live",children:"Open Live devices"})}):e.jsxs("div",{className:`rec-body${i.length>0?" rec-body--with-list":""}`,children:[e.jsxs("div",{className:"rec-player",children:[e.jsx("div",{className:"rec-grid",children:a.phones.map(r=>e.jsx(Ue,{groupId:n,phone:r,timeMs:f.timeMs,marks:M.filter(o=>o.recordingId===r.recordingId),showMarks:w,bind:f.bind},r.recordingId))}),e.jsxs("div",{className:"rec-transport",children:[e.jsx(I,{variant:"secondary",size:"icon","aria-label":f.playing?"Pause":"Play",onClick:f.toggle,children:f.playing?e.jsx(Se,{size:14,"aria-hidden":"true"}):e.jsx(Ne,{size:14,"aria-hidden":"true"})}),e.jsxs("span",{className:"rec-num rec-clock",children:[R(f.timeMs)," / ",R(y)]}),e.jsxs("div",{className:"rec-timeline",children:[e.jsx("input",{type:"range",className:"rec-range","aria-label":"Timeline","aria-valuetext":`${R(f.timeMs)} of ${R(y)}`,min:0,max:y,step:100,value:f.timeMs,onChange:r=>f.seek(Number(r.target.value))}),i.map(r=>e.jsx("button",{type:"button",className:"rec-mark",style:{left:`${xe(r.timecodeMs,y)}%`},title:r.label,"aria-label":`Bookmark: ${r.label}, ${R(r.timecodeMs)}`,onClick:()=>f.seek(r.timecodeMs)},r.id))]}),e.jsx("span",{role:"status",className:"rec-waiting",children:f.waiting?"Buffering…":""}),a.annotationCount>0&&e.jsxs("label",{className:"rec-toggle",children:[e.jsx("input",{type:"checkbox",checked:w,onChange:r=>x(r.target.checked)}),"Annotations"]})]})]}),i.length>0&&e.jsxs("section",{className:"rec-bookmarks","aria-labelledby":"rec-bookmarks-title",children:[e.jsx("h2",{id:"rec-bookmarks-title",className:"rec-bookmarks-title",children:"Bookmarks"}),e.jsx("ol",{className:"rec-bookmark-list",children:i.map(r=>e.jsx("li",{children:e.jsxs("button",{type:"button",className:"rec-bookmark",onClick:()=>f.seek(r.timecodeMs),children:[e.jsx("span",{className:"rec-bookmark-label",children:r.label}),e.jsxs("span",{className:"rec-num rec-bookmark-meta",children:[R(r.timecodeMs)," · ",C(r.recordingId)]})]})},r.id))})]})]}),e.jsxs(ue,{open:h,title:"Delete this recording?",onClose:()=>{g||z()},footer:e.jsxs(e.Fragment,{children:[e.jsx(I,{variant:"secondary",onClick:z,disabled:g,children:"Cancel"}),e.jsx(I,{variant:"danger",onClick:G,disabled:g,children:"Delete"})]}),children:[e.jsx("p",{children:"Its videos, bookmarks and annotations are removed for everyone."}),A&&e.jsx("p",{role:"alert",className:"rec-error",children:A})]})]})}export{at as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as V,F as Y,r as l,j as n,Z,A as z,e as q}from"./index-
|
|
1
|
+
import{u as V,F as Y,r as l,j as n,Z,A as z,e as q}from"./index-CHOr4JCs.js";import{P as G}from"./page-header-Cm1XL49f.js";import{T as Q,a as J,b as F,c as h,d as X,e as m}from"./Table-DlEuFgv-.js";import{B as v}from"./button-BxnHCCsX.js";import{E as y}from"./EmptyState-BE_5f8Vw.js";import{I as ee}from"./input-CJ8z3IO5.js";import{F as f}from"./FilterMenu-BQY75Su3.js";import{l as T}from"./recordings-BWe1ydXm.js";import{f as ne,a as te}from"./recordings-n-GTW3aT.js";import"./utils-CDN07tui.js";import"./Menu-BiW3os9u.js";import"./index-BiL0Enl_.js";import"./check-R6V3bot0.js";import"./plus-CIIvR_6Z.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 A(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=A(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(A(e),{replace:!0});l.useEffect(()=>{d.current=!0;const e=++u.current,c=window.setTimeout(()=>{T({...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 T({...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(G,{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(z,{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(Q,{className:"rec-table",children:[n.jsxs("caption",{className:"sr-only",children:["Recordings, ",j.length," shown"]}),n.jsx(J,{children:n.jsxs(F,{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(F,{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-CHOr4JCs.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-CHOr4JCs.js";import{B as r}from"./button-BxnHCCsX.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-CHOr4JCs.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,Q as I,V 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,Q as I,V as $}from"./index-CHOr4JCs.js";/* empty css */import{S,A as F}from"./SettingCard-Cw6lDD0l.js";import{P as B}from"./page-header-Cm1XL49f.js";import{L as T}from"./lock-BSXM1xvq.js";import{C as b}from"./circle-check-D4EzyGzs.js";import{A as E}from"./activity-CnLvNwae.js";import"./button-BxnHCCsX.js";import"./utils-CDN07tui.js";/**
|
|
2
2
|
* @license lucide-react v0.555.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as le,r as a,j as e,A as $,W as g,y as oe}from"./index-ClrpAMAT.js";/* empty css */import{a as L}from"./time-D-gjmE1o.js";import{T as ce,a as de,b as z,c as l,d as me,e as o}from"./Table-CIaR0QWV.js";import{F as m}from"./FieldGroup-DBIaNxl1.js";import{P as O}from"./page-header-B92DKLiq.js";import{M as B}from"./Modal-ByESeBRC.js";import{B as u}from"./button-CqhPBGRj.js";import{I as H}from"./input-CyKdLnEx.js";import{S as M}from"./select-BBOIZTYm.js";import{P as v}from"./plus-Dq3tCy2N.js";import{T as pe}from"./trash-2-NK_Iazmg.js";import{C as he}from"./check-DpbIM4E0.js";import{C as xe}from"./copy-BKNyOehd.js";import"./index-DauQh6ie.js";import"./utils-CDN07tui.js";const W=["read","sessions","devices","admin"],U={"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),[Q,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),V=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=W.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:V(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:Q,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:W.map(s=>e.jsxs("label",{style:ye,children:[e.jsx("input",{type:"checkbox",checked:j[s],onChange:t=>I({...j,[s]:t.target.checked})}),e.jsx("span",{children:s})]},s))})}),e.jsx(m,{label:"Rate limit (requests/min)",htmlFor:"apikey-ratelimit",children:e.jsx(H,{id:"apikey-ratelimit",type:"number",min:10,step:10,value:R,onChange:s=>P(parseInt(s.target.value)||300),className:"w-full"})}),e.jsx(m,{label:"Default team",description:e.jsxs(e.Fragment,{children:["Keys without a team can only reach shared-pool devices. Admins can override at session time via ",e.jsx("code",{children:"xe:options.team"}),"."]}),htmlFor:"apikey-team",children:e.jsxs(M,{id:"apikey-team",value:E,onChange:s=>D(s.target.value),className:"w-full",children:[e.jsx("option",{value:"",children:"No team (shared pool only)"}),b.map(s=>e.jsx("option",{value:s.id,children:s.name},s.id))]})}),e.jsx(m,{label:"Expires after",description:h==="never"?"Key never expires. Rotate manually when needed.":`Key will stop working on ${L(Y(h))}.`,htmlFor:"apikey-expiry",children:e.jsx(M,{id:"apikey-expiry",value:h,onChange:s=>F(s.target.value),className:"w-full",children:Object.keys(U).map(s=>e.jsx("option",{value:s,children:U[s]},s))})})]})}),e.jsx(B,{open:!!r,title:r?`Key created: ${r.name}`:"",width:560,onClose:()=>y(null),closeOnOverlayClick:!1,footer:e.jsxs(e.Fragment,{children:[e.jsxs(u,{variant:"primary",onClick:()=>r&&te(r.raw),disabled:!r,children:[T?e.jsx(he,{size:18}):e.jsx(xe,{size:18}),T?"Copied":"Copy to clipboard"]}),e.jsx(u,{variant:"secondary",onClick:()=>y(null),children:"I've saved it"})]}),children:r&&e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:16},children:[e.jsxs("div",{style:{background:"var(--status-busy-bg)",border:"1px solid var(--status-busy-border)",borderRadius:6,padding:12,display:"flex",gap:8,alignItems:"flex-start"},children:[e.jsx(oe,{size:18,style:{flexShrink:0,marginTop:2}}),e.jsxs("div",{children:[e.jsx("strong",{children:"This key will not be shown again."})," Copy it now and store it in your password manager, CI secret store, or client config."]})]}),e.jsx("div",{style:{fontFamily:"monospace",padding:12,background:"rgb(var(--rgb-black) / 0.3)",borderRadius:6,wordBreak:"break-all",fontSize:"0.9em"},children:r.raw})]})})]})},ye={display:"flex",alignItems:"center",gap:6,padding:"6px 12px",background:"rgb(var(--rgb-white) / 0.04)",borderRadius:6,cursor:"pointer",fontFamily:"monospace",fontSize:"0.9em"};export{Ee as ApiKeys};
|
|
1
|
+
import{t as le,r as a,j as e,A as $,W as g,y as oe}from"./index-CHOr4JCs.js";/* empty css */import{a as L}from"./time-D-gjmE1o.js";import{T as ce,a as de,b as z,c as l,d as me,e as o}from"./Table-DlEuFgv-.js";import{F as m}from"./FieldGroup-DqMf7Rf3.js";import{P as O}from"./page-header-Cm1XL49f.js";import{M as B}from"./Modal-DfawTxih.js";import{B as u}from"./button-BxnHCCsX.js";import{I as H}from"./input-CJ8z3IO5.js";import{S as M}from"./select-CZuCnold.js";import{P as v}from"./plus-CIIvR_6Z.js";import{T as pe}from"./trash-2-CcSsv4fS.js";import{C as he}from"./check-R6V3bot0.js";import{C as xe}from"./copy-Bc6P8v9V.js";import"./index-BiL0Enl_.js";import"./utils-CDN07tui.js";const W=["read","sessions","devices","admin"],U={"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),[Q,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),V=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=W.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:V(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:Q,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:W.map(s=>e.jsxs("label",{style:ye,children:[e.jsx("input",{type:"checkbox",checked:j[s],onChange:t=>I({...j,[s]:t.target.checked})}),e.jsx("span",{children:s})]},s))})}),e.jsx(m,{label:"Rate limit (requests/min)",htmlFor:"apikey-ratelimit",children:e.jsx(H,{id:"apikey-ratelimit",type:"number",min:10,step:10,value:R,onChange:s=>P(parseInt(s.target.value)||300),className:"w-full"})}),e.jsx(m,{label:"Default team",description:e.jsxs(e.Fragment,{children:["Keys without a team can only reach shared-pool devices. Admins can override at session time via ",e.jsx("code",{children:"xe:options.team"}),"."]}),htmlFor:"apikey-team",children:e.jsxs(M,{id:"apikey-team",value:E,onChange:s=>D(s.target.value),className:"w-full",children:[e.jsx("option",{value:"",children:"No team (shared pool only)"}),b.map(s=>e.jsx("option",{value:s.id,children:s.name},s.id))]})}),e.jsx(m,{label:"Expires after",description:h==="never"?"Key never expires. Rotate manually when needed.":`Key will stop working on ${L(Y(h))}.`,htmlFor:"apikey-expiry",children:e.jsx(M,{id:"apikey-expiry",value:h,onChange:s=>F(s.target.value),className:"w-full",children:Object.keys(U).map(s=>e.jsx("option",{value:s,children:U[s]},s))})})]})}),e.jsx(B,{open:!!r,title:r?`Key created: ${r.name}`:"",width:560,onClose:()=>y(null),closeOnOverlayClick:!1,footer:e.jsxs(e.Fragment,{children:[e.jsxs(u,{variant:"primary",onClick:()=>r&&te(r.raw),disabled:!r,children:[T?e.jsx(he,{size:18}):e.jsx(xe,{size:18}),T?"Copied":"Copy to clipboard"]}),e.jsx(u,{variant:"secondary",onClick:()=>y(null),children:"I've saved it"})]}),children:r&&e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:16},children:[e.jsxs("div",{style:{background:"var(--status-busy-bg)",border:"1px solid var(--status-busy-border)",borderRadius:6,padding:12,display:"flex",gap:8,alignItems:"flex-start"},children:[e.jsx(oe,{size:18,style:{flexShrink:0,marginTop:2}}),e.jsxs("div",{children:[e.jsx("strong",{children:"This key will not be shown again."})," Copy it now and store it in your password manager, CI secret store, or client config."]})]}),e.jsx("div",{style:{fontFamily:"monospace",padding:12,background:"rgb(var(--rgb-black) / 0.3)",borderRadius:6,wordBreak:"break-all",fontSize:"0.9em"},children:r.raw})]})})]})},ye={display:"flex",alignItems:"center",gap:6,padding:"6px 12px",background:"rgb(var(--rgb-white) / 0.04)",borderRadius:6,cursor:"pointer",fontFamily:"monospace",fontSize:"0.9em"};export{Ee as ApiKeys};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as k,j as e,r as i,A as K,t as ve,b as je,X as p,J as fe,q as V,z as ye,v as ge}from"./index-
|
|
1
|
+
import{c as k,j as e,r as i,A as K,t as ve,b as je,X as p,J as fe,q as V,z as ye,v as ge}from"./index-CHOr4JCs.js";import{f as Ne}from"./time-D-gjmE1o.js";import{c as be,B as x}from"./button-BxnHCCsX.js";import{c as ke}from"./utils-CDN07tui.js";import{P as we}from"./page-header-Cm1XL49f.js";import{S as Z}from"./select-CZuCnold.js";import{M as J}from"./Modal-DfawTxih.js";import{F as Q}from"./FieldGroup-DqMf7Rf3.js";import{U as ee,T as q}from"./upload-BYf26K71.js";import{C as Ce}from"./check-R6V3bot0.js";import{C as Ae}from"./copy-Bc6P8v9V.js";import{Z as Se}from"./zap-COC2tZaH.js";import{D as ze}from"./download-Bd8OGLzi.js";import{T as Me}from"./trash-2-CcSsv4fS.js";import"./index-BiL0Enl_.js";/**
|
|
2
2
|
* @license lucide-react v0.555.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -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-CHOr4JCs.js";import{N as l}from"./network-Ba_uFxWo.js";/**
|
|
2
2
|
* @license lucide-react v0.555.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const d=[["path",{d:"M18 8V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h8",key:"10dyio"}],["path",{d:"M10 19v-3.96 3.15",key:"1irgej"}],["path",{d:"M7 19h5",key:"qswx4l"}],["rect",{width:"6",height:"10",x:"16",y:"12",rx:"2",key:"1egngj"}]],c=i("monitor-smartphone",d),x=[{icon:o,title:"Self-healing selectors",body:"Broken locators recover through six escalating tiers before a test fails."},{icon:c,title:"Live Android & iOS devices",body:"Watch, drive and record real devices from the browser."},{icon:l,title:"Hub–node scaling",body:"One hub orchestrates device labs across machines."}];function b({children:t}){return e.jsxs("div",{className:"grid min-h-screen w-full grid-cols-1 bg-[var(--bg)] text-[var(--text)] md:grid-cols-[minmax(0,5fr)_minmax(0,7fr)]",children:[e.jsxs("aside",{className:"relative hidden overflow-hidden border-r border-[rgb(var(--rgb-fg)/0.06)] bg-[var(--surface-sunken)] md:flex md:flex-col",children:[e.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_90%_60%_at_0%_0%,rgb(var(--rgb-accent)/0.14),transparent_60%)]"}),e.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 bg-[linear-gradient(to_right,rgb(var(--rgb-white)/0.03)_1px,transparent_1px),linear-gradient(to_bottom,rgb(var(--rgb-white)/0.03)_1px,transparent_1px)] bg-[size:48px_48px] [mask-image:linear-gradient(to_bottom,black,transparent_85%)]"}),e.jsxs("div",{className:"relative flex flex-1 flex-col justify-between px-12 py-10",children:[e.jsx(n,{className:"h-8 w-auto self-start object-contain"}),e.jsxs("div",{className:"max-w-md",children:[e.jsxs("h2",{className:"text-4xl font-semibold leading-tight tracking-tight",children:["Your device lab,",e.jsx("br",{}),e.jsx("span",{className:"text-[var(--color-accent)]",children:"under control."})]}),e.jsx("p",{className:"mt-4 text-sm leading-relaxed text-[var(--text-muted)]",children:"Appium orchestration for the devices you own — with self-healing tests, live streaming and recordable proof of what ran."}),e.jsx("ul",{className:"mt-10 space-y-6",children:x.map(({icon:a,title:r,body:s})=>e.jsxs("li",{className:"flex gap-4",children:[e.jsx("span",{className:"grid h-9 w-9 shrink-0 place-items-center rounded-lg border border-[var(--accent-border)] bg-[var(--accent-subtle)]",children:e.jsx(a,{className:"h-4 w-4 text-[var(--color-accent)]","aria-hidden":"true"})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-[var(--text)]",children:r}),e.jsx("div",{className:"mt-0.5 text-sm text-[var(--text-muted)]",children:s})]})]},r))})]}),e.jsxs("footer",{className:"flex items-center justify-between border-t border-[rgb(var(--rgb-fg)/0.06)] pt-5 text-xs text-[var(--text-muted)]",children:[e.jsxs("span",{children:["Xenon v","2.
|
|
6
|
+
*/const d=[["path",{d:"M18 8V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h8",key:"10dyio"}],["path",{d:"M10 19v-3.96 3.15",key:"1irgej"}],["path",{d:"M7 19h5",key:"qswx4l"}],["rect",{width:"6",height:"10",x:"16",y:"12",rx:"2",key:"1egngj"}]],c=i("monitor-smartphone",d),x=[{icon:o,title:"Self-healing selectors",body:"Broken locators recover through six escalating tiers before a test fails."},{icon:c,title:"Live Android & iOS devices",body:"Watch, drive and record real devices from the browser."},{icon:l,title:"Hub–node scaling",body:"One hub orchestrates device labs across machines."}];function b({children:t}){return e.jsxs("div",{className:"grid min-h-screen w-full grid-cols-1 bg-[var(--bg)] text-[var(--text)] md:grid-cols-[minmax(0,5fr)_minmax(0,7fr)]",children:[e.jsxs("aside",{className:"relative hidden overflow-hidden border-r border-[rgb(var(--rgb-fg)/0.06)] bg-[var(--surface-sunken)] md:flex md:flex-col",children:[e.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_90%_60%_at_0%_0%,rgb(var(--rgb-accent)/0.14),transparent_60%)]"}),e.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 bg-[linear-gradient(to_right,rgb(var(--rgb-white)/0.03)_1px,transparent_1px),linear-gradient(to_bottom,rgb(var(--rgb-white)/0.03)_1px,transparent_1px)] bg-[size:48px_48px] [mask-image:linear-gradient(to_bottom,black,transparent_85%)]"}),e.jsxs("div",{className:"relative flex flex-1 flex-col justify-between px-12 py-10",children:[e.jsx(n,{className:"h-8 w-auto self-start object-contain"}),e.jsxs("div",{className:"max-w-md",children:[e.jsxs("h2",{className:"text-4xl font-semibold leading-tight tracking-tight",children:["Your device lab,",e.jsx("br",{}),e.jsx("span",{className:"text-[var(--color-accent)]",children:"under control."})]}),e.jsx("p",{className:"mt-4 text-sm leading-relaxed text-[var(--text-muted)]",children:"Appium orchestration for the devices you own — with self-healing tests, live streaming and recordable proof of what ran."}),e.jsx("ul",{className:"mt-10 space-y-6",children:x.map(({icon:a,title:r,body:s})=>e.jsxs("li",{className:"flex gap-4",children:[e.jsx("span",{className:"grid h-9 w-9 shrink-0 place-items-center rounded-lg border border-[var(--accent-border)] bg-[var(--accent-subtle)]",children:e.jsx(a,{className:"h-4 w-4 text-[var(--color-accent)]","aria-hidden":"true"})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-[var(--text)]",children:r}),e.jsx("div",{className:"mt-0.5 text-sm text-[var(--text-muted)]",children:s})]})]},r))})]}),e.jsxs("footer",{className:"flex items-center justify-between border-t border-[rgb(var(--rgb-fg)/0.06)] pt-5 text-xs text-[var(--text-muted)]",children:[e.jsxs("span",{children:["Xenon v","2.13.0"," · Self-hosted device lab"]}),e.jsx("a",{href:"/xenon/api-docs",target:"_blank",rel:"noreferrer",className:"text-[var(--text-muted)] underline-offset-4 hover:text-[var(--text)] hover:underline",children:"API docs"})]})]})]}),e.jsx("main",{className:"flex items-center justify-center px-6 py-10",children:e.jsx("div",{className:"w-full max-w-[400px] rounded-xl border border-[var(--border)] bg-[var(--surface)] px-8 py-9 shadow-[var(--shadow-lg)]",children:t})})]})}export{b as A};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as ee,r as h,p as te,X,j as e,z as V,R as _,f as se,T as ae,q as re,u as ne,i as le,t as oe,M as ie}from"./index-
|
|
1
|
+
import{c as ee,r as h,p as te,X,j as e,z as V,R as _,f as se,T as ae,q as re,u as ne,i as le,t as oe,M as ie}from"./index-CHOr4JCs.js";import{s as ce,b as L,P as de,T as B,i as xe,f as q,a as ue,c as me,d as pe,p as he,e as fe,r as ve,C as be,g as ge,h as je,j as A,k as Ne,l as W,S as we,m as ye,n as Se,u as Ce,o as $e}from"./use-builds-data-CHW-MhaP.js";import{I as J}from"./input-CJ8z3IO5.js";import{L as ke,a as Me}from"./list-checks-mXGHUVbB.js";import{B as O}from"./button-BxnHCCsX.js";import{D as Ee}from"./download-Bd8OGLzi.js";import{s as Te}from"./labels-C21SA4JG.js";import{C as Re}from"./circle-x-Cf6AF2B2.js";import{C as Be}from"./circle-check-D4EzyGzs.js";import{C as Le}from"./chevron-right-BA2Fntu-.js";import{T as Ie}from"./tablet-68J5f6zh.js";import{M as _e}from"./monitor-D8WQK8md.js";import{S}from"./stat-tile-DFhv8JoI.js";import{P as De}from"./page-header-Cm1XL49f.js";import{S as Ae}from"./select-CZuCnold.js";import{E as F}from"./EmptyState-BE_5f8Vw.js";import"./time-D-gjmE1o.js";import"./utils-CDN07tui.js";/**
|
|
2
2
|
* @license lucide-react v0.555.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as x,j as z}from"./index-
|
|
1
|
+
import{r as x,j as z}from"./index-CHOr4JCs.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 Q,j as s,r as u,C as pn,U as jr,X as G,t as Be,v as Ls,b as wr,u as $t,a as ts,T as kr,q as Ss,R as it,w as Sr,x as Cs,y as Fe,z as Os,I as ti,S as Ot,f as ot,A as Bt,B as Cr,i as si,D as Nr,E as Er,F as Tr,p as Ar}from"./index-
|
|
1
|
+
import{c as Q,j as s,r as u,C as pn,U as jr,X as G,t as Be,v as Ls,b as wr,u as $t,a as ts,T as kr,q as Ss,R as it,w as Sr,x as Cs,y as Fe,z as Os,I as ti,S as Ot,f as ot,A as Bt,B as Cr,i as si,D as Nr,E as Er,F as Tr,p as Ar}from"./index-CHOr4JCs.js";import{P as Rr}from"./page-header-Cm1XL49f.js";import{P as Wt,S as Mr,B as zr}from"./BugReportButton-D-DSGg8C.js";import{A as $r}from"./activity-CnLvNwae.js";import{h as Ir,M as ni,S as ii,C as _r,a as Nt,i as Dr,b as gn,H as Lr,A as wt,I as hs}from"./recording-group-store-BWeeNs2_.js";import{p as ss}from"./labels-C21SA4JG.js";import{B as P}from"./button-BxnHCCsX.js";import{S as ri}from"./select-CZuCnold.js";import{P as qt,M as Fs,a as be,b as ai}from"./Menu-BiW3os9u.js";import{M as ns}from"./Modal-DfawTxih.js";import{F as Vt}from"./FieldGroup-DqMf7Rf3.js";import{C as Or}from"./clock-EZfet0sS.js";import{P as Fr}from"./plus-CIIvR_6Z.js";import{C as $e}from"./copy-Bc6P8v9V.js";import{T as Pr}from"./tablet-68J5f6zh.js";import{S as Ur,a as vn}from"./SegmentedControl-B7m9kpom.js";import{T as Br,a as Wr,b as oi,c as Xt,d as Vr,e as st}from"./Table-DlEuFgv-.js";import{L as li,a as Hr}from"./list-checks-mXGHUVbB.js";import{C as Kr}from"./chevron-right-BA2Fntu-.js";import{M as yn}from"./mouse-pointer-2-Cw2tWzDX.js";import{Z as ci}from"./zap-COC2tZaH.js";import{C as At}from"./check-R6V3bot0.js";import{C as di}from"./circle-check-D4EzyGzs.js";import{C as ui}from"./circle-x-Cf6AF2B2.js";import{E as qr}from"./EmptyState-BE_5f8Vw.js";import{I as xn}from"./input-CJ8z3IO5.js";import{P as Xr,a as Yr}from"./play-C0CuKLXj.js";import{D as hi}from"./download-Bd8OGLzi.js";import{U as Gr,T as Jr}from"./upload-BYf26K71.js";import{A as Zr}from"./arrow-left-CLQWAiCY.js";import{A as Qr}from"./arrow-right-K6A5e_Ee.js";import{p as ea,A as ta}from"./AnnotationOverlay-CzbFYtPI.js";import{T as sa}from"./trash-2-CcSsv4fS.js";import{L as na}from"./lock-BSXM1xvq.js";import{F as bn}from"./FilterMenu-BQY75Su3.js";import"./utils-CDN07tui.js";import"./index-BiL0Enl_.js";/**
|
|
2
2
|
* @license lucide-react v0.555.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as t,j as e,e as m,g as b}from"./index-
|
|
1
|
+
import{r as t,j as e,e as m,g as b}from"./index-CHOr4JCs.js";import{u as g}from"./use-password-reset-mode-DozShXkk.js";import{A as c}from"./auth-shell-BYRHcZd6.js";import"./network-Ba_uFxWo.js";function N(){const[s,d]=t.useState(""),[a,o]=t.useState(!1),[u,x]=t.useState(!1),[n,l]=t.useState(null),i=g();async function f(r){r.preventDefault(),o(!0),l(null);try{await b(s),x(!0)}catch(h){l(h.message||"Request failed")}finally{o(!1)}}return i!=="email"?e.jsxs(c,{children:[e.jsx("h1",{className:"text-2xl font-semibold mb-1",children:"Forgot password?"}),i==="admin"&&e.jsx("p",{className:"text-sm text-[var(--text-muted)] mb-6",children:"This Xenon server can't send email, so passwords are reset by an administrator. Ask a Xenon admin to send you a reset link from the Users page."}),e.jsx("div",{className:"mt-6 text-center",children:e.jsx(m,{to:"/login",className:"text-sm text-[var(--color-accent)] underline-offset-4 hover:underline",children:"Back to sign in"})})]}):e.jsx(c,{children:e.jsxs("form",{onSubmit:f,children:[e.jsx("h1",{className:"text-2xl font-semibold mb-1",children:"Forgot password?"}),e.jsx("p",{className:"text-sm text-[var(--text-muted)] mb-6",children:"Enter your email and we'll send you a reset link if your account exists."}),u?e.jsx("div",{className:"text-sm text-[var(--text)] mb-6",children:"If your email is registered, you'll receive a reset link shortly. Check your spam folder if you don't see it within a minute."}):e.jsxs(e.Fragment,{children:[e.jsx("label",{htmlFor:"forgot-email",className:"block text-sm font-medium text-[var(--text)] mb-1.5",children:"Email"}),e.jsx("input",{id:"forgot-email",type:"email",autoComplete:"username",value:s,onChange:r=>d(r.target.value),autoFocus:!0,required:!0,className:"w-full mb-4 h-10 px-3 rounded-lg bg-[var(--bg)] border border-[var(--border-strong)] text-sm text-[var(--text)] outline-none focus:border-[var(--color-accent)] focus:shadow-[0_0_0_3px_var(--accent-subtle)]"}),n&&e.jsx("div",{role:"alert",className:"text-sm text-[var(--red)] mb-3",children:n}),e.jsx("button",{type:"submit",disabled:a||!s,className:"mt-5 w-full h-10 rounded-md bg-[var(--color-accent)] text-[var(--color-on-accent)] font-medium text-sm disabled:opacity-50",children:a?"Sending…":"Send reset link"})]}),e.jsx("div",{className:"mt-6 text-center",children:e.jsx(m,{to:"/login",className:"text-sm text-[var(--color-accent)] underline-offset-4 hover:underline",children:"Back to sign in"})})]})})}export{N as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as o,j as h,x as U,a2 as N}from"./index-
|
|
1
|
+
import{r as o,j as h,x as U,a2 as N}from"./index-CHOr4JCs.js";function T(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}function B(...e){return t=>{let r=!1;const s=e.map(n=>{const i=T(n,t);return!r&&typeof i=="function"&&(r=!0),i});if(r)return()=>{for(let n=0;n<s.length;n++){const i=s[n];typeof i=="function"?i():T(e[n],null)}}}}function W(...e){return o.useCallback(B(...e),e)}function V(e){const t=z(e),r=o.forwardRef((s,n)=>{const{children:i,...u}=s,c=o.Children.toArray(i),f=c.find(X);if(f){const a=f.props.children,l=c.map(v=>v===f?o.Children.count(a)>1?o.Children.only(null):o.isValidElement(a)?a.props.children:null:v);return h.jsx(t,{...u,ref:n,children:o.isValidElement(a)?o.cloneElement(a,void 0,l):null})}return h.jsx(t,{...u,ref:n,children:i})});return r.displayName=`${e}.Slot`,r}function z(e){const t=o.forwardRef((r,s)=>{const{children:n,...i}=r;if(o.isValidElement(n)){const u=Z(n),c=Y(i,n.props);return n.type!==o.Fragment&&(c.ref=s?B(s,u):u),o.cloneElement(n,c)}return o.Children.count(n)>1?o.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var K=Symbol("radix.slottable");function X(e){return o.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===K}function Y(e,t){const r={...t};for(const s in t){const n=e[s],i=t[s];/^on[A-Z]/.test(s)?n&&i?r[s]=(...c)=>{const f=i(...c);return n(...c),f}:n&&(r[s]=n):s==="style"?r[s]={...n,...i}:s==="className"&&(r[s]=[n,i].filter(Boolean).join(" "))}return{...e,...r}}function Z(e){var s,n;let t=(s=Object.getOwnPropertyDescriptor(e.props,"ref"))==null?void 0:s.get,r=t&&"isReactWarning"in t&&t.isReactWarning;return r?e.ref:(t=(n=Object.getOwnPropertyDescriptor(e,"ref"))==null?void 0:n.get,r=t&&"isReactWarning"in t&&t.isReactWarning,r?e.props.ref:e.props.ref||e.ref)}var q=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],$=q.reduce((e,t)=>{const r=V(`Primitive.${t}`),s=o.forwardRef((n,i)=>{const{asChild:u,...c}=n,f=u?r:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),h.jsx(f,{...c,ref:i})});return s.displayName=`Primitive.${t}`,{...e,[t]:s}},{});function G(e,t){e&&U.flushSync(()=>e.dispatchEvent(t))}function pe(e,t){const r=o.createContext(t),s=i=>{const{children:u,...c}=i,f=o.useMemo(()=>c,Object.values(c));return h.jsx(r.Provider,{value:f,children:u})};s.displayName=e+"Provider";function n(i){const u=o.useContext(r);if(u)return u;if(t!==void 0)return t;throw new Error(`\`${i}\` must be used within \`${e}\``)}return[s,n]}function ve(e,t=[]){let r=[];function s(i,u){const c=o.createContext(u),f=r.length;r=[...r,u];const a=v=>{var b;const{scope:d,children:m,...E}=v,y=((b=d==null?void 0:d[e])==null?void 0:b[f])||c,P=o.useMemo(()=>E,Object.values(E));return h.jsx(y.Provider,{value:P,children:m})};a.displayName=i+"Provider";function l(v,d){var y;const m=((y=d==null?void 0:d[e])==null?void 0:y[f])||c,E=o.useContext(m);if(E)return E;if(u!==void 0)return u;throw new Error(`\`${v}\` must be used within \`${i}\``)}return[a,l]}const n=()=>{const i=r.map(u=>o.createContext(u));return function(c){const f=(c==null?void 0:c[e])||i;return o.useMemo(()=>({[`__scope${e}`]:{...c,[e]:f}}),[c,f])}};return n.scopeName=e,[s,J(n,...t)]}function J(...e){const t=e[0];if(e.length===1)return t;const r=()=>{const s=e.map(n=>({useScope:n(),scopeName:n.scopeName}));return function(i){const u=s.reduce((c,{useScope:f,scopeName:a})=>{const v=f(i)[`__scope${a}`];return{...c,...v}},{});return o.useMemo(()=>({[`__scope${t.scopeName}`]:u}),[u])}};return r.scopeName=t.scopeName,r}function g(e){const t=o.useRef(e);return o.useEffect(()=>{t.current=e}),o.useMemo(()=>(...r)=>{var s;return(s=t.current)==null?void 0:s.call(t,...r)},[])}var j=globalThis!=null&&globalThis.document?o.useLayoutEffect:()=>{};function S(e,t,{checkForDefaultPrevented:r=!0}={}){return function(n){if(e==null||e(n),r===!1||!n.defaultPrevented)return t==null?void 0:t(n)}}function Q(e,t=globalThis==null?void 0:globalThis.document){const r=g(e);o.useEffect(()=>{const s=n=>{n.key==="Escape"&&r(n)};return t.addEventListener("keydown",s,{capture:!0}),()=>t.removeEventListener("keydown",s,{capture:!0})},[r,t])}var H="DismissableLayer",w="dismissableLayer.update",ee="dismissableLayer.pointerDownOutside",te="dismissableLayer.focusOutside",I,A=o.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),ne=o.forwardRef((e,t)=>{const{disableOutsidePointerEvents:r=!1,onEscapeKeyDown:s,onPointerDownOutside:n,onFocusOutside:i,onInteractOutside:u,onDismiss:c,...f}=e,a=o.useContext(A),[l,v]=o.useState(null),d=(l==null?void 0:l.ownerDocument)??(globalThis==null?void 0:globalThis.document),[,m]=o.useState({}),E=W(t,p=>v(p)),y=Array.from(a.layers),[P]=[...a.layersWithOutsidePointerEventsDisabled].slice(-1),b=y.indexOf(P),D=l?y.indexOf(l):-1,k=a.layersWithOutsidePointerEventsDisabled.size>0,R=D>=b,M=oe(p=>{const C=p.target,O=[...a.branches].some(x=>x.contains(C));!R||O||(n==null||n(p),u==null||u(p),p.defaultPrevented||c==null||c())},d),L=ie(p=>{const C=p.target;[...a.branches].some(x=>x.contains(C))||(i==null||i(p),u==null||u(p),p.defaultPrevented||c==null||c())},d);return Q(p=>{D===a.layers.size-1&&(s==null||s(p),!p.defaultPrevented&&c&&(p.preventDefault(),c()))},d),o.useEffect(()=>{if(l)return r&&(a.layersWithOutsidePointerEventsDisabled.size===0&&(I=d.body.style.pointerEvents,d.body.style.pointerEvents="none"),a.layersWithOutsidePointerEventsDisabled.add(l)),a.layers.add(l),_(),()=>{r&&a.layersWithOutsidePointerEventsDisabled.size===1&&(d.body.style.pointerEvents=I)}},[l,d,r,a]),o.useEffect(()=>()=>{l&&(a.layers.delete(l),a.layersWithOutsidePointerEventsDisabled.delete(l),_())},[l,a]),o.useEffect(()=>{const p=()=>m({});return document.addEventListener(w,p),()=>document.removeEventListener(w,p)},[]),h.jsx($.div,{...f,ref:E,style:{pointerEvents:k?R?"auto":"none":void 0,...e.style},onFocusCapture:S(e.onFocusCapture,L.onFocusCapture),onBlurCapture:S(e.onBlurCapture,L.onBlurCapture),onPointerDownCapture:S(e.onPointerDownCapture,M.onPointerDownCapture)})});ne.displayName=H;var re="DismissableLayerBranch",se=o.forwardRef((e,t)=>{const r=o.useContext(A),s=o.useRef(null),n=W(t,s);return o.useEffect(()=>{const i=s.current;if(i)return r.branches.add(i),()=>{r.branches.delete(i)}},[r.branches]),h.jsx($.div,{...e,ref:n})});se.displayName=re;function oe(e,t=globalThis==null?void 0:globalThis.document){const r=g(e),s=o.useRef(!1),n=o.useRef(()=>{});return o.useEffect(()=>{const i=c=>{if(c.target&&!s.current){let f=function(){F(ee,r,a,{discrete:!0})};const a={originalEvent:c};c.pointerType==="touch"?(t.removeEventListener("click",n.current),n.current=f,t.addEventListener("click",n.current,{once:!0})):f()}else t.removeEventListener("click",n.current);s.current=!1},u=window.setTimeout(()=>{t.addEventListener("pointerdown",i)},0);return()=>{window.clearTimeout(u),t.removeEventListener("pointerdown",i),t.removeEventListener("click",n.current)}},[t,r]),{onPointerDownCapture:()=>s.current=!0}}function ie(e,t=globalThis==null?void 0:globalThis.document){const r=g(e),s=o.useRef(!1);return o.useEffect(()=>{const n=i=>{i.target&&!s.current&&F(te,r,{originalEvent:i},{discrete:!1})};return t.addEventListener("focusin",n),()=>t.removeEventListener("focusin",n)},[t,r]),{onFocusCapture:()=>s.current=!0,onBlurCapture:()=>s.current=!1}}function _(){const e=new CustomEvent(w);document.dispatchEvent(e)}function F(e,t,r,{discrete:s}){const n=r.originalEvent.target,i=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:r});t&&n.addEventListener(e,t,{once:!0}),s?G(n,i):n.dispatchEvent(i)}var ce=N[" useId ".trim().toString()]||(()=>{}),ue=0;function Ee(e){const[t,r]=o.useState(ce());return j(()=>{r(s=>s??String(ue++))},[e]),e||(t?`radix-${t}`:"")}var ae=N[" useInsertionEffect ".trim().toString()]||j;function ye({prop:e,defaultProp:t,onChange:r=()=>{},caller:s}){const[n,i,u]=le({defaultProp:t,onChange:r}),c=e!==void 0,f=c?e:n;{const l=o.useRef(e!==void 0);o.useEffect(()=>{const v=l.current;v!==c&&console.warn(`${s} is changing from ${v?"controlled":"uncontrolled"} to ${c?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),l.current=c},[c,s])}const a=o.useCallback(l=>{var v;if(c){const d=fe(l)?l(e):l;d!==e&&((v=u.current)==null||v.call(u,d))}else i(l)},[c,e,i,u]);return[f,a]}function le({defaultProp:e,onChange:t}){const[r,s]=o.useState(e),n=o.useRef(r),i=o.useRef(t);return ae(()=>{i.current=t},[t]),o.useEffect(()=>{var u;n.current!==r&&((u=i.current)==null||u.call(i,r),n.current=r)},[r,n]),[r,s,i]}function fe(e){return typeof e=="function"}export{ne as D,$ as P,W as a,j as b,ye as c,Ee as d,S as e,ve as f,V as g,pe as h,B as i,g as u};
|