/
snap
/
lxd
/
current
/
share
/
lxd-ui
/
assets
/
File Upload :
llllll
Current File: //snap/lxd/current/share/lxd-ui/assets/StorageVolumeDetail-BvWcmzzS.js
import{r as V,j as e,d as n,t as R,l as v,c as q,v as O,n as U,R as E,q as F,d2 as Z,G as D,b as ee,i as T,a_ as re,F as te,aF as le,d1 as ce,f as Q,g as P,Y as de,d3 as H,aO as pe,am as me,y as ue,aQ as he,bv as ge,L as xe,cc as fe,bu as je,ap as z,T as be,p as K,c6 as oe,V as Y,aC as ye,aD as Se,aj as B,al as Ce,c7 as G,A as Ne,aJ as Fe,e as Ve}from"./index-B3cgCbnJ.js";import{R as ke}from"./RenameHeader-7HM7rJrm.js";import{m as we,i as Re,j as _e,r as Ie,k as se}from"./storage-volumes-BlpH9Ab1.js";import{u as L,D as $e}from"./DeleteStorageVolumeBtn-BmZXpQg5.js";import{S as Le}from"./StoragePoolSelectTable-BX9Dyx5x.js";import{V as w}from"./VolumeLinkChip-BLlXdIjS.js";import{c as Ee,g as Pe,i as ve}from"./snapshots-Bt9cFkFc.js";import{S as De}from"./StoragePoolSelector-_Ij9bIB_.js";import{a as Te,c as Be}from"./useVolumes-BGHjBnNk.js";import{C as Ue}from"./ClusterMemberSelector-iA98KA1k.js";import{u as ze}from"./projects-9DerJg4m.js";import{S as Me}from"./StorageUsedBy-CGXxcZ7s.js";import{S as qe,g as Oe,u as Ke,a as A,r as Ae,b as Qe,d as He,c as Ye,V as J,f as Ge}from"./VolumeAddSnapshotBtn-ChHAMGeq.js";import{v as ne,a as Je,M as W,b as We}from"./StorageVolumeForm-0OnQ0JYw.js";import{F as Xe}from"./FormFooterLayout-ChlQYZN0.js";import{F as Ze}from"./FormSubmitBtn-CI9Q_IyH.js";import{T as et}from"./TabLinks-BN40EEc5.js";import{S as tt}from"./SnapshotForm-D7tEadHd.js";import{I as ot}from"./ItemName-B_MTAAB6.js";import{S as st}from"./SelectableMainTable-CTM3_-pn.js";import{S as nt}from"./SelectedTableNotification-BBOESV7i.js";import{B as at}from"./BulkDeleteButton-CR5M7boY.js";import{u as it}from"./useBulkDetails-Bdf_X4A0.js";import{u as rt}from"./useSortTableData-DogFPcVj.js";import"./StoragePoolSize-34u3KM6q.js";import"./Meter-v0AAwaqr.js";import"./StoragePoolClusterMember-C_lGzG9t.js";import"./images-CA6qXE8n.js";import"./ExpandableList-DwC4iUKg.js";import"./UsedByItem-BtsI6fTe.js";import"./storageBucket-Ct9MZnMG.js";import"./FormMenuItem-BwEOqt61.js";import"./limits-CLEFMbq-.js";import"./AutoExpandingTextArea-BmFqLvbw.js";import"./scroll-BEbDVMxI.js";import"./instanceOptions-D4bz_1Ev.js";import"./ConfigFieldDescription-C9KDhW5s.js";import"./DiskSizeSelector-CIkNkBL4.js";const lt=({close:t,migrate:o,storageVolume:c})=>{const[r,p]=V.useState(""),d=j=>{j.key==="Escape"&&t()},m=()=>{if(r){p("");return}t()},i=r?"Confirm migration":`Choose storage pool for volume ${c.name}`,h=e.jsx("div",{className:"migrate-instance-summary",children:e.jsxs("p",{children:["This will migrate volume ",e.jsx("strong",{children:c.name})," to storage pool ",e.jsx("b",{children:r}),"."]})});return e.jsx(n.Modal,{close:t,className:"migrate-instance-modal",title:i,buttonRow:e.jsxs("div",{id:"migrate-instance-actions",children:[e.jsx(n.Button,{className:"u-no-margin--bottom",type:"button","aria-label":"cancel migrate",appearance:"base",onClick:m,children:"Cancel"}),e.jsx(n.ActionButton,{appearance:"positive",className:"u-no-margin--bottom",onClick:()=>{o(r)},disabled:!r,children:"Migrate"})]}),onKeyDown:d,children:r?h:e.jsx(Le,{onSelect:p,disablePool:{name:c.pool,reason:"Volume is already in this pool"}})})},ct=({volume:t,project:o,classname:c,onClose:r})=>{const p=R(),d=n.useToastNotification(),{openPortal:m,closePortal:i,isOpen:h,Portal:j}=n.usePortal(),f=v(),x=q(),[g,l]=V.useState(!1),{canEditVolume:a}=L(),s=(N,C)=>{const b=Z(t)?`/member/${encodeURIComponent(t.location)}`:"",I=`/ui/project/${encodeURIComponent(C.project)}/storage/pool/${encodeURIComponent(C.pool)}${b}/volumes/${encodeURIComponent(C.type)}/${encodeURIComponent(C.name)}`,$=`/ui/project/${encodeURIComponent(C.project)}/storage/pool/${encodeURIComponent(N)}${b}/volumes/${encodeURIComponent(C.type)}/${encodeURIComponent(C.name)}`,ae=e.jsx(E,{type:"volume",value:C.name,to:$}),ie=e.jsx(E,{type:"pool",value:N,to:`/ui/project/${encodeURIComponent(C.project)}/storage/pool/${encodeURIComponent(N)}`});d.success(e.jsxs(e.Fragment,{children:["Volume ",ae," successfully migrated to pool ",ie]})),window.location.pathname.startsWith(I)&&x($)},u=(N,C,b)=>{l(!1),d.failure(`Migration failed for volume ${C} to pool ${b}`,N,e.jsx(w,{volume:t}))},S=(N,C,b)=>{u(new Error(N),C,b)},y=()=>{f.invalidateQueries({queryKey:[F.storage,t.name]}),l(!1)},k=N=>{l(!0),we(t,N,t.project,t.location).then(C=>{p.set(C.metadata.id,()=>{s(N,t)},$=>{S($,t.name,N)},y);const b=e.jsx(U,{bold:!0,type:"volume",value:t.name}),I=e.jsx(E,{type:"pool",value:N,to:`/ui/project/${encodeURIComponent(t.project)}/storage/pool/${encodeURIComponent(N)}`});d.info(e.jsxs(e.Fragment,{children:["Migration started for volume ",b," to pool ",I]})),f.invalidateQueries({queryKey:[F.storage,t.name,o]})}).catch(C=>{u(C,t.name,N)}).finally(()=>{_()})},_=()=>{i(),r==null||r()};return e.jsxs(e.Fragment,{children:[h&&e.jsx(j,{children:e.jsx(lt,{close:_,migrate:k,storageVolume:t})}),e.jsxs(n.ActionButton,{onClick:m,type:"button",className:O("u-no-margin--bottom has-icon",c),loading:g,disabled:!a(t)||g,title:a(t)?"Migrate volume":"You do not have permission to migrate this volume",children:[e.jsx(n.Icon,{name:"machines"}),e.jsx("span",{children:"Migrate"})]})]})},dt=({volume:t,close:o})=>{var g;const c=R(),r=n.useToastNotification(),p=e.jsx(w,{volume:t}),{hasBackupMetadataVersion:d}=D(),{data:m}=ee(),i=((g=m==null?void 0:m.environment)==null?void 0:g.backup_metadata_version_range)??[],h=l=>{const a=new URLSearchParams;a.set("project",t.project),re(a,t.location);const s=`/1.0/storage-pools/${encodeURIComponent(t.pool)}/volumes/${encodeURIComponent(t.type)}/${encodeURIComponent(t.name)}/backups/${encodeURIComponent(l)}/export?${a.toString()}`,u=document.createElement("a");u.href=s,u.download=l,u.click(),window.URL.revokeObjectURL(s),r.success(e.jsxs(e.Fragment,{children:["Volume ",p," download started:",e.jsx("br",{}),e.jsx("a",{href:s,children:l})]}))},j=l=>{const a=new Date;return a.setHours(a.getHours()+l),a},f=l=>{const a=new Date().toISOString().replaceAll(":","-").split(".")[0],s=`${t.name}-${a}.tar${l.compression==="gzip"?".gz":""}`,u=JSON.stringify({name:s,expires_at:j(l.expirationHours).toISOString(),compression_algorithm:l.compression,volume_only:l.volumeOnly,optimized_storage:l.optimizedStorage,version:d?Number(l.exportVersion):void 0});Re(t,u).then(S=>{r.info(e.jsxs(e.Fragment,{children:["Backing up volume ",p,".",e.jsx("br",{}),"Download will start, when the export is ready."]})),c.set(S.metadata.id,()=>{h(s)},y=>r.failure(`Could not download volume ${t.name}`,new Error(y),p))}).catch(S=>r.failure(`Could not download volume ${t.name}`,S,p)).finally(()=>{o()})},x=T({initialValues:{compression:"gzip",exportVersion:"2",expirationHours:6,volumeOnly:!1,optimizedStorage:!0},onSubmit:l=>{f(l)}});return e.jsx(n.Modal,{close:o,className:"export-volume-modal",title:"Export Volume",buttonRow:e.jsxs(e.Fragment,{children:[e.jsx(n.Button,{appearance:"base",className:"u-no-margin--bottom",type:"button",onClick:o,children:"Cancel"}),e.jsx(n.ActionButton,{appearance:"positive",className:"u-no-margin--bottom",loading:x.isSubmitting,disabled:x.isSubmitting,onClick:()=>void x.submitForm(),children:"Export volume"})]}),children:e.jsxs(n.Form,{onSubmit:x.handleSubmit,children:[e.jsx(n.Select,{...x.getFieldProps("compression"),id:"project",label:"Compression",help:"No compression will be faster, but larger",options:[{value:"gzip",label:"Gzip"},{value:"none",label:"None"}]}),e.jsx(n.Select,{...x.getFieldProps("expirationHours"),id:"project",label:"Expiration",help:"Duration that the backup remains on the server",options:[{value:1,label:"1 hour"},{value:6,label:"6 hours"},{value:12,label:"12 hours"},{value:24,label:"1 day"},{value:72,label:"3 days"},{value:168,label:"7 days"}]}),d&&e.jsx(n.Select,{...x.getFieldProps("exportVersion"),id:"exportVersion",label:"Export version",help:"Lower versions allow imports on older LXD versions",options:i.map(l=>({value:l.toString(),label:l.toString()}))}),e.jsx(n.Input,{...x.getFieldProps("optimizedStorage"),type:"checkbox",label:"Use storage driver optimized format",help:"Can only be restored on a similar pool",checked:x.values.optimizedStorage}),e.jsx(n.Input,{...x.getFieldProps("volumeOnly"),type:"checkbox",label:"Export without volume snapshots",error:x.touched.volumeOnly?x.errors.volumeOnly:null,checked:x.values.volumeOnly}),e.jsx(n.Input,{type:"submit",hidden:!0,value:"Hidden input"})]})})},pt=({volume:t,classname:o,onClose:c})=>{const{openPortal:r,closePortal:p,isOpen:d,Portal:m}=n.usePortal(),{canManageVolumeBackups:i}=L(),{project:h}=te(),j=Ee(h),f=()=>{p(),c==null||c()},x=()=>i(t)?j?`Project "${h==null?void 0:h.name}" doesn't allow for backup creation.`:"Export volume":"You do not have permission to export this volume.";return e.jsxs(e.Fragment,{children:[d&&e.jsx(m,{children:e.jsx(dt,{close:f,volume:t})}),e.jsxs(n.Button,{appearance:"default",className:O("u-no-margin--bottom has-icon",o),onClick:r,title:x(),disabled:!i(t)||j,children:[e.jsx(n.Icon,{name:"export"}),e.jsx("span",{children:"Export"})]})]})},mt=({volume:t,close:o})=>{const c=n.useToastNotification(),r=V.useState(null),p=R(),{data:d=[],isLoading:m}=le(),{data:i}=ce(t.pool),{data:h=[],isLoading:j}=Te(t.project),f=s=>{const u={...t,name:s.name,project:s.project,pool:s.pool,location:s.location};c.success(e.jsxs(e.Fragment,{children:["Created volume ",e.jsx(w,{volume:u}),"."]}))},x=s=>{c.failure("Volume copy failed.",s,e.jsx(w,{volume:t}))},g=s=>{const u=s.name+"-copy";return pe(u,h)},l=Q().shape({name:P().required("Volume name is required"),project:P().required(),pool:P().required(),location:P().optional()}).test("deduplicate","",async function(s){const{name:u,project:S,pool:y,location:k}=s;return await de(u,S||"default",r,`storage-pools/${encodeURIComponent(y)}/volumes/custom`,k)?!0:this.createError({path:"name",message:"A volume with this name already exist in the target project and storage pool"})}),a=T({initialValues:{name:g(t),project:t.project,copySnapshots:!0,pool:t.pool,location:H((i==null?void 0:i.driver)??"")?"":t.location},enableReinitialize:!0,validationSchema:l,onSubmit:s=>{const u={name:s.name,type:"custom",config:t.config,description:t.description,content_type:t.content_type,source:{name:t.name,type:"copy",pool:t.pool,volume_only:!s.copySnapshots,project:s.project!==t.project?t.project:void 0,location:t.location}};_e(u,s.pool,s.project,s.location).then(S=>{c.info(e.jsxs(e.Fragment,{children:["Copy of volume ",e.jsx(w,{volume:t})," started."]})),p.set(S.metadata.id,()=>{f(s)},y=>{x(new Error(y))})}).catch(S=>{c.failure("Volume copy failed.",S)}).finally(()=>{o()})}});return e.jsx(n.Modal,{close:o,className:"copy-volumes-modal",title:"Copy volume",buttonRow:e.jsxs(e.Fragment,{children:[e.jsx(n.Button,{appearance:"base",className:"u-no-margin--bottom",type:"button",onClick:o,children:"Cancel"}),e.jsx(n.ActionButton,{appearance:"positive",className:"u-no-margin--bottom",loading:a.isSubmitting,disabled:!a.isValid||a.isSubmitting||m||j,onClick:()=>void a.submitForm(),children:"Copy"})]}),children:e.jsxs(n.Form,{onSubmit:a.handleSubmit,children:[e.jsx(n.Input,{...a.getFieldProps("name"),type:"text",label:"New volume name",error:a.touched.name?a.errors.name:null}),e.jsx(De,{value:a.values.pool,setValue:s=>void a.setFieldValue("pool",s),selectProps:{id:"pool",label:"Storage pool"}}),!H((i==null?void 0:i.driver)??"")&&e.jsx(Ue,{...a.getFieldProps("location")}),e.jsx(n.Select,{...a.getFieldProps("project"),id:"project",label:"Target project",options:d.map(s=>({label:s.name,value:s.name}))}),e.jsx(n.Input,{...a.getFieldProps("copySnapshots"),type:"checkbox",label:"Copy with snapshots",checked:a.values.copySnapshots,error:a.touched.copySnapshots?a.errors.copySnapshots:null}),e.jsx(n.Input,{type:"submit",hidden:!0,value:"Hidden input"})]})})},ut=({volume:t,classname:o,onClose:c})=>{const{openPortal:r,closePortal:p,isOpen:d,Portal:m}=n.usePortal(),{canCreateStorageVolumes:i}=ze(),{data:h}=me(t.project),j=()=>{p(),c==null||c()};return e.jsxs(e.Fragment,{children:[d&&e.jsx(m,{children:e.jsx(mt,{close:j,volume:t})}),e.jsxs(n.Button,{appearance:"default","aria-label":"Copy volume",className:O("u-no-margin--bottom has-icon",o),onClick:r,title:i(h)?"Copy volume":"You do not have permission to copy this volume",disabled:!i(h),children:[e.jsx(n.Icon,{name:"canvas"}),e.jsx("span",{children:"Copy"})]})]})},ht=({volume:t,project:o})=>{const c=ue(he),{hasClusterInternalCustomVolumeCopy:r}=D(),p=q(),d=n.useToastNotification(),m=c?"p-contextual-menu__link":"p-segmented-control__button",i=[e.jsx(ct,{volume:t,project:o,classname:m},"migrate"),...r?[e.jsx(ut,{volume:t,classname:m},"copy")]:[],e.jsx(pt,{volume:t,classname:m},"export"),e.jsx($e,{label:"Delete",volume:t,project:o,appearance:"",hasIcon:!0,onFinish:()=>{p(`/ui/project/${encodeURIComponent(o)}/storage/volumes`),d.success(e.jsxs(e.Fragment,{children:["Storage volume"," ",e.jsx(U,{bold:!0,type:"volume",value:t.name})," deleted."]}))},classname:m},"delete")];return e.jsx(e.Fragment,{children:c?e.jsx(n.ContextualMenu,{closeOnOutsideClick:!1,toggleLabel:"Actions",position:"left",hasToggleIcon:!0,title:"actions",children:h=>e.jsx("span",{children:[...i].map(j=>V.cloneElement(j,{onClose:h}))})}):e.jsx("div",{className:"p-segmented-control",children:e.jsx("div",{className:"p-segmented-control__list",children:i})})})},gt=({volume:t,project:o})=>{const c=q(),r=n.useNotify(),p=n.useToastNotification(),d=V.useState(null),{canEditVolume:m}=L(),i=R(),{hasStorageAndProfileOperations:h}=D(),j=s=>{var u;if((((u=s.used_by)==null?void 0:u.length)??0)>0)return"Can not rename, volume is currently in use.";if(!m(s))return"You do not have permission to rename this volume"},f=Q().shape({name:P().test(...ge(o,t.type,d,t)).required("This field is required")}),x=s=>{const u=Z(t)?`/ui/project/${encodeURIComponent(o)}/storage/pool/${encodeURIComponent(t.pool)}/member/${encodeURIComponent(t.location)}/volumes/${encodeURIComponent(t.type)}/${encodeURIComponent(s.name)}`:`/ui/project/${encodeURIComponent(o)}/storage/pool/${encodeURIComponent(t.pool)}/volumes/${encodeURIComponent(t.type)}/${encodeURIComponent(s.name)}`;c(u),p.success(e.jsxs(e.Fragment,{children:["Storage volume ",e.jsx("strong",{children:t.name})," renamed to"," ",e.jsx(E,{type:"volume",value:s.name,to:u}),"."]})),a.setFieldValue("isRenaming",!1)},g=s=>{r.failure("Renaming failed",s)},l=()=>{a.setSubmitting(!1)},a=T({initialValues:{name:t.name,isRenaming:!1},validationSchema:f,onSubmit:s=>{if(t.name===s.name){a.setFieldValue("isRenaming",!1),a.setSubmitting(!1);return}Ie(o,t,s.name,t.location).then(u=>{h?i.set(u.metadata.id,()=>{x(s)},S=>{g(new Error(S))},l):(x(s),l())}).catch(g)}});return e.jsx(ke,{name:t.name,parentItems:[e.jsx(xe,{to:`/ui/project/${encodeURIComponent(o)}/storage/volumes`,children:"Storage volumes"},1)],controls:t?e.jsx(ht,{project:o,volume:t}):null,isLoaded:!0,formik:a,renameDisabledReason:j(t)})},xt=({project:t,volume:o})=>{var p,d;const c=()=>{be("storage-overview-tab")};V.useEffect(c,[o]),n.useListener(window,c,"resize",!0);const{data:r}=ee();return e.jsxs("div",{className:"storage-overview-tab",children:[e.jsxs(n.Row,{className:"section",children:[e.jsx(n.Col,{size:3,children:e.jsx("h2",{className:"p-heading--5",children:"General"})}),e.jsx(n.Col,{size:7,children:e.jsx("table",{children:e.jsxs("tbody",{children:[e.jsxs("tr",{children:[e.jsx("th",{className:"u-text--muted",children:"Name"}),e.jsx("td",{children:o.name})]}),e.jsxs("tr",{children:[e.jsx("th",{className:"u-text--muted",children:"Type"}),e.jsx("td",{children:fe(o)})]}),e.jsxs("tr",{children:[e.jsx("th",{className:"u-text--muted",children:"Content type"}),e.jsx("td",{children:je(o)})]}),e.jsxs("tr",{children:[e.jsx("th",{className:"u-text--muted",children:"Description"}),e.jsx("td",{children:o.description?o.description:"-"})]}),e.jsxs("tr",{children:[e.jsx("th",{className:"u-text--muted",children:"Cluster member"}),e.jsx("td",{children:(p=r==null?void 0:r.environment)!=null&&p.server_clustered&&o.location?e.jsx(E,{type:"cluster-member",value:o.location,to:`/ui/cluster/member/${encodeURIComponent(o.location)}`}):"-"})]}),e.jsxs("tr",{children:[e.jsx("th",{className:"u-text--muted",children:"Pool"}),e.jsx("td",{children:e.jsx(E,{type:"pool",value:o.pool,to:`/ui/project/${encodeURIComponent(o.project)}/storage/pool/${encodeURIComponent(o.pool)}`})})]}),e.jsxs("tr",{children:[e.jsx("th",{className:"u-text--muted",children:"Date created"}),e.jsx("td",{children:z(o.created_at)})]}),e.jsxs("tr",{children:[e.jsx("th",{className:"u-text--muted",children:"Size"}),e.jsx("td",{children:e.jsx(qe,{volume:o})})]}),e.jsxs("tr",{children:[e.jsx("th",{className:"u-text--muted",children:"Custom config"}),e.jsx("td",{children:Object.entries(o.config).length===0?"-":e.jsx("table",{children:e.jsx("tbody",{children:Object.entries(o.config).map(([m,i],h)=>e.jsxs("tr",{children:[e.jsx("th",{className:"u-text--muted",children:m}),e.jsx("td",{children:i})]},h))})})})]})]})})})]}),e.jsxs(n.Row,{className:"section",children:[e.jsx(n.Col,{size:3,children:e.jsxs("h2",{className:"p-heading--5",children:["Used by (",((d=o.used_by)==null?void 0:d.length)??0,")"]})}),e.jsx(n.Col,{size:7,children:e.jsx(Me,{storage:o,project:t})})]})]})},M=(t,o)=>({name:t.name,project:t.project,pool:t.pool,size:t.config.size??"GiB",content_type:t.content_type,volumeType:t.type,security_shifted:t.config["security.shifted"],security_unmapped:t.config["security.unmapped"],snapshots_expiry:t.config["snapshots.expiry"],snapshots_pattern:t.config["snapshots.pattern"],snapshots_schedule:t.config["snapshots.schedule"],block_filesystem:t.config["block.filesystem"],block_mount_options:t.config["block.mount_options"],block_type:t.config["block.type"],zfs_blocksize:t.config["zfs.blocksize"],zfs_block_mode:t.config["zfs.block_mode"],zfs_delegate:t.config["zfs.delegate"],zfs_remove_snapshots:t.config["zfs.remove_snapshots"],zfs_use_refquota:t.config["zfs.use_refquota"],zfs_reserve_space:t.config["zfs.reserve_space"],readOnly:!0,isCreating:!1,entityType:"storageVolume",editRestriction:o,clusterMember:t.location}),ft=({volume:t})=>{const o=q(),c=n.useNotify(),r=n.useToastNotification(),p=v(),{section:d}=K(),{project:m}=K(),{canEditVolume:i}=L(),h=R(),{hasStorageAndProfileOperations:j}=D();if(!m)return e.jsx(e.Fragment,{children:"Missing project"});const f=Q().shape({name:P().required("This field is required")}),x=i(t)?void 0:"You do not have permission to edit this volume",g=y=>{s.setValues(M(y)),p.invalidateQueries({queryKey:[F.storage]}),p.invalidateQueries({queryKey:[F.storage,t.pool,m,y.type,y.name]}),r.success(e.jsxs(e.Fragment,{children:["Storage volume ",e.jsx(w,{volume:t})," updated."]}))},l=y=>{c.failure("Storage volume update failed",y)},a=()=>{s.setSubmitting(!1)},s=T({initialValues:M(t,x),validationSchema:f,enableReinitialize:!0,onSubmit:y=>{const k=ne(y,m,t);se(y.pool,m,{...k,etag:t.etag},t.location).then(_=>{j?h.set(_.metadata.id,()=>{g(k)},N=>{l(new Error(N))},a):(g(k),a())}).catch(l)}}),u=`${oe(t)}/configuration`,S=y=>{o(y===W?u:`${u}/${Y(y)}`)};return e.jsxs("div",{className:"edit-storage-volume",children:[e.jsx(Je,{formik:s,section:d??Y(W),setSection:S}),e.jsx(Xe,{children:s.values.readOnly?null:e.jsxs(e.Fragment,{children:[e.jsx(n.Button,{appearance:"base",onClick:async()=>s.setValues(M(t)),children:"Cancel"}),e.jsx(Ze,{formik:s,baseUrl:u,disabled:!s.values.name})]})})]})},jt=({volume:t,snapshot:o,close:c})=>{const r=R(),{hasStorageAndProfileOperations:p}=D(),d=n.useToastNotification(),m=v(),i=V.useState(null),h=async l=>new Promise((a,s)=>{Ae(t,o,l).then(u=>{r.set(u.metadata.id,()=>{a()},S=>{s(new Error(S))})}).catch(u=>{s(u)})}),[j,f]=o.expires_at?ye(new Date(o.expires_at)).slice(0,16).split(" "):[null,null],x=async l=>{let a=!0;l.name!==o.name&&await h(l.name).catch(s=>{d.failure("Snapshot update failed",s),a=!1}),a&&d.success(e.jsxs(e.Fragment,{children:["Snapshot ",e.jsx(A,{name:l.name,volume:t})," ","saved."]})),m.invalidateQueries({predicate:s=>s.queryKey[0]===F.volumes||s.queryKey[0]===F.storage}),g.setSubmitting(!1),c()},g=T({initialValues:{name:o.name,expirationDate:j,expirationTime:f},validateOnMount:!0,validationSchema:Oe(t,i,o.name),onSubmit:async l=>{const a=l.expirationDate&&l.expirationTime?Se(Pe(l.expirationDate,l.expirationTime)):null;a!==o.expires_at&&await Ke(t,o,a).then(s=>{p?r.set(s.metadata.id,()=>{x(l)},u=>{d.failure("Snapshot update failed",new Error(u))}):x(l)}).catch(s=>{d.failure("Snapshot update failed",s)})}});return e.jsx(tt,{isEdit:!0,formik:g,close:c})},bt=({volume:t,snapshot:o,isDeleting:c,isRestoring:r})=>{const{openPortal:p,closePortal:d,isOpen:m,Portal:i}=n.usePortal(),{canManageStorageVolumeSnapshots:h}=L();return e.jsxs(e.Fragment,{children:[m&&e.jsx(i,{children:e.jsx(jt,{close:d,volume:t,snapshot:o})}),e.jsx(n.Button,{appearance:"base",hasIcon:!0,dense:!0,disabled:!h(t)||c||r,onClick:p,type:"button","aria-label":"Edit snapshot",title:h(t)?"Edit":"You do not have permission to edit this snapshot",children:e.jsx(n.Icon,{name:"edit"})})]})},yt=({volume:t,snapshot:o})=>{const c=R(),r=n.useNotify(),p=n.useToastNotification(),[d,m]=V.useState(!1),[i,h]=V.useState(!1),j=v(),{canManageStorageVolumeSnapshots:f}=L(),x=a=>f(t)?`${a} snapshot`:`You do not have permission to ${a.toLowerCase()} this snapshot`,g=()=>{m(!0);const a=e.jsx(A,{name:o.name,volume:t});He(t,o).then(s=>{c.set(s.metadata.id,()=>p.success(e.jsxs(e.Fragment,{children:["Snapshot"," ",e.jsx(U,{bold:!0,type:"snapshot",value:o.name})," ","deleted for volume ",e.jsx(w,{volume:t}),"."]})),u=>p.failure(`Snapshot ${o.name} deletion failed`,new Error(u),a),()=>{m(!1),j.invalidateQueries({predicate:u=>u.queryKey[0]===F.volumes||u.queryKey[0]===F.storage})})}).catch(s=>{r.failure("Snapshot deletion failed",s,a),m(!1)})},l=()=>{h(!0),Qe(t,o).then(()=>{p.success(e.jsxs(e.Fragment,{children:["Snapshot"," ",e.jsx(A,{name:o.name,volume:t})," ","restored for volume ",e.jsx(w,{volume:t}),"."]}))}).catch(a=>{r.failure("Snapshot restore failed",a)}).finally(()=>{h(!1),j.invalidateQueries({predicate:a=>a.queryKey[0]===F.volumes||a.queryKey[0]===F.storage})})};return e.jsx(e.Fragment,{children:e.jsx(n.List,{inline:!0,className:O("u-no-margin--bottom","actions-list",{"u-snapshot-actions":!d&&!i}),items:[e.jsx(bt,{volume:t,snapshot:o,isDeleting:d,isRestoring:i},"edit"),e.jsx(n.ConfirmationButton,{appearance:"base",loading:i,className:"has-icon is-dense",title:"Confirm restore",confirmationModalProps:{title:"Confirm restore",children:e.jsxs("p",{children:["This will restore snapshot"," ",e.jsx(U,{type:"snapshot",value:o.name,bold:!0}),".",e.jsx("br",{}),"This action cannot be undone, and can result in data loss."]}),confirmButtonLabel:x("Restore"),confirmButtonAppearance:"positive",onConfirm:l},disabled:!f(t)||d||i,shiftClickEnabled:!0,showShiftClickHint:!0,children:e.jsx(n.Icon,{name:"change-version"})},"restore"),e.jsx(n.ConfirmationButton,{appearance:"base",loading:d,className:"has-icon is-dense",confirmationModalProps:{title:"Confirm delete",children:e.jsxs("p",{children:["This will permanently delete snapshot"," ",e.jsx(U,{type:"snapshot",value:o.name,bold:!0}),".",e.jsx("br",{}),"This action cannot be undone, and can result in data loss."]}),confirmButtonLabel:x("Delete"),onConfirm:g},disabled:!f(t)||d||i,shiftClickEnabled:!0,showShiftClickHint:!0,children:e.jsx(n.Icon,{name:"delete"})},"delete")]})})},St=({volume:t,snapshotNames:o,onStart:c,onFinish:r})=>{const p=R(),d=n.useToastNotification(),[m,i]=V.useState(!1),h=v(),{canManageStorageVolumeSnapshots:j}=L(),f=it(),x=o.length,g=()=>{i(!0),c(),Ye(t,o,p).then(l=>{const{fulfilledCount:a,rejectedCount:s}=Ce(l);a===x?d.success(`${o.length} ${B("snapshot",o.length)} deleted`,f(l)):s===x?d.failure("Snapshot bulk deletion failed",void 0,e.jsxs(e.Fragment,{children:[e.jsx("b",{children:x})," ",B("snapshot",x)," could not be deleted."]}),f(l)):d.failure("Snapshot bulk deletion partially failed",void 0,e.jsxs(e.Fragment,{children:[e.jsx("b",{children:a})," ",B("snapshot",a)," ","deleted.",e.jsx("br",{}),e.jsx("b",{children:s})," ",B("snapshot",s)," ","could not be deleted."]}),f(l)),h.invalidateQueries({predicate:u=>u.queryKey[0]===F.volumes||u.queryKey[0]===F.storage}),i(!1),r()}).catch(l=>{d.failure("Snapshot bulk deletion failed",l),i(!1)})};return e.jsx(at,{confirmationButtonProps:{loading:m,disabled:!j(t)||m,appearance:""},onDelete:g,entityType:"snapshot",entities:o,deletableEntities:o,buttonLabel:`Delete ${B("snapshot",o.length)}`,disabledReason:j(t)?void 0:"You do not have permission to manage snapshots for this volume"})},Ct=({volume:t,close:o})=>{const c=n.useNotify(),r=n.useToastNotification(),p=v(),d=R(),{hasStorageAndProfileOperations:m}=D(),i=()=>{r.success(e.jsxs(e.Fragment,{children:["Snapshot configuration updated for volume"," ",e.jsx(w,{volume:t}),"."]})),p.invalidateQueries({queryKey:[F.storage],predicate:g=>g.queryKey[0]===F.volumes||g.queryKey[0]===F.storage})},h=g=>{c.failure("Configuration update failed",g)},j=()=>{o(),f.setSubmitting(!1)},f=T({initialValues:M(t),onSubmit:g=>{const l=ne(g,t.project,t);se(t.pool,t.project,{...l,etag:t.etag},t.location).then(a=>{m?d.set(a.metadata.id,i,s=>{h(new Error(s))},j):(i(),j())}).catch(h)}}),x=g=>{g.key==="Escape"&&o()};return e.jsx(n.Modal,{close:o,className:"edit-snapshot-config",title:"Snapshot configuration",buttonRow:f.values.readOnly?e.jsx(n.Button,{className:"u-no-margin--bottom u-no-margin--right",onClick:o,children:"Close"}):e.jsxs(e.Fragment,{children:[e.jsx(n.Button,{appearance:"base",className:"u-no-margin--bottom",type:"button",onClick:o,children:"Cancel"}),e.jsx(n.ActionButton,{appearance:"positive",className:"u-no-margin--bottom",loading:f.isSubmitting,disabled:f.isSubmitting,onClick:()=>void f.submitForm(),children:"Save"})]}),onKeyDown:x,children:e.jsx(We,{formik:f})})},X=({volume:t,isDisabled:o,className:c})=>{const{openPortal:r,closePortal:p,isOpen:d,Portal:m}=n.usePortal(),{canEditVolume:i}=L();return e.jsxs(e.Fragment,{children:[d&&e.jsx(m,{children:e.jsx("div",{className:"snapshot-list",children:e.jsx(Ct,{close:p,volume:t})})}),e.jsx(n.Button,{onClick:r,className:c,disabled:!i(t)||o,title:i(t)?"Configure snapshot":"You do not have permission to configure this volume",children:"See configuration"})]})},Nt=({volume:t})=>{const[o,c]=V.useState(""),[r,p]=V.useState([]),[d,m]=V.useState([]),[i,h]=V.useState(G()),j=n.useNotify(),{project:f,isLoading:x}=te(),{data:g,error:l,isLoading:a}=Ne({queryKey:[F.storage,F.snapshots,t.pool,t.project,t.type,t.name,t.location],queryFn:async()=>Ge(t)}),s=ve(f);V.useEffect(()=>{const b=new Set(g==null?void 0:g.map($=>$.name)),I=r.filter($=>b.has($));I.length!==r.length&&p(I)},[g,r]);const u=(g==null?void 0:g.filter(b=>!(o&&!b.name.toLowerCase().includes(o.toLowerCase()))))??[],S=g&&g.length>0,y=[{content:i?e.jsxs(e.Fragment,{children:["Name",e.jsx("br",{}),e.jsx("div",{className:"header-second-row",children:"Date created"})]}):"Name",sortKey:i?"created_at":"name",className:"name"},...i?[]:[{content:"Date created",sortKey:"created_at",className:"created"}],{content:"Expiry date",sortKey:"expires_at",className:"expiration"},{"aria-label":"Actions",className:"actions"}],k=u.map(b=>{const I=e.jsx(yt,{volume:t,snapshot:b});return{key:b.name,className:"u-row",name:b.name,columns:[{content:e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"u-truncate",title:b.name,children:e.jsx(ot,{item:b})}),i&&e.jsx("div",{className:"u-text--muted",children:z(b.created_at)})]}),role:"rowheader","aria-label":"Name",className:"name"},...i?[]:[{content:z(b.created_at),role:"cell","aria-label":"Created at",className:"created"}],{content:z(b.expires_at??""),role:"cell","aria-label":"Expires at",className:"expiration"},{content:I,role:"cell","aria-label":"Actions",className:"u-align--right actions"}],sortData:{name:b.name.toLowerCase(),created_at:b.created_at,expires_at:b.expires_at}}}),{rows:_,updateSort:N}=rt({rows:k,defaultSort:"created_at",defaultSortDirection:"descending"}),C=()=>{h(G())};return n.useListener(window,C,"resize",!0),l&&j.failure("Loading storage volume snapshots failed",l),a||x?e.jsx(n.Spinner,{className:"u-loader",text:"Loading...",isMainComponent:!0}):g?e.jsxs("div",{className:"snapshot-list",children:[S&&e.jsx("div",{className:"upper-controls-bar",children:r.length===0?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"search-box-wrapper",children:e.jsx(n.SearchBox,{name:"search-snapshot",className:"search-box margin-right",type:"text",onChange:b=>{c(b)},placeholder:"Search for snapshots",value:o,"aria-label":"Search for snapshots"})}),e.jsx(X,{volume:t,className:"u-no-margin--right"}),e.jsx(J,{volume:t,className:"u-float-right",isDisabled:s})]}):e.jsx("div",{className:"p-panel__controls",children:e.jsx(St,{volume:t,snapshotNames:r,onStart:()=>{m(r)},onFinish:()=>{m([])}})})}),S?e.jsx(e.Fragment,{children:e.jsx(n.ScrollableTable,{dependencies:[u],tableId:"volume-snapshot-table",belowIds:["status-bar"],children:e.jsx(n.TablePagination,{data:_,id:"pagination",itemName:"snapshot",className:"u-no-margin--top","aria-label":"Table pagination control",description:r.length>0&&e.jsx(nt,{totalCount:g.length??0,itemName:"snapshot",parentName:"volume",selectedNames:r,setSelectedNames:p,filteredNames:u.map(b=>b.name)}),children:e.jsx(st,{id:"volume-snapshot-table",headers:y,rows:_,responsive:!0,sortable:!0,emptyStateMsg:"No snapshot found matching this search",itemName:"snapshot",parentName:"instance",selectedNames:r,setSelectedNames:p,disabledNames:d,filteredNames:u.map(b=>b.name),onUpdateSort:N,defaultSort:"created_at",defaultSortDirection:"descending"})})})}):e.jsxs(n.EmptyState,{className:"empty-state",image:e.jsx(n.Icon,{name:"snapshot",className:"empty-state-icon"}),title:"No snapshots found",children:[e.jsx("p",{children:f&&s?e.jsxs(e.Fragment,{children:["Snapshots are disabled for project"," ",e.jsx(E,{type:"project",value:f.name,to:`/ui/project/${f.name}/configuration`}),"."]}):"There are no snapshots for this volume."}),e.jsx("p",{children:e.jsx(Fe,{docPath:"/howto/storage_backup_volume/#storage-backup-snapshots",hasExternalIcon:!0,children:"Learn more about snapshots"})}),e.jsx(X,{volume:t,isDisabled:s}),e.jsx(J,{volume:t,className:"empty-state-button",isDisabled:s})]})]}):e.jsx(e.Fragment,{children:"Loading storage volume snapshots failed"})},Ft=["Overview","Configuration","Snapshots"],co=()=>{const t=n.useNotify(),{pool:o,project:c,member:r,activeTab:p,type:d,volume:m}=K();if(!o)return e.jsx(e.Fragment,{children:"Missing storage pool"});if(!c)return e.jsx(e.Fragment,{children:"Missing project"});if(!d)return e.jsx(e.Fragment,{children:"Missing type"});if(!m)return e.jsx(e.Fragment,{children:"Missing volume"});const{data:i,error:h,isLoading:j}=Be(o,c,d,m,r);return h&&t.failure("Loading storage volume failed",h),j?e.jsx(n.Spinner,{className:"u-loader",text:"Loading...",isMainComponent:!0}):i?e.jsx(n.CustomLayout,{header:e.jsx(gt,{volume:i,project:c}),contentClassName:"detail-page storage-volume-form u-no-padding--bottom",children:e.jsxs(n.Row,{children:[e.jsx(et,{tabs:Ft,activeTab:p,tabUrl:oe(i)}),e.jsx(Ve,{}),!p&&e.jsx("div",{role:"tabpanel","aria-labelledby":"overview",children:e.jsx(xt,{volume:i,project:c})}),p==="configuration"&&e.jsx("div",{role:"tabpanel","aria-labelledby":"configuration",children:e.jsx(ft,{volume:i})}),p==="snapshots"&&e.jsx("div",{role:"tabpanel","aria-labelledby":"snapshots",children:e.jsx(Nt,{volume:i})})]})}):e.jsx(e.Fragment,{children:"Loading storage volume failed"})};export{co as default};
Copyright ©2k19 -
Hexid
|
Tex7ure