mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
feat: IAM Frontend (#65)
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
import{c as B,y as $,z as C,v as F,j as s,t as K,A as b,C as v,L}from"./index.js";import{u as A}from"./useSuspenseQuery.js";import{B as E}from"./back-link.js";import{E as O}from"./error-banner.js";import{a as S}from"./s3.js";import{U,F as R,O as I}from"./upload-button.js";import"./alert-dialog.js";import"./download.js";import"./trash-2.js";function J(){const e=B.c(24),{bucket:n,_splat:k}=$.useParams(),r=C(k||""),{data:m}=A(F(n,r)),a=S();let d;e[0]!==m.Contents?(d=m.Contents||[],e[0]=m.Contents,e[1]=d):d=e[1];const o=d;let p;e[2]!==m.CommonPrefixes?(p=m.CommonPrefixes||[],e[2]=m.CommonPrefixes,e[3]=p):p=e[3];const i=p,u=r.split("/").filter(Boolean),y=[{name:n,path:`/s3/ls/${n}`},...u.map((t,l)=>{const c=`${u.slice(0,l+1).join("/")}/`;return{name:t,path:`/s3/ls/${n}/${c}`}})],P=u.length>1?`/s3/ls/${n}/${u.slice(0,-1).join("/")}/`:`/s3/ls/${n}`;let f;e[4]!==P?(f=s.jsx(E,{to:P,children:"Back"}),e[4]=P,e[5]=f):f=e[5];let x;e[6]!==n||e[7]!==r||e[8]!==a.isPending||e[9]!==a.mutateAsync?(x=s.jsx(U,{bucket:n,isPending:a.isPending,onUpload:a.mutateAsync,prefix:r}),e[6]=n,e[7]=r,e[8]=a.isPending,e[9]=a.mutateAsync,e[10]=x):x=e[10];let h;e[11]!==a.error?(h=a.error&&s.jsx(O,{error:a.error,msg:"Failed to upload object"}),e[11]=a.error,e[12]=h):h=e[12];let g;e[13]!==n||e[14]!==i||e[15]!==r?(g=i.length>0&&s.jsxs("div",{className:"mb-6",children:[s.jsx("h2",{className:"mb-3 font-semibold text-lg",children:"Folders"}),s.jsx("div",{className:"space-y-2",children:i.map(t=>{if(!t.Prefix)return null;const l=K(b(t.Prefix,r)),c=v(t.Prefix,r);return s.jsx(R,{bucketName:n,folderName:l,fullPrefix:c},t.Prefix)})})]}),e[13]=n,e[14]=i,e[15]=r,e[16]=g):g=e[16];let j;e[17]!==n||e[18]!==o||e[19]!==r?(j=o.length>0&&s.jsxs("div",{className:"space-y-2",children:[s.jsx("h2",{className:"mb-3 font-semibold text-lg",children:"Objects"}),o.map(t=>{if(!t.Key)return null;const l=b(t.Key,r),c=v(t.Key,r);return s.jsx(I,{bucketName:n,displayName:l,fullKey:c,object:t},t.Key)})]}),e[17]=n,e[18]=o,e[19]=r,e[20]=j):j=e[20];let N;return e[21]!==i.length||e[22]!==o.length?(N=o.length===0&&i.length===0&&s.jsx("p",{className:"text-muted-foreground",children:"No objects found in this folder."}),e[21]=i.length,e[22]=o.length,e[23]=N):N=e[23],s.jsxs(s.Fragment,{children:[f,s.jsx("div",{className:"mb-6",children:s.jsxs("div",{className:"mb-2 flex items-center justify-between",children:[s.jsx("div",{className:"flex items-center gap-2 text-muted-foreground text-sm",children:y.map((t,l)=>s.jsxs("div",{className:"flex items-center gap-2",children:[l>0&&s.jsx("span",{children:"/"}),l===y.length-1?s.jsx("span",{className:"text-foreground",children:t.name}):s.jsx(L,{className:"hover:text-foreground",to:t.path,children:t.name})]},t.path))}),x]})}),h,g,j,N]})}export{J as component};
|
||||
import{c as B,F as $,G as F,x as C,j as s,w as K,H as b,I as k,L}from"./index.js";import{u as E}from"./useSuspenseQuery.js";import{B as O}from"./back-link.js";import{E as S}from"./error-banner.js";import{a as U}from"./s3.js";import{U as A,F as I,O as R}from"./upload-button.js";import"./alert-dialog.js";import"./download.js";import"./trash-2.js";function J(){const e=B.c(24),{bucket:n,_splat:v}=$.useParams(),r=F(v||""),{data:m}=E(C(n,r)),a=U();let d;e[0]!==m.Contents?(d=m.Contents||[],e[0]=m.Contents,e[1]=d):d=e[1];const o=d;let p;e[2]!==m.CommonPrefixes?(p=m.CommonPrefixes||[],e[2]=m.CommonPrefixes,e[3]=p):p=e[3];const i=p,u=r.split("/").filter(Boolean),y=[{name:n,path:`/s3/ls/${n}`},...u.map((t,l)=>{const c=`${u.slice(0,l+1).join("/")}/`;return{name:t,path:`/s3/ls/${n}/${c}`}})],P=u.length>1?`/s3/ls/${n}/${u.slice(0,-1).join("/")}/`:`/s3/ls/${n}`;let x;e[4]!==P?(x=s.jsx(O,{to:P,children:"Back"}),e[4]=P,e[5]=x):x=e[5];let f;e[6]!==n||e[7]!==r||e[8]!==a.isPending||e[9]!==a.mutateAsync?(f=s.jsx(A,{bucket:n,isPending:a.isPending,onUpload:a.mutateAsync,prefix:r}),e[6]=n,e[7]=r,e[8]=a.isPending,e[9]=a.mutateAsync,e[10]=f):f=e[10];let h;e[11]!==a.error?(h=a.error&&s.jsx(S,{error:a.error,msg:"Failed to upload object"}),e[11]=a.error,e[12]=h):h=e[12];let g;e[13]!==n||e[14]!==i||e[15]!==r?(g=i.length>0&&s.jsxs("div",{className:"mb-6",children:[s.jsx("h2",{className:"mb-3 font-semibold text-lg",children:"Folders"}),s.jsx("div",{className:"space-y-2",children:i.map(t=>{if(!t.Prefix)return null;const l=K(b(t.Prefix,r)),c=k(t.Prefix,r);return s.jsx(I,{bucketName:n,folderName:l,fullPrefix:c},t.Prefix)})})]}),e[13]=n,e[14]=i,e[15]=r,e[16]=g):g=e[16];let j;e[17]!==n||e[18]!==o||e[19]!==r?(j=o.length>0&&s.jsxs("div",{className:"space-y-2",children:[s.jsx("h2",{className:"mb-3 font-semibold text-lg",children:"Objects"}),o.map(t=>{if(!t.Key)return null;const l=b(t.Key,r),c=k(t.Key,r);return s.jsx(R,{bucketName:n,displayName:l,fullKey:c,object:t},t.Key)})]}),e[17]=n,e[18]=o,e[19]=r,e[20]=j):j=e[20];let N;return e[21]!==i.length||e[22]!==o.length?(N=o.length===0&&i.length===0&&s.jsx("p",{className:"text-muted-foreground",children:"No objects found in this folder."}),e[21]=i.length,e[22]=o.length,e[23]=N):N=e[23],s.jsxs(s.Fragment,{children:[x,s.jsx("div",{className:"mb-6",children:s.jsxs("div",{className:"mb-2 flex items-center justify-between",children:[s.jsx("div",{className:"flex items-center gap-2 text-muted-foreground text-sm",children:y.map((t,l)=>s.jsxs("div",{className:"flex items-center gap-2",children:[l>0&&s.jsx("span",{children:"/"}),l===y.length-1?s.jsx("span",{className:"text-foreground",children:t.name}):s.jsx(L,{className:"hover:text-foreground",to:t.path,children:t.name})]},t.path))}),f]})}),h,g,j,N]})}export{J as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{ak as D,u as g,al as b,p as f,r as v,j as e,B as C,L as I}from"./index.js";import{u as d}from"./useSuspenseQuery.js";import{B as u}from"./back-link.js";import{D as l,a as t}from"./detail-row.js";import{E as V}from"./error-banner.js";import{P as S}from"./page-heading.js";import{S as y}from"./state-badge.js";import{g as P,f as A,b as k,a as B,c as w,d as N,e as T,h as O}from"./alert-dialog.js";import{g as H}from"./ec2.js";import{T as R}from"./trash-2.js";function q(){const{id:r}=D.useParams(),x=g(),{data:p}=d(b(r)),{data:m}=d(f),s=p.Vpcs?.[0],n=H(),[j,i]=v.useState(!1),o=m.Subnets?.filter(a=>a.VpcId===r)??[],h=async()=>{try{await n.mutateAsync(r),x({to:"/ec2/describe-vpcs"})}finally{i(!1)}};if(!s?.VpcId)return e.jsxs(e.Fragment,{children:[e.jsx(u,{to:"/ec2/describe-vpcs",children:"Back to VPCs"}),e.jsx("p",{className:"text-muted-foreground",children:"VPC not found."})]});const c=s.Tags?.find(a=>a.Key==="Name")?.Value;return e.jsxs(e.Fragment,{children:[e.jsx(u,{to:"/ec2/describe-vpcs",children:"Back to VPCs"}),n.error&&e.jsx(V,{error:n.error,msg:"Failed to delete VPC"}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(S,{actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(C,{onClick:()=>i(!0),size:"sm",variant:"destructive",children:[e.jsx(R,{className:"size-4"}),"Delete"]}),e.jsx(y,{state:s.State})]}),subtitle:"VPC Details",title:c?`${s.VpcId} (${c})`:s.VpcId}),e.jsxs(l,{children:[e.jsx(l.Header,{children:"VPC Information"}),e.jsxs(l.Content,{children:[e.jsx(t,{label:"VPC ID",value:s.VpcId}),e.jsx(t,{label:"State",value:s.State}),e.jsx(t,{label:"CIDR Block",value:s.CidrBlock}),e.jsx(t,{label:"Is Default",value:s.IsDefault?"Yes":"No"}),e.jsx(t,{label:"DHCP Options ID",value:s.DhcpOptionsId}),e.jsx(t,{label:"Instance Tenancy",value:s.InstanceTenancy}),e.jsx(t,{label:"Owner ID",value:s.OwnerId})]})]}),o.length>0&&e.jsxs(l,{children:[e.jsxs(l.Header,{children:["Subnets (",o.length,")"]}),o.map(a=>a.SubnetId?e.jsxs(l.Content,{children:[e.jsx(t,{label:"Subnet ID",value:e.jsx(I,{className:"text-primary hover:underline",params:{id:a.SubnetId},to:"/ec2/describe-subnets/$id",children:a.SubnetId})}),e.jsx(t,{label:"CIDR Block",value:a.CidrBlock}),e.jsx(t,{label:"Availability Zone",value:a.AvailabilityZone}),e.jsx(t,{label:"State",value:a.State})]},a.SubnetId):null)]})]}),e.jsx(P,{onOpenChange:i,open:j,children:e.jsxs(A,{children:[e.jsxs(k,{children:[e.jsx(B,{children:"Delete VPC"}),e.jsxs(w,{children:['Are you sure you want to delete the VPC "',s.VpcId,'"? This action cannot be undone. The VPC must have no associated subnets or internet gateways.']})]}),e.jsxs(N,{children:[e.jsx(T,{children:"Cancel"}),e.jsx(O,{disabled:n.isPending,onClick:h,children:n.isPending?"Deleting…":"Delete"})]})]})})]})}export{q as component};
|
||||
import{aJ as D,u as g,aK as b,t as f,r as v,j as e,B as C,L as I}from"./index.js";import{u as d}from"./useSuspenseQuery.js";import{B as u}from"./back-link.js";import{D as l,a as t}from"./detail-row.js";import{E as V}from"./error-banner.js";import{P as S}from"./page-heading.js";import{S as y}from"./state-badge.js";import{g as P,f as A,b as B,a as k,c as w,d as N,e as T,h as O}from"./alert-dialog.js";import{g as H}from"./ec2.js";import{T as R}from"./trash-2.js";function Y(){const{id:r}=D.useParams(),x=g(),{data:p}=d(b(r)),{data:m}=d(f),s=p.Vpcs?.[0],n=H(),[j,i]=v.useState(!1),o=m.Subnets?.filter(a=>a.VpcId===r)??[],h=async()=>{try{await n.mutateAsync(r),x({to:"/ec2/describe-vpcs"})}finally{i(!1)}};if(!s?.VpcId)return e.jsxs(e.Fragment,{children:[e.jsx(u,{to:"/ec2/describe-vpcs",children:"Back to VPCs"}),e.jsx("p",{className:"text-muted-foreground",children:"VPC not found."})]});const c=s.Tags?.find(a=>a.Key==="Name")?.Value;return e.jsxs(e.Fragment,{children:[e.jsx(u,{to:"/ec2/describe-vpcs",children:"Back to VPCs"}),n.error&&e.jsx(V,{error:n.error,msg:"Failed to delete VPC"}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(S,{actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(C,{onClick:()=>i(!0),size:"sm",variant:"destructive",children:[e.jsx(R,{className:"size-4"}),"Delete"]}),e.jsx(y,{state:s.State})]}),subtitle:"VPC Details",title:c?`${s.VpcId} (${c})`:s.VpcId}),e.jsxs(l,{children:[e.jsx(l.Header,{children:"VPC Information"}),e.jsxs(l.Content,{children:[e.jsx(t,{label:"VPC ID",value:s.VpcId}),e.jsx(t,{label:"State",value:s.State}),e.jsx(t,{label:"CIDR Block",value:s.CidrBlock}),e.jsx(t,{label:"Is Default",value:s.IsDefault?"Yes":"No"}),e.jsx(t,{label:"DHCP Options ID",value:s.DhcpOptionsId}),e.jsx(t,{label:"Instance Tenancy",value:s.InstanceTenancy}),e.jsx(t,{label:"Owner ID",value:s.OwnerId})]})]}),o.length>0&&e.jsxs(l,{children:[e.jsxs(l.Header,{children:["Subnets (",o.length,")"]}),o.map(a=>a.SubnetId?e.jsxs(l.Content,{children:[e.jsx(t,{label:"Subnet ID",value:e.jsx(I,{className:"text-primary hover:underline",params:{id:a.SubnetId},to:"/ec2/describe-subnets/$id",children:a.SubnetId})}),e.jsx(t,{label:"CIDR Block",value:a.CidrBlock}),e.jsx(t,{label:"Availability Zone",value:a.AvailabilityZone}),e.jsx(t,{label:"State",value:a.State})]},a.SubnetId):null)]})]}),e.jsx(P,{onOpenChange:i,open:j,children:e.jsxs(A,{children:[e.jsxs(B,{children:[e.jsx(k,{children:"Delete VPC"}),e.jsxs(w,{children:['Are you sure you want to delete the VPC "',s.VpcId,'"? This action cannot be undone. The VPC must have no associated subnets or internet gateways.']})]}),e.jsxs(N,{children:[e.jsx(T,{children:"Cancel"}),e.jsx(O,{disabled:n.isPending,onClick:h,children:n.isPending?"Deleting…":"Delete"})]})]})})]})}export{Y as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c as T,am as q,u as D,j as s,an as J,B as Q}from"./index.js";import{a as K,u as U}from"./zod.js";import{u as W}from"./useSuspenseQuery.js";import{B as H}from"./back-link.js";import{E as X}from"./error-banner.js";import{P as Y}from"./page-heading.js";import{F as Z,a as ee,b as se}from"./field.js";import{I as te}from"./input.js";import{h as ie}from"./ec2.js";import{m as re}from"./ec22.js";function xe(){const e=T.c(58),{id:R}=q.useParams(),o=D();let S;e[0]!==R?(S=J(R),e[0]=R,e[1]=S):S=e[1];const{data:L}=W(S),A=L.Volumes?.[0],t=A?.VolumeId,r=ie(),i=A?.Size??1;let a;e[2]!==i?(a=K(re.refine(l=>l.size>i,{message:`New size must be greater than current size (${i} GiB)`,path:["size"]})),e[2]=i,e[3]=a):a=e[3];let n;e[4]!==i?(n={size:i},e[4]=i,e[5]=n):n=e[5];let B;e[6]!==a||e[7]!==n?(B={resolver:a,defaultValues:n},e[6]=a,e[7]=n,e[8]=B):B=e[8];const{handleSubmit:k,register:E,formState:O}=U(B),{errors:V,isSubmitting:$}=O;if(!t){let l;return e[9]===Symbol.for("react.memo_cache_sentinel")?(l=s.jsxs(s.Fragment,{children:[s.jsx(H,{to:"/ec2/describe-volumes",children:"Back to volumes"}),s.jsx("p",{className:"text-muted-foreground",children:"Volume not found."})]}),e[9]=l):l=e[9],l}let F;e[10]!==r||e[11]!==o||e[12]!==t?(F=async l=>{await r.mutateAsync({...l,volumeId:t}),o({to:"/ec2/describe-volumes/$id",params:{id:t}})},e[10]=r,e[11]=o,e[12]=t,e[13]=F):F=e[13];const w=F;let m,c;e[14]!==t?(m=s.jsx(H,{params:{id:t},to:"/ec2/describe-volumes/$id",children:"Back to volume"}),c=s.jsx(Y,{subtitle:t,title:"Resize Volume"}),e[14]=t,e[15]=m,e[16]=c):(m=e[15],c=e[16]);let u;e[17]!==r.error?(u=r.error&&s.jsx(X,{error:r.error,msg:"Failed to resize volume"}),e[17]=r.error,e[18]=u):u=e[18];let d;e[19]!==k||e[20]!==w?(d=k(w),e[19]=k,e[20]=w,e[21]=d):d=e[21];let f;e[22]!==i?(f=s.jsx("div",{className:"space-y-2",children:s.jsxs("p",{className:"text-muted-foreground text-sm",children:["Current size: ",i," GiB"]})}),e[22]=i,e[23]=f):f=e[23];let N;e[24]===Symbol.for("react.memo_cache_sentinel")?(N=s.jsx(ee,{children:s.jsx("label",{htmlFor:"size",children:"New size (GiB)"})}),e[24]=N):N=e[24];const I=!!V.size,_=i+1;let p;e[25]!==E?(p=E("size",{valueAsNumber:!0}),e[25]=E,e[26]=p):p=e[26];let x;e[27]!==I||e[28]!==_||e[29]!==p?(x=s.jsx(te,{"aria-invalid":I,id:"size",min:_,type:"number",...p}),e[27]=I,e[28]=_,e[29]=p,e[30]=x):x=e[30];let h;e[31]!==V.size?(h=s.jsx(Z,{errors:[V.size]}),e[31]=V.size,e[32]=h):h=e[32];let b;e[33]!==x||e[34]!==h?(b=s.jsxs(se,{children:[N,x,h]}),e[33]=x,e[34]=h,e[35]=b):b=e[35];const C=$||r.isPending;let j;e[36]!==o||e[37]!==t?(j=()=>o({to:"/ec2/describe-volumes/$id",params:{id:t}}),e[36]=o,e[37]=t,e[38]=j):j=e[38];let z;e[39]!==C||e[40]!==j?(z=s.jsx(Q,{disabled:C,onClick:j,type:"button",variant:"outline",children:"Cancel"}),e[39]=C,e[40]=j,e[41]=z):z=e[41];const G=$||r.isPending,M=$||r.isPending?"Resizing…":"Resize Volume";let g;e[42]!==G||e[43]!==M?(g=s.jsx(Q,{disabled:G,type:"submit",children:M}),e[42]=G,e[43]=M,e[44]=g):g=e[44];let v;e[45]!==z||e[46]!==g?(v=s.jsxs("div",{className:"flex gap-2",children:[z,g]}),e[45]=z,e[46]=g,e[47]=v):v=e[47];let y;e[48]!==f||e[49]!==b||e[50]!==v||e[51]!==d?(y=s.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:d,children:[f,b,v]}),e[48]=f,e[49]=b,e[50]=v,e[51]=d,e[52]=y):y=e[52];let P;return e[53]!==y||e[54]!==m||e[55]!==c||e[56]!==u?(P=s.jsxs(s.Fragment,{children:[m,c,u,y]}),e[53]=y,e[54]=m,e[55]=c,e[56]=u,e[57]=P):P=e[57],P}export{xe as component};
|
||||
import{c as T,aL as q,u as D,j as s,aM as J,B as L}from"./index.js";import{a as K,u as U}from"./zod.js";import{u as W}from"./useSuspenseQuery.js";import{B as Q}from"./back-link.js";import{E as X}from"./error-banner.js";import{P as Y}from"./page-heading.js";import{F as Z,a as ee,b as se}from"./field.js";import{I as te}from"./input.js";import{h as ie}from"./ec2.js";import{m as re}from"./ec22.js";function xe(){const e=T.c(58),{id:R}=q.useParams(),o=D();let S;e[0]!==R?(S=J(R),e[0]=R,e[1]=S):S=e[1];const{data:H}=W(S),A=H.Volumes?.[0],t=A?.VolumeId,r=ie(),i=A?.Size??1;let a;e[2]!==i?(a=K(re.refine(l=>l.size>i,{message:`New size must be greater than current size (${i} GiB)`,path:["size"]})),e[2]=i,e[3]=a):a=e[3];let n;e[4]!==i?(n={size:i},e[4]=i,e[5]=n):n=e[5];let B;e[6]!==a||e[7]!==n?(B={resolver:a,defaultValues:n},e[6]=a,e[7]=n,e[8]=B):B=e[8];const{handleSubmit:k,register:E,formState:O}=U(B),{errors:V,isSubmitting:$}=O;if(!t){let l;return e[9]===Symbol.for("react.memo_cache_sentinel")?(l=s.jsxs(s.Fragment,{children:[s.jsx(Q,{to:"/ec2/describe-volumes",children:"Back to volumes"}),s.jsx("p",{className:"text-muted-foreground",children:"Volume not found."})]}),e[9]=l):l=e[9],l}let F;e[10]!==r||e[11]!==o||e[12]!==t?(F=async l=>{await r.mutateAsync({...l,volumeId:t}),o({to:"/ec2/describe-volumes/$id",params:{id:t}})},e[10]=r,e[11]=o,e[12]=t,e[13]=F):F=e[13];const w=F;let m,c;e[14]!==t?(m=s.jsx(Q,{params:{id:t},to:"/ec2/describe-volumes/$id",children:"Back to volume"}),c=s.jsx(Y,{subtitle:t,title:"Resize Volume"}),e[14]=t,e[15]=m,e[16]=c):(m=e[15],c=e[16]);let u;e[17]!==r.error?(u=r.error&&s.jsx(X,{error:r.error,msg:"Failed to resize volume"}),e[17]=r.error,e[18]=u):u=e[18];let d;e[19]!==k||e[20]!==w?(d=k(w),e[19]=k,e[20]=w,e[21]=d):d=e[21];let f;e[22]!==i?(f=s.jsx("div",{className:"space-y-2",children:s.jsxs("p",{className:"text-muted-foreground text-sm",children:["Current size: ",i," GiB"]})}),e[22]=i,e[23]=f):f=e[23];let N;e[24]===Symbol.for("react.memo_cache_sentinel")?(N=s.jsx(ee,{children:s.jsx("label",{htmlFor:"size",children:"New size (GiB)"})}),e[24]=N):N=e[24];const I=!!V.size,M=i+1;let p;e[25]!==E?(p=E("size",{valueAsNumber:!0}),e[25]=E,e[26]=p):p=e[26];let x;e[27]!==I||e[28]!==M||e[29]!==p?(x=s.jsx(te,{"aria-invalid":I,id:"size",min:M,type:"number",...p}),e[27]=I,e[28]=M,e[29]=p,e[30]=x):x=e[30];let h;e[31]!==V.size?(h=s.jsx(Z,{errors:[V.size]}),e[31]=V.size,e[32]=h):h=e[32];let b;e[33]!==x||e[34]!==h?(b=s.jsxs(se,{children:[N,x,h]}),e[33]=x,e[34]=h,e[35]=b):b=e[35];const _=$||r.isPending;let j;e[36]!==o||e[37]!==t?(j=()=>o({to:"/ec2/describe-volumes/$id",params:{id:t}}),e[36]=o,e[37]=t,e[38]=j):j=e[38];let z;e[39]!==_||e[40]!==j?(z=s.jsx(L,{disabled:_,onClick:j,type:"button",variant:"outline",children:"Cancel"}),e[39]=_,e[40]=j,e[41]=z):z=e[41];const C=$||r.isPending,G=$||r.isPending?"Resizing…":"Resize Volume";let g;e[42]!==C||e[43]!==G?(g=s.jsx(L,{disabled:C,type:"submit",children:G}),e[42]=C,e[43]=G,e[44]=g):g=e[44];let v;e[45]!==z||e[46]!==g?(v=s.jsxs("div",{className:"flex gap-2",children:[z,g]}),e[45]=z,e[46]=g,e[47]=v):v=e[47];let y;e[48]!==f||e[49]!==b||e[50]!==v||e[51]!==d?(y=s.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:d,children:[f,b,v]}),e[48]=f,e[49]=b,e[50]=v,e[51]=d,e[52]=y):y=e[52];let P;return e[53]!==y||e[54]!==m||e[55]!==c||e[56]!==u?(P=s.jsxs(s.Fragment,{children:[m,c,u,y]}),e[53]=y,e[54]=m,e[55]=c,e[56]=u,e[57]=P):P=e[57],P}export{xe as component};
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{az as x,u as j,aA as p,r as h,j as e,B as D,L as g}from"./index.js";import{u as S}from"./useSuspenseQuery.js";import{B as o}from"./back-link.js";import{D as l,a as s}from"./detail-row.js";import{E as f}from"./error-banner.js";import{P as v}from"./page-heading.js";import{S as A}from"./state-badge.js";import{g as I,f as y,b as C,a as B,c as P,d as k,e as N,h as w}from"./alert-dialog.js";import{l as F}from"./ec2.js";import{T as L}from"./trash-2.js";function Q(){const{id:r}=x.useParams(),c=j(),{data:u}=S(p(r)),t=u.Subnets?.[0],a=F(),[d,n]=h.useState(!1),b=async()=>{try{await a.mutateAsync(r),c({to:"/ec2/describe-subnets"})}finally{n(!1)}};if(!t?.SubnetId)return e.jsxs(e.Fragment,{children:[e.jsx(o,{to:"/ec2/describe-subnets",children:"Back to Subnets"}),e.jsx("p",{className:"text-muted-foreground",children:"Subnet not found."})]});const i=t.Tags?.find(m=>m.Key==="Name")?.Value;return e.jsxs(e.Fragment,{children:[e.jsx(o,{to:"/ec2/describe-subnets",children:"Back to Subnets"}),a.error&&e.jsx(f,{error:a.error,msg:"Failed to delete subnet"}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(v,{actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(D,{onClick:()=>n(!0),size:"sm",variant:"destructive",children:[e.jsx(L,{className:"size-4"}),"Delete"]}),e.jsx(A,{state:t.State})]}),subtitle:"Subnet Details",title:i?`${t.SubnetId} (${i})`:t.SubnetId}),e.jsxs(l,{children:[e.jsx(l.Header,{children:"Subnet Information"}),e.jsxs(l.Content,{children:[e.jsx(s,{label:"Subnet ID",value:t.SubnetId}),e.jsx(s,{label:"VPC ID",value:t.VpcId?e.jsx(g,{className:"text-primary hover:underline",params:{id:t.VpcId},to:"/ec2/describe-vpcs/$id",children:t.VpcId}):"—"}),e.jsx(s,{label:"State",value:t.State}),e.jsx(s,{label:"CIDR Block",value:t.CidrBlock}),e.jsx(s,{label:"Availability Zone",value:t.AvailabilityZone}),e.jsx(s,{label:"Available IP Count",value:t.AvailableIpAddressCount?.toString()}),e.jsx(s,{label:"Map Public IP on Launch",value:t.MapPublicIpOnLaunch?"Yes":"No"}),e.jsx(s,{label:"Default for AZ",value:t.DefaultForAz?"Yes":"No"})]})]})]}),e.jsx(I,{onOpenChange:n,open:d,children:e.jsxs(y,{children:[e.jsxs(C,{children:[e.jsx(B,{children:"Delete Subnet"}),e.jsxs(P,{children:['Are you sure you want to delete the subnet "',t.SubnetId,'"? This action cannot be undone.']})]}),e.jsxs(k,{children:[e.jsx(N,{children:"Cancel"}),e.jsx(w,{disabled:a.isPending,onClick:b,children:a.isPending?"Deleting…":"Delete"})]})]})})]})}export{Q as component};
|
||||
import{cX as x,u as j,cY as p,r as h,j as e,B as D,L as g}from"./index.js";import{u as S}from"./useSuspenseQuery.js";import{B as o}from"./back-link.js";import{D as l,a as s}from"./detail-row.js";import{E as f}from"./error-banner.js";import{P as v}from"./page-heading.js";import{S as A}from"./state-badge.js";import{g as I,f as y,b as C,a as B,c as P,d as k,e as N,h as w}from"./alert-dialog.js";import{l as F}from"./ec2.js";import{T as L}from"./trash-2.js";function $(){const{id:r}=x.useParams(),c=j(),{data:u}=S(p(r)),t=u.Subnets?.[0],a=F(),[d,n]=h.useState(!1),b=async()=>{try{await a.mutateAsync(r),c({to:"/ec2/describe-subnets"})}finally{n(!1)}};if(!t?.SubnetId)return e.jsxs(e.Fragment,{children:[e.jsx(o,{to:"/ec2/describe-subnets",children:"Back to Subnets"}),e.jsx("p",{className:"text-muted-foreground",children:"Subnet not found."})]});const i=t.Tags?.find(m=>m.Key==="Name")?.Value;return e.jsxs(e.Fragment,{children:[e.jsx(o,{to:"/ec2/describe-subnets",children:"Back to Subnets"}),a.error&&e.jsx(f,{error:a.error,msg:"Failed to delete subnet"}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(v,{actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(D,{onClick:()=>n(!0),size:"sm",variant:"destructive",children:[e.jsx(L,{className:"size-4"}),"Delete"]}),e.jsx(A,{state:t.State})]}),subtitle:"Subnet Details",title:i?`${t.SubnetId} (${i})`:t.SubnetId}),e.jsxs(l,{children:[e.jsx(l.Header,{children:"Subnet Information"}),e.jsxs(l.Content,{children:[e.jsx(s,{label:"Subnet ID",value:t.SubnetId}),e.jsx(s,{label:"VPC ID",value:t.VpcId?e.jsx(g,{className:"text-primary hover:underline",params:{id:t.VpcId},to:"/ec2/describe-vpcs/$id",children:t.VpcId}):"—"}),e.jsx(s,{label:"State",value:t.State}),e.jsx(s,{label:"CIDR Block",value:t.CidrBlock}),e.jsx(s,{label:"Availability Zone",value:t.AvailabilityZone}),e.jsx(s,{label:"Available IP Count",value:t.AvailableIpAddressCount?.toString()}),e.jsx(s,{label:"Map Public IP on Launch",value:t.MapPublicIpOnLaunch?"Yes":"No"}),e.jsx(s,{label:"Default for AZ",value:t.DefaultForAz?"Yes":"No"})]})]})]}),e.jsx(I,{onOpenChange:n,open:d,children:e.jsxs(y,{children:[e.jsxs(C,{children:[e.jsx(B,{children:"Delete Subnet"}),e.jsxs(P,{children:['Are you sure you want to delete the subnet "',t.SubnetId,'"? This action cannot be undone.']})]}),e.jsxs(k,{children:[e.jsx(N,{children:"Cancel"}),e.jsx(w,{disabled:a.isPending,onClick:b,children:a.isPending?"Deleting…":"Delete"})]})]})})]})}export{$ as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{k as z,aB as E,u as V,aC as O,e as L,r as l,j as e,ay as H,B as u,L as M}from"./index.js";import{u as m}from"./useSuspenseQuery.js";import{B as x}from"./back-link.js";import{D as c,a as t}from"./detail-row.js";import{E as j}from"./error-banner.js";import{P as Q}from"./page-heading.js";import{S as _}from"./state-badge.js";import{g,f as y,b as D,a as S,c as f,d as C,e as b,h as v}from"./alert-dialog.js";import{b as $,a as G}from"./field.js";import{I as Y}from"./input.js";import{m as q,n as J}from"./ec2.js";import{T as K}from"./trash-2.js";const U=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],W=z("copy",U);function de(){const{id:n}=E.useParams(),I=V(),{data:k}=m(O(n)),{data:A}=m(L),s=k.Snapshots?.[0],a=q(),o=J(),[w,i]=l.useState(!1),[B,r]=l.useState(!1),[d,p]=l.useState(""),N=A.Regions?.[0]?.RegionName??"ap-southeast-2",h=s?.State==="completed",P=async()=>{try{await a.mutateAsync(n),I({to:"/ec2/describe-snapshots"})}finally{i(!1)}},T=async()=>{try{await o.mutateAsync({sourceSnapshotId:n,sourceRegion:N,description:d||void 0}),r(!1),p("")}catch{}};if(!s?.SnapshotId)return e.jsxs(e.Fragment,{children:[e.jsx(x,{to:"/ec2/describe-snapshots",children:"Back to snapshots"}),e.jsx("p",{className:"text-muted-foreground",children:"Snapshot not found."})]});const F=H(s.StartTime);return e.jsxs(e.Fragment,{children:[e.jsx(x,{to:"/ec2/describe-snapshots",children:"Back to snapshots"}),a.error&&e.jsx(j,{error:a.error,msg:"Failed to delete snapshot"}),o.error&&e.jsx(j,{error:o.error,msg:"Failed to copy snapshot"}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(Q,{actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(u,{disabled:!h,onClick:()=>i(!0),size:"sm",variant:"destructive",children:[e.jsx(K,{className:"size-4"}),"Delete"]}),e.jsxs(u,{disabled:!h,onClick:()=>r(!0),size:"sm",variant:"outline",children:[e.jsx(W,{className:"size-4"}),"Copy Snapshot"]}),e.jsx(_,{state:s.State})]}),subtitle:"EC2 Snapshot Details",title:s.SnapshotId}),e.jsxs(c,{children:[e.jsx(c.Header,{children:"Snapshot Information"}),e.jsxs(c.Content,{children:[e.jsx(t,{label:"Snapshot ID",value:s.SnapshotId}),e.jsx(t,{label:"Volume ID",value:s.VolumeId?e.jsx(M,{className:"text-primary hover:underline",params:{id:s.VolumeId},to:"/ec2/describe-volumes/$id",children:s.VolumeId}):void 0}),e.jsx(t,{label:"Volume Size",value:`${s.VolumeSize} GiB`}),e.jsx(t,{label:"State",value:s.State}),e.jsx(t,{label:"Description",value:s.Description}),e.jsx(t,{label:"Progress",value:s.Progress}),e.jsx(t,{label:"Start Time",value:F}),e.jsx(t,{label:"Owner ID",value:s.OwnerId}),e.jsx(t,{label:"Encrypted",value:s.Encrypted?"Yes":"No"})]})]})]}),e.jsx(g,{onOpenChange:i,open:w,children:e.jsxs(y,{children:[e.jsxs(D,{children:[e.jsx(S,{children:"Delete Snapshot"}),e.jsxs(f,{children:['Are you sure you want to delete the snapshot "',s.SnapshotId,'"? This action cannot be undone.']})]}),e.jsxs(C,{children:[e.jsx(b,{children:"Cancel"}),e.jsx(v,{disabled:a.isPending,onClick:P,children:a.isPending?"Deleting…":"Delete"})]})]})}),e.jsx(g,{onOpenChange:r,open:B,children:e.jsxs(y,{children:[e.jsxs(D,{children:[e.jsx(S,{children:"Copy Snapshot"}),e.jsx(f,{children:"Create a copy of this snapshot in the current region."})]}),e.jsxs($,{children:[e.jsx(G,{children:e.jsx("label",{htmlFor:"copyDescription",children:"Description (optional)"})}),e.jsx(Y,{id:"copyDescription",onChange:R=>p(R.target.value),placeholder:"Description for the snapshot copy",value:d})]}),e.jsxs(C,{children:[e.jsx(b,{children:"Cancel"}),e.jsx(v,{disabled:o.isPending,onClick:T,children:o.isPending?"Copying…":"Copy Snapshot"})]})]})})]})}export{de as component};
|
||||
import{J as R,cZ as E,u as V,c_ as O,f as L,r as l,j as e,z as H,B as u,L as M}from"./index.js";import{u as m}from"./useSuspenseQuery.js";import{B as x}from"./back-link.js";import{D as c,a as t}from"./detail-row.js";import{E as j}from"./error-banner.js";import{P as Q}from"./page-heading.js";import{S as _}from"./state-badge.js";import{g,f as D,b as y,a as S,c as f,d as C,e as b,h as v}from"./alert-dialog.js";import{b as $,a as G}from"./field.js";import{I as J}from"./input.js";import{m as Y,n as Z}from"./ec2.js";import{T as q}from"./trash-2.js";const K=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],U=R("copy",K);function de(){const{id:n}=E.useParams(),I=V(),{data:A}=m(O(n)),{data:k}=m(L),s=A.Snapshots?.[0],a=Y(),o=Z(),[w,i]=l.useState(!1),[N,r]=l.useState(!1),[d,p]=l.useState(""),B=k.Regions?.[0]?.RegionName??"ap-southeast-2",h=s?.State==="completed",P=async()=>{try{await a.mutateAsync(n),I({to:"/ec2/describe-snapshots"})}finally{i(!1)}},T=async()=>{try{await o.mutateAsync({sourceSnapshotId:n,sourceRegion:B,description:d||void 0}),r(!1),p("")}catch{}};if(!s?.SnapshotId)return e.jsxs(e.Fragment,{children:[e.jsx(x,{to:"/ec2/describe-snapshots",children:"Back to snapshots"}),e.jsx("p",{className:"text-muted-foreground",children:"Snapshot not found."})]});const z=H(s.StartTime);return e.jsxs(e.Fragment,{children:[e.jsx(x,{to:"/ec2/describe-snapshots",children:"Back to snapshots"}),a.error&&e.jsx(j,{error:a.error,msg:"Failed to delete snapshot"}),o.error&&e.jsx(j,{error:o.error,msg:"Failed to copy snapshot"}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(Q,{actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(u,{disabled:!h,onClick:()=>i(!0),size:"sm",variant:"destructive",children:[e.jsx(q,{className:"size-4"}),"Delete"]}),e.jsxs(u,{disabled:!h,onClick:()=>r(!0),size:"sm",variant:"outline",children:[e.jsx(U,{className:"size-4"}),"Copy Snapshot"]}),e.jsx(_,{state:s.State})]}),subtitle:"EC2 Snapshot Details",title:s.SnapshotId}),e.jsxs(c,{children:[e.jsx(c.Header,{children:"Snapshot Information"}),e.jsxs(c.Content,{children:[e.jsx(t,{label:"Snapshot ID",value:s.SnapshotId}),e.jsx(t,{label:"Volume ID",value:s.VolumeId?e.jsx(M,{className:"text-primary hover:underline",params:{id:s.VolumeId},to:"/ec2/describe-volumes/$id",children:s.VolumeId}):void 0}),e.jsx(t,{label:"Volume Size",value:`${s.VolumeSize} GiB`}),e.jsx(t,{label:"State",value:s.State}),e.jsx(t,{label:"Description",value:s.Description}),e.jsx(t,{label:"Progress",value:s.Progress}),e.jsx(t,{label:"Start Time",value:z}),e.jsx(t,{label:"Owner ID",value:s.OwnerId}),e.jsx(t,{label:"Encrypted",value:s.Encrypted?"Yes":"No"})]})]})]}),e.jsx(g,{onOpenChange:i,open:w,children:e.jsxs(D,{children:[e.jsxs(y,{children:[e.jsx(S,{children:"Delete Snapshot"}),e.jsxs(f,{children:['Are you sure you want to delete the snapshot "',s.SnapshotId,'"? This action cannot be undone.']})]}),e.jsxs(C,{children:[e.jsx(b,{children:"Cancel"}),e.jsx(v,{disabled:a.isPending,onClick:P,children:a.isPending?"Deleting…":"Delete"})]})]})}),e.jsx(g,{onOpenChange:r,open:N,children:e.jsxs(D,{children:[e.jsxs(y,{children:[e.jsx(S,{children:"Copy Snapshot"}),e.jsx(f,{children:"Create a copy of this snapshot in the current region."})]}),e.jsxs($,{children:[e.jsx(G,{children:e.jsx("label",{htmlFor:"copyDescription",children:"Description (optional)"})}),e.jsx(J,{id:"copyDescription",onChange:F=>p(F.target.value),placeholder:"Description for the snapshot copy",value:d})]}),e.jsxs(C,{children:[e.jsx(b,{children:"Cancel"}),e.jsx(v,{disabled:o.isPending,onClick:T,children:o.isPending?"Copying…":"Copy Snapshot"})]})]})})]})}export{de as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{aD as x,u as p,aE as h,r as j,j as e,ay as g,B as D}from"./index.js";import{u as K}from"./useSuspenseQuery.js";import{B as o}from"./back-link.js";import{D as s,a as r}from"./detail-row.js";import{E as f}from"./error-banner.js";import{P as b}from"./page-heading.js";import{g as P,f as k,b as T,a as A,c as C,d as v,e as N,h as w}from"./alert-dialog.js";import{o as B}from"./ec2.js";import{T as E}from"./trash-2.js";function M(){const{id:l}=x.useParams(),c=p(),{data:d}=K(h(l)),a=d.KeyPairs?.[0],i=B(),[y,t]=j.useState(!1),m=async()=>{try{await i.mutateAsync(l),c({to:"/ec2/describe-key-pairs"})}finally{t(!1)}};if(!a?.KeyPairId)return e.jsxs(e.Fragment,{children:[e.jsx(o,{to:"/ec2/describe-key-pairs",children:"Back to key pairs"}),e.jsx("p",{className:"text-muted-foreground",children:"Key pair not found."})]});const u=g(a.CreateTime);return e.jsxs(e.Fragment,{children:[e.jsx(o,{to:"/ec2/describe-key-pairs",children:"Back to key pairs"}),i.error&&e.jsx(f,{error:i.error,msg:"Failed to delete key pair"}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(b,{actions:e.jsxs(D,{onClick:()=>t(!0),size:"sm",variant:"destructive",children:[e.jsx(E,{className:"size-4"}),"Delete"]}),subtitle:"EC2 Key Pair Details",title:a.KeyName??""}),e.jsxs(s,{children:[e.jsx(s.Header,{children:"Key Pair Information"}),e.jsxs(s.Content,{children:[e.jsx(r,{label:"Key Name",value:a.KeyName}),e.jsx(r,{label:"Key Pair ID",value:a.KeyPairId}),e.jsx(r,{label:"Key Type",value:a.KeyType}),e.jsx(r,{label:"Key Fingerprint",value:a.KeyFingerprint}),e.jsx(r,{label:"Creation Date",value:u})]})]}),a.Tags&&a.Tags.length>0&&e.jsxs(s,{children:[e.jsx(s.Header,{children:"Tags"}),e.jsx(s.Content,{children:a.Tags.map(n=>e.jsx(r,{label:n.Key||"",value:n.Value},n.Key))})]})]}),e.jsx(P,{onOpenChange:t,open:y,children:e.jsxs(k,{children:[e.jsxs(T,{children:[e.jsx(A,{children:"Delete Key Pair"}),e.jsxs(C,{children:['Are you sure you want to delete the key pair "',a.KeyName,'"? This action cannot be undone. Any instances using this key pair will no longer be able to be accessed with it.']})]}),e.jsxs(v,{children:[e.jsx(N,{children:"Cancel"}),e.jsx(w,{disabled:i.isPending,onClick:m,children:i.isPending?"Deleting…":"Delete"})]})]})})]})}export{M as component};
|
||||
import{c$ as x,u as p,d0 as h,r as j,j as e,z as g,B as D}from"./index.js";import{u as K}from"./useSuspenseQuery.js";import{B as o}from"./back-link.js";import{D as s,a as r}from"./detail-row.js";import{E as f}from"./error-banner.js";import{P as b}from"./page-heading.js";import{g as P,f as k,b as T,a as A,c as C,d as v,e as N,h as w}from"./alert-dialog.js";import{o as B}from"./ec2.js";import{T as F}from"./trash-2.js";function M(){const{id:l}=x.useParams(),c=p(),{data:d}=K(h(l)),a=d.KeyPairs?.[0],i=B(),[y,t]=j.useState(!1),m=async()=>{try{await i.mutateAsync(l),c({to:"/ec2/describe-key-pairs"})}finally{t(!1)}};if(!a?.KeyPairId)return e.jsxs(e.Fragment,{children:[e.jsx(o,{to:"/ec2/describe-key-pairs",children:"Back to key pairs"}),e.jsx("p",{className:"text-muted-foreground",children:"Key pair not found."})]});const u=g(a.CreateTime);return e.jsxs(e.Fragment,{children:[e.jsx(o,{to:"/ec2/describe-key-pairs",children:"Back to key pairs"}),i.error&&e.jsx(f,{error:i.error,msg:"Failed to delete key pair"}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(b,{actions:e.jsxs(D,{onClick:()=>t(!0),size:"sm",variant:"destructive",children:[e.jsx(F,{className:"size-4"}),"Delete"]}),subtitle:"EC2 Key Pair Details",title:a.KeyName??""}),e.jsxs(s,{children:[e.jsx(s.Header,{children:"Key Pair Information"}),e.jsxs(s.Content,{children:[e.jsx(r,{label:"Key Name",value:a.KeyName}),e.jsx(r,{label:"Key Pair ID",value:a.KeyPairId}),e.jsx(r,{label:"Key Type",value:a.KeyType}),e.jsx(r,{label:"Key Fingerprint",value:a.KeyFingerprint}),e.jsx(r,{label:"Creation Date",value:u})]})]}),a.Tags&&a.Tags.length>0&&e.jsxs(s,{children:[e.jsx(s.Header,{children:"Tags"}),e.jsx(s.Content,{children:a.Tags.map(n=>e.jsx(r,{label:n.Key||"",value:n.Value},n.Key))})]})]}),e.jsx(P,{onOpenChange:t,open:y,children:e.jsxs(k,{children:[e.jsxs(T,{children:[e.jsx(A,{children:"Delete Key Pair"}),e.jsxs(C,{children:['Are you sure you want to delete the key pair "',a.KeyName,'"? This action cannot be undone. Any instances using this key pair will no longer be able to be accessed with it.']})]}),e.jsxs(v,{children:[e.jsx(N,{children:"Cancel"}),e.jsx(w,{disabled:i.isPending,onClick:m,children:i.isPending?"Deleting…":"Delete"})]})]})})]})}export{M as component};
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{c as f,cz as u,j as t,aH as p}from"./index.js";import{u as x}from"./useSuspenseQuery.js";import{B as d}from"./back-link.js";import{P as I}from"./page-heading.js";import{S as j}from"./state-badge.js";import{A as h}from"./ami-details.js";import"./detail-row.js";function _(){const e=f.c(14),{id:n}=u.useParams();let o;e[0]!==n?(o=p(n),e[0]=n,e[1]=o):o=e[1];const{data:g}=x(o),s=g?.Images?.[0];if(!s?.ImageId){let l;return e[2]===Symbol.for("react.memo_cache_sentinel")?(l=t.jsxs(t.Fragment,{children:[t.jsx(d,{to:"/ec2/describe-images",children:"Back to images"}),t.jsx("p",{className:"text-muted-foreground",children:"Image not found."})]}),e[2]=l):l=e[2],l}let r;e[3]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(d,{to:"/ec2/describe-images",children:"Back to images"}),e[3]=r):r=e[3];let a;e[4]!==s.State?(a=t.jsx(j,{state:s.State}),e[4]=s.State,e[5]=a):a=e[5];let i;e[6]!==s.ImageId||e[7]!==a?(i=t.jsx(I,{actions:a,subtitle:"EC2 Image Details",title:s.ImageId}),e[6]=s.ImageId,e[7]=a,e[8]=i):i=e[8];let m;e[9]!==s?(m=t.jsx(h,{image:s,showExtendedDetails:!0}),e[9]=s,e[10]=m):m=e[10];let c;return e[11]!==i||e[12]!==m?(c=t.jsxs(t.Fragment,{children:[r,t.jsxs("div",{className:"space-y-6",children:[i,m]})]}),e[11]=i,e[12]=m,e[13]=c):c=e[13],c}export{_ as component};
|
||||
import{c as f,d4 as u,j as t,d3 as p}from"./index.js";import{u as x}from"./useSuspenseQuery.js";import{B as d}from"./back-link.js";import{P as I}from"./page-heading.js";import{S as j}from"./state-badge.js";import{A as h}from"./ami-details.js";import"./detail-row.js";function _(){const e=f.c(14),{id:n}=u.useParams();let o;e[0]!==n?(o=p(n),e[0]=n,e[1]=o):o=e[1];const{data:g}=x(o),s=g?.Images?.[0];if(!s?.ImageId){let l;return e[2]===Symbol.for("react.memo_cache_sentinel")?(l=t.jsxs(t.Fragment,{children:[t.jsx(d,{to:"/ec2/describe-images",children:"Back to images"}),t.jsx("p",{className:"text-muted-foreground",children:"Image not found."})]}),e[2]=l):l=e[2],l}let r;e[3]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(d,{to:"/ec2/describe-images",children:"Back to images"}),e[3]=r):r=e[3];let a;e[4]!==s.State?(a=t.jsx(j,{state:s.State}),e[4]=s.State,e[5]=a):a=e[5];let i;e[6]!==s.ImageId||e[7]!==a?(i=t.jsx(I,{actions:a,subtitle:"EC2 Image Details",title:s.ImageId}),e[6]=s.ImageId,e[7]=a,e[8]=i):i=e[8];let m;e[9]!==s?(m=t.jsx(h,{image:s,showExtendedDetails:!0}),e[9]=s,e[10]=m):m=e[10];let c;return e[11]!==i||e[12]!==m?(c=t.jsxs(t.Fragment,{children:[r,t.jsxs("div",{className:"space-y-6",children:[i,m]})]}),e[11]=i,e[12]=m,e[13]=c):c=e[13],c}export{_ as component};
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
import{c as h,j as e,av as j,u as f,aw as P,r as g,ax as v,B as A,z as N}from"./index.js";import{u}from"./useSuspenseQuery.js";import{B as p}from"./back-link.js";import{D as n,a as l}from"./detail-row.js";import{E as b}from"./error-banner.js";import{P as C}from"./page-heading.js";import{g as w,f as I,b as B,a as R,c as k,d as E,e as O,h as S}from"./alert-dialog.js";import{h as T}from"./iam.js";import{T as V}from"./trash-2.js";function F(r){const t=h.c(4),{document:a}=r;let i;try{let s;t[0]!==a?(s=JSON.stringify(JSON.parse(a),null,2),t[0]=a,t[1]=s):s=t[1],i=s}catch{i=a}let o;return t[2]!==i?(o=e.jsx("pre",{className:"overflow-auto rounded-md border bg-muted p-4 font-mono text-sm",children:i}),t[2]=i,t[3]=o):o=t[3],o}function G(){const{policyArn:r}=j.useParams(),t=decodeURIComponent(r),a=f(),{data:i}=u(P(t)),o=i.Policy,s=T(),[x,c]=g.useState(!1),y=o?.DefaultVersionId??"v1",{data:d}=u(v(t,y)),m=d?.PolicyVersion?.Document?decodeURIComponent(d.PolicyVersion.Document):null,D=async()=>{try{await s.mutateAsync(t),a({to:"/iam/list-policies"})}finally{c(!1)}};return o?e.jsxs(e.Fragment,{children:[e.jsx(p,{to:"/iam/list-policies",children:"Back to policies"}),s.error&&e.jsx(b,{error:s.error,msg:"Failed to delete policy"}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(C,{actions:e.jsxs(A,{onClick:()=>c(!0),size:"sm",variant:"destructive",children:[e.jsx(V,{className:"size-4"}),"Delete"]}),subtitle:"IAM Policy Details",title:o.PolicyName??""}),e.jsxs(n,{children:[e.jsx(n.Header,{children:"Policy Information"}),e.jsxs(n.Content,{children:[e.jsx(l,{label:"Policy Name",value:o.PolicyName}),e.jsx(l,{label:"Policy ID",value:o.PolicyId}),e.jsx(l,{label:"ARN",value:o.Arn}),e.jsx(l,{label:"Path",value:o.Path}),e.jsx(l,{label:"Description",value:o.Description||"-"}),e.jsx(l,{label:"Created",value:N(o.CreateDate)})]})]}),m&&e.jsxs(n,{children:[e.jsx(n.Header,{children:"Policy Document"}),e.jsx("div",{className:"p-4",children:e.jsx(F,{document:m})})]})]}),e.jsx(w,{onOpenChange:c,open:x,children:e.jsxs(I,{children:[e.jsxs(B,{children:[e.jsx(R,{children:"Delete Policy"}),e.jsxs(k,{children:['Are you sure you want to delete the policy "',o.PolicyName,'"? This action cannot be undone.']})]}),e.jsxs(E,{children:[e.jsx(O,{children:"Cancel"}),e.jsx(S,{disabled:s.isPending,onClick:D,children:s.isPending?"Deleting...":"Delete"})]})]})})]}):e.jsxs(e.Fragment,{children:[e.jsx(p,{to:"/iam/list-policies",children:"Back to policies"}),e.jsx("p",{className:"text-muted-foreground",children:"Policy not found."})]})}export{G as component};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{c as g,ay as k,j as t,L as M}from"./index.js";import{D as T,a}from"./detail-row.js";function C(s){const e=g.c(58),{image:l,showExtendedDetails:P}=s,i=P===void 0?!1:P;let E;e[0]!==l.CreationDate?(E=k(l.CreationDate),e[0]=l.CreationDate,e[1]=E):E=e[1];const R=E,S=i?"AMI Information":"AMI Details";let o;e[2]!==S?(o=t.jsx(T.Header,{children:S}),e[2]=S,e[3]=o):o=e[3];let r;e[4]!==l.ImageId||e[5]!==i?(r=l.ImageId&&!i?t.jsx(M,{className:"text-primary hover:underline",params:{id:l.ImageId},to:"/ec2/describe-images/$id",children:l.ImageId}):l.ImageId,e[4]=l.ImageId,e[5]=i,e[6]=r):r=e[6];let c;e[7]!==r?(c=t.jsx(a,{label:"AMI ID",value:r}),e[7]=r,e[8]=c):c=e[8];let n;e[9]!==l.Name?(n=t.jsx(a,{label:"AMI Name",value:l.Name}),e[9]=l.Name,e[10]=n):n=e[10];let u;e[11]!==l.Description?(u=t.jsx(a,{label:"Description",value:l.Description}),e[11]=l.Description,e[12]=u):u=e[12];let m;e[13]!==l.Architecture?(m=t.jsx(a,{label:"Architecture",value:l.Architecture}),e[13]=l.Architecture,e[14]=m):m=e[14];let v;e[15]!==l.VirtualizationType?(v=t.jsx(a,{label:"Virtualization Type",value:l.VirtualizationType}),e[15]=l.VirtualizationType,e[16]=v):v=e[16];const A=l.Platform||"Linux";let D;e[17]!==A?(D=t.jsx(a,{label:"Platform",value:A}),e[17]=A,e[18]=D):D=e[18];let d;e[19]!==l.PlatformDetails?(d=t.jsx(a,{label:"Platform Details",value:l.PlatformDetails}),e[19]=l.PlatformDetails,e[20]=d):d=e[20];let x;e[21]!==l.ImageType?(x=t.jsx(a,{label:"Image Type",value:l.ImageType}),e[21]=l.ImageType,e[22]=x):x=e[22];let b;e[23]!==l.RootDeviceType?(b=t.jsx(a,{label:"Root Device Type",value:l.RootDeviceType}),e[23]=l.RootDeviceType,e[24]=b):b=e[24];let j;e[25]!==l.RootDeviceName?(j=t.jsx(a,{label:"Root Device Name",value:l.RootDeviceName}),e[25]=l.RootDeviceName,e[26]=j):j=e[26];let f;e[27]!==l.OwnerId?(f=t.jsx(a,{label:"Owner",value:l.OwnerId}),e[27]=l.OwnerId,e[28]=f):f=e[28];let I;e[29]!==l.State?(I=t.jsx(a,{label:"State",value:l.State}),e[29]=l.State,e[30]=I):I=e[30];let h;e[31]!==R||e[32]!==l.Public||e[33]!==i?(h=i&&t.jsxs(t.Fragment,{children:[t.jsx(a,{label:"Creation Date",value:R}),t.jsx(a,{label:"Public",value:l.Public?"Yes":"No"})]}),e[31]=R,e[32]=l.Public,e[33]=i,e[34]=h):h=e[34];let p;e[35]!==v||e[36]!==D||e[37]!==d||e[38]!==x||e[39]!==b||e[40]!==j||e[41]!==f||e[42]!==I||e[43]!==h||e[44]!==c||e[45]!==n||e[46]!==u||e[47]!==m?(p=t.jsxs(T.Content,{children:[c,n,u,m,v,D,d,x,b,j,f,I,h]}),e[35]=v,e[36]=D,e[37]=d,e[38]=x,e[39]=b,e[40]=j,e[41]=f,e[42]=I,e[43]=h,e[44]=c,e[45]=n,e[46]=u,e[47]=m,e[48]=p):p=e[48];let N;e[49]!==p||e[50]!==o?(N=t.jsxs(T,{children:[o,p]}),e[49]=p,e[50]=o,e[51]=N):N=e[51];let y;e[52]!==l.BlockDeviceMappings||e[53]!==i?(y=i&&l.BlockDeviceMappings&&l.BlockDeviceMappings.length>0&&l.BlockDeviceMappings.map(w),e[52]=l.BlockDeviceMappings,e[53]=i,e[54]=y):y=e[54];let V;return e[55]!==N||e[56]!==y?(V=t.jsxs(t.Fragment,{children:[N,y]}),e[55]=N,e[56]=y,e[57]=V):V=e[57],V}function w(s){return t.jsxs(T,{children:[t.jsxs(T.Header,{children:["Block Device: ",s.DeviceName]}),t.jsxs(T.Content,{children:[t.jsx(a,{label:"Device Name",value:s.DeviceName}),s.Ebs&&t.jsxs(t.Fragment,{children:[t.jsx(a,{label:"Volume Size",value:s.Ebs.VolumeSize?`${s.Ebs.VolumeSize} GB`:void 0}),t.jsx(a,{label:"Volume Type",value:s.Ebs.VolumeType}),t.jsx(a,{label:"Delete On Termination",value:s.Ebs.DeleteOnTermination?"Yes":"No"}),t.jsx(a,{label:"Encrypted",value:s.Ebs.Encrypted?"Yes":"No"}),s.Ebs.SnapshotId&&t.jsx(a,{label:"Snapshot ID",value:t.jsx(M,{className:"text-primary hover:underline",params:{id:s.Ebs.SnapshotId},to:"/ec2/describe-snapshots/$id",children:s.Ebs.SnapshotId})})]}),s.VirtualName&&t.jsx(a,{label:"Virtual Name",value:s.VirtualName})]})]},s.DeviceName)}export{C as A};
|
||||
import{c as g,z,j as t,L as M}from"./index.js";import{D as T,a}from"./detail-row.js";function C(s){const e=g.c(58),{image:l,showExtendedDetails:P}=s,i=P===void 0?!1:P;let E;e[0]!==l.CreationDate?(E=z(l.CreationDate),e[0]=l.CreationDate,e[1]=E):E=e[1];const R=E,S=i?"AMI Information":"AMI Details";let o;e[2]!==S?(o=t.jsx(T.Header,{children:S}),e[2]=S,e[3]=o):o=e[3];let r;e[4]!==l.ImageId||e[5]!==i?(r=l.ImageId&&!i?t.jsx(M,{className:"text-primary hover:underline",params:{id:l.ImageId},to:"/ec2/describe-images/$id",children:l.ImageId}):l.ImageId,e[4]=l.ImageId,e[5]=i,e[6]=r):r=e[6];let c;e[7]!==r?(c=t.jsx(a,{label:"AMI ID",value:r}),e[7]=r,e[8]=c):c=e[8];let n;e[9]!==l.Name?(n=t.jsx(a,{label:"AMI Name",value:l.Name}),e[9]=l.Name,e[10]=n):n=e[10];let u;e[11]!==l.Description?(u=t.jsx(a,{label:"Description",value:l.Description}),e[11]=l.Description,e[12]=u):u=e[12];let m;e[13]!==l.Architecture?(m=t.jsx(a,{label:"Architecture",value:l.Architecture}),e[13]=l.Architecture,e[14]=m):m=e[14];let v;e[15]!==l.VirtualizationType?(v=t.jsx(a,{label:"Virtualization Type",value:l.VirtualizationType}),e[15]=l.VirtualizationType,e[16]=v):v=e[16];const A=l.Platform||"Linux";let D;e[17]!==A?(D=t.jsx(a,{label:"Platform",value:A}),e[17]=A,e[18]=D):D=e[18];let d;e[19]!==l.PlatformDetails?(d=t.jsx(a,{label:"Platform Details",value:l.PlatformDetails}),e[19]=l.PlatformDetails,e[20]=d):d=e[20];let x;e[21]!==l.ImageType?(x=t.jsx(a,{label:"Image Type",value:l.ImageType}),e[21]=l.ImageType,e[22]=x):x=e[22];let b;e[23]!==l.RootDeviceType?(b=t.jsx(a,{label:"Root Device Type",value:l.RootDeviceType}),e[23]=l.RootDeviceType,e[24]=b):b=e[24];let j;e[25]!==l.RootDeviceName?(j=t.jsx(a,{label:"Root Device Name",value:l.RootDeviceName}),e[25]=l.RootDeviceName,e[26]=j):j=e[26];let f;e[27]!==l.OwnerId?(f=t.jsx(a,{label:"Owner",value:l.OwnerId}),e[27]=l.OwnerId,e[28]=f):f=e[28];let I;e[29]!==l.State?(I=t.jsx(a,{label:"State",value:l.State}),e[29]=l.State,e[30]=I):I=e[30];let h;e[31]!==R||e[32]!==l.Public||e[33]!==i?(h=i&&t.jsxs(t.Fragment,{children:[t.jsx(a,{label:"Creation Date",value:R}),t.jsx(a,{label:"Public",value:l.Public?"Yes":"No"})]}),e[31]=R,e[32]=l.Public,e[33]=i,e[34]=h):h=e[34];let p;e[35]!==v||e[36]!==D||e[37]!==d||e[38]!==x||e[39]!==b||e[40]!==j||e[41]!==f||e[42]!==I||e[43]!==h||e[44]!==c||e[45]!==n||e[46]!==u||e[47]!==m?(p=t.jsxs(T.Content,{children:[c,n,u,m,v,D,d,x,b,j,f,I,h]}),e[35]=v,e[36]=D,e[37]=d,e[38]=x,e[39]=b,e[40]=j,e[41]=f,e[42]=I,e[43]=h,e[44]=c,e[45]=n,e[46]=u,e[47]=m,e[48]=p):p=e[48];let N;e[49]!==p||e[50]!==o?(N=t.jsxs(T,{children:[o,p]}),e[49]=p,e[50]=o,e[51]=N):N=e[51];let y;e[52]!==l.BlockDeviceMappings||e[53]!==i?(y=i&&l.BlockDeviceMappings&&l.BlockDeviceMappings.length>0&&l.BlockDeviceMappings.map(k),e[52]=l.BlockDeviceMappings,e[53]=i,e[54]=y):y=e[54];let V;return e[55]!==N||e[56]!==y?(V=t.jsxs(t.Fragment,{children:[N,y]}),e[55]=N,e[56]=y,e[57]=V):V=e[57],V}function k(s){return t.jsxs(T,{children:[t.jsxs(T.Header,{children:["Block Device: ",s.DeviceName]}),t.jsxs(T.Content,{children:[t.jsx(a,{label:"Device Name",value:s.DeviceName}),s.Ebs&&t.jsxs(t.Fragment,{children:[t.jsx(a,{label:"Volume Size",value:s.Ebs.VolumeSize?`${s.Ebs.VolumeSize} GB`:void 0}),t.jsx(a,{label:"Volume Type",value:s.Ebs.VolumeType}),t.jsx(a,{label:"Delete On Termination",value:s.Ebs.DeleteOnTermination?"Yes":"No"}),t.jsx(a,{label:"Encrypted",value:s.Ebs.Encrypted?"Yes":"No"}),s.Ebs.SnapshotId&&t.jsx(a,{label:"Snapshot ID",value:t.jsx(M,{className:"text-primary hover:underline",params:{id:s.Ebs.SnapshotId},to:"/ec2/describe-snapshots/$id",children:s.Ebs.SnapshotId})})]}),s.VirtualName&&t.jsx(a,{label:"Virtual Name",value:s.VirtualName})]})]},s.DeviceName)}export{C as A};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{k as o,c as r,j as l,L as a}from"./index.js";const m=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],x=o("arrow-left",m);function p(i){const e=r.c(7);let s,t;e[0]!==i?({children:s,...t}=i,e[0]=i,e[1]=s,e[2]=t):(s=e[1],t=e[2]);let n;e[3]===Symbol.for("react.memo_cache_sentinel")?(n=l.jsx(x,{className:"size-4"}),e[3]=n):n=e[3];let c;return e[4]!==s||e[5]!==t?(c=l.jsxs(a,{className:"mb-6 inline-flex items-center gap-2 text-sm",...t,children:[n,s]}),e[4]=s,e[5]=t,e[6]=c):c=e[6],c}export{p as B};
|
||||
import{J as o,c as r,j as l,L as a}from"./index.js";const m=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],x=o("arrow-left",m);function p(i){const e=r.c(7);let s,t;e[0]!==i?({children:s,...t}=i,e[0]=i,e[1]=s,e[2]=t):(s=e[1],t=e[2]);let n;e[3]===Symbol.for("react.memo_cache_sentinel")?(n=l.jsx(x,{className:"size-4"}),e[3]=n):n=e[3];let c;return e[4]!==s||e[5]!==t?(c=l.jsxs(a,{className:"mb-6 inline-flex items-center gap-2 text-sm",...t,children:[n,s]}),e[4]=s,e[5]=t,e[6]=c):c=e[6],c}export{p as B};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{k as c}from"./index.js";const e=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],t=c("check",e);export{t as C};
|
||||
import{J as c}from"./index.js";const e=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],t=c("check",e);export{t as C};
|
||||
|
||||
@@ -1 +1 @@
|
||||
import{o as M,f as $,c as I,u as R,j as t,B as E}from"./index.js";import{a as A,u as H}from"./zod.js";import{B as L}from"./back-link.js";import{E as O}from"./error-banner.js";import{P as T}from"./page-heading.js";import{F as q,a as D,b as G}from"./field.js";import{I as J}from"./input.js";import{u as K}from"./s3.js";const Q=M({bucketName:$().min(3,"Bucket name must be at least 3 characters").max(63,"Bucket name must be at most 63 characters").regex(/^[a-z0-9][a-z0-9.-]*[a-z0-9]$/,"Must start and end with a lowercase letter or number").regex(/^[a-z0-9.-]+$/,"Only lowercase letters, numbers, hyphens, and periods allowed").refine(e=>!e.includes(".."),"Must not contain consecutive periods").refine(e=>!(e.includes(".-")||e.includes("-.")),"Must not contain adjacent period and hyphen")});function se(){const e=I.c(40),r=R(),s=K();let p;e[0]===Symbol.for("react.memo_cache_sentinel")?(p={resolver:A(Q)},e[0]=p):p=e[0];const{handleSubmit:y,register:N,formState:P}=H(p),{errors:x,isSubmitting:S}=P;let h;e[1]!==s||e[2]!==r?(h=async z=>{await s.mutateAsync(z),r({to:"/s3/ls"})},e[1]=s,e[2]=r,e[3]=h):h=e[3];const F=h;let k,j;e[4]===Symbol.for("react.memo_cache_sentinel")?(k=t.jsx(L,{to:"/s3/ls",children:"Back to buckets"}),j=t.jsx(T,{title:"Create Bucket"}),e[4]=k,e[5]=j):(k=e[4],j=e[5]);let a;e[6]!==s.error?(a=s.error&&t.jsx(O,{error:s.error,msg:"Failed to create bucket"}),e[6]=s.error,e[7]=a):a=e[7];let i;e[8]!==y||e[9]!==F?(i=y(F),e[8]=y,e[9]=F,e[10]=i):i=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=t.jsx(D,{children:t.jsx("label",{htmlFor:"bucketName",children:"Bucket Name"})}),e[11]=g):g=e[11];const v=!!x.bucketName;let l;e[12]!==N?(l=N("bucketName"),e[12]=N,e[13]=l):l=e[13];let n;e[14]!==v||e[15]!==l?(n=t.jsx(J,{"aria-invalid":v,id:"bucketName",placeholder:"my-bucket",type:"text",...l}),e[14]=v,e[15]=l,e[16]=n):n=e[16];let o;e[17]!==x.bucketName?(o=t.jsx(q,{errors:[x.bucketName]}),e[17]=x.bucketName,e[18]=o):o=e[18];let c;e[19]!==n||e[20]!==o?(c=t.jsxs(G,{children:[g,n,o]}),e[19]=n,e[20]=o,e[21]=c):c=e[21];const C=S||s.isPending;let m;e[22]!==r?(m=()=>r({to:"/s3/ls"}),e[22]=r,e[23]=m):m=e[23];let u;e[24]!==C||e[25]!==m?(u=t.jsx(E,{disabled:C,onClick:m,type:"button",variant:"outline",children:"Cancel"}),e[24]=C,e[25]=m,e[26]=u):u=e[26];const w=S||s.isPending,_=S||s.isPending?"Creating…":"Create Bucket";let d;e[27]!==w||e[28]!==_?(d=t.jsx(E,{disabled:w,type:"submit",children:_}),e[27]=w,e[28]=_,e[29]=d):d=e[29];let f;e[30]!==u||e[31]!==d?(f=t.jsxs("div",{className:"flex gap-2",children:[u,d]}),e[30]=u,e[31]=d,e[32]=f):f=e[32];let b;e[33]!==c||e[34]!==f||e[35]!==i?(b=t.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:i,children:[c,f]}),e[33]=c,e[34]=f,e[35]=i,e[36]=b):b=e[36];let B;return e[37]!==b||e[38]!==a?(B=t.jsxs(t.Fragment,{children:[k,j,a,b]}),e[37]=b,e[38]=a,e[39]=B):B=e[39],B}export{se as component};
|
||||
import{o as M,i as $,c as I,u as R,j as t,B as E}from"./index.js";import{a as A,u as H}from"./zod.js";import{B as L}from"./back-link.js";import{E as O}from"./error-banner.js";import{P as T}from"./page-heading.js";import{F as q,a as D,b as G}from"./field.js";import{I as J}from"./input.js";import{u as K}from"./s3.js";const Q=M({bucketName:$().min(3,"Bucket name must be at least 3 characters").max(63,"Bucket name must be at most 63 characters").regex(/^[a-z0-9][a-z0-9.-]*[a-z0-9]$/,"Must start and end with a lowercase letter or number").regex(/^[a-z0-9.-]+$/,"Only lowercase letters, numbers, hyphens, and periods allowed").refine(e=>!e.includes(".."),"Must not contain consecutive periods").refine(e=>!(e.includes(".-")||e.includes("-.")),"Must not contain adjacent period and hyphen")});function se(){const e=I.c(40),r=R(),s=K();let p;e[0]===Symbol.for("react.memo_cache_sentinel")?(p={resolver:A(Q)},e[0]=p):p=e[0];const{handleSubmit:y,register:N,formState:P}=H(p),{errors:x,isSubmitting:S}=P;let h;e[1]!==s||e[2]!==r?(h=async z=>{await s.mutateAsync(z),r({to:"/s3/ls"})},e[1]=s,e[2]=r,e[3]=h):h=e[3];const F=h;let k,j;e[4]===Symbol.for("react.memo_cache_sentinel")?(k=t.jsx(L,{to:"/s3/ls",children:"Back to buckets"}),j=t.jsx(T,{title:"Create Bucket"}),e[4]=k,e[5]=j):(k=e[4],j=e[5]);let a;e[6]!==s.error?(a=s.error&&t.jsx(O,{error:s.error,msg:"Failed to create bucket"}),e[6]=s.error,e[7]=a):a=e[7];let i;e[8]!==y||e[9]!==F?(i=y(F),e[8]=y,e[9]=F,e[10]=i):i=e[10];let g;e[11]===Symbol.for("react.memo_cache_sentinel")?(g=t.jsx(D,{children:t.jsx("label",{htmlFor:"bucketName",children:"Bucket Name"})}),e[11]=g):g=e[11];const v=!!x.bucketName;let l;e[12]!==N?(l=N("bucketName"),e[12]=N,e[13]=l):l=e[13];let n;e[14]!==v||e[15]!==l?(n=t.jsx(J,{"aria-invalid":v,id:"bucketName",placeholder:"my-bucket",type:"text",...l}),e[14]=v,e[15]=l,e[16]=n):n=e[16];let o;e[17]!==x.bucketName?(o=t.jsx(q,{errors:[x.bucketName]}),e[17]=x.bucketName,e[18]=o):o=e[18];let c;e[19]!==n||e[20]!==o?(c=t.jsxs(G,{children:[g,n,o]}),e[19]=n,e[20]=o,e[21]=c):c=e[21];const C=S||s.isPending;let m;e[22]!==r?(m=()=>r({to:"/s3/ls"}),e[22]=r,e[23]=m):m=e[23];let u;e[24]!==C||e[25]!==m?(u=t.jsx(E,{disabled:C,onClick:m,type:"button",variant:"outline",children:"Cancel"}),e[24]=C,e[25]=m,e[26]=u):u=e[26];const w=S||s.isPending,_=S||s.isPending?"Creating…":"Create Bucket";let d;e[27]!==w||e[28]!==_?(d=t.jsx(E,{disabled:w,type:"submit",children:_}),e[27]=w,e[28]=_,e[29]=d):d=e[29];let f;e[30]!==u||e[31]!==d?(f=t.jsxs("div",{className:"flex gap-2",children:[u,d]}),e[30]=u,e[31]=d,e[32]=f):f=e[32];let b;e[33]!==c||e[34]!==f||e[35]!==i?(b=t.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:i,children:[c,f]}),e[33]=c,e[34]=f,e[35]=i,e[36]=b):b=e[36];let B;return e[37]!==b||e[38]!==a?(B=t.jsxs(t.Fragment,{children:[k,j,a,b]}),e[37]=b,e[38]=a,e[39]=B):B=e[39],B}export{se as component};
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{c as G,u as K,j as t,B as Y}from"./index.js";import{a as Q,u as W}from"./zod.js";import{B as X}from"./back-link.js";import{E as Z}from"./error-banner.js";import{P as ee}from"./page-heading.js";import{F as U,a as V,b as H}from"./field.js";import{I as $}from"./input.js";import{T as te}from"./textarea.js";import{a as ie}from"./iam.js";import{a as le}from"./iam2.js";const oe=JSON.stringify({Version:"2012-10-17",Statement:[{Effect:"Allow",Action:"*",Resource:"*"}]},null,2);function ue(){const e=G.c(63),s=K(),l=ie();let _;e[0]===Symbol.for("react.memo_cache_sentinel")?(_={resolver:Q(le),defaultValues:{policyDocument:oe}},e[0]=_):_=e[0];const{handleSubmit:k,register:o,formState:q}=W(_),{errors:i,isSubmitting:w}=q;let F;e[1]!==l||e[2]!==s?(F=async z=>{await l.mutateAsync(z),s({to:"/iam/list-policies"})},e[1]=l,e[2]=s,e[3]=F):F=e[3];const O=F;let C,E;e[4]===Symbol.for("react.memo_cache_sentinel")?(C=t.jsx(X,{to:"/iam/list-policies",children:"Back to policies"}),E=t.jsx(ee,{title:"Create Policy"}),e[4]=C,e[5]=E):(C=e[4],E=e[5]);let r;e[6]!==l.error?(r=l.error&&t.jsx(Z,{error:l.error,msg:"Failed to create policy"}),e[6]=l.error,e[7]=r):r=e[7];let c;e[8]!==k||e[9]!==O?(c=k(O),e[8]=k,e[9]=O,e[10]=c):c=e[10];let v;e[11]===Symbol.for("react.memo_cache_sentinel")?(v=t.jsx(V,{children:t.jsx("label",{htmlFor:"policyName",children:"Policy Name"})}),e[11]=v):v=e[11];const I=!!i.policyName;let a;e[12]!==o?(a=o("policyName"),e[12]=o,e[13]=a):a=e[13];let n;e[14]!==I||e[15]!==a?(n=t.jsx($,{"aria-invalid":I,id:"policyName",placeholder:"my-policy...",...a}),e[14]=I,e[15]=a,e[16]=n):n=e[16];let m;e[17]!==i.policyName?(m=t.jsx(U,{errors:[i.policyName]}),e[17]=i.policyName,e[18]=m):m=e[18];let p;e[19]!==n||e[20]!==m?(p=t.jsxs(H,{children:[v,n,m]}),e[19]=n,e[20]=m,e[21]=p):p=e[21];let B;e[22]===Symbol.for("react.memo_cache_sentinel")?(B=t.jsx(V,{children:t.jsx("label",{htmlFor:"description",children:"Description (optional)"})}),e[22]=B):B=e[22];let f;e[23]!==o?(f=o("description"),e[23]=o,e[24]=f):f=e[24];let d;e[25]!==f?(d=t.jsx($,{id:"description",placeholder:"A brief description of this policy...",...f}),e[25]=f,e[26]=d):d=e[26];let y;e[27]!==i.description?(y=t.jsx(U,{errors:[i.description]}),e[27]=i.description,e[28]=y):y=e[28];let u;e[29]!==d||e[30]!==y?(u=t.jsxs(H,{children:[B,d,y]}),e[29]=d,e[30]=y,e[31]=u):u=e[31];let A;e[32]===Symbol.for("react.memo_cache_sentinel")?(A=t.jsx(V,{children:t.jsx("label",{htmlFor:"policyDocument",children:"Policy Document (JSON)"})}),e[32]=A):A=e[32];const L=!!i.policyDocument;let x;e[33]!==o?(x=o("policyDocument"),e[33]=o,e[34]=x):x=e[34];let h;e[35]!==L||e[36]!==x?(h=t.jsx(te,{"aria-invalid":L,className:"font-mono text-sm",id:"policyDocument",rows:15,...x}),e[35]=L,e[36]=x,e[37]=h):h=e[37];let j;e[38]!==i.policyDocument?(j=t.jsx(U,{errors:[i.policyDocument]}),e[38]=i.policyDocument,e[39]=j):j=e[39];let b;e[40]!==h||e[41]!==j?(b=t.jsxs(H,{children:[A,h,j]}),e[40]=h,e[41]=j,e[42]=b):b=e[42];const R=w||l.isPending;let N;e[43]!==s?(N=()=>s({to:"/iam/list-policies"}),e[43]=s,e[44]=N):N=e[44];let g;e[45]!==R||e[46]!==N?(g=t.jsx(Y,{disabled:R,onClick:N,type:"button",variant:"outline",children:"Cancel"}),e[45]=R,e[46]=N,e[47]=g):g=e[47];const J=w||l.isPending,M=w||l.isPending?"Creating...":"Create Policy";let S;e[48]!==J||e[49]!==M?(S=t.jsx(Y,{disabled:J,type:"submit",children:M}),e[48]=J,e[49]=M,e[50]=S):S=e[50];let P;e[51]!==g||e[52]!==S?(P=t.jsxs("div",{className:"flex gap-2",children:[g,S]}),e[51]=g,e[52]=S,e[53]=P):P=e[53];let D;e[54]!==p||e[55]!==u||e[56]!==b||e[57]!==P||e[58]!==c?(D=t.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:c,children:[p,u,b,P]}),e[54]=p,e[55]=u,e[56]=b,e[57]=P,e[58]=c,e[59]=D):D=e[59];let T;return e[60]!==D||e[61]!==r?(T=t.jsxs(t.Fragment,{children:[C,E,r,D]}),e[60]=D,e[61]=r,e[62]=T):T=e[62],T}export{ue as component};
|
||||
@@ -1 +1 @@
|
||||
import{c as q,u as J,i as K,R as U,j as t,B as G}from"./index.js";import{a as W,u as X,C as Y}from"./zod.js";import{u as Z}from"./useSuspenseQuery.js";import{B as ee}from"./back-link.js";import{E as te}from"./error-banner.js";import{P as se}from"./page-heading.js";import{F as le,b as H,a as L}from"./field.js";import{S as oe,a as re,b as ie,c as ae,d as ne}from"./select.js";import{T as ce}from"./textarea.js";import{c as me}from"./ec2.js";import{d as de}from"./ec22.js";import"./check.js";function ye(){const e=q.c(51),l=J(),{data:B}=Z(K),s=me();let j;e[0]!==B.Volumes?(j=B.Volumes??[],e[0]=B.Volumes,e[1]=j):j=e[1];const b=j,{volumeId:M}=U.useSearch(),E=M??b[0]?.VolumeId??"";let v;e[2]===Symbol.for("react.memo_cache_sentinel")?(v=W(de),e[2]=v):v=e[2];let I;e[3]!==E?(I={resolver:v,defaultValues:{volumeId:E,description:""}},e[3]=E,e[4]=I):I=e[4];const{control:P,handleSubmit:k,register:N,formState:O}=X(I),{errors:o,isSubmitting:R}=O;let g;e[5]!==s||e[6]!==l?(g=async z=>{await s.mutateAsync(z),l({to:"/ec2/describe-snapshots"})},e[5]=s,e[6]=l,e[7]=g):g=e[7];const T=g;let V,C;e[8]===Symbol.for("react.memo_cache_sentinel")?(V=t.jsx(ee,{to:"/ec2/describe-snapshots",children:"Back to snapshots"}),C=t.jsx(se,{title:"Create Snapshot"}),e[8]=V,e[9]=C):(V=e[8],C=e[9]);let r;e[10]!==s.error?(r=s.error&&t.jsx(te,{error:s.error,msg:"Failed to create snapshot"}),e[10]=s.error,e[11]=r):r=e[11];let i;e[12]!==k||e[13]!==T?(i=k(T),e[12]=k,e[13]=T,e[14]=i):i=e[14];let y;e[15]===Symbol.for("react.memo_cache_sentinel")?(y=t.jsx(L,{children:t.jsx("label",{htmlFor:"volumeId",children:"Volume"})}),e[15]=y):y=e[15];let a;e[16]!==o.volumeId||e[17]!==b?(a=z=>{const{field:A}=z;return t.jsxs(oe,{onValueChange:$=>A.onChange($),value:A.value??"",children:[t.jsx(re,{"aria-invalid":!!o.volumeId,className:"w-full",id:"volumeId",children:t.jsx(ie,{})}),t.jsx(ae,{children:b.map(ue)})]})},e[16]=o.volumeId,e[17]=b,e[18]=a):a=e[18];let n;e[19]!==P||e[20]!==a?(n=t.jsx(Y,{control:P,name:"volumeId",render:a}),e[19]=P,e[20]=a,e[21]=n):n=e[21];let c;e[22]!==o.volumeId?(c=t.jsx(le,{errors:[o.volumeId]}),e[22]=o.volumeId,e[23]=c):c=e[23];let m;e[24]!==n||e[25]!==c?(m=t.jsxs(H,{children:[y,n,c]}),e[24]=n,e[25]=c,e[26]=m):m=e[26];let F;e[27]===Symbol.for("react.memo_cache_sentinel")?(F=t.jsx(L,{children:t.jsx("label",{htmlFor:"description",children:"Description (optional)"})}),e[27]=F):F=e[27];let d;e[28]!==N?(d=N("description"),e[28]=N,e[29]=d):d=e[29];let u;e[30]!==d?(u=t.jsxs(H,{children:[F,t.jsx(ce,{id:"description",placeholder:"Snapshot description",...d})]}),e[30]=d,e[31]=u):u=e[31];const w=R||s.isPending;let f;e[32]!==l?(f=()=>l({to:"/ec2/describe-snapshots"}),e[32]=l,e[33]=f):f=e[33];let p;e[34]!==w||e[35]!==f?(p=t.jsx(G,{disabled:w,onClick:f,type:"button",variant:"outline",children:"Cancel"}),e[34]=w,e[35]=f,e[36]=p):p=e[36];const D=R||s.isPending,Q=R||s.isPending?"Creating…":"Create Snapshot";let h;e[37]!==D||e[38]!==Q?(h=t.jsx(G,{disabled:D,type:"submit",children:Q}),e[37]=D,e[38]=Q,e[39]=h):h=e[39];let x;e[40]!==p||e[41]!==h?(x=t.jsxs("div",{className:"flex gap-2",children:[p,h]}),e[40]=p,e[41]=h,e[42]=x):x=e[42];let S;e[43]!==m||e[44]!==u||e[45]!==x||e[46]!==i?(S=t.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:i,children:[m,u,x]}),e[43]=m,e[44]=u,e[45]=x,e[46]=i,e[47]=S):S=e[47];let _;return e[48]!==S||e[49]!==r?(_=t.jsxs(t.Fragment,{children:[V,C,r,S]}),e[48]=S,e[49]=r,e[50]=_):_=e[50],_}function ue(e){return t.jsxs(ne,{value:e.VolumeId??"",children:[e.VolumeId," (",e.Size," GiB)"]},e.VolumeId)}export{ye as component};
|
||||
import{c as q,u as J,m as K,R as U,j as t,B as G}from"./index.js";import{a as W,u as X,C as Y}from"./zod.js";import{u as Z}from"./useSuspenseQuery.js";import{B as ee}from"./back-link.js";import{E as te}from"./error-banner.js";import{P as se}from"./page-heading.js";import{F as le,b as H,a as L}from"./field.js";import{S as oe,a as re,b as ie,c as ae,d as ne}from"./select.js";import{T as ce}from"./textarea.js";import{c as me}from"./ec2.js";import{d as de}from"./ec22.js";import"./check.js";function ye(){const e=q.c(51),l=J(),{data:B}=Z(K),s=me();let j;e[0]!==B.Volumes?(j=B.Volumes??[],e[0]=B.Volumes,e[1]=j):j=e[1];const b=j,{volumeId:M}=U.useSearch(),E=M??b[0]?.VolumeId??"";let v;e[2]===Symbol.for("react.memo_cache_sentinel")?(v=W(de),e[2]=v):v=e[2];let I;e[3]!==E?(I={resolver:v,defaultValues:{volumeId:E,description:""}},e[3]=E,e[4]=I):I=e[4];const{control:P,handleSubmit:k,register:N,formState:O}=X(I),{errors:o,isSubmitting:R}=O;let g;e[5]!==s||e[6]!==l?(g=async z=>{await s.mutateAsync(z),l({to:"/ec2/describe-snapshots"})},e[5]=s,e[6]=l,e[7]=g):g=e[7];const T=g;let V,C;e[8]===Symbol.for("react.memo_cache_sentinel")?(V=t.jsx(ee,{to:"/ec2/describe-snapshots",children:"Back to snapshots"}),C=t.jsx(se,{title:"Create Snapshot"}),e[8]=V,e[9]=C):(V=e[8],C=e[9]);let r;e[10]!==s.error?(r=s.error&&t.jsx(te,{error:s.error,msg:"Failed to create snapshot"}),e[10]=s.error,e[11]=r):r=e[11];let i;e[12]!==k||e[13]!==T?(i=k(T),e[12]=k,e[13]=T,e[14]=i):i=e[14];let y;e[15]===Symbol.for("react.memo_cache_sentinel")?(y=t.jsx(L,{children:t.jsx("label",{htmlFor:"volumeId",children:"Volume"})}),e[15]=y):y=e[15];let a;e[16]!==o.volumeId||e[17]!==b?(a=z=>{const{field:A}=z;return t.jsxs(oe,{onValueChange:$=>A.onChange($),value:A.value??"",children:[t.jsx(re,{"aria-invalid":!!o.volumeId,className:"w-full",id:"volumeId",children:t.jsx(ie,{})}),t.jsx(ae,{children:b.map(ue)})]})},e[16]=o.volumeId,e[17]=b,e[18]=a):a=e[18];let n;e[19]!==P||e[20]!==a?(n=t.jsx(Y,{control:P,name:"volumeId",render:a}),e[19]=P,e[20]=a,e[21]=n):n=e[21];let c;e[22]!==o.volumeId?(c=t.jsx(le,{errors:[o.volumeId]}),e[22]=o.volumeId,e[23]=c):c=e[23];let m;e[24]!==n||e[25]!==c?(m=t.jsxs(H,{children:[y,n,c]}),e[24]=n,e[25]=c,e[26]=m):m=e[26];let F;e[27]===Symbol.for("react.memo_cache_sentinel")?(F=t.jsx(L,{children:t.jsx("label",{htmlFor:"description",children:"Description (optional)"})}),e[27]=F):F=e[27];let d;e[28]!==N?(d=N("description"),e[28]=N,e[29]=d):d=e[29];let u;e[30]!==d?(u=t.jsxs(H,{children:[F,t.jsx(ce,{id:"description",placeholder:"Snapshot description",...d})]}),e[30]=d,e[31]=u):u=e[31];const w=R||s.isPending;let f;e[32]!==l?(f=()=>l({to:"/ec2/describe-snapshots"}),e[32]=l,e[33]=f):f=e[33];let p;e[34]!==w||e[35]!==f?(p=t.jsx(G,{disabled:w,onClick:f,type:"button",variant:"outline",children:"Cancel"}),e[34]=w,e[35]=f,e[36]=p):p=e[36];const D=R||s.isPending,Q=R||s.isPending?"Creating…":"Create Snapshot";let h;e[37]!==D||e[38]!==Q?(h=t.jsx(G,{disabled:D,type:"submit",children:Q}),e[37]=D,e[38]=Q,e[39]=h):h=e[39];let x;e[40]!==p||e[41]!==h?(x=t.jsxs("div",{className:"flex gap-2",children:[p,h]}),e[40]=p,e[41]=h,e[42]=x):x=e[42];let S;e[43]!==m||e[44]!==u||e[45]!==x||e[46]!==i?(S=t.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:i,children:[m,u,x]}),e[43]=m,e[44]=u,e[45]=x,e[46]=i,e[47]=S):S=e[47];let _;return e[48]!==S||e[49]!==r?(_=t.jsxs(t.Fragment,{children:[V,C,r,S]}),e[48]=S,e[49]=r,e[50]=_):_=e[50],_}function ue(e){return t.jsxs(ne,{value:e.VolumeId??"",children:[e.VolumeId," (",e.Size," GiB)"]},e.VolumeId)}export{ye as component};
|
||||
|
||||
@@ -1 +1 @@
|
||||
import{c as oe,u as ce,h as de,g as me,j as t,B as Y}from"./index.js";import{a as ue,u as fe,C as ee}from"./zod.js";import{u as te}from"./useSuspenseQuery.js";import{B as pe}from"./back-link.js";import{E as be}from"./error-banner.js";import{P as he}from"./page-heading.js";import{F as se,a as U,b as W}from"./field.js";import{I as xe}from"./input.js";import{S as le,a as ie,b as ne,c as re,d as X}from"./select.js";import{b as je}from"./ec2.js";import{b as ve}from"./ec22.js";import"./check.js";function Ee(){const e=oe.c(66),s=ce(),{data:Q}=te(de),{data:R}=te(me),l=je();let V;e[0]!==Q.Vpcs?(V=Q.Vpcs??[],e[0]=Q.Vpcs,e[1]=V):V=e[1];const k=V;let _;e[2]!==R.AvailabilityZones?(_=R.AvailabilityZones??[],e[2]=R.AvailabilityZones,e[3]=_):_=e[3];const T=_;let Z;e[4]===Symbol.for("react.memo_cache_sentinel")?(Z=ue(ve),e[4]=Z):Z=e[4];const O=k[0]?.VpcId??"";let F;e[5]!==O?(F={resolver:Z,defaultValues:{vpcId:O,cidrBlock:"10.0.1.0/24",availabilityZone:""}},e[5]=O,e[6]=F):F=e[6];const{control:r,handleSubmit:H,register:K,formState:ae}=fe(F),{errors:i,isSubmitting:L}=ae;let N;e[7]!==l||e[8]!==s?(N=async B=>{const n=(await l.mutateAsync(B)).Subnet?.SubnetId;s(n?{to:"/ec2/describe-subnets/$id",params:{id:n}}:{to:"/ec2/describe-subnets"})},e[7]=l,e[8]=s,e[9]=N):N=e[9];const M=N;let A,P;e[10]===Symbol.for("react.memo_cache_sentinel")?(A=t.jsx(pe,{to:"/ec2/describe-subnets",children:"Back to Subnets"}),P=t.jsx(he,{title:"Create Subnet"}),e[10]=A,e[11]=P):(A=e[10],P=e[11]);let a;e[12]!==l.error?(a=l.error&&t.jsx(be,{error:l.error,msg:"Failed to create subnet"}),e[12]=l.error,e[13]=a):a=e[13];let o;e[14]!==H||e[15]!==M?(o=H(M),e[14]=H,e[15]=M,e[16]=o):o=e[16];let $;e[17]===Symbol.for("react.memo_cache_sentinel")?($=t.jsx(U,{children:t.jsx("label",{htmlFor:"vpcId",children:"VPC"})}),e[17]=$):$=e[17];let c;e[18]!==i.vpcId||e[19]!==k?(c=B=>{const{field:C}=B;return t.jsxs(le,{onValueChange:n=>C.onChange(n),value:C.value??"",children:[t.jsx(ie,{"aria-invalid":!!i.vpcId,className:"w-full",id:"vpcId",children:t.jsx(ne,{})}),t.jsx(re,{children:k.map(ye)})]})},e[18]=i.vpcId,e[19]=k,e[20]=c):c=e[20];let d;e[21]!==r||e[22]!==c?(d=t.jsx(ee,{control:r,name:"vpcId",render:c}),e[21]=r,e[22]=c,e[23]=d):d=e[23];let m;e[24]!==i.vpcId?(m=t.jsx(se,{errors:[i.vpcId]}),e[24]=i.vpcId,e[25]=m):m=e[25];let u;e[26]!==d||e[27]!==m?(u=t.jsxs(W,{children:[$,d,m]}),e[26]=d,e[27]=m,e[28]=u):u=e[28];let E;e[29]===Symbol.for("react.memo_cache_sentinel")?(E=t.jsx(U,{children:t.jsx("label",{htmlFor:"cidrBlock",children:"CIDR Block"})}),e[29]=E):E=e[29];const q=!!i.cidrBlock;let f;e[30]!==K?(f=K("cidrBlock"),e[30]=K,e[31]=f):f=e[31];let p;e[32]!==q||e[33]!==f?(p=t.jsx(xe,{"aria-invalid":q,id:"cidrBlock",placeholder:"10.0.1.0/24",...f}),e[32]=q,e[33]=f,e[34]=p):p=e[34];let b;e[35]!==i.cidrBlock?(b=t.jsx(se,{errors:[i.cidrBlock]}),e[35]=i.cidrBlock,e[36]=b):b=e[36];let h;e[37]!==p||e[38]!==b?(h=t.jsxs(W,{children:[E,p,b]}),e[37]=p,e[38]=b,e[39]=h):h=e[39];let w;e[40]===Symbol.for("react.memo_cache_sentinel")?(w=t.jsx(U,{children:t.jsx("label",{htmlFor:"availabilityZone",children:"Availability Zone (optional)"})}),e[40]=w):w=e[40];let x;e[41]!==T?(x=B=>{const{field:C}=B;return t.jsxs(le,{onValueChange:n=>C.onChange(n==="none"?"":n),value:C.value||"none",children:[t.jsx(ie,{className:"w-full",id:"availabilityZone",children:t.jsx(ne,{})}),t.jsxs(re,{children:[t.jsx(X,{value:"none",children:"none"}),T.map(Se)]})]})},e[41]=T,e[42]=x):x=e[42];let j;e[43]!==r||e[44]!==x?(j=t.jsxs(W,{children:[w,t.jsx(ee,{control:r,name:"availabilityZone",render:x})]}),e[43]=r,e[44]=x,e[45]=j):j=e[45];const z=L||l.isPending;let v;e[46]!==s?(v=()=>s({to:"/ec2/describe-subnets"}),e[46]=s,e[47]=v):v=e[47];let S;e[48]!==z||e[49]!==v?(S=t.jsx(Y,{disabled:z,onClick:v,type:"button",variant:"outline",children:"Cancel"}),e[48]=z,e[49]=v,e[50]=S):S=e[50];const G=L||l.isPending,J=L||l.isPending?"Creating…":"Create Subnet";let y;e[51]!==G||e[52]!==J?(y=t.jsx(Y,{disabled:G,type:"submit",children:J}),e[51]=G,e[52]=J,e[53]=y):y=e[53];let g;e[54]!==S||e[55]!==y?(g=t.jsxs("div",{className:"flex gap-2",children:[S,y]}),e[54]=S,e[55]=y,e[56]=g):g=e[56];let I;e[57]!==o||e[58]!==u||e[59]!==h||e[60]!==j||e[61]!==g?(I=t.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:o,children:[u,h,j,g]}),e[57]=o,e[58]=u,e[59]=h,e[60]=j,e[61]=g,e[62]=I):I=e[62];let D;return e[63]!==I||e[64]!==a?(D=t.jsxs(t.Fragment,{children:[A,P,a,I]}),e[63]=I,e[64]=a,e[65]=D):D=e[65],D}function Se(e){return t.jsx(X,{value:e.ZoneName??"",children:e.ZoneName},e.ZoneName)}function ye(e){const s=e.Tags?.find(ge)?.Value;return t.jsx(X,{value:e.VpcId??"",children:s?`${e.VpcId} (${s})`:`${e.VpcId} (${e.CidrBlock})`},e.VpcId)}function ge(e){return e.Key==="Name"}export{Ee as component};
|
||||
import{c as oe,u as ce,l as de,k as me,j as t,B as Y}from"./index.js";import{a as ue,u as fe,C as ee}from"./zod.js";import{u as te}from"./useSuspenseQuery.js";import{B as pe}from"./back-link.js";import{E as be}from"./error-banner.js";import{P as xe}from"./page-heading.js";import{F as se,a as U,b as W}from"./field.js";import{I as he}from"./input.js";import{S as le,a as ie,b as ne,c as re,d as X}from"./select.js";import{b as je}from"./ec2.js";import{b as ve}from"./ec22.js";import"./check.js";function Ee(){const e=oe.c(66),s=ce(),{data:Q}=te(de),{data:R}=te(me),l=je();let k;e[0]!==Q.Vpcs?(k=Q.Vpcs??[],e[0]=Q.Vpcs,e[1]=k):k=e[1];const V=k;let _;e[2]!==R.AvailabilityZones?(_=R.AvailabilityZones??[],e[2]=R.AvailabilityZones,e[3]=_):_=e[3];const T=_;let Z;e[4]===Symbol.for("react.memo_cache_sentinel")?(Z=ue(ve),e[4]=Z):Z=e[4];const O=V[0]?.VpcId??"";let F;e[5]!==O?(F={resolver:Z,defaultValues:{vpcId:O,cidrBlock:"10.0.1.0/24",availabilityZone:""}},e[5]=O,e[6]=F):F=e[6];const{control:r,handleSubmit:H,register:K,formState:ae}=fe(F),{errors:i,isSubmitting:L}=ae;let N;e[7]!==l||e[8]!==s?(N=async B=>{const n=(await l.mutateAsync(B)).Subnet?.SubnetId;s(n?{to:"/ec2/describe-subnets/$id",params:{id:n}}:{to:"/ec2/describe-subnets"})},e[7]=l,e[8]=s,e[9]=N):N=e[9];const M=N;let A,P;e[10]===Symbol.for("react.memo_cache_sentinel")?(A=t.jsx(pe,{to:"/ec2/describe-subnets",children:"Back to Subnets"}),P=t.jsx(xe,{title:"Create Subnet"}),e[10]=A,e[11]=P):(A=e[10],P=e[11]);let a;e[12]!==l.error?(a=l.error&&t.jsx(be,{error:l.error,msg:"Failed to create subnet"}),e[12]=l.error,e[13]=a):a=e[13];let o;e[14]!==H||e[15]!==M?(o=H(M),e[14]=H,e[15]=M,e[16]=o):o=e[16];let $;e[17]===Symbol.for("react.memo_cache_sentinel")?($=t.jsx(U,{children:t.jsx("label",{htmlFor:"vpcId",children:"VPC"})}),e[17]=$):$=e[17];let c;e[18]!==i.vpcId||e[19]!==V?(c=B=>{const{field:C}=B;return t.jsxs(le,{onValueChange:n=>C.onChange(n),value:C.value??"",children:[t.jsx(ie,{"aria-invalid":!!i.vpcId,className:"w-full",id:"vpcId",children:t.jsx(ne,{})}),t.jsx(re,{children:V.map(ye)})]})},e[18]=i.vpcId,e[19]=V,e[20]=c):c=e[20];let d;e[21]!==r||e[22]!==c?(d=t.jsx(ee,{control:r,name:"vpcId",render:c}),e[21]=r,e[22]=c,e[23]=d):d=e[23];let m;e[24]!==i.vpcId?(m=t.jsx(se,{errors:[i.vpcId]}),e[24]=i.vpcId,e[25]=m):m=e[25];let u;e[26]!==d||e[27]!==m?(u=t.jsxs(W,{children:[$,d,m]}),e[26]=d,e[27]=m,e[28]=u):u=e[28];let E;e[29]===Symbol.for("react.memo_cache_sentinel")?(E=t.jsx(U,{children:t.jsx("label",{htmlFor:"cidrBlock",children:"CIDR Block"})}),e[29]=E):E=e[29];const q=!!i.cidrBlock;let f;e[30]!==K?(f=K("cidrBlock"),e[30]=K,e[31]=f):f=e[31];let p;e[32]!==q||e[33]!==f?(p=t.jsx(he,{"aria-invalid":q,id:"cidrBlock",placeholder:"10.0.1.0/24",...f}),e[32]=q,e[33]=f,e[34]=p):p=e[34];let b;e[35]!==i.cidrBlock?(b=t.jsx(se,{errors:[i.cidrBlock]}),e[35]=i.cidrBlock,e[36]=b):b=e[36];let x;e[37]!==p||e[38]!==b?(x=t.jsxs(W,{children:[E,p,b]}),e[37]=p,e[38]=b,e[39]=x):x=e[39];let w;e[40]===Symbol.for("react.memo_cache_sentinel")?(w=t.jsx(U,{children:t.jsx("label",{htmlFor:"availabilityZone",children:"Availability Zone (optional)"})}),e[40]=w):w=e[40];let h;e[41]!==T?(h=B=>{const{field:C}=B;return t.jsxs(le,{onValueChange:n=>C.onChange(n==="none"?"":n),value:C.value||"none",children:[t.jsx(ie,{className:"w-full",id:"availabilityZone",children:t.jsx(ne,{})}),t.jsxs(re,{children:[t.jsx(X,{value:"none",children:"none"}),T.map(Se)]})]})},e[41]=T,e[42]=h):h=e[42];let j;e[43]!==r||e[44]!==h?(j=t.jsxs(W,{children:[w,t.jsx(ee,{control:r,name:"availabilityZone",render:h})]}),e[43]=r,e[44]=h,e[45]=j):j=e[45];const z=L||l.isPending;let v;e[46]!==s?(v=()=>s({to:"/ec2/describe-subnets"}),e[46]=s,e[47]=v):v=e[47];let S;e[48]!==z||e[49]!==v?(S=t.jsx(Y,{disabled:z,onClick:v,type:"button",variant:"outline",children:"Cancel"}),e[48]=z,e[49]=v,e[50]=S):S=e[50];const G=L||l.isPending,J=L||l.isPending?"Creating…":"Create Subnet";let y;e[51]!==G||e[52]!==J?(y=t.jsx(Y,{disabled:G,type:"submit",children:J}),e[51]=G,e[52]=J,e[53]=y):y=e[53];let I;e[54]!==S||e[55]!==y?(I=t.jsxs("div",{className:"flex gap-2",children:[S,y]}),e[54]=S,e[55]=y,e[56]=I):I=e[56];let g;e[57]!==o||e[58]!==u||e[59]!==x||e[60]!==j||e[61]!==I?(g=t.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:o,children:[u,x,j,I]}),e[57]=o,e[58]=u,e[59]=x,e[60]=j,e[61]=I,e[62]=g):g=e[62];let D;return e[63]!==g||e[64]!==a?(D=t.jsxs(t.Fragment,{children:[A,P,a,g]}),e[63]=g,e[64]=a,e[65]=D):D=e[65],D}function Se(e){return t.jsx(X,{value:e.ZoneName??"",children:e.ZoneName},e.ZoneName)}function ye(e){const s=e.Tags?.find(Ie)?.Value;return t.jsx(X,{value:e.VpcId??"",children:s?`${e.VpcId} (${s})`:`${e.VpcId} (${e.CidrBlock})`},e.VpcId)}function Ie(e){return e.Key==="Name"}export{Ee as component};
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
import{c as z,u as D,j as t,B as A}from"./index.js";import{a as G,u as J}from"./zod.js";import{B as K}from"./back-link.js";import{E as O}from"./error-banner.js";import{P as Q}from"./page-heading.js";import{F as H,a as L,b as M}from"./field.js";import{I as T}from"./input.js";import{u as V}from"./iam.js";import{c as W}from"./iam2.js";function ae(){const e=z.c(51),l=D(),s=V();let y;e[0]===Symbol.for("react.memo_cache_sentinel")?(y={resolver:G(W)},e[0]=y):y=e[0];const{handleSubmit:P,register:i,formState:$}=J(y),{errors:r,isSubmitting:U}=$;let S;e[1]!==s||e[2]!==l?(S=async q=>{await s.mutateAsync(q),l({to:"/iam/list-users"})},e[1]=s,e[2]=l,e[3]=S):S=e[3];const E=S;let F,_;e[4]===Symbol.for("react.memo_cache_sentinel")?(F=t.jsx(K,{to:"/iam/list-users",children:"Back to users"}),_=t.jsx(Q,{title:"Create User"}),e[4]=F,e[5]=_):(F=e[4],_=e[5]);let a;e[6]!==s.error?(a=s.error&&t.jsx(O,{error:s.error,msg:"Failed to create user"}),e[6]=s.error,e[7]=a):a=e[7];let o;e[8]!==P||e[9]!==E?(o=P(E),e[8]=P,e[9]=E,e[10]=o):o=e[10];let C;e[11]===Symbol.for("react.memo_cache_sentinel")?(C=t.jsx(L,{children:t.jsx("label",{htmlFor:"userName",children:"User Name"})}),e[11]=C):C=e[11];const k=!!r.userName;let n;e[12]!==i?(n=i("userName"),e[12]=i,e[13]=n):n=e[13];let m;e[14]!==k||e[15]!==n?(m=t.jsx(T,{"aria-invalid":k,id:"userName",placeholder:"my-user...",...n}),e[14]=k,e[15]=n,e[16]=m):m=e[16];let c;e[17]!==r.userName?(c=t.jsx(H,{errors:[r.userName]}),e[17]=r.userName,e[18]=c):c=e[18];let f;e[19]!==m||e[20]!==c?(f=t.jsxs(M,{children:[C,m,c]}),e[19]=m,e[20]=c,e[21]=f):f=e[21];let v;e[22]===Symbol.for("react.memo_cache_sentinel")?(v=t.jsx(L,{children:t.jsx("label",{htmlFor:"path",children:"Path (optional)"})}),e[22]=v):v=e[22];let u;e[23]!==i?(u=i("path"),e[23]=i,e[24]=u):u=e[24];let d;e[25]!==u?(d=t.jsx(T,{id:"path",placeholder:"/",...u}),e[25]=u,e[26]=d):d=e[26];let h;e[27]!==r.path?(h=t.jsx(H,{errors:[r.path]}),e[27]=r.path,e[28]=h):h=e[28];let p;e[29]!==d||e[30]!==h?(p=t.jsxs(M,{children:[v,d,h]}),e[29]=d,e[30]=h,e[31]=p):p=e[31];const w=U||s.isPending;let x;e[32]!==l?(x=()=>l({to:"/iam/list-users"}),e[32]=l,e[33]=x):x=e[33];let j;e[34]!==w||e[35]!==x?(j=t.jsx(A,{disabled:w,onClick:x,type:"button",variant:"outline",children:"Cancel"}),e[34]=w,e[35]=x,e[36]=j):j=e[36];const I=U||s.isPending,R=U||s.isPending?"Creating...":"Create User";let b;e[37]!==I||e[38]!==R?(b=t.jsx(A,{disabled:I,type:"submit",children:R}),e[37]=I,e[38]=R,e[39]=b):b=e[39];let g;e[40]!==j||e[41]!==b?(g=t.jsxs("div",{className:"flex gap-2",children:[j,b]}),e[40]=j,e[41]=b,e[42]=g):g=e[42];let N;e[43]!==f||e[44]!==p||e[45]!==g||e[46]!==o?(N=t.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:o,children:[f,p,g]}),e[43]=f,e[44]=p,e[45]=g,e[46]=o,e[47]=N):N=e[47];let B;return e[48]!==N||e[49]!==a?(B=t.jsxs(t.Fragment,{children:[F,_,a,N]}),e[48]=N,e[49]=a,e[50]=B):B=e[50],B}export{ae as component};
|
||||
@@ -1 +1 @@
|
||||
import{c as K,u as U,g as W,j as t,B as L}from"./index.js";import{a as X,u as Y,C as ee}from"./zod.js";import{u as te}from"./useSuspenseQuery.js";import{B as ie}from"./back-link.js";import{E as le}from"./error-banner.js";import{P as ae}from"./page-heading.js";import{F as M,a as O,b as $}from"./field.js";import{I as se}from"./input.js";import{S as re,a as oe,b as ne,c as me,d as ce}from"./select.js";import{a as ue}from"./ec2.js";import{a as fe}from"./ec22.js";import"./check.js";function Fe(){const e=K.c(57),a=U(),{data:V}=te(W),i=ue();let j;e[0]!==V.AvailabilityZones?(j=V.AvailabilityZones??[],e[0]=V.AvailabilityZones,e[1]=j):j=e[1];const Z=j,B=Z[0]?.ZoneName??"";let g;e[2]===Symbol.for("react.memo_cache_sentinel")?(g=X(fe),e[2]=g):g=e[2];let S;e[3]!==B?(S={resolver:g,defaultValues:{size:1,availabilityZone:B}},e[3]=B,e[4]=S):S=e[4];const{control:E,handleSubmit:P,register:k,formState:q}=Y(S),{errors:l,isSubmitting:w}=q;let C;e[5]!==i||e[6]!==a?(C=async G=>{await i.mutateAsync(G),a({to:"/ec2/describe-volumes"})},e[5]=i,e[6]=a,e[7]=C):C=e[7];const I=C;let z,F;e[8]===Symbol.for("react.memo_cache_sentinel")?(z=t.jsx(ie,{to:"/ec2/describe-volumes",children:"Back to volumes"}),F=t.jsx(ae,{title:"Create Volume"}),e[8]=z,e[9]=F):(z=e[8],F=e[9]);let s;e[10]!==i.error?(s=i.error&&t.jsx(le,{error:i.error,msg:"Failed to create volume"}),e[10]=i.error,e[11]=s):s=e[11];let r;e[12]!==P||e[13]!==I?(r=P(I),e[12]=P,e[13]=I,e[14]=r):r=e[14];let N;e[15]===Symbol.for("react.memo_cache_sentinel")?(N=t.jsx(O,{children:t.jsx("label",{htmlFor:"size",children:"Size (GiB)"})}),e[15]=N):N=e[15];const Q=!!l.size;let o;e[16]!==k?(o=k("size",{valueAsNumber:!0}),e[16]=k,e[17]=o):o=e[17];let n;e[18]!==Q||e[19]!==o?(n=t.jsx(se,{"aria-invalid":Q,id:"size",max:16384,min:1,type:"number",...o}),e[18]=Q,e[19]=o,e[20]=n):n=e[20];let m;e[21]!==l.size?(m=t.jsx(M,{errors:[l.size]}),e[21]=l.size,e[22]=m):m=e[22];let c;e[23]!==n||e[24]!==m?(c=t.jsxs($,{children:[N,n,m]}),e[23]=n,e[24]=m,e[25]=c):c=e[25];let _;e[26]===Symbol.for("react.memo_cache_sentinel")?(_=t.jsx(O,{children:t.jsx("label",{htmlFor:"availabilityZone",children:"Availability Zone"})}),e[26]=_):_=e[26];let u;e[27]!==Z||e[28]!==l.availabilityZone?(u=G=>{const{field:H}=G;return t.jsxs(re,{onValueChange:J=>H.onChange(J),value:H.value??"",children:[t.jsx(oe,{"aria-invalid":!!l.availabilityZone,className:"w-full",id:"availabilityZone",children:t.jsx(ne,{})}),t.jsx(me,{children:Z.map(de)})]})},e[27]=Z,e[28]=l.availabilityZone,e[29]=u):u=e[29];let f;e[30]!==E||e[31]!==u?(f=t.jsx(ee,{control:E,name:"availabilityZone",render:u}),e[30]=E,e[31]=u,e[32]=f):f=e[32];let d;e[33]!==l.availabilityZone?(d=t.jsx(M,{errors:[l.availabilityZone]}),e[33]=l.availabilityZone,e[34]=d):d=e[34];let b;e[35]!==f||e[36]!==d?(b=t.jsxs($,{children:[_,f,d]}),e[35]=f,e[36]=d,e[37]=b):b=e[37];const R=w||i.isPending;let v;e[38]!==a?(v=()=>a({to:"/ec2/describe-volumes"}),e[38]=a,e[39]=v):v=e[39];let x;e[40]!==R||e[41]!==v?(x=t.jsx(L,{disabled:R,onClick:v,type:"button",variant:"outline",children:"Cancel"}),e[40]=R,e[41]=v,e[42]=x):x=e[42];const T=w||i.isPending,D=w||i.isPending?"Creating…":"Create Volume";let y;e[43]!==T||e[44]!==D?(y=t.jsx(L,{disabled:T,type:"submit",children:D}),e[43]=T,e[44]=D,e[45]=y):y=e[45];let p;e[46]!==x||e[47]!==y?(p=t.jsxs("div",{className:"flex gap-2",children:[x,y]}),e[46]=x,e[47]=y,e[48]=p):p=e[48];let h;e[49]!==c||e[50]!==b||e[51]!==p||e[52]!==r?(h=t.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:r,children:[c,b,p]}),e[49]=c,e[50]=b,e[51]=p,e[52]=r,e[53]=h):h=e[53];let A;return e[54]!==h||e[55]!==s?(A=t.jsxs(t.Fragment,{children:[z,F,s,h]}),e[54]=h,e[55]=s,e[56]=A):A=e[56],A}function de(e){return t.jsx(ce,{value:e.ZoneName??"",children:e.ZoneName},e.ZoneName)}export{Fe as component};
|
||||
import{c as K,u as U,k as W,j as t,B as L}from"./index.js";import{a as X,u as Y,C as ee}from"./zod.js";import{u as te}from"./useSuspenseQuery.js";import{B as ie}from"./back-link.js";import{E as le}from"./error-banner.js";import{P as ae}from"./page-heading.js";import{F as M,a as O,b as $}from"./field.js";import{I as se}from"./input.js";import{S as re,a as oe,b as ne,c as me,d as ce}from"./select.js";import{a as ue}from"./ec2.js";import{a as fe}from"./ec22.js";import"./check.js";function Fe(){const e=K.c(57),a=U(),{data:V}=te(W),i=ue();let j;e[0]!==V.AvailabilityZones?(j=V.AvailabilityZones??[],e[0]=V.AvailabilityZones,e[1]=j):j=e[1];const Z=j,B=Z[0]?.ZoneName??"";let S;e[2]===Symbol.for("react.memo_cache_sentinel")?(S=X(fe),e[2]=S):S=e[2];let g;e[3]!==B?(g={resolver:S,defaultValues:{size:1,availabilityZone:B}},e[3]=B,e[4]=g):g=e[4];const{control:k,handleSubmit:E,register:P,formState:q}=Y(g),{errors:l,isSubmitting:w}=q;let C;e[5]!==i||e[6]!==a?(C=async G=>{await i.mutateAsync(G),a({to:"/ec2/describe-volumes"})},e[5]=i,e[6]=a,e[7]=C):C=e[7];const I=C;let z,F;e[8]===Symbol.for("react.memo_cache_sentinel")?(z=t.jsx(ie,{to:"/ec2/describe-volumes",children:"Back to volumes"}),F=t.jsx(ae,{title:"Create Volume"}),e[8]=z,e[9]=F):(z=e[8],F=e[9]);let s;e[10]!==i.error?(s=i.error&&t.jsx(le,{error:i.error,msg:"Failed to create volume"}),e[10]=i.error,e[11]=s):s=e[11];let r;e[12]!==E||e[13]!==I?(r=E(I),e[12]=E,e[13]=I,e[14]=r):r=e[14];let N;e[15]===Symbol.for("react.memo_cache_sentinel")?(N=t.jsx(O,{children:t.jsx("label",{htmlFor:"size",children:"Size (GiB)"})}),e[15]=N):N=e[15];const Q=!!l.size;let o;e[16]!==P?(o=P("size",{valueAsNumber:!0}),e[16]=P,e[17]=o):o=e[17];let n;e[18]!==Q||e[19]!==o?(n=t.jsx(se,{"aria-invalid":Q,id:"size",max:16384,min:1,type:"number",...o}),e[18]=Q,e[19]=o,e[20]=n):n=e[20];let m;e[21]!==l.size?(m=t.jsx(M,{errors:[l.size]}),e[21]=l.size,e[22]=m):m=e[22];let c;e[23]!==n||e[24]!==m?(c=t.jsxs($,{children:[N,n,m]}),e[23]=n,e[24]=m,e[25]=c):c=e[25];let _;e[26]===Symbol.for("react.memo_cache_sentinel")?(_=t.jsx(O,{children:t.jsx("label",{htmlFor:"availabilityZone",children:"Availability Zone"})}),e[26]=_):_=e[26];let u;e[27]!==Z||e[28]!==l.availabilityZone?(u=G=>{const{field:H}=G;return t.jsxs(re,{onValueChange:J=>H.onChange(J),value:H.value??"",children:[t.jsx(oe,{"aria-invalid":!!l.availabilityZone,className:"w-full",id:"availabilityZone",children:t.jsx(ne,{})}),t.jsx(me,{children:Z.map(de)})]})},e[27]=Z,e[28]=l.availabilityZone,e[29]=u):u=e[29];let f;e[30]!==k||e[31]!==u?(f=t.jsx(ee,{control:k,name:"availabilityZone",render:u}),e[30]=k,e[31]=u,e[32]=f):f=e[32];let d;e[33]!==l.availabilityZone?(d=t.jsx(M,{errors:[l.availabilityZone]}),e[33]=l.availabilityZone,e[34]=d):d=e[34];let b;e[35]!==f||e[36]!==d?(b=t.jsxs($,{children:[_,f,d]}),e[35]=f,e[36]=d,e[37]=b):b=e[37];const R=w||i.isPending;let v;e[38]!==a?(v=()=>a({to:"/ec2/describe-volumes"}),e[38]=a,e[39]=v):v=e[39];let x;e[40]!==R||e[41]!==v?(x=t.jsx(L,{disabled:R,onClick:v,type:"button",variant:"outline",children:"Cancel"}),e[40]=R,e[41]=v,e[42]=x):x=e[42];const T=w||i.isPending,D=w||i.isPending?"Creating…":"Create Volume";let y;e[43]!==T||e[44]!==D?(y=t.jsx(L,{disabled:T,type:"submit",children:D}),e[43]=T,e[44]=D,e[45]=y):y=e[45];let p;e[46]!==x||e[47]!==y?(p=t.jsxs("div",{className:"flex gap-2",children:[x,y]}),e[46]=x,e[47]=y,e[48]=p):p=e[48];let h;e[49]!==c||e[50]!==b||e[51]!==p||e[52]!==r?(h=t.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:r,children:[c,b,p]}),e[49]=c,e[50]=b,e[51]=p,e[52]=r,e[53]=h):h=e[53];let A;return e[54]!==h||e[55]!==s?(A=t.jsxs(t.Fragment,{children:[z,F,s,h]}),e[54]=h,e[55]=s,e[56]=A):A=e[56],A}function de(e){return t.jsx(ce,{value:e.ZoneName??"",children:e.ZoneName},e.ZoneName)}export{Fe as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{k as o}from"./index.js";const a=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],e=o("download",a);export{e as D};
|
||||
import{J as o}from"./index.js";const a=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],e=o("download",a);export{e as D};
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{o as i,f as e,ao as a,ap as s,aq as t}from"./index.js";const r=i({imageId:e("Please select an Image"),instanceType:e("Please select an instance type"),keyName:e("Please select a key pair"),subnetId:e().optional(),count:s("Instance count must be a whole number").min(1,"Instance count must be at least 1")}),c=i({keyName:e().min(1,"Key name is required").max(255,"Key name must be 255 characters or less").regex(/^[\w\s._\-:/()#,@[\]+=&;{}!$*]+$/,"Key name contains invalid characters")}),m=i({keyName:e().min(1,"Key name is required").max(255,"Key name must be 255 characters or less").regex(/^[\w\s._\-:/()#,@[\]+=&;{}!$*]+$/,"Key name contains invalid characters"),publicKeyMaterial:e().min(1,"Public key is required").refine(n=>n.trim().length>0,"Public key cannot be empty")}),l=i({size:a().int("Size must be a whole number").min(1,"Size must be at least 1 GiB").max(16384,"Size must be at most 16384 GiB"),availabilityZone:e().min(1,"Availability zone is required")}),u=i({size:a().int("Size must be a whole number").min(1,"Size must be at least 1 GiB")}),d=i({volumeId:e().min(1,"Volume is required"),description:e().optional()});i({sourceSnapshotId:e().min(1,"Source snapshot is required"),sourceRegion:e().min(1,"Source region is required"),description:e().optional()});i({volumeId:e().min(1,"Volume is required"),instanceId:e().min(1,"Instance is required"),device:e().optional()});i({volumeId:e().min(1,"Volume is required"),instanceId:e().optional(),force:t().optional()});i({instanceType:e().min(1,"Instance type is required")});i({name:e().min(1,"Name is required"),description:e().optional()});const b=i({vpcId:e().min(1,"VPC is required"),cidrBlock:e().min(1,"CIDR block is required").regex(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/,"Must be a valid CIDR block (e.g. 10.0.1.0/24)"),availabilityZone:e().optional()}),p=i({cidrBlock:e().min(1,"CIDR block is required").regex(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/,"Must be a valid CIDR block (e.g. 10.0.0.0/16)"),name:e().optional()});export{l as a,b,p as c,d,c as e,r as f,m as i,u as m};
|
||||
import{o as i,i as e,aN as a,aO as s,aP as t}from"./index.js";const r=i({imageId:e("Please select an Image"),instanceType:e("Please select an instance type"),keyName:e("Please select a key pair"),subnetId:e().optional(),count:s("Instance count must be a whole number").min(1,"Instance count must be at least 1")}),c=i({keyName:e().min(1,"Key name is required").max(255,"Key name must be 255 characters or less").regex(/^[\w\s._\-:/()#,@[\]+=&;{}!$*]+$/,"Key name contains invalid characters")}),m=i({keyName:e().min(1,"Key name is required").max(255,"Key name must be 255 characters or less").regex(/^[\w\s._\-:/()#,@[\]+=&;{}!$*]+$/,"Key name contains invalid characters"),publicKeyMaterial:e().min(1,"Public key is required").refine(n=>n.trim().length>0,"Public key cannot be empty")}),l=i({size:a().int("Size must be a whole number").min(1,"Size must be at least 1 GiB").max(16384,"Size must be at most 16384 GiB"),availabilityZone:e().min(1,"Availability zone is required")}),u=i({size:a().int("Size must be a whole number").min(1,"Size must be at least 1 GiB")}),d=i({volumeId:e().min(1,"Volume is required"),description:e().optional()});i({sourceSnapshotId:e().min(1,"Source snapshot is required"),sourceRegion:e().min(1,"Source region is required"),description:e().optional()});i({volumeId:e().min(1,"Volume is required"),instanceId:e().min(1,"Instance is required"),device:e().optional()});i({volumeId:e().min(1,"Volume is required"),instanceId:e().optional(),force:t().optional()});i({instanceType:e().min(1,"Instance type is required")});i({name:e().min(1,"Name is required"),description:e().optional()});const b=i({vpcId:e().min(1,"VPC is required"),cidrBlock:e().min(1,"CIDR block is required").regex(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/,"Must be a valid CIDR block (e.g. 10.0.1.0/24)"),availabilityZone:e().optional()}),p=i({cidrBlock:e().min(1,"CIDR block is required").regex(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/,"Must be a valid CIDR block (e.g. 10.0.0.0/16)"),name:e().optional()});export{l as a,b,p as c,d,c as e,r as f,m as i,u as m};
|
||||
|
||||
@@ -1 +1 @@
|
||||
import{cs as d,ct as m,cu as c,cv as p,cw as l,aj as b,r as h,cx as v,cy as f,c as y,j as u}from"./index.js";var x=class extends d{#e;#i=void 0;#t;#s;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#r()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){const t=this.options;this.options=this.#e.defaultMutationOptions(e),m(this.options,t)||this.#e.getMutationCache().notify({type:"observerOptionsUpdated",mutation:this.#t,observer:this}),t?.mutationKey&&this.options.mutationKey&&c(t.mutationKey)!==c(this.options.mutationKey)?this.reset():this.#t?.state.status==="pending"&&this.#t.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#t?.removeObserver(this)}onMutationUpdate(e){this.#r(),this.#o(e)}getCurrentResult(){return this.#i}reset(){this.#t?.removeObserver(this),this.#t=void 0,this.#r(),this.#o()}mutate(e,t){return this.#s=t,this.#t?.removeObserver(this),this.#t=this.#e.getMutationCache().build(this.#e,this.options),this.#t.addObserver(this),this.#t.execute(e)}#r(){const e=this.#t?.state??p();this.#i={...e,isPending:e.status==="pending",isSuccess:e.status==="success",isError:e.status==="error",isIdle:e.status==="idle",mutate:this.mutate,reset:this.reset}}#o(e){l.batch(()=>{if(this.#s&&this.hasListeners()){const t=this.#i.variables,r=this.#i.context,s={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type==="success"){try{this.#s.onSuccess?.(e.data,t,r,s)}catch(i){Promise.reject(i)}try{this.#s.onSettled?.(e.data,null,t,r,s)}catch(i){Promise.reject(i)}}else if(e?.type==="error"){try{this.#s.onError?.(e.error,t,r,s)}catch(i){Promise.reject(i)}try{this.#s.onSettled?.(void 0,e.error,t,r,s)}catch(i){Promise.reject(i)}}}this.listeners.forEach(t=>{t(this.#i)})})}};function E(e,t){const r=b(),[s]=h.useState(()=>new x(r,e));h.useEffect(()=>{s.setOptions(e)},[s,e]);const i=h.useSyncExternalStore(h.useCallback(o=>s.subscribe(l.batchCalls(o)),[s]),()=>s.getCurrentResult(),()=>s.getCurrentResult()),n=h.useCallback((o,a)=>{s.mutate(o,a).catch(v)},[s]);if(i.error&&f(s.options.throwOnError,[i.error]))throw i.error;return{...i,mutate:n,mutateAsync:i.mutate}}function g(e){const t=y.c(7),{msg:r,error:s}=e;let i;s&&(i=s.name!=="Error"?s.name:s.message);let n;t[0]!==r?(n=r&&u.jsx("h2",{className:"text-destructive text-sm",children:r}),t[0]=r,t[1]=n):n=t[1];let o;t[2]!==i?(o=i&&u.jsx("p",{className:"text-destructive text-sm",children:i}),t[2]=i,t[3]=o):o=t[3];let a;return t[4]!==n||t[5]!==o?(a=u.jsxs("div",{className:"mb-6 max-w-4xl rounded-md border border-destructive bg-destructive/10 p-4",children:[n,o]}),t[4]=n,t[5]=o,t[6]=a):a=t[6],a}export{g as E,E as u};
|
||||
import{ba as d,bd as m,bp as c,bq as b,bn as l,aq as p,r as h,bf as v,bo as f,c as y,j as u}from"./index.js";var x=class extends d{#e;#i=void 0;#t;#s;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#r()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){const t=this.options;this.options=this.#e.defaultMutationOptions(e),m(this.options,t)||this.#e.getMutationCache().notify({type:"observerOptionsUpdated",mutation:this.#t,observer:this}),t?.mutationKey&&this.options.mutationKey&&c(t.mutationKey)!==c(this.options.mutationKey)?this.reset():this.#t?.state.status==="pending"&&this.#t.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#t?.removeObserver(this)}onMutationUpdate(e){this.#r(),this.#o(e)}getCurrentResult(){return this.#i}reset(){this.#t?.removeObserver(this),this.#t=void 0,this.#r(),this.#o()}mutate(e,t){return this.#s=t,this.#t?.removeObserver(this),this.#t=this.#e.getMutationCache().build(this.#e,this.options),this.#t.addObserver(this),this.#t.execute(e)}#r(){const e=this.#t?.state??b();this.#i={...e,isPending:e.status==="pending",isSuccess:e.status==="success",isError:e.status==="error",isIdle:e.status==="idle",mutate:this.mutate,reset:this.reset}}#o(e){l.batch(()=>{if(this.#s&&this.hasListeners()){const t=this.#i.variables,r=this.#i.context,s={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type==="success"){try{this.#s.onSuccess?.(e.data,t,r,s)}catch(i){Promise.reject(i)}try{this.#s.onSettled?.(e.data,null,t,r,s)}catch(i){Promise.reject(i)}}else if(e?.type==="error"){try{this.#s.onError?.(e.error,t,r,s)}catch(i){Promise.reject(i)}try{this.#s.onSettled?.(void 0,e.error,t,r,s)}catch(i){Promise.reject(i)}}}this.listeners.forEach(t=>{t(this.#i)})})}};function E(e,t){const r=p(),[s]=h.useState(()=>new x(r,e));h.useEffect(()=>{s.setOptions(e)},[s,e]);const i=h.useSyncExternalStore(h.useCallback(o=>s.subscribe(l.batchCalls(o)),[s]),()=>s.getCurrentResult(),()=>s.getCurrentResult()),n=h.useCallback((o,a)=>{s.mutate(o,a).catch(v)},[s]);if(i.error&&f(s.options.throwOnError,[i.error]))throw i.error;return{...i,mutate:n,mutateAsync:i.mutate}}function g(e){const t=y.c(7),{msg:r,error:s}=e;let i;s&&(i=s.name!=="Error"?s.name:s.message);let n;t[0]!==r?(n=r&&u.jsx("h2",{className:"text-destructive text-sm",children:r}),t[0]=r,t[1]=n):n=t[1];let o;t[2]!==i?(o=i&&u.jsx("p",{className:"text-destructive text-sm",children:i}),t[2]=i,t[3]=o):o=t[3];let a;return t[4]!==n||t[5]!==o?(a=u.jsxs("div",{className:"mb-6 max-w-4xl rounded-md border border-destructive bg-destructive/10 p-4",children:[n,o]}),t[4]=n,t[5]=o,t[6]=a):a=t[6],a}export{g as E,E as u};
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{N as a,ay as i,Q as o,az as d,aA as y,aB as C,aC as p,aD as A,aE as f,aF as P,aG as I,aH as U,c as r,aq as u,aI as l}from"./index.js";import{u as m}from"./error-banner.js";class K extends a.classBuilder().ep(i).m(function(t,n,s,c){return[o(s,t.getEndpointParameterInstructions())]}).s("AWSIdentityManagementV20100508","AttachUserPolicy",{}).n("IAMClient","AttachUserPolicyCommand").sc(d).build(){}class D extends a.classBuilder().ep(i).m(function(t,n,s,c){return[o(s,t.getEndpointParameterInstructions())]}).s("AWSIdentityManagementV20100508","CreateAccessKey",{}).n("IAMClient","CreateAccessKeyCommand").sc(y).build(){}class g extends a.classBuilder().ep(i).m(function(t,n,s,c){return[o(s,t.getEndpointParameterInstructions())]}).s("AWSIdentityManagementV20100508","CreatePolicy",{}).n("IAMClient","CreatePolicyCommand").sc(C).build(){}class q extends a.classBuilder().ep(i).m(function(t,n,s,c){return[o(s,t.getEndpointParameterInstructions())]}).s("AWSIdentityManagementV20100508","CreateUser",{}).n("IAMClient","CreateUserCommand").sc(p).build(){}class M extends a.classBuilder().ep(i).m(function(t,n,s,c){return[o(s,t.getEndpointParameterInstructions())]}).s("AWSIdentityManagementV20100508","DeleteAccessKey",{}).n("IAMClient","DeleteAccessKeyCommand").sc(A).build(){}class S extends a.classBuilder().ep(i).m(function(t,n,s,c){return[o(s,t.getEndpointParameterInstructions())]}).s("AWSIdentityManagementV20100508","DeletePolicy",{}).n("IAMClient","DeletePolicyCommand").sc(f).build(){}class $ extends a.classBuilder().ep(i).m(function(t,n,s,c){return[o(s,t.getEndpointParameterInstructions())]}).s("AWSIdentityManagementV20100508","DeleteUser",{}).n("IAMClient","DeleteUserCommand").sc(P).build(){}class h extends a.classBuilder().ep(i).m(function(t,n,s,c){return[o(s,t.getEndpointParameterInstructions())]}).s("AWSIdentityManagementV20100508","DetachUserPolicy",{}).n("IAMClient","DetachUserPolicyCommand").sc(I).build(){}class N extends a.classBuilder().ep(i).m(function(t,n,s,c){return[o(s,t.getEndpointParameterInstructions())]}).s("AWSIdentityManagementV20100508","UpdateAccessKey",{}).n("IAMClient","UpdateAccessKeyCommand").sc(U).build(){}function k(){const e=r.c(2),t=u();let n;return e[0]!==t?(n={mutationFn:E,onSuccess:()=>{t.invalidateQueries({queryKey:["iam","users"]})}},e[0]=t,e[1]=n):n=e[1],m(n)}function E(e){const t=new q({UserName:e.userName,Path:e.path||void 0});return l().send(t)}function z(){const e=r.c(2),t=u();let n;return e[0]!==t?(n={mutationFn:v,onSuccess:()=>{t.invalidateQueries({queryKey:["iam","users"]})}},e[0]=t,e[1]=n):n=e[1],m(n)}function v(e){const t=new $({UserName:e});return l().send(t)}function G(){const e=r.c(2),t=u();let n;return e[0]!==t?(n={mutationFn:x,onSuccess:()=>{t.invalidateQueries({queryKey:["iam","access-keys"]})}},e[0]=t,e[1]=n):n=e[1],m(n)}function x(e){const t=new D({UserName:e});return l().send(t)}function H(){const e=r.c(2),t=u();let n;return e[0]!==t?(n={mutationFn:Q,onSuccess:()=>{t.invalidateQueries({queryKey:["iam","access-keys"]})}},e[0]=t,e[1]=n):n=e[1],m(n)}function Q(e){const{userName:t,accessKeyId:n}=e,s=new M({UserName:t,AccessKeyId:n});return l().send(s)}function R(){const e=r.c(2),t=u();let n;return e[0]!==t?(n={mutationFn:b,onSuccess:()=>{t.invalidateQueries({queryKey:["iam","access-keys"]})}},e[0]=t,e[1]=n):n=e[1],m(n)}function b(e){const{userName:t,accessKeyId:n,status:s}=e,c=new N({UserName:t,AccessKeyId:n,Status:s});return l().send(c)}function j(){const e=r.c(2),t=u();let n;return e[0]!==t?(n={mutationFn:B,onSuccess:()=>{t.invalidateQueries({queryKey:["iam","policies"]})}},e[0]=t,e[1]=n):n=e[1],m(n)}function B(e){const t=new g({PolicyName:e.policyName,Description:e.description||void 0,PolicyDocument:e.policyDocument});return l().send(t)}function J(){const e=r.c(2),t=u();let n;return e[0]!==t?(n={mutationFn:F,onSuccess:()=>{t.invalidateQueries({queryKey:["iam","policies"]})}},e[0]=t,e[1]=n):n=e[1],m(n)}function F(e){const t=new S({PolicyArn:e});return l().send(t)}function L(){const e=r.c(2),t=u();let n;return e[0]!==t?(n={mutationFn:w,onSuccess:()=>{t.invalidateQueries({queryKey:["iam","attached-user-policies"]})}},e[0]=t,e[1]=n):n=e[1],m(n)}function w(e){const{userName:t,policyArn:n}=e,s=new K({UserName:t,PolicyArn:n});return l().send(s)}function O(){const e=r.c(2),t=u();let n;return e[0]!==t?(n={mutationFn:V,onSuccess:()=>{t.invalidateQueries({queryKey:["iam","attached-user-policies"]})}},e[0]=t,e[1]=n):n=e[1],m(n)}function V(e){const{userName:t,policyArn:n}=e,s=new h({UserName:t,PolicyArn:n});return l().send(s)}export{j as a,z as b,G as c,H as d,R as e,L as f,O as g,J as h,k as u};
|
||||
@@ -0,0 +1 @@
|
||||
import{o as r,i as e}from"./index.js";const c=r({userName:e().min(1,"User name is required").max(64,"User name must be 64 characters or less").regex(/^[\w+=,.@-]+$/,"User name contains invalid characters"),path:e().optional()}),i=r({policyName:e().min(1,"Policy name is required").max(128,"Policy name must be 128 characters or less"),description:e().optional(),policyDocument:e().min(1,"Policy document is required").refine(a=>{try{return JSON.parse(a),!0}catch{return!1}},{message:"Policy document must be valid JSON"})});export{i as a,c};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+40
-40
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{c as m,m as l,j as t,L as n,B as c}from"./index.js";import{u as p}from"./useSuspenseQuery.js";import{L as d}from"./list-card.js";import{P as y}from"./page-heading.js";function P(){const e=m.c(4),{data:s}=p(l);let r;if(e[0]!==s.KeyPairs){const a=(s.KeyPairs||[]).toSorted(f);let i;e[2]===Symbol.for("react.memo_cache_sentinel")?(i=t.jsx(n,{to:"/ec2/import-key-pair",children:t.jsx(c,{variant:"outline",children:"Import Key Pair"})}),e[2]=i):i=e[2];let o;e[3]===Symbol.for("react.memo_cache_sentinel")?(o=t.jsx(y,{actions:t.jsxs("div",{className:"flex gap-2",children:[i,t.jsx(n,{to:"/ec2/create-key-pair",children:t.jsx(c,{children:"Create Key Pair"})})]}),title:"EC2 Key Pairs"}),e[3]=o):o=e[3],r=t.jsxs(t.Fragment,{children:[o,a.length>0?t.jsx("div",{className:"space-y-4",children:a.map(u)}):t.jsx("p",{className:"text-muted-foreground",children:"No key pairs found."})]}),e[0]=s.KeyPairs,e[1]=r}else r=e[1];return r}function u(e){return e.KeyPairId?t.jsx(d,{params:{id:e.KeyPairId},subtitle:`${e.KeyPairId} • ${e.KeyType}`,title:e.KeyName??"",to:"/ec2/describe-key-pairs/$id"},e.KeyPairId):null}function f(e,s){const r=e.KeyName?.toLowerCase()??"",a=s.KeyName?.toLowerCase()??"";return r.localeCompare(a)}export{P as component};
|
||||
import{c as o,t as c,j as t,L as u,B as m}from"./index.js";import{u as l}from"./useSuspenseQuery.js";import{L as d}from"./list-card.js";import{P as p}from"./page-heading.js";import{S}from"./state-badge.js";function $(){const e=o.c(5),{data:s}=l(c);let n;e[0]!==s.Subnets?(n=s.Subnets||[],e[0]=s.Subnets,e[1]=n):n=e[1];const a=n;let r;e[2]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(p,{actions:t.jsx(u,{to:"/ec2/create-subnet",children:t.jsx(m,{children:"Create Subnet"})}),title:"Subnets"}),e[2]=r):r=e[2];let i;return e[3]!==a?(i=t.jsxs(t.Fragment,{children:[r,a.length>0?t.jsx("div",{className:"space-y-4",children:a.map(f)}):t.jsx("p",{className:"text-muted-foreground",children:"No subnets found."})]}),e[3]=a,e[4]=i):i=e[4],i}function f(e){if(!e.SubnetId)return null;const s=e.Tags?.find(b)?.Value;return t.jsx(d,{badge:t.jsx(S,{state:e.State}),params:{id:e.SubnetId},subtitle:`${e.CidrBlock??""} • ${e.AvailabilityZone??""}`,title:s?`${e.SubnetId} (${s})`:e.SubnetId,to:"/ec2/describe-subnets/$id"},e.SubnetId)}function b(e){return e.Key==="Name"}export{$ as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c as u,x as f,j as t,L as I,B as x}from"./index.js";import{u as g}from"./useSuspenseQuery.js";import{L as h}from"./list-card.js";import{P as j}from"./page-heading.js";import{S}from"./state-badge.js";function L(){const e=u.c(5),{data:o}=g(f);let s;e[0]===Symbol.for("react.memo_cache_sentinel")?(s={running:0,pending:1,stopping:2,"shutting-down":3,stopped:4,terminated:5},e[0]=s):s=e[0];const c=s;let n;if(e[1]!==o.Reservations){let a;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=(m,l)=>{const d=c[m.State?.Name??""]??6,p=c[l.State?.Name??""]??6;return d!==p?d-p:(m.InstanceId??"").localeCompare(l.InstanceId??"")},e[3]=a):a=e[3];const i=(o.Reservations?.flatMap(_)||[]).toSorted(a);let r;e[4]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(j,{actions:t.jsx(I,{to:"/ec2/run-instances",children:t.jsx(x,{children:"Run Instances"})}),title:"EC2 Instances"}),e[4]=r):r=e[4],n=t.jsxs(t.Fragment,{children:[r,i.length>0?t.jsx("div",{className:"space-y-4",children:i.map(y)}):t.jsx("p",{className:"text-muted-foreground",children:"No instances found."})]}),e[1]=o.Reservations,e[2]=n}else n=e[2];return n}function y(e){return e.InstanceId?t.jsx(h,{badge:t.jsx(S,{state:e.State?.Name}),params:{id:e.InstanceId},subtitle:`${e.InstanceType} • ${e.ImageId}`,title:e.InstanceId,to:"/ec2/describe-instances/$id"},e.InstanceId):null}function _(e){return e.Instances||[]}export{L as component};
|
||||
import{c as i,C as c,j as e,L as m,B as p}from"./index.js";import{u as l}from"./useSuspenseQuery.js";import{L as d}from"./list-card.js";import{P as u}from"./page-heading.js";import{S}from"./state-badge.js";function b(){const t=i.c(5),{data:r}=l(c);let s;t[0]!==r.Snapshots?(s=r.Snapshots||[],t[0]=r.Snapshots,t[1]=s):s=t[1];const o=s;let a;t[2]===Symbol.for("react.memo_cache_sentinel")?(a=e.jsx(u,{actions:e.jsx(m,{to:"/ec2/create-snapshot",children:e.jsx(p,{children:"Create Snapshot"})}),title:"EC2 Snapshots"}),t[2]=a):a=t[2];let n;return t[3]!==o?(n=e.jsxs(e.Fragment,{children:[a,o.length>0?e.jsx("div",{className:"space-y-4",children:o.map(h)}):e.jsx("p",{className:"text-muted-foreground",children:"No snapshots found."})]}),t[3]=o,t[4]=n):n=t[4],n}function h(t){return t.SnapshotId?e.jsx(d,{badge:e.jsx(S,{state:t.State}),params:{id:t.SnapshotId},subtitle:`${t.VolumeSize} GiB • ${t.VolumeId}`,title:t.SnapshotId,to:"/ec2/describe-snapshots/$id"},t.SnapshotId):null}export{b as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c as n,l as i,j as t}from"./index.js";import{u as c}from"./useSuspenseQuery.js";import{L as l}from"./list-card.js";import{P as d}from"./page-heading.js";import{S as p}from"./state-badge.js";function h(){const e=n.c(5),{data:o}=c(i);let s;e[0]!==o.Images?(s=o.Images||[],e[0]=o.Images,e[1]=s):s=e[1];const a=s;let m;e[2]===Symbol.for("react.memo_cache_sentinel")?(m=t.jsx(d,{title:"EC2 Images"}),e[2]=m):m=e[2];let r;return e[3]!==a?(r=t.jsxs(t.Fragment,{children:[m,a.length>0?t.jsx("div",{className:"space-y-4",children:a.map(u)}):t.jsx("p",{className:"text-muted-foreground",children:"No images found."})]}),e[3]=a,e[4]=r):r=e[4],r}function u(e){return e.ImageId?t.jsx(l,{badge:t.jsx(p,{state:e.State}),params:{id:e.ImageId},subtitle:e.Name,title:e.ImageId,to:"/ec2/describe-images/$id"},e.ImageId):null}export{h as component};
|
||||
import{c as m,p as l,j as t,L as n,B as c}from"./index.js";import{u as p}from"./useSuspenseQuery.js";import{L as d}from"./list-card.js";import{P as y}from"./page-heading.js";function P(){const e=m.c(4),{data:s}=p(l);let r;if(e[0]!==s.KeyPairs){const a=(s.KeyPairs||[]).toSorted(f);let i;e[2]===Symbol.for("react.memo_cache_sentinel")?(i=t.jsx(n,{to:"/ec2/import-key-pair",children:t.jsx(c,{variant:"outline",children:"Import Key Pair"})}),e[2]=i):i=e[2];let o;e[3]===Symbol.for("react.memo_cache_sentinel")?(o=t.jsx(y,{actions:t.jsxs("div",{className:"flex gap-2",children:[i,t.jsx(n,{to:"/ec2/create-key-pair",children:t.jsx(c,{children:"Create Key Pair"})})]}),title:"EC2 Key Pairs"}),e[3]=o):o=e[3],r=t.jsxs(t.Fragment,{children:[o,a.length>0?t.jsx("div",{className:"space-y-4",children:a.map(u)}):t.jsx("p",{className:"text-muted-foreground",children:"No key pairs found."})]}),e[0]=s.KeyPairs,e[1]=r}else r=e[1];return r}function u(e){return e.KeyPairId?t.jsx(d,{params:{id:e.KeyPairId},subtitle:`${e.KeyPairId} • ${e.KeyType}`,title:e.KeyName??"",to:"/ec2/describe-key-pairs/$id"},e.KeyPairId):null}function f(e,s){const r=e.KeyName?.toLowerCase()??"",a=s.KeyName?.toLowerCase()??"";return r.localeCompare(a)}export{P as component};
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
import{c as u,E as f,j as t,L as I,B as x}from"./index.js";import{u as g}from"./useSuspenseQuery.js";import{L as h}from"./list-card.js";import{P as j}from"./page-heading.js";import{S}from"./state-badge.js";function L(){const e=u.c(5),{data:o}=g(f);let s;e[0]===Symbol.for("react.memo_cache_sentinel")?(s={running:0,pending:1,stopping:2,"shutting-down":3,stopped:4,terminated:5},e[0]=s):s=e[0];const c=s;let n;if(e[1]!==o.Reservations){let a;e[3]===Symbol.for("react.memo_cache_sentinel")?(a=(m,l)=>{const d=c[m.State?.Name??""]??6,p=c[l.State?.Name??""]??6;return d!==p?d-p:(m.InstanceId??"").localeCompare(l.InstanceId??"")},e[3]=a):a=e[3];const i=(o.Reservations?.flatMap(_)||[]).toSorted(a);let r;e[4]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(j,{actions:t.jsx(I,{to:"/ec2/run-instances",children:t.jsx(x,{children:"Run Instances"})}),title:"EC2 Instances"}),e[4]=r):r=e[4],n=t.jsxs(t.Fragment,{children:[r,i.length>0?t.jsx("div",{className:"space-y-4",children:i.map(y)}):t.jsx("p",{className:"text-muted-foreground",children:"No instances found."})]}),e[1]=o.Reservations,e[2]=n}else n=e[2];return n}function y(e){return e.InstanceId?t.jsx(h,{badge:t.jsx(S,{state:e.State?.Name}),params:{id:e.InstanceId},subtitle:`${e.InstanceType} • ${e.ImageId}`,title:e.InstanceId,to:"/ec2/describe-instances/$id"},e.InstanceId):null}function _(e){return e.Instances||[]}export{L as component};
|
||||
@@ -0,0 +1 @@
|
||||
import{c as n,n as i,j as t}from"./index.js";import{u as c}from"./useSuspenseQuery.js";import{L as l}from"./list-card.js";import{P as d}from"./page-heading.js";import{S as p}from"./state-badge.js";function h(){const e=n.c(5),{data:o}=c(i);let s;e[0]!==o.Images?(s=o.Images||[],e[0]=o.Images,e[1]=s):s=e[1];const a=s;let m;e[2]===Symbol.for("react.memo_cache_sentinel")?(m=t.jsx(d,{title:"EC2 Images"}),e[2]=m):m=e[2];let r;return e[3]!==a?(r=t.jsxs(t.Fragment,{children:[m,a.length>0?t.jsx("div",{className:"space-y-4",children:a.map(u)}):t.jsx("p",{className:"text-muted-foreground",children:"No images found."})]}),e[3]=a,e[4]=r):r=e[4],r}function u(e){return e.ImageId?t.jsx(l,{badge:t.jsx(p,{state:e.State}),params:{id:e.ImageId},subtitle:e.Name,title:e.ImageId,to:"/ec2/describe-images/$id"},e.ImageId):null}export{h as component};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{cK as z,cL as x}from"./index.js";class T{marshaller;serializer;deserializer;serdeContext;defaultContentType;constructor({marshaller:i,serializer:n,deserializer:o,serdeContext:c,defaultContentType:y}){this.marshaller=i,this.serializer=n,this.deserializer=o,this.serdeContext=c,this.defaultContentType=y}async serializeEventStream({eventStream:i,requestSchema:n,initialRequest:o}){const c=this.marshaller,y=n.getEventStreamMember(),p=n.getMemberSchema(y),d=this.serializer,f=this.defaultContentType,h=Symbol("initialRequestMarker"),S={async*[Symbol.asyncIterator](){if(o){const r={":event-type":{type:"string",value:"initial-request"},":message-type":{type:"string",value:"event"},":content-type":{type:"string",value:f}};d.write(n,o);const t=d.flush();yield{[h]:!0,headers:r,body:t}}for await(const r of i)yield r}};return c.serialize(S,r=>{if(r[h])return{headers:r.headers,body:r.body};const t=Object.keys(r).find(s=>s!=="__type")??"",{additionalHeaders:e,body:a,eventType:l,explicitPayloadContentType:m}=this.writeEventBody(t,p,r);return{headers:{":event-type":{type:"string",value:l},":message-type":{type:"string",value:"event"},":content-type":{type:"string",value:m??f},...e},body:a}})}async deserializeEventStream({response:i,responseSchema:n,initialResponseContainer:o}){const c=this.marshaller,y=n.getEventStreamMember(),d=n.getMemberSchema(y).getMemberSchemas(),f=Symbol("initialResponseMarker"),h=c.deserialize(i.body,async t=>{const e=Object.keys(t).find(l=>l!=="__type")??"",a=t[e].body;if(e==="initial-response"){const l=await this.deserializer.read(n,a);return delete l[y],{[f]:!0,...l}}else if(e in d){const l=d[e];if(l.isStructSchema()){const m={};let u=!1;for(const[s,g]of l.structIterator()){const{eventHeader:v,eventPayload:w}=g.getMergedTraits();if(u=u||!!(v||w),w)g.isBlobSchema()?m[s]=a:g.isStringSchema()?m[s]=(this.serdeContext?.utf8Encoder??z)(a):g.isStructSchema()&&(m[s]=await this.deserializer.read(g,a));else if(v){const b=t[e].headers[s]?.value;b!=null&&(g.isNumericSchema()?b&&typeof b=="object"&&"bytes"in b?m[s]=BigInt(b.toString()):m[s]=Number(b):m[s]=b)}}if(u)return{[e]:m};if(a.byteLength===0)return{[e]:{}}}return{[e]:await this.deserializer.read(l,a)}}else return{$unknown:t}}),S=h[Symbol.asyncIterator](),r=await S.next();if(r.done)return h;if(r.value?.[f]){if(!n)throw new Error("@smithy::core/protocols - initial-response event encountered in event stream but no response schema given.");for(const[t,e]of Object.entries(r.value))o[t]=e}return{async*[Symbol.asyncIterator](){for(r?.value?.[f]||(yield r.value);;){const{done:t,value:e}=await S.next();if(t)break;yield e}}}}writeEventBody(i,n,o){const c=this.serializer;let y=i,p=null,d;const f=n.getSchema()[4].includes(i),h={};if(f){const t=n.getMemberSchema(i);if(t.isStructSchema()){for(const[e,a]of t.structIterator()){const{eventHeader:l,eventPayload:m}=a.getMergedTraits();if(m)p=e;else if(l){const u=o[i][e];let s="binary";a.isNumericSchema()?(-2)**31<=u&&u<=2**31-1?s="integer":s="long":a.isTimestampSchema()?s="timestamp":a.isStringSchema()?s="string":a.isBooleanSchema()&&(s="boolean"),u!=null&&(h[e]={type:s,value:u},delete o[i][e])}}if(p!==null){const e=t.getMemberSchema(p);e.isBlobSchema()?d="application/octet-stream":e.isStringSchema()&&(d="text/plain"),c.write(e,o[i][p])}else c.write(t,o[i])}else if(t.isUnitSchema())c.write(t,{});else throw new Error("@smithy/core/event-streams - non-struct member not supported in event stream union.")}else{const[t,e]=o[i];y=t,c.write(15,e)}const S=c.flush();return{body:typeof S=="string"?(this.serdeContext?.utf8Decoder??x)(S):S,eventType:y,explicitPayloadContentType:d,additionalHeaders:h}}}export{T as EventStreamSerde};
|
||||
import{d5 as z,d6 as x}from"./index.js";class T{marshaller;serializer;deserializer;serdeContext;defaultContentType;constructor({marshaller:i,serializer:n,deserializer:o,serdeContext:c,defaultContentType:d}){this.marshaller=i,this.serializer=n,this.deserializer=o,this.serdeContext=c,this.defaultContentType=d}async serializeEventStream({eventStream:i,requestSchema:n,initialRequest:o}){const c=this.marshaller,d=n.getEventStreamMember(),p=n.getMemberSchema(d),y=this.serializer,f=this.defaultContentType,h=Symbol("initialRequestMarker"),S={async*[Symbol.asyncIterator](){if(o){const r={":event-type":{type:"string",value:"initial-request"},":message-type":{type:"string",value:"event"},":content-type":{type:"string",value:f}};y.write(n,o);const t=y.flush();yield{[h]:!0,headers:r,body:t}}for await(const r of i)yield r}};return c.serialize(S,r=>{if(r[h])return{headers:r.headers,body:r.body};const t=Object.keys(r).find(s=>s!=="__type")??"",{additionalHeaders:e,body:a,eventType:l,explicitPayloadContentType:m}=this.writeEventBody(t,p,r);return{headers:{":event-type":{type:"string",value:l},":message-type":{type:"string",value:"event"},":content-type":{type:"string",value:m??f},...e},body:a}})}async deserializeEventStream({response:i,responseSchema:n,initialResponseContainer:o}){const c=this.marshaller,d=n.getEventStreamMember(),y=n.getMemberSchema(d).getMemberSchemas(),f=Symbol("initialResponseMarker"),h=c.deserialize(i.body,async t=>{const e=Object.keys(t).find(l=>l!=="__type")??"",a=t[e].body;if(e==="initial-response"){const l=await this.deserializer.read(n,a);return delete l[d],{[f]:!0,...l}}else if(e in y){const l=y[e];if(l.isStructSchema()){const m={};let u=!1;for(const[s,g]of l.structIterator()){const{eventHeader:v,eventPayload:w}=g.getMergedTraits();if(u=u||!!(v||w),w)g.isBlobSchema()?m[s]=a:g.isStringSchema()?m[s]=(this.serdeContext?.utf8Encoder??z)(a):g.isStructSchema()&&(m[s]=await this.deserializer.read(g,a));else if(v){const b=t[e].headers[s]?.value;b!=null&&(g.isNumericSchema()?b&&typeof b=="object"&&"bytes"in b?m[s]=BigInt(b.toString()):m[s]=Number(b):m[s]=b)}}if(u)return{[e]:m};if(a.byteLength===0)return{[e]:{}}}return{[e]:await this.deserializer.read(l,a)}}else return{$unknown:t}}),S=h[Symbol.asyncIterator](),r=await S.next();if(r.done)return h;if(r.value?.[f]){if(!n)throw new Error("@smithy::core/protocols - initial-response event encountered in event stream but no response schema given.");for(const[t,e]of Object.entries(r.value))o[t]=e}return{async*[Symbol.asyncIterator](){for(r?.value?.[f]||(yield r.value);;){const{done:t,value:e}=await S.next();if(t)break;yield e}}}}writeEventBody(i,n,o){const c=this.serializer;let d=i,p=null,y;const f=n.getSchema()[4].includes(i),h={};if(f){const t=n.getMemberSchema(i);if(t.isStructSchema()){for(const[e,a]of t.structIterator()){const{eventHeader:l,eventPayload:m}=a.getMergedTraits();if(m)p=e;else if(l){const u=o[i][e];let s="binary";a.isNumericSchema()?(-2)**31<=u&&u<=2**31-1?s="integer":s="long":a.isTimestampSchema()?s="timestamp":a.isStringSchema()?s="string":a.isBooleanSchema()&&(s="boolean"),u!=null&&(h[e]={type:s,value:u},delete o[i][e])}}if(p!==null){const e=t.getMemberSchema(p);e.isBlobSchema()?y="application/octet-stream":e.isStringSchema()&&(y="text/plain"),c.write(e,o[i][p])}else c.write(t,o[i])}else if(t.isUnitSchema())c.write(t,{});else throw new Error("@smithy/core/event-streams - non-struct member not supported in event stream union.")}else{const[t,e]=o[i];d=t,c.write(15,e)}const S=c.flush();return{body:typeof S=="string"?(this.serdeContext?.utf8Decoder??x)(S):S,eventType:d,explicitPayloadContentType:y,additionalHeaders:h}}}export{T as EventStreamSerde};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c as n,e as r,j as i}from"./index.js";import{u as a}from"./useSuspenseQuery.js";import{P as p}from"./page-heading.js";function g(){const e=n.c(2),{data:t}=a(r),s=`${t?.Regions?.[0]?.RegionName} Dashboard`;let o;return e[0]!==s?(o=i.jsx(p,{title:s}),e[0]=s,e[1]=o):o=e[1],o}export{g as component};
|
||||
import{c as n,f as r,j as i}from"./index.js";import{u as a}from"./useSuspenseQuery.js";import{P as p}from"./page-heading.js";function f(){const e=n.c(2),{data:t}=a(r),s=`${t?.Regions?.[0]?.RegionName} Dashboard`;let o;return e[0]!==s?(o=i.jsx(p,{title:s}),e[0]=s,e[1]=o):o=e[1],o}export{f as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c as i,d as c,j as t,L as m,B as u}from"./index.js";import{u as l}from"./useSuspenseQuery.js";import{L as p}from"./list-card.js";import{P as d}from"./page-heading.js";function h(){const e=i.c(5),{data:n}=l(c);let s;e[0]!==n.Buckets?(s=n.Buckets||[],e[0]=n.Buckets,e[1]=s):s=e[1];const a=s;let r;e[2]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(d,{actions:t.jsx(m,{to:"/s3/create-bucket",children:t.jsx(u,{children:"Create Bucket"})}),title:"S3 Buckets"}),e[2]=r):r=e[2];let o;return e[3]!==a?(o=t.jsxs(t.Fragment,{children:[r,a.length>0?t.jsx("div",{className:"space-y-4",children:a.map(f)}):t.jsx("p",{className:"text-muted-foreground",children:"No buckets found."})]}),e[3]=a,e[4]=o):o=e[4],o}function f(e){return e.Name?t.jsx(p,{params:{bucket:e.Name},subtitle:e.CreationDate?`Created: ${e.CreationDate.toLocaleString()}`:void 0,title:e.Name,to:"/s3/ls/$bucket"},e.Name):null}export{h as component};
|
||||
import{c as i,h as c,j as t,L as m,B as u}from"./index.js";import{u as l}from"./useSuspenseQuery.js";import{L as p}from"./list-card.js";import{P as d}from"./page-heading.js";function k(){const e=i.c(5),{data:n}=l(c);let s;e[0]!==n.Buckets?(s=n.Buckets||[],e[0]=n.Buckets,e[1]=s):s=e[1];const a=s;let r;e[2]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(d,{actions:t.jsx(m,{to:"/s3/create-bucket",children:t.jsx(u,{children:"Create Bucket"})}),title:"S3 Buckets"}),e[2]=r):r=e[2];let o;return e[3]!==a?(o=t.jsxs(t.Fragment,{children:[r,a.length>0?t.jsx("div",{className:"space-y-4",children:a.map(f)}):t.jsx("p",{className:"text-muted-foreground",children:"No buckets found."})]}),e[3]=a,e[4]=o):o=e[4],o}function f(e){return e.Name?t.jsx(p,{params:{bucket:e.Name},subtitle:e.CreationDate?`Created: ${e.CreationDate.toLocaleString()}`:void 0,title:e.Name,to:"/s3/ls/$bucket"},e.Name):null}export{k as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c as b,q as y,j as s,t as k,v as N}from"./index.js";import{u as B}from"./useSuspenseQuery.js";import{B as O}from"./back-link.js";import{E as C}from"./error-banner.js";import{P as v}from"./page-heading.js";import{a as F}from"./s3.js";import{U as K,F as E,O as U}from"./upload-button.js";import"./alert-dialog.js";import"./download.js";import"./trash-2.js";function T(){const e=b.c(31),{bucket:t}=y.useParams();let x;e[0]!==t?(x=N(t),e[0]=t,e[1]=x):x=e[1];const{data:i}=B(x),r=F();let p;e[2]!==i.Contents?(p=i.Contents||[],e[2]=i.Contents,e[3]=p):p=e[3];const o=p;let h;e[4]!==i.CommonPrefixes?(h=i.CommonPrefixes||[],e[4]=i.CommonPrefixes,e[5]=h):h=e[5];const l=h;let g;e[6]===Symbol.for("react.memo_cache_sentinel")?(g=s.jsx(O,{to:"/s3/ls",children:"Back to buckets"}),e[6]=g):g=e[6];let a;e[7]!==t||e[8]!==r.isPending||e[9]!==r.mutateAsync?(a=s.jsx(K,{bucket:t,isPending:r.isPending,onUpload:r.mutateAsync}),e[7]=t,e[8]=r.isPending,e[9]=r.mutateAsync,e[10]=a):a=e[10];let m;e[11]!==t||e[12]!==a?(m=s.jsx(v,{actions:a,title:t}),e[11]=t,e[12]=a,e[13]=m):m=e[13];let c;e[14]!==r.error?(c=r.error&&s.jsx(C,{error:r.error,msg:"Failed to upload object"}),e[14]=r.error,e[15]=c):c=e[15];let u;e[16]!==t||e[17]!==l?(u=l.length>0&&s.jsxs("div",{className:"mb-6",children:[s.jsx("h2",{className:"mb-3 font-semibold text-lg",children:"Folders"}),s.jsx("div",{className:"space-y-2",children:l.map(n=>{if(!n.Prefix)return null;const P=k(n.Prefix);return s.jsx(E,{bucketName:t,folderName:P,fullPrefix:n.Prefix},n.Prefix)})})]}),e[16]=t,e[17]=l,e[18]=u):u=e[18];let f;e[19]!==t||e[20]!==o?(f=o.length>0&&s.jsxs("div",{className:"space-y-2",children:[s.jsx("h2",{className:"mb-3 font-semibold text-lg",children:"Objects"}),o.map(n=>n.Key?s.jsx(U,{bucketName:t,displayName:n.Key,fullKey:n.Key,object:n},n.Key):null)]}),e[19]=t,e[20]=o,e[21]=f):f=e[21];let d;e[22]!==l.length||e[23]!==o.length?(d=o.length===0&&l.length===0&&s.jsx("p",{className:"text-muted-foreground",children:"No objects found in this bucket."}),e[22]=l.length,e[23]=o.length,e[24]=d):d=e[24];let j;return e[25]!==m||e[26]!==c||e[27]!==u||e[28]!==f||e[29]!==d?(j=s.jsxs(s.Fragment,{children:[g,m,c,u,f,d]}),e[25]=m,e[26]=c,e[27]=u,e[28]=f,e[29]=d,e[30]=j):j=e[30],j}export{T as component};
|
||||
import{c as b,v as y,j as s,w as k,x as N}from"./index.js";import{u as B}from"./useSuspenseQuery.js";import{B as O}from"./back-link.js";import{E as C}from"./error-banner.js";import{P as v}from"./page-heading.js";import{a as F}from"./s3.js";import{U as K,F as E,O as U}from"./upload-button.js";import"./alert-dialog.js";import"./download.js";import"./trash-2.js";function T(){const e=b.c(31),{bucket:t}=y.useParams();let x;e[0]!==t?(x=N(t),e[0]=t,e[1]=x):x=e[1];const{data:i}=B(x),r=F();let p;e[2]!==i.Contents?(p=i.Contents||[],e[2]=i.Contents,e[3]=p):p=e[3];const o=p;let h;e[4]!==i.CommonPrefixes?(h=i.CommonPrefixes||[],e[4]=i.CommonPrefixes,e[5]=h):h=e[5];const l=h;let g;e[6]===Symbol.for("react.memo_cache_sentinel")?(g=s.jsx(O,{to:"/s3/ls",children:"Back to buckets"}),e[6]=g):g=e[6];let a;e[7]!==t||e[8]!==r.isPending||e[9]!==r.mutateAsync?(a=s.jsx(K,{bucket:t,isPending:r.isPending,onUpload:r.mutateAsync}),e[7]=t,e[8]=r.isPending,e[9]=r.mutateAsync,e[10]=a):a=e[10];let m;e[11]!==t||e[12]!==a?(m=s.jsx(v,{actions:a,title:t}),e[11]=t,e[12]=a,e[13]=m):m=e[13];let c;e[14]!==r.error?(c=r.error&&s.jsx(C,{error:r.error,msg:"Failed to upload object"}),e[14]=r.error,e[15]=c):c=e[15];let u;e[16]!==t||e[17]!==l?(u=l.length>0&&s.jsxs("div",{className:"mb-6",children:[s.jsx("h2",{className:"mb-3 font-semibold text-lg",children:"Folders"}),s.jsx("div",{className:"space-y-2",children:l.map(n=>{if(!n.Prefix)return null;const P=k(n.Prefix);return s.jsx(E,{bucketName:t,folderName:P,fullPrefix:n.Prefix},n.Prefix)})})]}),e[16]=t,e[17]=l,e[18]=u):u=e[18];let f;e[19]!==t||e[20]!==o?(f=o.length>0&&s.jsxs("div",{className:"space-y-2",children:[s.jsx("h2",{className:"mb-3 font-semibold text-lg",children:"Objects"}),o.map(n=>n.Key?s.jsx(U,{bucketName:t,displayName:n.Key,fullKey:n.Key,object:n},n.Key):null)]}),e[19]=t,e[20]=o,e[21]=f):f=e[21];let d;e[22]!==l.length||e[23]!==o.length?(d=o.length===0&&l.length===0&&s.jsx("p",{className:"text-muted-foreground",children:"No objects found in this bucket."}),e[22]=l.length,e[23]=o.length,e[24]=d):d=e[24];let j;return e[25]!==m||e[26]!==c||e[27]!==u||e[28]!==f||e[29]!==d?(j=s.jsxs(s.Fragment,{children:[g,m,c,u,f,d]}),e[25]=m,e[26]=c,e[27]=u,e[28]=f,e[29]=d,e[30]=j):j=e[30],j}export{T as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c,h as i,j as t,L as m,B as d}from"./index.js";import{u as l}from"./useSuspenseQuery.js";import{L as p}from"./list-card.js";import{P as u}from"./page-heading.js";import{S as f}from"./state-badge.js";function I(){const e=c.c(5),{data:s}=l(i);let r;e[0]!==s.Vpcs?(r=s.Vpcs||[],e[0]=s.Vpcs,e[1]=r):r=e[1];const a=r;let n;e[2]===Symbol.for("react.memo_cache_sentinel")?(n=t.jsx(u,{actions:t.jsx(m,{to:"/ec2/create-vpc",children:t.jsx(d,{children:"Create VPC"})}),title:"VPCs"}),e[2]=n):n=e[2];let o;return e[3]!==a?(o=t.jsxs(t.Fragment,{children:[n,a.length>0?t.jsx("div",{className:"space-y-4",children:a.map(V)}):t.jsx("p",{className:"text-muted-foreground",children:"No VPCs found."})]}),e[3]=a,e[4]=o):o=e[4],o}function V(e){if(!e.VpcId)return null;const s=e.Tags?.find(x)?.Value;return t.jsx(p,{badge:t.jsx(f,{state:e.State}),params:{id:e.VpcId},subtitle:e.CidrBlock??"",title:s?`${e.VpcId} (${s})`:e.VpcId,to:"/ec2/describe-vpcs/$id"},e.VpcId)}function x(e){return e.Key==="Name"}export{I as component};
|
||||
import{c as m,y as n,j as s,z as i,L as c,B as l}from"./index.js";import{u}from"./useSuspenseQuery.js";import{L as p}from"./list-card.js";import{P as d}from"./page-heading.js";function C(){const e=m.c(3),{data:r}=u(n);let t;if(e[0]!==r.Users){const a=(r.Users||[]).toSorted(U);let o;e[2]===Symbol.for("react.memo_cache_sentinel")?(o=s.jsx(d,{actions:s.jsx(c,{to:"/iam/create-user",children:s.jsx(l,{children:"Create User"})}),title:"IAM Users"}),e[2]=o):o=e[2],t=s.jsxs(s.Fragment,{children:[o,a.length>0?s.jsx("div",{className:"space-y-4",children:a.map(f)}):s.jsx("p",{className:"text-muted-foreground",children:"No IAM users found."})]}),e[0]=r.Users,e[1]=t}else t=e[1];return t}function f(e){return e.UserName?s.jsx(p,{params:{userName:e.UserName},subtitle:`${e.UserId} • ${e.Path??"/"} • Created ${i(e.CreateDate)}`,title:e.UserName,to:"/iam/list-users/$userName"},e.UserName):null}function U(e,r){const t=e.UserName?.toLowerCase()??"",a=r.UserName?.toLowerCase()??"";return t.localeCompare(a)}export{C as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c as m,i as l,j as t,L as n,B as u}from"./index.js";import{u as c}from"./useSuspenseQuery.js";import{L as d}from"./list-card.js";import{P as p}from"./page-heading.js";import{S as f}from"./state-badge.js";function y(){const e=m.c(5),{data:a}=c(l);let s;e[0]!==a.Volumes?(s=a.Volumes||[],e[0]=a.Volumes,e[1]=s):s=e[1];const o=s;let r;e[2]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(p,{actions:t.jsx(n,{to:"/ec2/create-volume",children:t.jsx(u,{children:"Create Volume"})}),title:"EC2 Volumes"}),e[2]=r):r=e[2];let i;return e[3]!==o?(i=t.jsxs(t.Fragment,{children:[r,o.length>0?t.jsx("div",{className:"space-y-4",children:o.map(x)}):t.jsx("p",{className:"text-muted-foreground",children:"No volumes found."})]}),e[3]=o,e[4]=i):i=e[4],i}function x(e){return e.VolumeId?t.jsx(d,{badge:t.jsx(f,{state:e.State}),params:{id:e.VolumeId},subtitle:`${e.Size} GiB • ${e.VolumeType}`,title:e.VolumeId,to:"/ec2/describe-volumes/$id"},e.VolumeId):null}export{y as component};
|
||||
import{c as n,A as a,j as t,z as c,L as m,B as l}from"./index.js";import{u as p}from"./useSuspenseQuery.js";import{L as u}from"./list-card.js";import{P as d}from"./page-heading.js";function h(){const e=n.c(3),{data:s}=p(a);let o;if(e[0]!==s.Policies){const i=(s.Policies||[]).toSorted(x);let r;e[2]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(d,{actions:t.jsx(m,{to:"/iam/create-policy",children:t.jsx(l,{children:"Create Policy"})}),title:"IAM Policies"}),e[2]=r):r=e[2],o=t.jsxs(t.Fragment,{children:[r,i.length>0?t.jsx("div",{className:"space-y-4",children:i.map(f)}):t.jsx("p",{className:"text-muted-foreground",children:"No IAM policies found."})]}),e[0]=s.Policies,e[1]=o}else o=e[1];return o}function f(e){return e.Arn?t.jsx(u,{params:{policyArn:encodeURIComponent(e.Arn)},subtitle:`${e.Arn} • Created ${c(e.CreateDate)}`,title:e.PolicyName??"",to:"/iam/list-policies/$policyArn"},e.Arn):null}function x(e,s){const o=e.PolicyName?.toLowerCase()??"",i=s.PolicyName?.toLowerCase()??"";return o.localeCompare(i)}export{h as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c as o,p as c,j as t,L as u,B as m}from"./index.js";import{u as l}from"./useSuspenseQuery.js";import{L as d}from"./list-card.js";import{P as p}from"./page-heading.js";import{S}from"./state-badge.js";function $(){const e=o.c(5),{data:s}=l(c);let n;e[0]!==s.Subnets?(n=s.Subnets||[],e[0]=s.Subnets,e[1]=n):n=e[1];const a=n;let r;e[2]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(p,{actions:t.jsx(u,{to:"/ec2/create-subnet",children:t.jsx(m,{children:"Create Subnet"})}),title:"Subnets"}),e[2]=r):r=e[2];let i;return e[3]!==a?(i=t.jsxs(t.Fragment,{children:[r,a.length>0?t.jsx("div",{className:"space-y-4",children:a.map(f)}):t.jsx("p",{className:"text-muted-foreground",children:"No subnets found."})]}),e[3]=a,e[4]=i):i=e[4],i}function f(e){if(!e.SubnetId)return null;const s=e.Tags?.find(b)?.Value;return t.jsx(d,{badge:t.jsx(S,{state:e.State}),params:{id:e.SubnetId},subtitle:`${e.CidrBlock??""} • ${e.AvailabilityZone??""}`,title:s?`${e.SubnetId} (${s})`:e.SubnetId,to:"/ec2/describe-subnets/$id"},e.SubnetId)}function b(e){return e.Key==="Name"}export{$ as component};
|
||||
import{c,l as i,j as t,L as m,B as l}from"./index.js";import{u as d}from"./useSuspenseQuery.js";import{L as p}from"./list-card.js";import{P as u}from"./page-heading.js";import{S as f}from"./state-badge.js";function I(){const e=c.c(5),{data:s}=d(i);let r;e[0]!==s.Vpcs?(r=s.Vpcs||[],e[0]=s.Vpcs,e[1]=r):r=e[1];const a=r;let n;e[2]===Symbol.for("react.memo_cache_sentinel")?(n=t.jsx(u,{actions:t.jsx(m,{to:"/ec2/create-vpc",children:t.jsx(l,{children:"Create VPC"})}),title:"VPCs"}),e[2]=n):n=e[2];let o;return e[3]!==a?(o=t.jsxs(t.Fragment,{children:[n,a.length>0?t.jsx("div",{className:"space-y-4",children:a.map(V)}):t.jsx("p",{className:"text-muted-foreground",children:"No VPCs found."})]}),e[3]=a,e[4]=o):o=e[4],o}function V(e){if(!e.VpcId)return null;const s=e.Tags?.find(x)?.Value;return t.jsx(p,{badge:t.jsx(f,{state:e.State}),params:{id:e.VpcId},subtitle:e.CidrBlock??"",title:s?`${e.VpcId} (${s})`:e.VpcId,to:"/ec2/describe-vpcs/$id"},e.VpcId)}function x(e){return e.Key==="Name"}export{I as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c as i,w as c,j as e,L as m,B as p}from"./index.js";import{u as l}from"./useSuspenseQuery.js";import{L as d}from"./list-card.js";import{P as u}from"./page-heading.js";import{S}from"./state-badge.js";function b(){const t=i.c(5),{data:r}=l(c);let s;t[0]!==r.Snapshots?(s=r.Snapshots||[],t[0]=r.Snapshots,t[1]=s):s=t[1];const o=s;let a;t[2]===Symbol.for("react.memo_cache_sentinel")?(a=e.jsx(u,{actions:e.jsx(m,{to:"/ec2/create-snapshot",children:e.jsx(p,{children:"Create Snapshot"})}),title:"EC2 Snapshots"}),t[2]=a):a=t[2];let n;return t[3]!==o?(n=e.jsxs(e.Fragment,{children:[a,o.length>0?e.jsx("div",{className:"space-y-4",children:o.map(h)}):e.jsx("p",{className:"text-muted-foreground",children:"No snapshots found."})]}),t[3]=o,t[4]=n):n=t[4],n}function h(t){return t.SnapshotId?e.jsx(d,{badge:e.jsx(S,{state:t.State}),params:{id:t.SnapshotId},subtitle:`${t.VolumeSize} GiB • ${t.VolumeId}`,title:t.SnapshotId,to:"/ec2/describe-snapshots/$id"},t.SnapshotId):null}export{b as component};
|
||||
import{c as i,m as l,j as t,L as n,B as u}from"./index.js";import{u as c}from"./useSuspenseQuery.js";import{L as d}from"./list-card.js";import{P as p}from"./page-heading.js";import{S as f}from"./state-badge.js";function y(){const e=i.c(5),{data:a}=c(l);let s;e[0]!==a.Volumes?(s=a.Volumes||[],e[0]=a.Volumes,e[1]=s):s=e[1];const o=s;let r;e[2]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(p,{actions:t.jsx(n,{to:"/ec2/create-volume",children:t.jsx(u,{children:"Create Volume"})}),title:"EC2 Volumes"}),e[2]=r):r=e[2];let m;return e[3]!==o?(m=t.jsxs(t.Fragment,{children:[r,o.length>0?t.jsx("div",{className:"space-y-4",children:o.map(x)}):t.jsx("p",{className:"text-muted-foreground",children:"No volumes found."})]}),e[3]=o,e[4]=m):m=e[4],m}function x(e){return e.VolumeId?t.jsx(d,{badge:t.jsx(f,{state:e.State}),params:{id:e.VolumeId},subtitle:`${e.Size} GiB • ${e.VolumeType}`,title:e.VolumeId,to:"/ec2/describe-volumes/$id"},e.VolumeId):null}export{y as component};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{r as b,a_ as h,b2 as U,b3 as $,bv as A,aT as K,bt as S,j as F,c as _,a as q}from"./index.js";import{d as z,h as G,e as H,f as J,g as O,i as Q}from"./field.js";const W=b.forwardRef(function(e,a){const{render:r,className:l,id:i,name:o,value:s,disabled:I=!1,onValueChange:w,defaultValue:v,autoFocus:f=!1,...V}=e,{state:T,name:D,disabled:N,setTouched:g,setDirty:P,validityData:j,setFocused:d,setFilled:c,validationMode:k,validation:n}=z(),x=N||I,R=D??o,L={...T,disabled:x},{labelId:M}=G(),y=H({id:i});h(()=>{const t=s!=null;n.inputRef.current?.value||t&&s!==""?c(!0):t&&s===""&&c(!1)},[n.inputRef,c,s]);const p=b.useRef(null);h(()=>{f&&p.current===U($(p.current))&&d(!0)},[f,d]);const[B]=J({controlled:s,default:v,name:"FieldControl",state:"value"}),C=s!==void 0,E=C?B:void 0;return O({id:y,name:R,commit:n.commit,value:E,getValue:()=>n.inputRef.current?.value,controlRef:n.inputRef}),A("input",e,{ref:[a,p],state:L,props:[{id:y,disabled:x,name:R,ref:n.inputRef,"aria-labelledby":M,autoFocus:f,...C?{value:E}:{defaultValue:v},onChange(t){const m=t.currentTarget.value;w?.(m,K(S,t.nativeEvent)),P(m!==j.initialValue),c(m!=="")},onFocus(){d(!0)},onBlur(t){g(!0),d(!1),k==="onBlur"&&n.commit(t.currentTarget.value)},onKeyDown(t){t.currentTarget.tagName==="INPUT"&&t.key==="Enter"&&(g(!0),n.commit(t.currentTarget.value))}},n.getInputValidationProps(),V],stateAttributesMapping:Q})}),X=b.forwardRef(function(e,a){return F.jsx(W,{ref:a,...e})});function te(u){const e=_.c(10);let a,r,l;e[0]!==u?({className:a,type:l,...r}=u,e[0]=u,e[1]=a,e[2]=r,e[3]=l):(a=e[1],r=e[2],l=e[3]);let i;e[4]!==a?(i=q("h-7 w-full min-w-0 rounded-md border border-input bg-input/20 px-2 py-0.5 text-sm outline-none transition-colors file:inline-flex file:h-6 file:border-0 file:bg-transparent file:font-medium file:text-foreground file:text-xs/relaxed placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/30 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 md:text-xs/relaxed dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",a),e[4]=a,e[5]=i):i=e[5];let o;return e[6]!==r||e[7]!==i||e[8]!==l?(o=F.jsx(X,{className:i,"data-slot":"input",type:l,...r}),e[6]=r,e[7]=i,e[8]=l,e[9]=o):o=e[9],o}export{te as I};
|
||||
import{r as b,b1 as h,b5 as U,b6 as $,b7 as A,b8 as K,b9 as S,j as F,c as q,a as z}from"./index.js";import{u as G,d as H,e as J,f as O,g as Q,h as W}from"./field.js";const X=b.forwardRef(function(e,a){const{render:r,className:l,id:i,name:o,value:s,disabled:I=!1,onValueChange:w,defaultValue:v,autoFocus:f=!1,...V}=e,{state:D,name:N,disabled:P,setTouched:g,setDirty:T,validityData:j,setFocused:d,setFilled:c,validationMode:k,validation:n}=G(),x=P||I,R=N??o,L={...D,disabled:x},{labelId:M}=H(),y=J({id:i});h(()=>{const t=s!=null;n.inputRef.current?.value||t&&s!==""?c(!0):t&&s===""&&c(!1)},[n.inputRef,c,s]);const p=b.useRef(null);h(()=>{f&&p.current===U($(p.current))&&d(!0)},[f,d]);const[B]=O({controlled:s,default:v,name:"FieldControl",state:"value"}),C=s!==void 0,E=C?B:void 0;return Q({id:y,name:R,commit:n.commit,value:E,getValue:()=>n.inputRef.current?.value,controlRef:n.inputRef}),A("input",e,{ref:[a,p],state:L,props:[{id:y,disabled:x,name:R,ref:n.inputRef,"aria-labelledby":M,autoFocus:f,...C?{value:E}:{defaultValue:v},onChange(t){const m=t.currentTarget.value;w?.(m,K(S,t.nativeEvent)),T(m!==j.initialValue),c(m!=="")},onFocus(){d(!0)},onBlur(t){g(!0),d(!1),k==="onBlur"&&n.commit(t.currentTarget.value)},onKeyDown(t){t.currentTarget.tagName==="INPUT"&&t.key==="Enter"&&(g(!0),n.commit(t.currentTarget.value))}},n.getInputValidationProps(),V],stateAttributesMapping:W})}),Y=b.forwardRef(function(e,a){return F.jsx(X,{ref:a,...e})});function te(u){const e=q.c(10);let a,r,l;e[0]!==u?({className:a,type:l,...r}=u,e[0]=u,e[1]=a,e[2]=r,e[3]=l):(a=e[1],r=e[2],l=e[3]);let i;e[4]!==a?(i=z("h-7 w-full min-w-0 rounded-md border border-input bg-input/20 px-2 py-0.5 text-sm outline-none transition-colors file:inline-flex file:h-6 file:border-0 file:bg-transparent file:font-medium file:text-foreground file:text-xs/relaxed placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/30 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 md:text-xs/relaxed dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",a),e[4]=a,e[5]=i):i=e[5];let o;return e[6]!==r||e[7]!==i||e[8]!==l?(o=F.jsx(Y,{className:i,"data-slot":"input",type:l,...r}),e[6]=r,e[7]=i,e[8]=l,e[9]=o):o=e[9],o}export{te as I};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{c as b,a as v,j as a,u as P,b as D,s as L,B as R}from"./index.js";import{a as X,u as B}from"./zod.js";import{F,a as _,b as z,c as G}from"./field.js";import{I as $}from"./input.js";function O(e){const s=b.c(10);let l,t,r;s[0]!==e?({className:l,size:r,...t}=e,s[0]=e,s[1]=l,s[2]=t,s[3]=r):(l=s[1],t=s[2],r=s[3]);const c=r===void 0?"default":r;let i;s[4]!==l?(i=v("group/card flex flex-col gap-4 overflow-hidden rounded-lg bg-card py-4 text-card-foreground text-xs/relaxed ring-1 ring-foreground/10 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg",l),s[4]=l,s[5]=i):i=s[5];let o;return s[6]!==t||s[7]!==c||s[8]!==i?(o=a.jsx("div",{className:i,"data-size":c,"data-slot":"card",...t}),s[6]=t,s[7]=c,s[8]=i,s[9]=o):o=s[9],o}function T(e){const s=b.c(8);let l,t;s[0]!==e?({className:l,...t}=e,s[0]=e,s[1]=l,s[2]=t):(l=s[1],t=s[2]);let r;s[3]!==l?(r=v("group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-lg px-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3",l),s[3]=l,s[4]=r):r=s[4];let c;return s[5]!==t||s[6]!==r?(c=a.jsx("div",{className:r,"data-slot":"card-header",...t}),s[5]=t,s[6]=r,s[7]=c):c=s[7],c}function Y(e){const s=b.c(8);let l,t;s[0]!==e?({className:l,...t}=e,s[0]=e,s[1]=l,s[2]=t):(l=s[1],t=s[2]);let r;s[3]!==l?(r=v("font-medium text-sm",l),s[3]=l,s[4]=r):r=s[4];let c;return s[5]!==t||s[6]!==r?(c=a.jsx("div",{className:r,"data-slot":"card-title",...t}),s[5]=t,s[6]=r,s[7]=c):c=s[7],c}function H(e){const s=b.c(8);let l,t;s[0]!==e?({className:l,...t}=e,s[0]=e,s[1]=l,s[2]=t):(l=s[1],t=s[2]);let r;s[3]!==l?(r=v("px-4 group-data-[size=sm]/card:px-3",l),s[3]=l,s[4]=r):r=s[4];let c;return s[5]!==t||s[6]!==r?(c=a.jsx("div",{className:r,"data-slot":"card-content",...t}),s[5]=t,s[6]=r,s[7]=c):c=s[7],c}function Q(){const e=b.c(38),s=P();let l;e[0]===Symbol.for("react.memo_cache_sentinel")?(l={resolver:X(D)},e[0]=l):l=e[0];const{register:t,handleSubmit:r,formState:c}=B(l),{errors:i,isSubmitting:o}=c;let K;e[1]!==s?(K=function(M){L(M),s({to:"/"})},e[1]=s,e[2]=K):K=e[2];const C=K;let N;e[3]===Symbol.for("react.memo_cache_sentinel")?(N=a.jsx(T,{children:a.jsx(Y,{children:"AWS Credentials"})}),e[3]=N):N=e[3];let d;e[4]!==r||e[5]!==C?(d=r(C),e[4]=r,e[5]=C,e[6]=d):d=e[6];let S;e[7]===Symbol.for("react.memo_cache_sentinel")?(S=a.jsx(_,{children:a.jsx("label",{htmlFor:"accessKeyId",children:"Access Key ID"})}),e[7]=S):S=e[7];const w=!!i.accessKeyId;let n;e[8]!==t?(n=t("accessKeyId"),e[8]=t,e[9]=n):n=e[9];let m;e[10]!==w||e[11]!==n?(m=a.jsx($,{"aria-invalid":w,autoComplete:"username",id:"accessKeyId",placeholder:"AKIAIOSFODNN7EXAMPLE",...n}),e[10]=w,e[11]=n,e[12]=m):m=e[12];let f;e[13]!==i.accessKeyId?(f=a.jsx(F,{errors:[i.accessKeyId]}),e[13]=i.accessKeyId,e[14]=f):f=e[14];let u;e[15]!==m||e[16]!==f?(u=a.jsxs(z,{children:[S,m,f]}),e[15]=m,e[16]=f,e[17]=u):u=e[17];let A;e[18]===Symbol.for("react.memo_cache_sentinel")?(A=a.jsx(_,{children:a.jsx("label",{htmlFor:"secretAccessKey",children:"Secret Access Key"})}),e[18]=A):A=e[18];const E=!!i.secretAccessKey;let p;e[19]!==t?(p=t("secretAccessKey"),e[19]=t,e[20]=p):p=e[20];let x;e[21]!==E||e[22]!==p?(x=a.jsx($,{"aria-invalid":E,autoComplete:"current-password",id:"secretAccessKey",placeholder:"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",type:"password",...p}),e[21]=E,e[22]=p,e[23]=x):x=e[23];let h;e[24]!==i.secretAccessKey?(h=a.jsx(F,{errors:[i.secretAccessKey]}),e[24]=i.secretAccessKey,e[25]=h):h=e[25];let g;e[26]!==x||e[27]!==h?(g=a.jsxs(z,{children:[A,x,h]}),e[26]=x,e[27]=h,e[28]=g):g=e[28];let j;e[29]!==o?(j=a.jsx(R,{className:"w-full",disabled:o,type:"submit",children:"Sign In"}),e[29]=o,e[30]=j):j=e[30];let y;e[31]!==u||e[32]!==g||e[33]!==j?(y=a.jsxs(G,{children:[u,g,j]}),e[31]=u,e[32]=g,e[33]=j,e[34]=y):y=e[34];let I;return e[35]!==y||e[36]!==d?(I=a.jsx("div",{className:"flex flex-1 items-center justify-center",children:a.jsxs(O,{className:"w-full max-w-sm",children:[N,a.jsx(H,{children:a.jsx("form",{onSubmit:d,children:y})})]})}),e[35]=y,e[36]=d,e[37]=I):I=e[37],I}export{Q as component};
|
||||
import{c as A,a as F,j as c,u as G,r as O,b as T,d as $,s as Y,g as k,D as H,e as J,B as U}from"./index.js";import{a as W,u as q}from"./zod.js";import{F as M,a as L,b as R,c as Q}from"./field.js";import{I as X}from"./input.js";function V(e){const s=A.c(10);let t,a,l;s[0]!==e?({className:t,size:l,...a}=e,s[0]=e,s[1]=t,s[2]=a,s[3]=l):(t=s[1],a=s[2],l=s[3]);const r=l===void 0?"default":l;let i;s[4]!==t?(i=F("group/card flex flex-col gap-4 overflow-hidden rounded-lg bg-card py-4 text-card-foreground text-xs/relaxed ring-1 ring-foreground/10 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg",t),s[4]=t,s[5]=i):i=s[5];let n;return s[6]!==a||s[7]!==r||s[8]!==i?(n=c.jsx("div",{className:i,"data-size":r,"data-slot":"card",...a}),s[6]=a,s[7]=r,s[8]=i,s[9]=n):n=s[9],n}function Z(e){const s=A.c(8);let t,a;s[0]!==e?({className:t,...a}=e,s[0]=e,s[1]=t,s[2]=a):(t=s[1],a=s[2]);let l;s[3]!==t?(l=F("group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-lg px-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3",t),s[3]=t,s[4]=l):l=s[4];let r;return s[5]!==a||s[6]!==l?(r=c.jsx("div",{className:l,"data-slot":"card-header",...a}),s[5]=a,s[6]=l,s[7]=r):r=s[7],r}function ee(e){const s=A.c(8);let t,a;s[0]!==e?({className:t,...a}=e,s[0]=e,s[1]=t,s[2]=a):(t=s[1],a=s[2]);let l;s[3]!==t?(l=F("font-medium text-sm",t),s[3]=t,s[4]=l):l=s[4];let r;return s[5]!==a||s[6]!==l?(r=c.jsx("div",{className:l,"data-slot":"card-title",...a}),s[5]=a,s[6]=l,s[7]=r):r=s[7],r}function se(e){const s=A.c(8);let t,a;s[0]!==e?({className:t,...a}=e,s[0]=e,s[1]=t,s[2]=a):(t=s[1],a=s[2]);let l;s[3]!==t?(l=F("px-4 group-data-[size=sm]/card:px-3",t),s[3]=t,s[4]=l):l=s[4];let r;return s[5]!==a||s[6]!==l?(r=c.jsx("div",{className:l,"data-slot":"card-content",...a}),s[5]=a,s[6]=l,s[7]=r):r=s[7],r}function ie(){const e=A.c(44),s=G(),[t,a]=O.useState(null);let l;e[0]===Symbol.for("react.memo_cache_sentinel")?(l={resolver:W(T)},e[0]=l):l=e[0];const{register:r,handleSubmit:i,formState:n}=q(l),{errors:o,isSubmitting:I}=n;let N;e[1]!==s?(N=async function(B){a(null),$(),Y(B);try{await k().send(new H({})),s({to:"/"})}catch{J(),$(),a("Invalid credentials. Please check your Access Key ID and Secret Access Key.")}},e[1]=s,e[2]=N):N=e[2];const _=N;let v;e[3]===Symbol.for("react.memo_cache_sentinel")?(v=c.jsx(Z,{children:c.jsx(ee,{children:"AWS Credentials"})}),e[3]=v):v=e[3];let d;e[4]!==t?(d=t&&c.jsx("p",{className:"mb-4 rounded-md bg-destructive/10 p-3 text-destructive text-sm",children:t}),e[4]=t,e[5]=d):d=e[5];let m;e[6]!==i||e[7]!==_?(m=i(_),e[6]=i,e[7]=_,e[8]=m):m=e[8];let C;e[9]===Symbol.for("react.memo_cache_sentinel")?(C=c.jsx(L,{children:c.jsx("label",{htmlFor:"accessKeyId",children:"Access Key ID"})}),e[9]=C):C=e[9];const z=!!o.accessKeyId;let f;e[10]!==r?(f=r("accessKeyId"),e[10]=r,e[11]=f):f=e[11];let u;e[12]!==z||e[13]!==f?(u=c.jsx(X,{"aria-invalid":z,autoComplete:"username",id:"accessKeyId",placeholder:"AKIAIOSFODNN7EXAMPLE",...f}),e[12]=z,e[13]=f,e[14]=u):u=e[14];let p;e[15]!==o.accessKeyId?(p=c.jsx(M,{errors:[o.accessKeyId]}),e[15]=o.accessKeyId,e[16]=p):p=e[16];let x;e[17]!==p||e[18]!==u?(x=c.jsxs(R,{children:[C,u,p]}),e[17]=p,e[18]=u,e[19]=x):x=e[19];let E;e[20]===Symbol.for("react.memo_cache_sentinel")?(E=c.jsx(L,{children:c.jsx("label",{htmlFor:"secretAccessKey",children:"Secret Access Key"})}),e[20]=E):E=e[20];const D=!!o.secretAccessKey;let h;e[21]!==r?(h=r("secretAccessKey"),e[21]=r,e[22]=h):h=e[22];let g;e[23]!==D||e[24]!==h?(g=c.jsx(X,{"aria-invalid":D,autoComplete:"current-password",id:"secretAccessKey",placeholder:"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",type:"password",...h}),e[23]=D,e[24]=h,e[25]=g):g=e[25];let y;e[26]!==o.secretAccessKey?(y=c.jsx(M,{errors:[o.secretAccessKey]}),e[26]=o.secretAccessKey,e[27]=y):y=e[27];let b;e[28]!==g||e[29]!==y?(b=c.jsxs(R,{children:[E,g,y]}),e[28]=g,e[29]=y,e[30]=b):b=e[30];const P=I?"Signing in...":"Sign In";let j;e[31]!==I||e[32]!==P?(j=c.jsx(U,{className:"w-full",disabled:I,type:"submit",children:P}),e[31]=I,e[32]=P,e[33]=j):j=e[33];let K;e[34]!==x||e[35]!==b||e[36]!==j?(K=c.jsxs(Q,{children:[x,b,j]}),e[34]=x,e[35]=b,e[36]=j,e[37]=K):K=e[37];let S;e[38]!==K||e[39]!==m?(S=c.jsx("form",{onSubmit:m,children:K}),e[38]=K,e[39]=m,e[40]=S):S=e[40];let w;return e[41]!==S||e[42]!==d?(w=c.jsx("div",{className:"flex flex-1 items-center justify-center",children:c.jsxs(V,{className:"w-full max-w-sm",children:[v,c.jsxs(se,{children:[d,S]})]})}),e[41]=S,e[42]=d,e[43]=w):w=e[43],w}export{ie as component};
|
||||
|
||||
@@ -1 +1 @@
|
||||
import{u as $,l as R,m as U,n as q,p as H,j as e,B as C}from"./index.js";import{u as L,a as M,C as x}from"./zod.js";import{u as h}from"./useSuspenseQuery.js";import{B as W}from"./back-link.js";import{E as S}from"./error-banner.js";import{P as z}from"./page-heading.js";import{b as c,a as l,F as j}from"./field.js";import{I as G}from"./input.js";import{S as p,a as y,b as I,c as g,d as o}from"./select.js";import{f as J}from"./ec2.js";import{f as X}from"./ec22.js";import"./check.js";function oe(){const f=$(),{data:T}=h(R),{data:F}=h(U),{data:k}=h(q),{data:P}=h(H),r=J(),b=T.Images??[],N=F.KeyPairs??[],w=P.Subnets??[],d=k.InstanceTypes?.reduce((n,a)=>{const s=a.InstanceType;return s&&(n[s]=(n[s]||0)+1),n},{})??{},i=Object.keys(d).sort(),K=b[0]?.ImageId,B=N[0]?.KeyName,V=i.find(n=>n.endsWith(".nano"))??i[0],{control:m,handleSubmit:A,register:E,watch:O,formState:{errors:t,isSubmitting:v}}=L({resolver:M(X.refine(n=>n.count<=(d[n.instanceType]??1),{message:"Cannot exceed available capacity",path:["count"]})),defaultValues:{count:1,imageId:K??"",keyName:B??"",instanceType:V??""}}),u=O("instanceType"),Q=u?d[u]??1:1,D=async n=>{await r.mutateAsync(n),f({to:"/ec2/describe-instances"})};return e.jsxs(e.Fragment,{children:[e.jsx(W,{to:"/ec2/describe-instances",children:"Back to instances"}),e.jsx(z,{title:"Run EC2 Instances"}),i.length===0&&e.jsx(S,{msg:"No compute available. No new instances can be created until compute is available."}),r.error&&e.jsx(S,{error:r.error,msg:"Failed to create instance"}),e.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:A(D),children:[e.jsxs(c,{children:[e.jsx(l,{children:e.jsx("label",{htmlFor:"imageId",children:"Image"})}),e.jsx(x,{control:m,name:"imageId",render:({field:n})=>{const a=b.find(s=>s.ImageId===n.value);return e.jsxs(p,{onValueChange:s=>n.onChange(s),value:n.value??"",children:[e.jsx(y,{"aria-invalid":!!t.imageId,className:"w-full",id:"imageId",children:e.jsx(I,{children:a?`${a.Name||"Unnamed"} (${a.Architecture})`:""})}),e.jsx(g,{children:b.map(s=>e.jsxs(o,{value:s.ImageId??"",children:[s.Name||"Unnamed"," (",s.Architecture,")"]},s.ImageId))})]})}}),e.jsx(j,{errors:[t.imageId]})]}),e.jsxs(c,{children:[e.jsx(l,{children:e.jsx("label",{htmlFor:"instanceType",children:"Instance Type"})}),e.jsx(x,{control:m,name:"instanceType",render:({field:n})=>e.jsxs(p,{onValueChange:a=>n.onChange(a),value:n.value?n.value:"",children:[e.jsx(y,{"aria-invalid":!!t.instanceType,className:"w-full",id:"instanceType",children:e.jsx(I,{})}),e.jsx(g,{children:i.map(a=>e.jsxs(o,{value:a,children:[a," (",d[a]," available)"]},a))})]})}),e.jsx(j,{errors:[t.instanceType]})]}),e.jsxs(c,{children:[e.jsx(l,{children:e.jsx("label",{htmlFor:"keyName",children:"Key Pair"})}),e.jsx(x,{control:m,name:"keyName",render:({field:n})=>e.jsxs(p,{onValueChange:a=>n.onChange(a),value:n.value?n.value:"",children:[e.jsx(y,{"aria-invalid":!!t.keyName,className:"w-full",id:"keyName",children:e.jsx(I,{})}),e.jsx(g,{children:N.map(a=>e.jsx(o,{value:a.KeyName??"",children:a.KeyName},a.KeyPairId))})]})}),e.jsx(j,{errors:[t.keyName]})]}),e.jsxs(c,{children:[e.jsx(l,{children:e.jsx("label",{htmlFor:"subnetId",children:"Subnet"})}),e.jsx(x,{control:m,name:"subnetId",render:({field:n})=>e.jsxs(p,{onValueChange:a=>n.onChange(a==="none"?void 0:a),value:n.value??"none",children:[e.jsx(y,{className:"w-full",id:"subnetId",children:e.jsx(I,{})}),e.jsxs(g,{children:[e.jsx(o,{value:"none",children:"none"}),w.map(a=>e.jsx(o,{value:a.SubnetId??"",children:a.SubnetId},a.SubnetId))]})]})})]}),e.jsxs(c,{children:[e.jsx(l,{children:e.jsx("label",{htmlFor:"count",children:"Number of Instances"})}),e.jsx(G,{"aria-describedby":"count-description","aria-invalid":!!t.count,id:"count",type:"number",...E("count",{valueAsNumber:!0})}),e.jsx("p",{className:"text-muted-foreground text-xs",id:"count-description",children:u&&`Available capacity for ${u}: ${Q}`}),e.jsx(j,{errors:[t.count]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(C,{disabled:v||r.isPending,onClick:()=>f({to:"/ec2/describe-instances"}),type:"button",variant:"outline",children:"Cancel"}),e.jsx(C,{disabled:v||r.isPending||i.length===0,type:"submit",children:v||r.isPending?"Creating…":"Create Instance"})]})]})]})}export{oe as component};
|
||||
import{u as $,n as q,p as R,q as U,t as H,j as e,B as C}from"./index.js";import{u as L,a as M,C as x}from"./zod.js";import{u as h}from"./useSuspenseQuery.js";import{B as W}from"./back-link.js";import{E as S}from"./error-banner.js";import{P as z}from"./page-heading.js";import{b as c,a as l,F as j}from"./field.js";import{I as G}from"./input.js";import{S as p,a as y,b as I,c as g,d as o}from"./select.js";import{f as J}from"./ec2.js";import{f as X}from"./ec22.js";import"./check.js";function oe(){const f=$(),{data:T}=h(q),{data:F}=h(R),{data:k}=h(U),{data:P}=h(H),r=J(),b=T.Images??[],N=F.KeyPairs??[],w=P.Subnets??[],d=k.InstanceTypes?.reduce((n,a)=>{const s=a.InstanceType;return s&&(n[s]=(n[s]||0)+1),n},{})??{},i=Object.keys(d).sort(),K=b[0]?.ImageId,B=N[0]?.KeyName,V=i.find(n=>n.endsWith(".nano"))??i[0],{control:m,handleSubmit:A,register:E,watch:O,formState:{errors:t,isSubmitting:v}}=L({resolver:M(X.refine(n=>n.count<=(d[n.instanceType]??1),{message:"Cannot exceed available capacity",path:["count"]})),defaultValues:{count:1,imageId:K??"",keyName:B??"",instanceType:V??""}}),u=O("instanceType"),Q=u?d[u]??1:1,D=async n=>{await r.mutateAsync(n),f({to:"/ec2/describe-instances"})};return e.jsxs(e.Fragment,{children:[e.jsx(W,{to:"/ec2/describe-instances",children:"Back to instances"}),e.jsx(z,{title:"Run EC2 Instances"}),i.length===0&&e.jsx(S,{msg:"No compute available. No new instances can be created until compute is available."}),r.error&&e.jsx(S,{error:r.error,msg:"Failed to create instance"}),e.jsxs("form",{className:"max-w-4xl space-y-6",onSubmit:A(D),children:[e.jsxs(c,{children:[e.jsx(l,{children:e.jsx("label",{htmlFor:"imageId",children:"Image"})}),e.jsx(x,{control:m,name:"imageId",render:({field:n})=>{const a=b.find(s=>s.ImageId===n.value);return e.jsxs(p,{onValueChange:s=>n.onChange(s),value:n.value??"",children:[e.jsx(y,{"aria-invalid":!!t.imageId,className:"w-full",id:"imageId",children:e.jsx(I,{children:a?`${a.Name||"Unnamed"} (${a.Architecture})`:""})}),e.jsx(g,{children:b.map(s=>e.jsxs(o,{value:s.ImageId??"",children:[s.Name||"Unnamed"," (",s.Architecture,")"]},s.ImageId))})]})}}),e.jsx(j,{errors:[t.imageId]})]}),e.jsxs(c,{children:[e.jsx(l,{children:e.jsx("label",{htmlFor:"instanceType",children:"Instance Type"})}),e.jsx(x,{control:m,name:"instanceType",render:({field:n})=>e.jsxs(p,{onValueChange:a=>n.onChange(a),value:n.value?n.value:"",children:[e.jsx(y,{"aria-invalid":!!t.instanceType,className:"w-full",id:"instanceType",children:e.jsx(I,{})}),e.jsx(g,{children:i.map(a=>e.jsxs(o,{value:a,children:[a," (",d[a]," available)"]},a))})]})}),e.jsx(j,{errors:[t.instanceType]})]}),e.jsxs(c,{children:[e.jsx(l,{children:e.jsx("label",{htmlFor:"keyName",children:"Key Pair"})}),e.jsx(x,{control:m,name:"keyName",render:({field:n})=>e.jsxs(p,{onValueChange:a=>n.onChange(a),value:n.value?n.value:"",children:[e.jsx(y,{"aria-invalid":!!t.keyName,className:"w-full",id:"keyName",children:e.jsx(I,{})}),e.jsx(g,{children:N.map(a=>e.jsx(o,{value:a.KeyName??"",children:a.KeyName},a.KeyPairId))})]})}),e.jsx(j,{errors:[t.keyName]})]}),e.jsxs(c,{children:[e.jsx(l,{children:e.jsx("label",{htmlFor:"subnetId",children:"Subnet"})}),e.jsx(x,{control:m,name:"subnetId",render:({field:n})=>e.jsxs(p,{onValueChange:a=>n.onChange(a==="none"?void 0:a),value:n.value??"none",children:[e.jsx(y,{className:"w-full",id:"subnetId",children:e.jsx(I,{})}),e.jsxs(g,{children:[e.jsx(o,{value:"none",children:"none"}),w.map(a=>e.jsx(o,{value:a.SubnetId??"",children:a.SubnetId},a.SubnetId))]})]})})]}),e.jsxs(c,{children:[e.jsx(l,{children:e.jsx("label",{htmlFor:"count",children:"Number of Instances"})}),e.jsx(G,{"aria-describedby":"count-description","aria-invalid":!!t.count,id:"count",type:"number",...E("count",{valueAsNumber:!0})}),e.jsx("p",{className:"text-muted-foreground text-xs",id:"count-description",children:u&&`Available capacity for ${u}: ${Q}`}),e.jsx(j,{errors:[t.count]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(C,{disabled:v||r.isPending,onClick:()=>f({to:"/ec2/describe-instances"}),type:"button",variant:"outline",children:"Cancel"}),e.jsx(C,{disabled:v||r.isPending||i.length===0,type:"submit",children:v||r.isPending?"Creating…":"Create Instance"})]})]})]})}export{oe as component};
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{c as g,j as l}from"./index.js";function i(d){const t=g.c(3),{state:e}=d;let r="bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-100";e==="running"||e==="available"||e==="completed"?r="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-100":e==="stopped"||e==="error"?r="bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-100":e==="pending"||e==="shutting-down"||e==="stopping"?r="bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-100":e==="terminated"&&(r="bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400");const n=`rounded-full px-2 py-1 text-xs ${r}`;let a;return t[0]!==e||t[1]!==n?(a=l.jsx("div",{className:n,children:e}),t[0]=e,t[1]=n,t[2]=a):a=t[2],a}export{i as S};
|
||||
import{c as g,j as i}from"./index.js";function s(d){const t=g.c(3),{state:e}=d;let r="bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-100";e==="running"||e==="available"||e==="completed"||e==="Active"?r="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-100":e==="stopped"||e==="error"?r="bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-100":e==="pending"||e==="shutting-down"||e==="stopping"?r="bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-100":e==="terminated"&&(r="bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400");const n=`rounded-full px-2 py-1 text-xs ${r}`;let a;return t[0]!==e||t[1]!==n?(a=i.jsx("div",{className:n,children:e}),t[0]=e,t[1]=n,t[2]=a):a=t[2],a}export{s as S};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{k as a}from"./index.js";const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],o=a("trash-2",t);export{o as T};
|
||||
import{J as a}from"./index.js";const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],o=a("trash-2",t);export{o as T};
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
import{J as e}from"./index.js";const a=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],o=e("triangle-alert",a);export{o as T};
|
||||
@@ -1 +1 @@
|
||||
import{k as u,H as g,D as j,E as b,F as y,G as k,I as C,c as w,j as e,L as v,r as f,J as D,K as N,B as A}from"./index.js";import{E as M}from"./error-banner.js";import{g as S,f as E,b as R,a as L,c as O,d as z,e as B,h as F}from"./alert-dialog.js";import{g as $,b as P,c as U}from"./s3.js";import{D as _}from"./download.js";import{T}from"./trash-2.js";const H=[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}]],I=u("file",H);const G=[["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]],K=u("folder",G);const q=[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m17 8-5-5-5 5",key:"7q97r8"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}]],V=u("upload",q),W=l=>(t,a)=>async r=>{const n=await t(r),{response:s}=n;if(g.isInstance(s)&&s.headers.expires){s.headers.expiresstring=s.headers.expires;try{j(s.headers.expires)}catch(o){a.logger?.warn(`AWS SDK Warning for ${a.clientName}::${a.commandName} response parsing (${s.headers.expires}): ${o}`),delete s.headers.expires}}return n},J={tags:["S3"],name:"s3ExpiresMiddleware",override:!0,relation:"after",toMiddleware:"deserializerMiddleware"},Z=l=>({applyToStack:t=>{t.addRelativeTo(W(),J)}});class Q extends b.classBuilder().ep({...y,Bucket:{type:"contextParams",name:"Bucket"},Key:{type:"contextParams",name:"Key"}}).m(function(t,a,r,n){return[k(r,t.getEndpointParameterInstructions()),$(r,{requestChecksumRequired:!1,requestValidationModeMember:"ChecksumMode",responseAlgorithms:["CRC64NVME","CRC32","CRC32C","SHA256","SHA1"]}),P(r),Z()]}).s("AmazonS3","GetObject",{}).n("S3Client","GetObjectCommand").sc(C).build(){}function re(l){const t=w.c(9),{folderName:a,fullPrefix:r,bucketName:n}=l;let s;t[0]!==n||t[1]!==r?(s={bucket:n,_splat:r},t[0]=n,t[1]=r,t[2]=s):s=t[2];let o;t[3]===Symbol.for("react.memo_cache_sentinel")?(o=e.jsx(K,{className:"size-5 text-muted-foreground"}),t[3]=o):o=t[3];let i;t[4]!==a?(i=e.jsx("span",{className:"font-medium",children:a}),t[4]=a,t[5]=i):i=t[5];let c;return t[6]!==s||t[7]!==i?(c=e.jsxs(v,{className:"flex items-center gap-3 rounded-lg border bg-card p-4 transition-colors hover:bg-accent",params:s,to:"/s3/ls/$bucket/$",children:[o,i]}),t[6]=s,t[7]=i,t[8]=c):c=t[8],c}function ne({object:l,bucketName:t,displayName:a,fullKey:r}){const[n,s]=f.useState(!1),o=U();async function i(){try{const m=new Q({Bucket:t,Key:r}),p=await N().send(m);if(p.Body){const x=await p.Body.transformToByteArray(),h=URL.createObjectURL(new Blob([x])),d=document.createElement("a");d.href=h,d.download=a,document.body.appendChild(d),d.click(),document.body.removeChild(d),URL.revokeObjectURL(h)}}catch{throw new Error("Failed to download object")}}async function c(){try{await o.mutateAsync({bucket:t,key:r})}finally{s(!1)}}return e.jsxs("div",{children:[o.error&&e.jsx(M,{error:o.error,msg:"Failed to delete object"}),e.jsxs("div",{className:"flex items-center justify-between rounded-lg border bg-card p-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(I,{className:"size-5 text-muted-foreground"}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-medium",children:a}),l.LastModified&&e.jsxs("p",{className:"text-muted-foreground text-sm",children:["Last Modified: ",l.LastModified.toLocaleString()]})]})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"text-muted-foreground text-sm",children:D(l.Size||0)}),e.jsx("button",{className:"rounded-md p-2 transition-colors hover:bg-accent",onClick:i,type:"button",children:e.jsx(_,{className:"size-4"})}),e.jsx("button",{className:"rounded-md p-2 text-destructive transition-colors hover:bg-accent",onClick:()=>s(!0),type:"button",children:e.jsx(T,{className:"size-4"})})]}),e.jsx(S,{onOpenChange:s,open:n,children:e.jsxs(E,{children:[e.jsxs(R,{children:[e.jsx(L,{children:"Delete Object"}),e.jsxs(O,{children:["Are you sure you want to delete ",e.jsx("strong",{children:a}),"? This action cannot be undone."]})]}),e.jsxs(z,{children:[e.jsx(B,{children:"Cancel"}),e.jsx(F,{className:"bg-destructive hover:bg-destructive/90",onClick:c,children:o.isPending?"Deleting…":"Delete"})]})]})})]})]},l.Key)}function oe({bucket:l,prefix:t="",isPending:a,onUpload:r}){const n=f.useRef(null);async function s(o){const i=o.target.files;if(!(!i||i.length===0))try{await Promise.all(Array.from(i).map(c=>{const m=`${t}${c.name}`;return r({bucket:l,key:m,file:c})}))}finally{n.current&&(n.current.value="")}}return e.jsxs(e.Fragment,{children:[e.jsx("input",{accept:"*/*","aria-label":"Choose files to upload",className:"hidden",multiple:!0,onChange:s,ref:n,type:"file"}),e.jsxs(A,{disabled:a,onClick:()=>n.current?.click(),size:"sm",children:[e.jsx(V,{className:"mr-2 size-4"}),a?"Uploading…":"Upload Files"]})]})}export{re as F,ne as O,oe as U};
|
||||
import{J as u,K as g,M as j,N as b,P as y,Q as k,S as C,c as w,j as e,L as v,r as f,T as N,U as D,B as A}from"./index.js";import{E as M}from"./error-banner.js";import{g as S,f as R,b as E,a as L,c as O,d as z,e as B,h as $}from"./alert-dialog.js";import{g as F,b as P,c as U}from"./s3.js";import{D as T}from"./download.js";import{T as _}from"./trash-2.js";const H=[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}]],I=u("file",H);const K=[["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]],q=u("folder",K);const G=[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m17 8-5-5-5 5",key:"7q97r8"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}]],V=u("upload",G),W=l=>(t,a)=>async r=>{const n=await t(r),{response:s}=n;if(g.isInstance(s)&&s.headers.expires){s.headers.expiresstring=s.headers.expires;try{j(s.headers.expires)}catch(o){a.logger?.warn(`AWS SDK Warning for ${a.clientName}::${a.commandName} response parsing (${s.headers.expires}): ${o}`),delete s.headers.expires}}return n},J={tags:["S3"],name:"s3ExpiresMiddleware",override:!0,relation:"after",toMiddleware:"deserializerMiddleware"},Q=l=>({applyToStack:t=>{t.addRelativeTo(W(),J)}});class Z extends b.classBuilder().ep({...y,Bucket:{type:"contextParams",name:"Bucket"},Key:{type:"contextParams",name:"Key"}}).m(function(t,a,r,n){return[k(r,t.getEndpointParameterInstructions()),F(r,{requestChecksumRequired:!1,requestValidationModeMember:"ChecksumMode",responseAlgorithms:["CRC64NVME","CRC32","CRC32C","SHA256","SHA1"]}),P(r),Q()]}).s("AmazonS3","GetObject",{}).n("S3Client","GetObjectCommand").sc(C).build(){}function re(l){const t=w.c(9),{folderName:a,fullPrefix:r,bucketName:n}=l;let s;t[0]!==n||t[1]!==r?(s={bucket:n,_splat:r},t[0]=n,t[1]=r,t[2]=s):s=t[2];let o;t[3]===Symbol.for("react.memo_cache_sentinel")?(o=e.jsx(q,{className:"size-5 text-muted-foreground"}),t[3]=o):o=t[3];let i;t[4]!==a?(i=e.jsx("span",{className:"font-medium",children:a}),t[4]=a,t[5]=i):i=t[5];let c;return t[6]!==s||t[7]!==i?(c=e.jsxs(v,{className:"flex items-center gap-3 rounded-lg border bg-card p-4 transition-colors hover:bg-accent",params:s,to:"/s3/ls/$bucket/$",children:[o,i]}),t[6]=s,t[7]=i,t[8]=c):c=t[8],c}function ne({object:l,bucketName:t,displayName:a,fullKey:r}){const[n,s]=f.useState(!1),o=U();async function i(){try{const m=new Z({Bucket:t,Key:r}),p=await D().send(m);if(p.Body){const x=await p.Body.transformToByteArray(),h=URL.createObjectURL(new Blob([x])),d=document.createElement("a");d.href=h,d.download=a,document.body.appendChild(d),d.click(),document.body.removeChild(d),URL.revokeObjectURL(h)}}catch{throw new Error("Failed to download object")}}async function c(){try{await o.mutateAsync({bucket:t,key:r})}finally{s(!1)}}return e.jsxs("div",{children:[o.error&&e.jsx(M,{error:o.error,msg:"Failed to delete object"}),e.jsxs("div",{className:"flex items-center justify-between rounded-lg border bg-card p-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(I,{className:"size-5 text-muted-foreground"}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-medium",children:a}),l.LastModified&&e.jsxs("p",{className:"text-muted-foreground text-sm",children:["Last Modified: ",l.LastModified.toLocaleString()]})]})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"text-muted-foreground text-sm",children:N(l.Size||0)}),e.jsx("button",{className:"rounded-md p-2 transition-colors hover:bg-accent",onClick:i,type:"button",children:e.jsx(T,{className:"size-4"})}),e.jsx("button",{className:"rounded-md p-2 text-destructive transition-colors hover:bg-accent",onClick:()=>s(!0),type:"button",children:e.jsx(_,{className:"size-4"})})]}),e.jsx(S,{onOpenChange:s,open:n,children:e.jsxs(R,{children:[e.jsxs(E,{children:[e.jsx(L,{children:"Delete Object"}),e.jsxs(O,{children:["Are you sure you want to delete ",e.jsx("strong",{children:a}),"? This action cannot be undone."]})]}),e.jsxs(z,{children:[e.jsx(B,{children:"Cancel"}),e.jsx($,{className:"bg-destructive hover:bg-destructive/90",onClick:c,children:o.isPending?"Deleting…":"Delete"})]})]})})]})]},l.Key)}function oe({bucket:l,prefix:t="",isPending:a,onUpload:r}){const n=f.useRef(null);async function s(o){const i=o.target.files;if(!(!i||i.length===0))try{await Promise.all(Array.from(i).map(c=>{const m=`${t}${c.name}`;return r({bucket:l,key:m,file:c})}))}finally{n.current&&(n.current.value="")}}return e.jsxs(e.Fragment,{children:[e.jsx("input",{accept:"*/*","aria-label":"Choose files to upload",className:"hidden",multiple:!0,onChange:s,ref:n,type:"file"}),e.jsxs(A,{disabled:a,onClick:()=>n.current?.click(),size:"sm",children:[e.jsx(V,{className:"mr-2 size-4"}),a?"Uploading…":"Upload Files"]})]})}export{re as F,ne as O,oe as U};
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -11,6 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-ec2": "^3.1000.0",
|
||||
"@aws-sdk/client-iam": "^3.1000.0",
|
||||
"@aws-sdk/client-s3": "^3.995.0",
|
||||
"@aws-sdk/lib-storage": "^3.995.0",
|
||||
"@base-ui/react": "^1.2.0",
|
||||
|
||||
+52
@@ -14,6 +14,9 @@ importers:
|
||||
'@aws-sdk/client-ec2':
|
||||
specifier: ^3.1000.0
|
||||
version: 3.1000.0
|
||||
'@aws-sdk/client-iam':
|
||||
specifier: ^3.1000.0
|
||||
version: 3.1000.0
|
||||
'@aws-sdk/client-s3':
|
||||
specifier: ^3.995.0
|
||||
version: 3.1000.0
|
||||
@@ -135,6 +138,10 @@ packages:
|
||||
resolution: {integrity: sha512-SLdVSUScYXbUq2VRdKa3MloNRGnKqnmVdXkfQfJ4WyR5Lzrh1Gs6t9MXBxBMYPaFEdZhav/wMK92PSYdqLBKnA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/client-iam@3.1000.0':
|
||||
resolution: {integrity: sha512-RR4mq7t+4Fb2iaFDTcXF6Tcigl2nSWUyH61rwtiSbRrNp9A3xSexCSw79SIAkfwsuhk8Ig/ZVt5qpRHWRj2zgA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/client-s3@3.1000.0':
|
||||
resolution: {integrity: sha512-7kPy33qNGq3NfwHC0412T6LDK1bp4+eiPzetX0sVd9cpTSXuQDKpoOFnB0Njj6uZjJDcLS3n2OeyarwwgkQ0Ow==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
@@ -1936,6 +1943,51 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- aws-crt
|
||||
|
||||
'@aws-sdk/client-iam@3.1000.0':
|
||||
dependencies:
|
||||
'@aws-crypto/sha256-browser': 5.2.0
|
||||
'@aws-crypto/sha256-js': 5.2.0
|
||||
'@aws-sdk/core': 3.973.15
|
||||
'@aws-sdk/credential-provider-node': 3.972.14
|
||||
'@aws-sdk/middleware-host-header': 3.972.6
|
||||
'@aws-sdk/middleware-logger': 3.972.6
|
||||
'@aws-sdk/middleware-recursion-detection': 3.972.6
|
||||
'@aws-sdk/middleware-user-agent': 3.972.15
|
||||
'@aws-sdk/region-config-resolver': 3.972.6
|
||||
'@aws-sdk/types': 3.973.4
|
||||
'@aws-sdk/util-endpoints': 3.996.3
|
||||
'@aws-sdk/util-user-agent-browser': 3.972.6
|
||||
'@aws-sdk/util-user-agent-node': 3.973.0
|
||||
'@smithy/config-resolver': 4.4.9
|
||||
'@smithy/core': 3.23.6
|
||||
'@smithy/fetch-http-handler': 5.3.11
|
||||
'@smithy/hash-node': 4.2.10
|
||||
'@smithy/invalid-dependency': 4.2.10
|
||||
'@smithy/middleware-content-length': 4.2.10
|
||||
'@smithy/middleware-endpoint': 4.4.20
|
||||
'@smithy/middleware-retry': 4.4.37
|
||||
'@smithy/middleware-serde': 4.2.11
|
||||
'@smithy/middleware-stack': 4.2.10
|
||||
'@smithy/node-config-provider': 4.3.10
|
||||
'@smithy/node-http-handler': 4.4.12
|
||||
'@smithy/protocol-http': 5.3.10
|
||||
'@smithy/smithy-client': 4.12.0
|
||||
'@smithy/types': 4.13.0
|
||||
'@smithy/url-parser': 4.2.10
|
||||
'@smithy/util-base64': 4.3.1
|
||||
'@smithy/util-body-length-browser': 4.2.1
|
||||
'@smithy/util-body-length-node': 4.2.2
|
||||
'@smithy/util-defaults-mode-browser': 4.3.36
|
||||
'@smithy/util-defaults-mode-node': 4.2.39
|
||||
'@smithy/util-endpoints': 3.3.1
|
||||
'@smithy/util-middleware': 4.2.10
|
||||
'@smithy/util-retry': 4.2.10
|
||||
'@smithy/util-utf8': 4.2.1
|
||||
'@smithy/util-waiter': 4.2.10
|
||||
tslib: 2.8.1
|
||||
transitivePeerDependencies:
|
||||
- aws-crt
|
||||
|
||||
'@aws-sdk/client-s3@3.1000.0':
|
||||
dependencies:
|
||||
'@aws-crypto/sha1-browser': 5.2.0
|
||||
|
||||
@@ -2,7 +2,12 @@ export function StateBadge({ state }: { state: string | undefined }) {
|
||||
let className =
|
||||
"bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-100"
|
||||
|
||||
if (state === "running" || state === "available" || state === "completed") {
|
||||
if (
|
||||
state === "running" ||
|
||||
state === "available" ||
|
||||
state === "completed" ||
|
||||
state === "Active"
|
||||
) {
|
||||
className =
|
||||
"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-100"
|
||||
} else if (state === "stopped" || state === "error") {
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
LogOut,
|
||||
Network,
|
||||
Server,
|
||||
Shield,
|
||||
Users,
|
||||
} from "lucide-react"
|
||||
|
||||
// import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||
@@ -181,6 +183,41 @@ export function SidebarLayout() {
|
||||
</SidebarMenu>
|
||||
</SidebarGroup>
|
||||
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>IAM</SidebarGroupLabel>
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<Link to="/iam/list-users">
|
||||
<SidebarMenuButton
|
||||
isActive={
|
||||
pathname.startsWith("/iam/list-users") ||
|
||||
pathname.startsWith("/iam/create-user")
|
||||
}
|
||||
tooltip="Users"
|
||||
>
|
||||
<Users className="size-4" />
|
||||
<span>Users</span>
|
||||
</SidebarMenuButton>
|
||||
</Link>
|
||||
</SidebarMenuItem>
|
||||
|
||||
<SidebarMenuItem>
|
||||
<Link to="/iam/list-policies">
|
||||
<SidebarMenuButton
|
||||
isActive={
|
||||
pathname.startsWith("/iam/list-policies") ||
|
||||
pathname.startsWith("/iam/create-policy")
|
||||
}
|
||||
tooltip="Policies"
|
||||
>
|
||||
<Shield className="size-4" />
|
||||
<span>Policies</span>
|
||||
</SidebarMenuButton>
|
||||
</Link>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
</SidebarGroup>
|
||||
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>S3</SidebarGroupLabel>
|
||||
<SidebarMenu>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { EC2Client } from "@aws-sdk/client-ec2"
|
||||
import { IAMClient } from "@aws-sdk/client-iam"
|
||||
import { S3Client } from "@aws-sdk/client-s3"
|
||||
|
||||
import { getCredentials } from "./auth"
|
||||
@@ -8,6 +9,7 @@ const s3Endpoint = `${window.location.protocol}//${window.location.hostname}:844
|
||||
|
||||
// Cached singleton clients
|
||||
let ec2Client: EC2Client | null = null
|
||||
let iamClient: IAMClient | null = null
|
||||
let s3Client: S3Client | null = null
|
||||
|
||||
export function getEc2Client(): EC2Client {
|
||||
@@ -28,6 +30,24 @@ export function getEc2Client(): EC2Client {
|
||||
return ec2Client
|
||||
}
|
||||
|
||||
export function getIamClient(): IAMClient {
|
||||
if (!iamClient) {
|
||||
const credentials = getCredentials()
|
||||
if (!credentials) {
|
||||
throw new Error("AWS credentials not configured")
|
||||
}
|
||||
iamClient = new IAMClient({
|
||||
endpoint: awsEndpoint,
|
||||
region: "ap-southeast-2",
|
||||
credentials: {
|
||||
accessKeyId: credentials.accessKeyId,
|
||||
secretAccessKey: credentials.secretAccessKey,
|
||||
},
|
||||
})
|
||||
}
|
||||
return iamClient
|
||||
}
|
||||
|
||||
export function getS3Client(): S3Client {
|
||||
if (!s3Client) {
|
||||
const credentials = getCredentials()
|
||||
@@ -67,5 +87,6 @@ export function getS3Client(): S3Client {
|
||||
// Call on logout to clear cached clients
|
||||
export function clearClients(): void {
|
||||
ec2Client = null
|
||||
iamClient = null
|
||||
s3Client = null
|
||||
}
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
import {
|
||||
AttachUserPolicyCommand,
|
||||
CreateAccessKeyCommand,
|
||||
CreatePolicyCommand,
|
||||
CreateUserCommand,
|
||||
DeleteAccessKeyCommand,
|
||||
DeletePolicyCommand,
|
||||
DeleteUserCommand,
|
||||
DetachUserPolicyCommand,
|
||||
UpdateAccessKeyCommand,
|
||||
} from "@aws-sdk/client-iam"
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query"
|
||||
|
||||
import { getIamClient } from "@/lib/awsClient"
|
||||
import type {
|
||||
CreatePolicyFormData,
|
||||
CreateUserFormData,
|
||||
DeleteAccessKeyParams,
|
||||
UpdateAccessKeyParams,
|
||||
UserPolicyParams,
|
||||
} from "@/types/iam"
|
||||
|
||||
export function useCreateUser() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (params: CreateUserFormData) => {
|
||||
const command = new CreateUserCommand({
|
||||
UserName: params.userName,
|
||||
Path: params.path || undefined,
|
||||
})
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["iam", "users"] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useDeleteUser() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (userName: string) => {
|
||||
const command = new DeleteUserCommand({ UserName: userName })
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["iam", "users"] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useCreateAccessKey() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (userName: string) => {
|
||||
const command = new CreateAccessKeyCommand({ UserName: userName })
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["iam", "access-keys"] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useDeleteAccessKey() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: ({ userName, accessKeyId }: DeleteAccessKeyParams) => {
|
||||
const command = new DeleteAccessKeyCommand({
|
||||
UserName: userName,
|
||||
AccessKeyId: accessKeyId,
|
||||
})
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["iam", "access-keys"] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useUpdateAccessKey() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: ({ userName, accessKeyId, status }: UpdateAccessKeyParams) => {
|
||||
const command = new UpdateAccessKeyCommand({
|
||||
UserName: userName,
|
||||
AccessKeyId: accessKeyId,
|
||||
Status: status,
|
||||
})
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["iam", "access-keys"] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useCreatePolicy() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (params: CreatePolicyFormData) => {
|
||||
const command = new CreatePolicyCommand({
|
||||
PolicyName: params.policyName,
|
||||
Description: params.description || undefined,
|
||||
PolicyDocument: params.policyDocument,
|
||||
})
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["iam", "policies"] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useDeletePolicy() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (policyArn: string) => {
|
||||
const command = new DeletePolicyCommand({ PolicyArn: policyArn })
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["iam", "policies"] })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useAttachUserPolicy() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: ({ userName, policyArn }: UserPolicyParams) => {
|
||||
const command = new AttachUserPolicyCommand({
|
||||
UserName: userName,
|
||||
PolicyArn: policyArn,
|
||||
})
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["iam", "attached-user-policies"],
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function useDetachUserPolicy() {
|
||||
const queryClient = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: ({ userName, policyArn }: UserPolicyParams) => {
|
||||
const command = new DetachUserPolicyCommand({
|
||||
UserName: userName,
|
||||
PolicyArn: policyArn,
|
||||
})
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["iam", "attached-user-policies"],
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import {
|
||||
GetPolicyCommand,
|
||||
GetPolicyVersionCommand,
|
||||
GetUserCommand,
|
||||
ListAccessKeysCommand,
|
||||
ListAttachedUserPoliciesCommand,
|
||||
ListPoliciesCommand,
|
||||
ListUsersCommand,
|
||||
} from "@aws-sdk/client-iam"
|
||||
import { queryOptions } from "@tanstack/react-query"
|
||||
|
||||
import { getIamClient } from "@/lib/awsClient"
|
||||
|
||||
export const iamUsersQueryOptions = queryOptions({
|
||||
queryKey: ["iam", "users"],
|
||||
queryFn: () => {
|
||||
const command = new ListUsersCommand({})
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
staleTime: 300_000,
|
||||
})
|
||||
|
||||
export const iamUserQueryOptions = (userName: string) =>
|
||||
queryOptions({
|
||||
queryKey: ["iam", "users", userName],
|
||||
queryFn: () => {
|
||||
const command = new GetUserCommand({ UserName: userName })
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
staleTime: 300_000,
|
||||
})
|
||||
|
||||
export const iamAccessKeysQueryOptions = (userName: string) =>
|
||||
queryOptions({
|
||||
queryKey: ["iam", "access-keys", userName],
|
||||
queryFn: () => {
|
||||
const command = new ListAccessKeysCommand({ UserName: userName })
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
staleTime: 300_000,
|
||||
})
|
||||
|
||||
export const iamPoliciesQueryOptions = queryOptions({
|
||||
queryKey: ["iam", "policies"],
|
||||
queryFn: () => {
|
||||
const command = new ListPoliciesCommand({ Scope: "Local" })
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
staleTime: 300_000,
|
||||
})
|
||||
|
||||
export const iamPolicyQueryOptions = (policyArn: string) =>
|
||||
queryOptions({
|
||||
queryKey: ["iam", "policies", policyArn],
|
||||
queryFn: () => {
|
||||
const command = new GetPolicyCommand({ PolicyArn: policyArn })
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
staleTime: 300_000,
|
||||
})
|
||||
|
||||
export const iamPolicyVersionQueryOptions = (
|
||||
policyArn: string,
|
||||
versionId: string,
|
||||
) =>
|
||||
queryOptions({
|
||||
queryKey: ["iam", "policy-versions", policyArn, versionId],
|
||||
queryFn: () => {
|
||||
const command = new GetPolicyVersionCommand({
|
||||
PolicyArn: policyArn,
|
||||
VersionId: versionId,
|
||||
})
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
staleTime: 300_000,
|
||||
})
|
||||
|
||||
export const iamAttachedUserPoliciesQueryOptions = (userName: string) =>
|
||||
queryOptions({
|
||||
queryKey: ["iam", "attached-user-policies", userName],
|
||||
queryFn: () => {
|
||||
const command = new ListAttachedUserPoliciesCommand({
|
||||
UserName: userName,
|
||||
})
|
||||
return getIamClient().send(command)
|
||||
},
|
||||
staleTime: 300_000,
|
||||
})
|
||||
@@ -14,6 +14,8 @@ import { Route as AuthRouteRouteImport } from './routes/_auth/route'
|
||||
import { Route as AuthIndexRouteImport } from './routes/_auth/index'
|
||||
import { Route as AuthS3LsIndexRouteImport } from './routes/_auth/s3/ls/index'
|
||||
import { Route as AuthS3bucketsCreateBucketRouteImport } from './routes/_auth/s3/(buckets)/create-bucket'
|
||||
import { Route as AuthIamusersCreateUserRouteImport } from './routes/_auth/iam/(users)/create-user'
|
||||
import { Route as AuthIampoliciesCreatePolicyRouteImport } from './routes/_auth/iam/(policies)/create-policy'
|
||||
import { Route as AuthEc2vpcCreateVpcRouteImport } from './routes/_auth/ec2/(vpc)/create-vpc'
|
||||
import { Route as AuthEc2volumesCreateVolumeRouteImport } from './routes/_auth/ec2/(volumes)/create-volume'
|
||||
import { Route as AuthEc2subnetCreateSubnetRouteImport } from './routes/_auth/ec2/(subnet)/create-subnet'
|
||||
@@ -23,6 +25,8 @@ import { Route as AuthEc2keyCreateKeyPairRouteImport } from './routes/_auth/ec2/
|
||||
import { Route as AuthEc2instancesRunInstancesRouteImport } from './routes/_auth/ec2/(instances)/run-instances'
|
||||
import { Route as AuthS3LsBucketRouteRouteImport } from './routes/_auth/s3/ls/$bucket/route'
|
||||
import { Route as AuthS3LsBucketIndexRouteImport } from './routes/_auth/s3/ls/$bucket/index'
|
||||
import { Route as AuthIamusersListUsersIndexRouteImport } from './routes/_auth/iam/(users)/list-users/index'
|
||||
import { Route as AuthIampoliciesListPoliciesIndexRouteImport } from './routes/_auth/iam/(policies)/list-policies/index'
|
||||
import { Route as AuthEc2vpcDescribeVpcsIndexRouteImport } from './routes/_auth/ec2/(vpc)/describe-vpcs/index'
|
||||
import { Route as AuthEc2volumesDescribeVolumesIndexRouteImport } from './routes/_auth/ec2/(volumes)/describe-volumes/index'
|
||||
import { Route as AuthEc2subnetDescribeSubnetsIndexRouteImport } from './routes/_auth/ec2/(subnet)/describe-subnets/index'
|
||||
@@ -31,6 +35,8 @@ import { Route as AuthEc2keyDescribeKeyPairsIndexRouteImport } from './routes/_a
|
||||
import { Route as AuthEc2instancesDescribeInstancesIndexRouteImport } from './routes/_auth/ec2/(instances)/describe-instances/index'
|
||||
import { Route as AuthEc2imagesDescribeImagesIndexRouteImport } from './routes/_auth/ec2/(images)/describe-images/index'
|
||||
import { Route as AuthS3LsBucketSplatRouteImport } from './routes/_auth/s3/ls/$bucket/$'
|
||||
import { Route as AuthIamusersListUsersUserNameRouteImport } from './routes/_auth/iam/(users)/list-users/$userName'
|
||||
import { Route as AuthIampoliciesListPoliciesPolicyArnRouteImport } from './routes/_auth/iam/(policies)/list-policies/$policyArn'
|
||||
import { Route as AuthEc2vpcDescribeVpcsIdRouteImport } from './routes/_auth/ec2/(vpc)/describe-vpcs/$id'
|
||||
import { Route as AuthEc2volumesModifyVolumeIdRouteImport } from './routes/_auth/ec2/(volumes)/modify-volume/$id'
|
||||
import { Route as AuthEc2volumesDescribeVolumesIdRouteImport } from './routes/_auth/ec2/(volumes)/describe-volumes/$id'
|
||||
@@ -65,6 +71,17 @@ const AuthS3bucketsCreateBucketRoute =
|
||||
path: '/s3/create-bucket',
|
||||
getParentRoute: () => AuthRouteRoute,
|
||||
} as any)
|
||||
const AuthIamusersCreateUserRoute = AuthIamusersCreateUserRouteImport.update({
|
||||
id: '/iam/(users)/create-user',
|
||||
path: '/iam/create-user',
|
||||
getParentRoute: () => AuthRouteRoute,
|
||||
} as any)
|
||||
const AuthIampoliciesCreatePolicyRoute =
|
||||
AuthIampoliciesCreatePolicyRouteImport.update({
|
||||
id: '/iam/(policies)/create-policy',
|
||||
path: '/iam/create-policy',
|
||||
getParentRoute: () => AuthRouteRoute,
|
||||
} as any)
|
||||
const AuthEc2vpcCreateVpcRoute = AuthEc2vpcCreateVpcRouteImport.update({
|
||||
id: '/ec2/(vpc)/create-vpc',
|
||||
path: '/ec2/create-vpc',
|
||||
@@ -114,6 +131,18 @@ const AuthS3LsBucketIndexRoute = AuthS3LsBucketIndexRouteImport.update({
|
||||
path: '/',
|
||||
getParentRoute: () => AuthS3LsBucketRouteRoute,
|
||||
} as any)
|
||||
const AuthIamusersListUsersIndexRoute =
|
||||
AuthIamusersListUsersIndexRouteImport.update({
|
||||
id: '/iam/(users)/list-users/',
|
||||
path: '/iam/list-users/',
|
||||
getParentRoute: () => AuthRouteRoute,
|
||||
} as any)
|
||||
const AuthIampoliciesListPoliciesIndexRoute =
|
||||
AuthIampoliciesListPoliciesIndexRouteImport.update({
|
||||
id: '/iam/(policies)/list-policies/',
|
||||
path: '/iam/list-policies/',
|
||||
getParentRoute: () => AuthRouteRoute,
|
||||
} as any)
|
||||
const AuthEc2vpcDescribeVpcsIndexRoute =
|
||||
AuthEc2vpcDescribeVpcsIndexRouteImport.update({
|
||||
id: '/ec2/(vpc)/describe-vpcs/',
|
||||
@@ -161,6 +190,18 @@ const AuthS3LsBucketSplatRoute = AuthS3LsBucketSplatRouteImport.update({
|
||||
path: '/$',
|
||||
getParentRoute: () => AuthS3LsBucketRouteRoute,
|
||||
} as any)
|
||||
const AuthIamusersListUsersUserNameRoute =
|
||||
AuthIamusersListUsersUserNameRouteImport.update({
|
||||
id: '/iam/(users)/list-users/$userName',
|
||||
path: '/iam/list-users/$userName',
|
||||
getParentRoute: () => AuthRouteRoute,
|
||||
} as any)
|
||||
const AuthIampoliciesListPoliciesPolicyArnRoute =
|
||||
AuthIampoliciesListPoliciesPolicyArnRouteImport.update({
|
||||
id: '/iam/(policies)/list-policies/$policyArn',
|
||||
path: '/iam/list-policies/$policyArn',
|
||||
getParentRoute: () => AuthRouteRoute,
|
||||
} as any)
|
||||
const AuthEc2vpcDescribeVpcsIdRoute =
|
||||
AuthEc2vpcDescribeVpcsIdRouteImport.update({
|
||||
id: '/ec2/(vpc)/describe-vpcs/$id',
|
||||
@@ -221,6 +262,8 @@ export interface FileRoutesByFullPath {
|
||||
'/ec2/create-subnet': typeof AuthEc2subnetCreateSubnetRoute
|
||||
'/ec2/create-volume': typeof AuthEc2volumesCreateVolumeRoute
|
||||
'/ec2/create-vpc': typeof AuthEc2vpcCreateVpcRoute
|
||||
'/iam/create-policy': typeof AuthIampoliciesCreatePolicyRoute
|
||||
'/iam/create-user': typeof AuthIamusersCreateUserRoute
|
||||
'/s3/create-bucket': typeof AuthS3bucketsCreateBucketRoute
|
||||
'/s3/ls/': typeof AuthS3LsIndexRoute
|
||||
'/ec2/describe-images/$id': typeof AuthEc2imagesDescribeImagesIdRoute
|
||||
@@ -231,6 +274,8 @@ export interface FileRoutesByFullPath {
|
||||
'/ec2/describe-volumes/$id': typeof AuthEc2volumesDescribeVolumesIdRoute
|
||||
'/ec2/modify-volume/$id': typeof AuthEc2volumesModifyVolumeIdRoute
|
||||
'/ec2/describe-vpcs/$id': typeof AuthEc2vpcDescribeVpcsIdRoute
|
||||
'/iam/list-policies/$policyArn': typeof AuthIampoliciesListPoliciesPolicyArnRoute
|
||||
'/iam/list-users/$userName': typeof AuthIamusersListUsersUserNameRoute
|
||||
'/s3/ls/$bucket/$': typeof AuthS3LsBucketSplatRoute
|
||||
'/ec2/describe-images/': typeof AuthEc2imagesDescribeImagesIndexRoute
|
||||
'/ec2/describe-instances/': typeof AuthEc2instancesDescribeInstancesIndexRoute
|
||||
@@ -239,6 +284,8 @@ export interface FileRoutesByFullPath {
|
||||
'/ec2/describe-subnets/': typeof AuthEc2subnetDescribeSubnetsIndexRoute
|
||||
'/ec2/describe-volumes/': typeof AuthEc2volumesDescribeVolumesIndexRoute
|
||||
'/ec2/describe-vpcs/': typeof AuthEc2vpcDescribeVpcsIndexRoute
|
||||
'/iam/list-policies/': typeof AuthIampoliciesListPoliciesIndexRoute
|
||||
'/iam/list-users/': typeof AuthIamusersListUsersIndexRoute
|
||||
'/s3/ls/$bucket/': typeof AuthS3LsBucketIndexRoute
|
||||
}
|
||||
export interface FileRoutesByTo {
|
||||
@@ -251,6 +298,8 @@ export interface FileRoutesByTo {
|
||||
'/ec2/create-subnet': typeof AuthEc2subnetCreateSubnetRoute
|
||||
'/ec2/create-volume': typeof AuthEc2volumesCreateVolumeRoute
|
||||
'/ec2/create-vpc': typeof AuthEc2vpcCreateVpcRoute
|
||||
'/iam/create-policy': typeof AuthIampoliciesCreatePolicyRoute
|
||||
'/iam/create-user': typeof AuthIamusersCreateUserRoute
|
||||
'/s3/create-bucket': typeof AuthS3bucketsCreateBucketRoute
|
||||
'/s3/ls': typeof AuthS3LsIndexRoute
|
||||
'/ec2/describe-images/$id': typeof AuthEc2imagesDescribeImagesIdRoute
|
||||
@@ -261,6 +310,8 @@ export interface FileRoutesByTo {
|
||||
'/ec2/describe-volumes/$id': typeof AuthEc2volumesDescribeVolumesIdRoute
|
||||
'/ec2/modify-volume/$id': typeof AuthEc2volumesModifyVolumeIdRoute
|
||||
'/ec2/describe-vpcs/$id': typeof AuthEc2vpcDescribeVpcsIdRoute
|
||||
'/iam/list-policies/$policyArn': typeof AuthIampoliciesListPoliciesPolicyArnRoute
|
||||
'/iam/list-users/$userName': typeof AuthIamusersListUsersUserNameRoute
|
||||
'/s3/ls/$bucket/$': typeof AuthS3LsBucketSplatRoute
|
||||
'/ec2/describe-images': typeof AuthEc2imagesDescribeImagesIndexRoute
|
||||
'/ec2/describe-instances': typeof AuthEc2instancesDescribeInstancesIndexRoute
|
||||
@@ -269,6 +320,8 @@ export interface FileRoutesByTo {
|
||||
'/ec2/describe-subnets': typeof AuthEc2subnetDescribeSubnetsIndexRoute
|
||||
'/ec2/describe-volumes': typeof AuthEc2volumesDescribeVolumesIndexRoute
|
||||
'/ec2/describe-vpcs': typeof AuthEc2vpcDescribeVpcsIndexRoute
|
||||
'/iam/list-policies': typeof AuthIampoliciesListPoliciesIndexRoute
|
||||
'/iam/list-users': typeof AuthIamusersListUsersIndexRoute
|
||||
'/s3/ls/$bucket': typeof AuthS3LsBucketIndexRoute
|
||||
}
|
||||
export interface FileRoutesById {
|
||||
@@ -284,6 +337,8 @@ export interface FileRoutesById {
|
||||
'/_auth/ec2/(subnet)/create-subnet': typeof AuthEc2subnetCreateSubnetRoute
|
||||
'/_auth/ec2/(volumes)/create-volume': typeof AuthEc2volumesCreateVolumeRoute
|
||||
'/_auth/ec2/(vpc)/create-vpc': typeof AuthEc2vpcCreateVpcRoute
|
||||
'/_auth/iam/(policies)/create-policy': typeof AuthIampoliciesCreatePolicyRoute
|
||||
'/_auth/iam/(users)/create-user': typeof AuthIamusersCreateUserRoute
|
||||
'/_auth/s3/(buckets)/create-bucket': typeof AuthS3bucketsCreateBucketRoute
|
||||
'/_auth/s3/ls/': typeof AuthS3LsIndexRoute
|
||||
'/_auth/ec2/(images)/describe-images/$id': typeof AuthEc2imagesDescribeImagesIdRoute
|
||||
@@ -294,6 +349,8 @@ export interface FileRoutesById {
|
||||
'/_auth/ec2/(volumes)/describe-volumes/$id': typeof AuthEc2volumesDescribeVolumesIdRoute
|
||||
'/_auth/ec2/(volumes)/modify-volume/$id': typeof AuthEc2volumesModifyVolumeIdRoute
|
||||
'/_auth/ec2/(vpc)/describe-vpcs/$id': typeof AuthEc2vpcDescribeVpcsIdRoute
|
||||
'/_auth/iam/(policies)/list-policies/$policyArn': typeof AuthIampoliciesListPoliciesPolicyArnRoute
|
||||
'/_auth/iam/(users)/list-users/$userName': typeof AuthIamusersListUsersUserNameRoute
|
||||
'/_auth/s3/ls/$bucket/$': typeof AuthS3LsBucketSplatRoute
|
||||
'/_auth/ec2/(images)/describe-images/': typeof AuthEc2imagesDescribeImagesIndexRoute
|
||||
'/_auth/ec2/(instances)/describe-instances/': typeof AuthEc2instancesDescribeInstancesIndexRoute
|
||||
@@ -302,6 +359,8 @@ export interface FileRoutesById {
|
||||
'/_auth/ec2/(subnet)/describe-subnets/': typeof AuthEc2subnetDescribeSubnetsIndexRoute
|
||||
'/_auth/ec2/(volumes)/describe-volumes/': typeof AuthEc2volumesDescribeVolumesIndexRoute
|
||||
'/_auth/ec2/(vpc)/describe-vpcs/': typeof AuthEc2vpcDescribeVpcsIndexRoute
|
||||
'/_auth/iam/(policies)/list-policies/': typeof AuthIampoliciesListPoliciesIndexRoute
|
||||
'/_auth/iam/(users)/list-users/': typeof AuthIamusersListUsersIndexRoute
|
||||
'/_auth/s3/ls/$bucket/': typeof AuthS3LsBucketIndexRoute
|
||||
}
|
||||
export interface FileRouteTypes {
|
||||
@@ -317,6 +376,8 @@ export interface FileRouteTypes {
|
||||
| '/ec2/create-subnet'
|
||||
| '/ec2/create-volume'
|
||||
| '/ec2/create-vpc'
|
||||
| '/iam/create-policy'
|
||||
| '/iam/create-user'
|
||||
| '/s3/create-bucket'
|
||||
| '/s3/ls/'
|
||||
| '/ec2/describe-images/$id'
|
||||
@@ -327,6 +388,8 @@ export interface FileRouteTypes {
|
||||
| '/ec2/describe-volumes/$id'
|
||||
| '/ec2/modify-volume/$id'
|
||||
| '/ec2/describe-vpcs/$id'
|
||||
| '/iam/list-policies/$policyArn'
|
||||
| '/iam/list-users/$userName'
|
||||
| '/s3/ls/$bucket/$'
|
||||
| '/ec2/describe-images/'
|
||||
| '/ec2/describe-instances/'
|
||||
@@ -335,6 +398,8 @@ export interface FileRouteTypes {
|
||||
| '/ec2/describe-subnets/'
|
||||
| '/ec2/describe-volumes/'
|
||||
| '/ec2/describe-vpcs/'
|
||||
| '/iam/list-policies/'
|
||||
| '/iam/list-users/'
|
||||
| '/s3/ls/$bucket/'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to:
|
||||
@@ -347,6 +412,8 @@ export interface FileRouteTypes {
|
||||
| '/ec2/create-subnet'
|
||||
| '/ec2/create-volume'
|
||||
| '/ec2/create-vpc'
|
||||
| '/iam/create-policy'
|
||||
| '/iam/create-user'
|
||||
| '/s3/create-bucket'
|
||||
| '/s3/ls'
|
||||
| '/ec2/describe-images/$id'
|
||||
@@ -357,6 +424,8 @@ export interface FileRouteTypes {
|
||||
| '/ec2/describe-volumes/$id'
|
||||
| '/ec2/modify-volume/$id'
|
||||
| '/ec2/describe-vpcs/$id'
|
||||
| '/iam/list-policies/$policyArn'
|
||||
| '/iam/list-users/$userName'
|
||||
| '/s3/ls/$bucket/$'
|
||||
| '/ec2/describe-images'
|
||||
| '/ec2/describe-instances'
|
||||
@@ -365,6 +434,8 @@ export interface FileRouteTypes {
|
||||
| '/ec2/describe-subnets'
|
||||
| '/ec2/describe-volumes'
|
||||
| '/ec2/describe-vpcs'
|
||||
| '/iam/list-policies'
|
||||
| '/iam/list-users'
|
||||
| '/s3/ls/$bucket'
|
||||
id:
|
||||
| '__root__'
|
||||
@@ -379,6 +450,8 @@ export interface FileRouteTypes {
|
||||
| '/_auth/ec2/(subnet)/create-subnet'
|
||||
| '/_auth/ec2/(volumes)/create-volume'
|
||||
| '/_auth/ec2/(vpc)/create-vpc'
|
||||
| '/_auth/iam/(policies)/create-policy'
|
||||
| '/_auth/iam/(users)/create-user'
|
||||
| '/_auth/s3/(buckets)/create-bucket'
|
||||
| '/_auth/s3/ls/'
|
||||
| '/_auth/ec2/(images)/describe-images/$id'
|
||||
@@ -389,6 +462,8 @@ export interface FileRouteTypes {
|
||||
| '/_auth/ec2/(volumes)/describe-volumes/$id'
|
||||
| '/_auth/ec2/(volumes)/modify-volume/$id'
|
||||
| '/_auth/ec2/(vpc)/describe-vpcs/$id'
|
||||
| '/_auth/iam/(policies)/list-policies/$policyArn'
|
||||
| '/_auth/iam/(users)/list-users/$userName'
|
||||
| '/_auth/s3/ls/$bucket/$'
|
||||
| '/_auth/ec2/(images)/describe-images/'
|
||||
| '/_auth/ec2/(instances)/describe-instances/'
|
||||
@@ -397,6 +472,8 @@ export interface FileRouteTypes {
|
||||
| '/_auth/ec2/(subnet)/describe-subnets/'
|
||||
| '/_auth/ec2/(volumes)/describe-volumes/'
|
||||
| '/_auth/ec2/(vpc)/describe-vpcs/'
|
||||
| '/_auth/iam/(policies)/list-policies/'
|
||||
| '/_auth/iam/(users)/list-users/'
|
||||
| '/_auth/s3/ls/$bucket/'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
@@ -442,6 +519,20 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof AuthS3bucketsCreateBucketRouteImport
|
||||
parentRoute: typeof AuthRouteRoute
|
||||
}
|
||||
'/_auth/iam/(users)/create-user': {
|
||||
id: '/_auth/iam/(users)/create-user'
|
||||
path: '/iam/create-user'
|
||||
fullPath: '/iam/create-user'
|
||||
preLoaderRoute: typeof AuthIamusersCreateUserRouteImport
|
||||
parentRoute: typeof AuthRouteRoute
|
||||
}
|
||||
'/_auth/iam/(policies)/create-policy': {
|
||||
id: '/_auth/iam/(policies)/create-policy'
|
||||
path: '/iam/create-policy'
|
||||
fullPath: '/iam/create-policy'
|
||||
preLoaderRoute: typeof AuthIampoliciesCreatePolicyRouteImport
|
||||
parentRoute: typeof AuthRouteRoute
|
||||
}
|
||||
'/_auth/ec2/(vpc)/create-vpc': {
|
||||
id: '/_auth/ec2/(vpc)/create-vpc'
|
||||
path: '/ec2/create-vpc'
|
||||
@@ -505,6 +596,20 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof AuthS3LsBucketIndexRouteImport
|
||||
parentRoute: typeof AuthS3LsBucketRouteRoute
|
||||
}
|
||||
'/_auth/iam/(users)/list-users/': {
|
||||
id: '/_auth/iam/(users)/list-users/'
|
||||
path: '/iam/list-users'
|
||||
fullPath: '/iam/list-users/'
|
||||
preLoaderRoute: typeof AuthIamusersListUsersIndexRouteImport
|
||||
parentRoute: typeof AuthRouteRoute
|
||||
}
|
||||
'/_auth/iam/(policies)/list-policies/': {
|
||||
id: '/_auth/iam/(policies)/list-policies/'
|
||||
path: '/iam/list-policies'
|
||||
fullPath: '/iam/list-policies/'
|
||||
preLoaderRoute: typeof AuthIampoliciesListPoliciesIndexRouteImport
|
||||
parentRoute: typeof AuthRouteRoute
|
||||
}
|
||||
'/_auth/ec2/(vpc)/describe-vpcs/': {
|
||||
id: '/_auth/ec2/(vpc)/describe-vpcs/'
|
||||
path: '/ec2/describe-vpcs'
|
||||
@@ -561,6 +666,20 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof AuthS3LsBucketSplatRouteImport
|
||||
parentRoute: typeof AuthS3LsBucketRouteRoute
|
||||
}
|
||||
'/_auth/iam/(users)/list-users/$userName': {
|
||||
id: '/_auth/iam/(users)/list-users/$userName'
|
||||
path: '/iam/list-users/$userName'
|
||||
fullPath: '/iam/list-users/$userName'
|
||||
preLoaderRoute: typeof AuthIamusersListUsersUserNameRouteImport
|
||||
parentRoute: typeof AuthRouteRoute
|
||||
}
|
||||
'/_auth/iam/(policies)/list-policies/$policyArn': {
|
||||
id: '/_auth/iam/(policies)/list-policies/$policyArn'
|
||||
path: '/iam/list-policies/$policyArn'
|
||||
fullPath: '/iam/list-policies/$policyArn'
|
||||
preLoaderRoute: typeof AuthIampoliciesListPoliciesPolicyArnRouteImport
|
||||
parentRoute: typeof AuthRouteRoute
|
||||
}
|
||||
'/_auth/ec2/(vpc)/describe-vpcs/$id': {
|
||||
id: '/_auth/ec2/(vpc)/describe-vpcs/$id'
|
||||
path: '/ec2/describe-vpcs/$id'
|
||||
@@ -643,6 +762,8 @@ interface AuthRouteRouteChildren {
|
||||
AuthEc2subnetCreateSubnetRoute: typeof AuthEc2subnetCreateSubnetRoute
|
||||
AuthEc2volumesCreateVolumeRoute: typeof AuthEc2volumesCreateVolumeRoute
|
||||
AuthEc2vpcCreateVpcRoute: typeof AuthEc2vpcCreateVpcRoute
|
||||
AuthIampoliciesCreatePolicyRoute: typeof AuthIampoliciesCreatePolicyRoute
|
||||
AuthIamusersCreateUserRoute: typeof AuthIamusersCreateUserRoute
|
||||
AuthS3bucketsCreateBucketRoute: typeof AuthS3bucketsCreateBucketRoute
|
||||
AuthS3LsIndexRoute: typeof AuthS3LsIndexRoute
|
||||
AuthEc2imagesDescribeImagesIdRoute: typeof AuthEc2imagesDescribeImagesIdRoute
|
||||
@@ -653,6 +774,8 @@ interface AuthRouteRouteChildren {
|
||||
AuthEc2volumesDescribeVolumesIdRoute: typeof AuthEc2volumesDescribeVolumesIdRoute
|
||||
AuthEc2volumesModifyVolumeIdRoute: typeof AuthEc2volumesModifyVolumeIdRoute
|
||||
AuthEc2vpcDescribeVpcsIdRoute: typeof AuthEc2vpcDescribeVpcsIdRoute
|
||||
AuthIampoliciesListPoliciesPolicyArnRoute: typeof AuthIampoliciesListPoliciesPolicyArnRoute
|
||||
AuthIamusersListUsersUserNameRoute: typeof AuthIamusersListUsersUserNameRoute
|
||||
AuthEc2imagesDescribeImagesIndexRoute: typeof AuthEc2imagesDescribeImagesIndexRoute
|
||||
AuthEc2instancesDescribeInstancesIndexRoute: typeof AuthEc2instancesDescribeInstancesIndexRoute
|
||||
AuthEc2keyDescribeKeyPairsIndexRoute: typeof AuthEc2keyDescribeKeyPairsIndexRoute
|
||||
@@ -660,6 +783,8 @@ interface AuthRouteRouteChildren {
|
||||
AuthEc2subnetDescribeSubnetsIndexRoute: typeof AuthEc2subnetDescribeSubnetsIndexRoute
|
||||
AuthEc2volumesDescribeVolumesIndexRoute: typeof AuthEc2volumesDescribeVolumesIndexRoute
|
||||
AuthEc2vpcDescribeVpcsIndexRoute: typeof AuthEc2vpcDescribeVpcsIndexRoute
|
||||
AuthIampoliciesListPoliciesIndexRoute: typeof AuthIampoliciesListPoliciesIndexRoute
|
||||
AuthIamusersListUsersIndexRoute: typeof AuthIamusersListUsersIndexRoute
|
||||
}
|
||||
|
||||
const AuthRouteRouteChildren: AuthRouteRouteChildren = {
|
||||
@@ -672,6 +797,8 @@ const AuthRouteRouteChildren: AuthRouteRouteChildren = {
|
||||
AuthEc2subnetCreateSubnetRoute: AuthEc2subnetCreateSubnetRoute,
|
||||
AuthEc2volumesCreateVolumeRoute: AuthEc2volumesCreateVolumeRoute,
|
||||
AuthEc2vpcCreateVpcRoute: AuthEc2vpcCreateVpcRoute,
|
||||
AuthIampoliciesCreatePolicyRoute: AuthIampoliciesCreatePolicyRoute,
|
||||
AuthIamusersCreateUserRoute: AuthIamusersCreateUserRoute,
|
||||
AuthS3bucketsCreateBucketRoute: AuthS3bucketsCreateBucketRoute,
|
||||
AuthS3LsIndexRoute: AuthS3LsIndexRoute,
|
||||
AuthEc2imagesDescribeImagesIdRoute: AuthEc2imagesDescribeImagesIdRoute,
|
||||
@@ -684,6 +811,9 @@ const AuthRouteRouteChildren: AuthRouteRouteChildren = {
|
||||
AuthEc2volumesDescribeVolumesIdRoute: AuthEc2volumesDescribeVolumesIdRoute,
|
||||
AuthEc2volumesModifyVolumeIdRoute: AuthEc2volumesModifyVolumeIdRoute,
|
||||
AuthEc2vpcDescribeVpcsIdRoute: AuthEc2vpcDescribeVpcsIdRoute,
|
||||
AuthIampoliciesListPoliciesPolicyArnRoute:
|
||||
AuthIampoliciesListPoliciesPolicyArnRoute,
|
||||
AuthIamusersListUsersUserNameRoute: AuthIamusersListUsersUserNameRoute,
|
||||
AuthEc2imagesDescribeImagesIndexRoute: AuthEc2imagesDescribeImagesIndexRoute,
|
||||
AuthEc2instancesDescribeInstancesIndexRoute:
|
||||
AuthEc2instancesDescribeInstancesIndexRoute,
|
||||
@@ -695,6 +825,8 @@ const AuthRouteRouteChildren: AuthRouteRouteChildren = {
|
||||
AuthEc2volumesDescribeVolumesIndexRoute:
|
||||
AuthEc2volumesDescribeVolumesIndexRoute,
|
||||
AuthEc2vpcDescribeVpcsIndexRoute: AuthEc2vpcDescribeVpcsIndexRoute,
|
||||
AuthIampoliciesListPoliciesIndexRoute: AuthIampoliciesListPoliciesIndexRoute,
|
||||
AuthIamusersListUsersIndexRoute: AuthIamusersListUsersIndexRoute,
|
||||
}
|
||||
|
||||
const AuthRouteRouteWithChildren = AuthRouteRoute._addFileChildren(
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { createFileRoute, useNavigate } from "@tanstack/react-router"
|
||||
import { useForm } from "react-hook-form"
|
||||
|
||||
import { BackLink } from "@/components/back-link"
|
||||
import { ErrorBanner } from "@/components/error-banner"
|
||||
import { PageHeading } from "@/components/page-heading"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Field, FieldError, FieldTitle } from "@/components/ui/field"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Textarea } from "@/components/ui/textarea"
|
||||
import { useCreatePolicy } from "@/mutations/iam"
|
||||
import { type CreatePolicyFormData, createPolicySchema } from "@/types/iam"
|
||||
|
||||
const DEFAULT_POLICY_DOCUMENT = JSON.stringify(
|
||||
{
|
||||
Version: "2012-10-17",
|
||||
Statement: [
|
||||
{
|
||||
Effect: "Allow",
|
||||
Action: "*",
|
||||
Resource: "*",
|
||||
},
|
||||
],
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)
|
||||
|
||||
export const Route = createFileRoute("/_auth/iam/(policies)/create-policy")({
|
||||
head: () => ({
|
||||
meta: [{ title: "Create Policy | IAM | Mulga" }],
|
||||
}),
|
||||
component: CreatePolicy,
|
||||
})
|
||||
|
||||
function CreatePolicy() {
|
||||
const navigate = useNavigate()
|
||||
const createMutation = useCreatePolicy()
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
register,
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm({
|
||||
resolver: zodResolver(createPolicySchema),
|
||||
defaultValues: {
|
||||
policyDocument: DEFAULT_POLICY_DOCUMENT,
|
||||
},
|
||||
})
|
||||
|
||||
const onSubmit = async (data: CreatePolicyFormData) => {
|
||||
await createMutation.mutateAsync(data)
|
||||
navigate({ to: "/iam/list-policies" })
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<BackLink to="/iam/list-policies">Back to policies</BackLink>
|
||||
<PageHeading title="Create Policy" />
|
||||
|
||||
{createMutation.error && (
|
||||
<ErrorBanner
|
||||
error={createMutation.error}
|
||||
msg="Failed to create policy"
|
||||
/>
|
||||
)}
|
||||
|
||||
<form className="max-w-4xl space-y-6" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Field>
|
||||
<FieldTitle>
|
||||
<label htmlFor="policyName">Policy Name</label>
|
||||
</FieldTitle>
|
||||
<Input
|
||||
aria-invalid={!!errors.policyName}
|
||||
id="policyName"
|
||||
placeholder="my-policy..."
|
||||
{...register("policyName")}
|
||||
/>
|
||||
<FieldError errors={[errors.policyName]} />
|
||||
</Field>
|
||||
|
||||
<Field>
|
||||
<FieldTitle>
|
||||
<label htmlFor="description">Description (optional)</label>
|
||||
</FieldTitle>
|
||||
<Input
|
||||
id="description"
|
||||
placeholder="A brief description of this policy..."
|
||||
{...register("description")}
|
||||
/>
|
||||
<FieldError errors={[errors.description]} />
|
||||
</Field>
|
||||
|
||||
<Field>
|
||||
<FieldTitle>
|
||||
<label htmlFor="policyDocument">Policy Document (JSON)</label>
|
||||
</FieldTitle>
|
||||
<Textarea
|
||||
aria-invalid={!!errors.policyDocument}
|
||||
className="font-mono text-sm"
|
||||
id="policyDocument"
|
||||
rows={15}
|
||||
{...register("policyDocument")}
|
||||
/>
|
||||
<FieldError errors={[errors.policyDocument]} />
|
||||
</Field>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
disabled={isSubmitting || createMutation.isPending}
|
||||
onClick={() => navigate({ to: "/iam/list-policies" })}
|
||||
type="button"
|
||||
variant="outline"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
disabled={isSubmitting || createMutation.isPending}
|
||||
type="submit"
|
||||
>
|
||||
{isSubmitting || createMutation.isPending
|
||||
? "Creating..."
|
||||
: "Create Policy"}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
)
|
||||
}
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
import { useSuspenseQuery } from "@tanstack/react-query"
|
||||
import { createFileRoute, useNavigate } from "@tanstack/react-router"
|
||||
import { Trash2 } from "lucide-react"
|
||||
import { useState } from "react"
|
||||
|
||||
import { BackLink } from "@/components/back-link"
|
||||
import { DetailCard } from "@/components/detail-card"
|
||||
import { DetailRow } from "@/components/detail-row"
|
||||
import { ErrorBanner } from "@/components/error-banner"
|
||||
import { PageHeading } from "@/components/page-heading"
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
} from "@/components/ui/alert-dialog"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { formatDateTime } from "@/lib/utils"
|
||||
import { useDeletePolicy } from "@/mutations/iam"
|
||||
import {
|
||||
iamPolicyQueryOptions,
|
||||
iamPolicyVersionQueryOptions,
|
||||
} from "@/queries/iam"
|
||||
import { PolicyDocumentViewer } from "../../-components/policy-document-viewer"
|
||||
|
||||
export const Route = createFileRoute(
|
||||
"/_auth/iam/(policies)/list-policies/$policyArn",
|
||||
)({
|
||||
loader: async ({ context, params }) => {
|
||||
const policyArn = decodeURIComponent(params.policyArn)
|
||||
const policyData = await context.queryClient.ensureQueryData(
|
||||
iamPolicyQueryOptions(policyArn),
|
||||
)
|
||||
const versionId = policyData.Policy?.DefaultVersionId
|
||||
if (versionId) {
|
||||
await context.queryClient.ensureQueryData(
|
||||
iamPolicyVersionQueryOptions(policyArn, versionId),
|
||||
)
|
||||
}
|
||||
return policyData
|
||||
},
|
||||
head: ({ loaderData }) => ({
|
||||
meta: [
|
||||
{
|
||||
title: `${loaderData?.Policy?.PolicyName ?? "Policy"} | IAM | Mulga`,
|
||||
},
|
||||
],
|
||||
}),
|
||||
component: PolicyDetail,
|
||||
})
|
||||
|
||||
function PolicyDetail() {
|
||||
const { policyArn: encodedArn } = Route.useParams()
|
||||
const policyArn = decodeURIComponent(encodedArn)
|
||||
const navigate = useNavigate()
|
||||
const { data: policyData } = useSuspenseQuery(
|
||||
iamPolicyQueryOptions(policyArn),
|
||||
)
|
||||
const policy = policyData.Policy
|
||||
const deleteMutation = useDeletePolicy()
|
||||
const [showDeleteDialog, setShowDeleteDialog] = useState(false)
|
||||
|
||||
const versionId = policy?.DefaultVersionId ?? "v1"
|
||||
const { data: versionData } = useSuspenseQuery(
|
||||
iamPolicyVersionQueryOptions(policyArn, versionId),
|
||||
)
|
||||
|
||||
const policyDocument = versionData?.PolicyVersion?.Document
|
||||
? decodeURIComponent(versionData.PolicyVersion.Document)
|
||||
: null
|
||||
|
||||
const handleDelete = async () => {
|
||||
try {
|
||||
await deleteMutation.mutateAsync(policyArn)
|
||||
navigate({ to: "/iam/list-policies" })
|
||||
} finally {
|
||||
setShowDeleteDialog(false)
|
||||
}
|
||||
}
|
||||
|
||||
if (!policy) {
|
||||
return (
|
||||
<>
|
||||
<BackLink to="/iam/list-policies">Back to policies</BackLink>
|
||||
<p className="text-muted-foreground">Policy not found.</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<BackLink to="/iam/list-policies">Back to policies</BackLink>
|
||||
|
||||
{deleteMutation.error && (
|
||||
<ErrorBanner
|
||||
error={deleteMutation.error}
|
||||
msg="Failed to delete policy"
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="space-y-6">
|
||||
<PageHeading
|
||||
actions={
|
||||
<Button
|
||||
onClick={() => setShowDeleteDialog(true)}
|
||||
size="sm"
|
||||
variant="destructive"
|
||||
>
|
||||
<Trash2 className="size-4" />
|
||||
Delete
|
||||
</Button>
|
||||
}
|
||||
subtitle="IAM Policy Details"
|
||||
title={policy.PolicyName ?? ""}
|
||||
/>
|
||||
|
||||
<DetailCard>
|
||||
<DetailCard.Header>Policy Information</DetailCard.Header>
|
||||
<DetailCard.Content>
|
||||
<DetailRow label="Policy Name" value={policy.PolicyName} />
|
||||
<DetailRow label="Policy ID" value={policy.PolicyId} />
|
||||
<DetailRow label="ARN" value={policy.Arn} />
|
||||
<DetailRow label="Path" value={policy.Path} />
|
||||
<DetailRow label="Description" value={policy.Description || "-"} />
|
||||
<DetailRow
|
||||
label="Created"
|
||||
value={formatDateTime(policy.CreateDate)}
|
||||
/>
|
||||
</DetailCard.Content>
|
||||
</DetailCard>
|
||||
|
||||
{policyDocument && (
|
||||
<DetailCard>
|
||||
<DetailCard.Header>Policy Document</DetailCard.Header>
|
||||
<div className="p-4">
|
||||
<PolicyDocumentViewer document={policyDocument} />
|
||||
</div>
|
||||
</DetailCard>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<AlertDialog onOpenChange={setShowDeleteDialog} open={showDeleteDialog}>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Delete Policy</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
Are you sure you want to delete the policy "{policy.PolicyName}"?
|
||||
This action cannot be undone.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
disabled={deleteMutation.isPending}
|
||||
onClick={handleDelete}
|
||||
>
|
||||
{deleteMutation.isPending ? "Deleting..." : "Delete"}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import type { Policy } from "@aws-sdk/client-iam"
|
||||
import { useSuspenseQuery } from "@tanstack/react-query"
|
||||
import { createFileRoute, Link } from "@tanstack/react-router"
|
||||
|
||||
import { ListCard } from "@/components/list-card"
|
||||
import { PageHeading } from "@/components/page-heading"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { formatDateTime } from "@/lib/utils"
|
||||
import { iamPoliciesQueryOptions } from "@/queries/iam"
|
||||
|
||||
export const Route = createFileRoute("/_auth/iam/(policies)/list-policies/")({
|
||||
loader: async ({ context }) => {
|
||||
await context.queryClient.ensureQueryData(iamPoliciesQueryOptions)
|
||||
},
|
||||
head: () => ({
|
||||
meta: [{ title: "Policies | IAM | Mulga" }],
|
||||
}),
|
||||
component: Policies,
|
||||
})
|
||||
|
||||
function Policies() {
|
||||
const { data } = useSuspenseQuery(iamPoliciesQueryOptions)
|
||||
|
||||
const policies = (data.Policies || []).toSorted((a, b) => {
|
||||
const nameA = a.PolicyName?.toLowerCase() ?? ""
|
||||
const nameB = b.PolicyName?.toLowerCase() ?? ""
|
||||
return nameA.localeCompare(nameB)
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeading
|
||||
actions={
|
||||
<Link to="/iam/create-policy">
|
||||
<Button>Create Policy</Button>
|
||||
</Link>
|
||||
}
|
||||
title="IAM Policies"
|
||||
/>
|
||||
|
||||
{policies.length > 0 ? (
|
||||
<div className="space-y-4">
|
||||
{policies.map((policy: Policy) => {
|
||||
if (!policy.Arn) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<ListCard
|
||||
key={policy.Arn}
|
||||
params={{ policyArn: encodeURIComponent(policy.Arn) }}
|
||||
subtitle={`${policy.Arn} • Created ${formatDateTime(policy.CreateDate)}`}
|
||||
title={policy.PolicyName ?? ""}
|
||||
to="/iam/list-policies/$policyArn"
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-muted-foreground">No IAM policies found.</p>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { createFileRoute, useNavigate } from "@tanstack/react-router"
|
||||
import { useForm } from "react-hook-form"
|
||||
|
||||
import { BackLink } from "@/components/back-link"
|
||||
import { ErrorBanner } from "@/components/error-banner"
|
||||
import { PageHeading } from "@/components/page-heading"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Field, FieldError, FieldTitle } from "@/components/ui/field"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { useCreateUser } from "@/mutations/iam"
|
||||
import { type CreateUserFormData, createUserSchema } from "@/types/iam"
|
||||
|
||||
export const Route = createFileRoute("/_auth/iam/(users)/create-user")({
|
||||
head: () => ({
|
||||
meta: [{ title: "Create User | IAM | Mulga" }],
|
||||
}),
|
||||
component: CreateUser,
|
||||
})
|
||||
|
||||
function CreateUser() {
|
||||
const navigate = useNavigate()
|
||||
const createMutation = useCreateUser()
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
register,
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm({
|
||||
resolver: zodResolver(createUserSchema),
|
||||
})
|
||||
|
||||
const onSubmit = async (data: CreateUserFormData) => {
|
||||
await createMutation.mutateAsync(data)
|
||||
navigate({ to: "/iam/list-users" })
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<BackLink to="/iam/list-users">Back to users</BackLink>
|
||||
<PageHeading title="Create User" />
|
||||
|
||||
{createMutation.error && (
|
||||
<ErrorBanner error={createMutation.error} msg="Failed to create user" />
|
||||
)}
|
||||
|
||||
<form className="max-w-4xl space-y-6" onSubmit={handleSubmit(onSubmit)}>
|
||||
<Field>
|
||||
<FieldTitle>
|
||||
<label htmlFor="userName">User Name</label>
|
||||
</FieldTitle>
|
||||
<Input
|
||||
aria-invalid={!!errors.userName}
|
||||
id="userName"
|
||||
placeholder="my-user..."
|
||||
{...register("userName")}
|
||||
/>
|
||||
<FieldError errors={[errors.userName]} />
|
||||
</Field>
|
||||
|
||||
<Field>
|
||||
<FieldTitle>
|
||||
<label htmlFor="path">Path (optional)</label>
|
||||
</FieldTitle>
|
||||
<Input id="path" placeholder="/" {...register("path")} />
|
||||
<FieldError errors={[errors.path]} />
|
||||
</Field>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
disabled={isSubmitting || createMutation.isPending}
|
||||
onClick={() => navigate({ to: "/iam/list-users" })}
|
||||
type="button"
|
||||
variant="outline"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
disabled={isSubmitting || createMutation.isPending}
|
||||
type="submit"
|
||||
>
|
||||
{isSubmitting || createMutation.isPending
|
||||
? "Creating..."
|
||||
: "Create User"}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
import type { AccessKeyMetadata, AttachedPolicy } from "@aws-sdk/client-iam"
|
||||
import { useSuspenseQuery } from "@tanstack/react-query"
|
||||
import { createFileRoute, useNavigate } from "@tanstack/react-router"
|
||||
import { Trash2 } from "lucide-react"
|
||||
import { useState } from "react"
|
||||
|
||||
import { BackLink } from "@/components/back-link"
|
||||
import { DetailCard } from "@/components/detail-card"
|
||||
import { DetailRow } from "@/components/detail-row"
|
||||
import { ErrorBanner } from "@/components/error-banner"
|
||||
import { PageHeading } from "@/components/page-heading"
|
||||
import { StateBadge } from "@/components/state-badge"
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
} from "@/components/ui/alert-dialog"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { formatDateTime } from "@/lib/utils"
|
||||
import {
|
||||
useAttachUserPolicy,
|
||||
useCreateAccessKey,
|
||||
useDeleteAccessKey,
|
||||
useDeleteUser,
|
||||
useDetachUserPolicy,
|
||||
useUpdateAccessKey,
|
||||
} from "@/mutations/iam"
|
||||
import {
|
||||
iamAccessKeysQueryOptions,
|
||||
iamAttachedUserPoliciesQueryOptions,
|
||||
iamPoliciesQueryOptions,
|
||||
iamUserQueryOptions,
|
||||
} from "@/queries/iam"
|
||||
import { AccessKeyModal } from "../../-components/access-key-modal"
|
||||
|
||||
export const Route = createFileRoute("/_auth/iam/(users)/list-users/$userName")(
|
||||
{
|
||||
loader: async ({ context, params }) => {
|
||||
await Promise.all([
|
||||
context.queryClient.ensureQueryData(
|
||||
iamUserQueryOptions(params.userName),
|
||||
),
|
||||
context.queryClient.ensureQueryData(
|
||||
iamAccessKeysQueryOptions(params.userName),
|
||||
),
|
||||
context.queryClient.ensureQueryData(
|
||||
iamAttachedUserPoliciesQueryOptions(params.userName),
|
||||
),
|
||||
context.queryClient.ensureQueryData(iamPoliciesQueryOptions),
|
||||
])
|
||||
},
|
||||
head: ({ params }) => ({
|
||||
meta: [{ title: `${params.userName} | IAM | Mulga` }],
|
||||
}),
|
||||
component: UserDetail,
|
||||
},
|
||||
)
|
||||
|
||||
function UserDetail() {
|
||||
const { userName } = Route.useParams()
|
||||
const navigate = useNavigate()
|
||||
const { data: userData } = useSuspenseQuery(iamUserQueryOptions(userName))
|
||||
const { data: accessKeysData } = useSuspenseQuery(
|
||||
iamAccessKeysQueryOptions(userName),
|
||||
)
|
||||
const { data: attachedPoliciesData } = useSuspenseQuery(
|
||||
iamAttachedUserPoliciesQueryOptions(userName),
|
||||
)
|
||||
const { data: allPoliciesData } = useSuspenseQuery(iamPoliciesQueryOptions)
|
||||
|
||||
const deleteMutation = useDeleteUser()
|
||||
const createAccessKeyMutation = useCreateAccessKey()
|
||||
const deleteAccessKeyMutation = useDeleteAccessKey()
|
||||
const updateAccessKeyMutation = useUpdateAccessKey()
|
||||
const attachPolicyMutation = useAttachUserPolicy()
|
||||
const detachPolicyMutation = useDetachUserPolicy()
|
||||
|
||||
const [showDeleteDialog, setShowDeleteDialog] = useState(false)
|
||||
const [newAccessKey, setNewAccessKey] = useState<{
|
||||
accessKeyId: string
|
||||
secretAccessKey: string
|
||||
} | null>(null)
|
||||
const [showAttachSelect, setShowAttachSelect] = useState(false)
|
||||
const [pendingKeyAction, setPendingKeyAction] = useState<string | null>(null)
|
||||
const [pendingPolicyAction, setPendingPolicyAction] = useState<string | null>(
|
||||
null,
|
||||
)
|
||||
|
||||
const user = userData.User
|
||||
const accessKeys = accessKeysData.AccessKeyMetadata || []
|
||||
const attachedPolicies = attachedPoliciesData.AttachedPolicies || []
|
||||
const allPolicies = allPoliciesData.Policies || []
|
||||
|
||||
const attachedArns = new Set(attachedPolicies.map((p) => p.PolicyArn))
|
||||
const availablePolicies = allPolicies.filter(
|
||||
(p) => p.Arn && !attachedArns.has(p.Arn),
|
||||
)
|
||||
|
||||
const handleDelete = async () => {
|
||||
try {
|
||||
await deleteMutation.mutateAsync(userName)
|
||||
navigate({ to: "/iam/list-users" })
|
||||
} finally {
|
||||
setShowDeleteDialog(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleCreateAccessKey = async () => {
|
||||
const response = await createAccessKeyMutation.mutateAsync(userName)
|
||||
if (response.AccessKey) {
|
||||
setNewAccessKey({
|
||||
accessKeyId: response.AccessKey.AccessKeyId ?? "",
|
||||
secretAccessKey: response.AccessKey.SecretAccessKey ?? "",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleToggleAccessKey = async (key: AccessKeyMetadata) => {
|
||||
if (!key.AccessKeyId) {
|
||||
return
|
||||
}
|
||||
setPendingKeyAction(key.AccessKeyId)
|
||||
try {
|
||||
await updateAccessKeyMutation.mutateAsync({
|
||||
userName,
|
||||
accessKeyId: key.AccessKeyId,
|
||||
status: key.Status === "Active" ? "Inactive" : "Active",
|
||||
})
|
||||
} finally {
|
||||
setPendingKeyAction(null)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDeleteAccessKey = async (accessKeyId: string) => {
|
||||
setPendingKeyAction(accessKeyId)
|
||||
try {
|
||||
await deleteAccessKeyMutation.mutateAsync({ userName, accessKeyId })
|
||||
} finally {
|
||||
setPendingKeyAction(null)
|
||||
}
|
||||
}
|
||||
|
||||
const handleAttachPolicy = async (policyArn: string) => {
|
||||
await attachPolicyMutation.mutateAsync({ userName, policyArn })
|
||||
setShowAttachSelect(false)
|
||||
}
|
||||
|
||||
const handleDetachPolicy = async (policyArn: string) => {
|
||||
setPendingPolicyAction(policyArn)
|
||||
try {
|
||||
await detachPolicyMutation.mutateAsync({ userName, policyArn })
|
||||
} finally {
|
||||
setPendingPolicyAction(null)
|
||||
}
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return (
|
||||
<>
|
||||
<BackLink to="/iam/list-users">Back to users</BackLink>
|
||||
<p className="text-muted-foreground">User not found.</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<BackLink to="/iam/list-users">Back to users</BackLink>
|
||||
|
||||
{deleteMutation.error && (
|
||||
<ErrorBanner error={deleteMutation.error} msg="Failed to delete user" />
|
||||
)}
|
||||
{createAccessKeyMutation.error && (
|
||||
<ErrorBanner
|
||||
error={createAccessKeyMutation.error}
|
||||
msg="Failed to create access key"
|
||||
/>
|
||||
)}
|
||||
{deleteAccessKeyMutation.error && (
|
||||
<ErrorBanner
|
||||
error={deleteAccessKeyMutation.error}
|
||||
msg="Failed to delete access key"
|
||||
/>
|
||||
)}
|
||||
{attachPolicyMutation.error && (
|
||||
<ErrorBanner
|
||||
error={attachPolicyMutation.error}
|
||||
msg="Failed to attach policy"
|
||||
/>
|
||||
)}
|
||||
{detachPolicyMutation.error && (
|
||||
<ErrorBanner
|
||||
error={detachPolicyMutation.error}
|
||||
msg="Failed to detach policy"
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="space-y-6">
|
||||
<PageHeading
|
||||
actions={
|
||||
<Button
|
||||
onClick={() => setShowDeleteDialog(true)}
|
||||
size="sm"
|
||||
variant="destructive"
|
||||
>
|
||||
<Trash2 className="size-4" />
|
||||
Delete
|
||||
</Button>
|
||||
}
|
||||
subtitle="IAM User Details"
|
||||
title={user.UserName ?? ""}
|
||||
/>
|
||||
|
||||
<DetailCard>
|
||||
<DetailCard.Header>User Information</DetailCard.Header>
|
||||
<DetailCard.Content>
|
||||
<DetailRow label="User Name" value={user.UserName} />
|
||||
<DetailRow label="User ID" value={user.UserId} />
|
||||
<DetailRow label="ARN" value={user.Arn} />
|
||||
<DetailRow label="Path" value={user.Path} />
|
||||
<DetailRow
|
||||
label="Created"
|
||||
value={formatDateTime(user.CreateDate)}
|
||||
/>
|
||||
</DetailCard.Content>
|
||||
</DetailCard>
|
||||
|
||||
{/* Access Keys */}
|
||||
<DetailCard>
|
||||
<DetailCard.Header>
|
||||
<div className="flex items-center justify-between">
|
||||
<span>Access Keys</span>
|
||||
<Button
|
||||
disabled={createAccessKeyMutation.isPending}
|
||||
onClick={handleCreateAccessKey}
|
||||
size="sm"
|
||||
>
|
||||
{createAccessKeyMutation.isPending
|
||||
? "Creating..."
|
||||
: "Create Access Key"}
|
||||
</Button>
|
||||
</div>
|
||||
</DetailCard.Header>
|
||||
<DetailCard.Content>
|
||||
{accessKeys.length > 0 ? (
|
||||
<div className="col-span-2 space-y-3">
|
||||
{accessKeys.map((key: AccessKeyMetadata) => (
|
||||
<div
|
||||
className="flex items-center justify-between rounded-md border p-3"
|
||||
key={key.AccessKeyId}
|
||||
>
|
||||
<div className="space-y-1">
|
||||
<p className="font-mono text-sm">{key.AccessKeyId}</p>
|
||||
<p className="text-muted-foreground text-xs">
|
||||
Created {formatDateTime(key.CreateDate)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<StateBadge state={key.Status} />
|
||||
<Button
|
||||
disabled={pendingKeyAction === key.AccessKeyId}
|
||||
onClick={() => handleToggleAccessKey(key)}
|
||||
size="sm"
|
||||
variant="outline"
|
||||
>
|
||||
{key.Status === "Active" ? "Deactivate" : "Activate"}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={pendingKeyAction === key.AccessKeyId}
|
||||
onClick={() =>
|
||||
key.AccessKeyId &&
|
||||
handleDeleteAccessKey(key.AccessKeyId)
|
||||
}
|
||||
size="sm"
|
||||
variant="destructive"
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="col-span-2 text-muted-foreground text-sm">
|
||||
No access keys.
|
||||
</p>
|
||||
)}
|
||||
</DetailCard.Content>
|
||||
</DetailCard>
|
||||
|
||||
{/* Attached Policies */}
|
||||
<DetailCard>
|
||||
<DetailCard.Header>
|
||||
<div className="flex items-center justify-between">
|
||||
<span>Attached Policies</span>
|
||||
<Button
|
||||
onClick={() => setShowAttachSelect(!showAttachSelect)}
|
||||
size="sm"
|
||||
>
|
||||
Attach Policy
|
||||
</Button>
|
||||
</div>
|
||||
</DetailCard.Header>
|
||||
<DetailCard.Content>
|
||||
{showAttachSelect && availablePolicies.length > 0 && (
|
||||
<div className="col-span-2 space-y-2 rounded-md border p-3">
|
||||
<p className="font-medium text-sm">
|
||||
Select a policy to attach:
|
||||
</p>
|
||||
<div className="space-y-1">
|
||||
{availablePolicies.map((policy) => (
|
||||
<button
|
||||
className="flex w-full items-center justify-between rounded-md p-2 text-left text-sm hover:bg-accent"
|
||||
disabled={attachPolicyMutation.isPending}
|
||||
key={policy.Arn}
|
||||
onClick={() =>
|
||||
policy.Arn && handleAttachPolicy(policy.Arn)
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<span>{policy.PolicyName}</span>
|
||||
<span className="text-muted-foreground text-xs">
|
||||
{policy.Arn}
|
||||
</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{showAttachSelect && availablePolicies.length === 0 && (
|
||||
<p className="col-span-2 text-muted-foreground text-sm">
|
||||
No policies available to attach.
|
||||
</p>
|
||||
)}
|
||||
{attachedPolicies.length > 0 ? (
|
||||
<div className="col-span-2 space-y-3">
|
||||
{attachedPolicies.map((policy: AttachedPolicy) => (
|
||||
<div
|
||||
className="flex items-center justify-between rounded-md border p-3"
|
||||
key={policy.PolicyArn}
|
||||
>
|
||||
<div className="space-y-1">
|
||||
<p className="font-medium text-sm">{policy.PolicyName}</p>
|
||||
<p className="text-muted-foreground text-xs">
|
||||
{policy.PolicyArn}
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
disabled={pendingPolicyAction === policy.PolicyArn}
|
||||
onClick={() =>
|
||||
policy.PolicyArn && handleDetachPolicy(policy.PolicyArn)
|
||||
}
|
||||
size="sm"
|
||||
variant="outline"
|
||||
>
|
||||
Detach
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="col-span-2 text-muted-foreground text-sm">
|
||||
No attached policies.
|
||||
</p>
|
||||
)}
|
||||
</DetailCard.Content>
|
||||
</DetailCard>
|
||||
</div>
|
||||
|
||||
{/* Delete Confirmation Dialog */}
|
||||
<AlertDialog onOpenChange={setShowDeleteDialog} open={showDeleteDialog}>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Delete User</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
Are you sure you want to delete the user "{userName}"? This action
|
||||
cannot be undone. You must detach all policies and delete all
|
||||
access keys first.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
disabled={deleteMutation.isPending}
|
||||
onClick={handleDelete}
|
||||
>
|
||||
{deleteMutation.isPending ? "Deleting..." : "Delete"}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
||||
{/* Access Key Secret Modal */}
|
||||
{newAccessKey && (
|
||||
<AccessKeyModal
|
||||
accessKeyId={newAccessKey.accessKeyId}
|
||||
onClose={() => setNewAccessKey(null)}
|
||||
secretAccessKey={newAccessKey.secretAccessKey}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import type { User } from "@aws-sdk/client-iam"
|
||||
import { useSuspenseQuery } from "@tanstack/react-query"
|
||||
import { createFileRoute, Link } from "@tanstack/react-router"
|
||||
|
||||
import { ListCard } from "@/components/list-card"
|
||||
import { PageHeading } from "@/components/page-heading"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { formatDateTime } from "@/lib/utils"
|
||||
import { iamUsersQueryOptions } from "@/queries/iam"
|
||||
|
||||
export const Route = createFileRoute("/_auth/iam/(users)/list-users/")({
|
||||
loader: async ({ context }) => {
|
||||
await context.queryClient.ensureQueryData(iamUsersQueryOptions)
|
||||
},
|
||||
head: () => ({
|
||||
meta: [{ title: "Users | IAM | Mulga" }],
|
||||
}),
|
||||
component: Users,
|
||||
})
|
||||
|
||||
function Users() {
|
||||
const { data } = useSuspenseQuery(iamUsersQueryOptions)
|
||||
|
||||
const users = (data.Users || []).toSorted((a, b) => {
|
||||
const nameA = a.UserName?.toLowerCase() ?? ""
|
||||
const nameB = b.UserName?.toLowerCase() ?? ""
|
||||
return nameA.localeCompare(nameB)
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeading
|
||||
actions={
|
||||
<Link to="/iam/create-user">
|
||||
<Button>Create User</Button>
|
||||
</Link>
|
||||
}
|
||||
title="IAM Users"
|
||||
/>
|
||||
|
||||
{users.length > 0 ? (
|
||||
<div className="space-y-4">
|
||||
{users.map((user: User) => {
|
||||
if (!user.UserName) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<ListCard
|
||||
key={user.UserName}
|
||||
params={{ userName: user.UserName }}
|
||||
subtitle={`${user.UserId} • ${user.Path ?? "/"} • Created ${formatDateTime(user.CreateDate)}`}
|
||||
title={user.UserName}
|
||||
to="/iam/list-users/$userName"
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-muted-foreground">No IAM users found.</p>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
import { AlertTriangle, Check } from "lucide-react"
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogMedia,
|
||||
AlertDialogTitle,
|
||||
} from "@/components/ui/alert-dialog"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
const COPY_FEEDBACK_DURATION_MS = 2000
|
||||
|
||||
interface AccessKeyModalProps {
|
||||
onClose: () => void
|
||||
accessKeyId: string
|
||||
secretAccessKey: string
|
||||
}
|
||||
|
||||
export function AccessKeyModal({
|
||||
onClose,
|
||||
accessKeyId,
|
||||
secretAccessKey,
|
||||
}: AccessKeyModalProps) {
|
||||
const [copied, setCopied] = useState(false)
|
||||
const timerRef = useRef<ReturnType<typeof setTimeout>>(null)
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleCopy = async () => {
|
||||
const text = `Access Key ID: ${accessKeyId}\nSecret Access Key: ${secretAccessKey}`
|
||||
await navigator.clipboard.writeText(text)
|
||||
setCopied(true)
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current)
|
||||
}
|
||||
timerRef.current = setTimeout(
|
||||
() => setCopied(false),
|
||||
COPY_FEEDBACK_DURATION_MS,
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<AlertDialog open>
|
||||
<AlertDialogContent className="max-w-2xl">
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogMedia>
|
||||
<AlertTriangle className="text-destructive" />
|
||||
</AlertDialogMedia>
|
||||
<AlertDialogTitle>Save Your Access Key</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This is your only chance to view the secret access key. Please copy
|
||||
it now. You won't be able to retrieve it again.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="space-y-2 rounded-md border p-4 font-mono text-sm">
|
||||
<div>
|
||||
<span className="text-muted-foreground">Access Key ID: </span>
|
||||
{accessKeyId}
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-muted-foreground">Secret Access Key: </span>
|
||||
{secretAccessKey}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
className="w-full"
|
||||
onClick={handleCopy}
|
||||
type="button"
|
||||
variant="outline"
|
||||
>
|
||||
{copied ? (
|
||||
<>
|
||||
<Check className="mr-2 size-4" />
|
||||
Copied!
|
||||
</>
|
||||
) : (
|
||||
"Copy to Clipboard"
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel onClick={onClose}>
|
||||
Close and Continue
|
||||
</AlertDialogCancel>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
)
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
interface PolicyDocumentViewerProps {
|
||||
document: string
|
||||
}
|
||||
|
||||
export function PolicyDocumentViewer({ document }: PolicyDocumentViewerProps) {
|
||||
let formatted: string
|
||||
try {
|
||||
formatted = JSON.stringify(JSON.parse(document), null, 2)
|
||||
} catch {
|
||||
formatted = document
|
||||
}
|
||||
|
||||
return (
|
||||
<pre className="overflow-auto rounded-md border bg-muted p-4 font-mono text-sm">
|
||||
{formatted}
|
||||
</pre>
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import { DescribeInstancesCommand } from "@aws-sdk/client-ec2"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { createFileRoute, redirect, useNavigate } from "@tanstack/react-router"
|
||||
import { useState } from "react"
|
||||
import { useForm } from "react-hook-form"
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
@@ -14,9 +16,11 @@ import { Input } from "@/components/ui/input"
|
||||
import {
|
||||
type AwsCredentials,
|
||||
awsCredentialsSchema,
|
||||
clearCredentials,
|
||||
getCredentials,
|
||||
setCredentials,
|
||||
} from "@/lib/auth"
|
||||
import { clearClients, getEc2Client } from "@/lib/awsClient"
|
||||
|
||||
export const Route = createFileRoute("/login")({
|
||||
beforeLoad: () => {
|
||||
@@ -29,6 +33,7 @@ export const Route = createFileRoute("/login")({
|
||||
|
||||
function LoginPage() {
|
||||
const navigate = useNavigate()
|
||||
const [authError, setAuthError] = useState<string | null>(null)
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
@@ -37,9 +42,21 @@ function LoginPage() {
|
||||
resolver: zodResolver(awsCredentialsSchema),
|
||||
})
|
||||
|
||||
function onSubmit(data: AwsCredentials) {
|
||||
async function onSubmit(data: AwsCredentials) {
|
||||
setAuthError(null)
|
||||
// Clear cached clients so the new creds are picked up
|
||||
clearClients()
|
||||
setCredentials(data)
|
||||
navigate({ to: "/" })
|
||||
try {
|
||||
await getEc2Client().send(new DescribeInstancesCommand({}))
|
||||
navigate({ to: "/" })
|
||||
} catch {
|
||||
clearCredentials()
|
||||
clearClients()
|
||||
setAuthError(
|
||||
"Invalid credentials. Please check your Access Key ID and Secret Access Key.",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -49,6 +66,11 @@ function LoginPage() {
|
||||
<CardTitle>AWS Credentials</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{authError && (
|
||||
<p className="mb-4 rounded-md bg-destructive/10 p-3 text-destructive text-sm">
|
||||
{authError}
|
||||
</p>
|
||||
)}
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<FieldGroup>
|
||||
<Field>
|
||||
@@ -79,7 +101,7 @@ function LoginPage() {
|
||||
<FieldError errors={[errors.secretAccessKey]} />
|
||||
</Field>
|
||||
<Button className="w-full" disabled={isSubmitting} type="submit">
|
||||
Sign In
|
||||
{isSubmitting ? "Signing in..." : "Sign In"}
|
||||
</Button>
|
||||
</FieldGroup>
|
||||
</form>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const createUserSchema = z.object({
|
||||
userName: z
|
||||
.string()
|
||||
.min(1, "User name is required")
|
||||
.max(64, "User name must be 64 characters or less")
|
||||
.regex(/^[\w+=,.@-]+$/, "User name contains invalid characters"),
|
||||
path: z.string().optional(),
|
||||
})
|
||||
|
||||
export type CreateUserFormData = z.infer<typeof createUserSchema>
|
||||
|
||||
export const createPolicySchema = z.object({
|
||||
policyName: z
|
||||
.string()
|
||||
.min(1, "Policy name is required")
|
||||
.max(128, "Policy name must be 128 characters or less"),
|
||||
description: z.string().optional(),
|
||||
policyDocument: z
|
||||
.string()
|
||||
.min(1, "Policy document is required")
|
||||
.refine(
|
||||
(val) => {
|
||||
try {
|
||||
JSON.parse(val)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
},
|
||||
{ message: "Policy document must be valid JSON" },
|
||||
),
|
||||
})
|
||||
|
||||
export type CreatePolicyFormData = z.infer<typeof createPolicySchema>
|
||||
|
||||
export interface DeleteAccessKeyParams {
|
||||
userName: string
|
||||
accessKeyId: string
|
||||
}
|
||||
|
||||
export interface UpdateAccessKeyParams {
|
||||
userName: string
|
||||
accessKeyId: string
|
||||
status: "Active" | "Inactive"
|
||||
}
|
||||
|
||||
export interface UserPolicyParams {
|
||||
userName: string
|
||||
policyArn: string
|
||||
}
|
||||
Reference in New Issue
Block a user