| Current Path : /snap/lxd/current/share/lxd-ui/assets/ |
| Current File : //snap/lxd/current/share/lxd-ui/assets/ProjectConfiguration-BvlzMNvp.js |
import{cJ as H,af as Q,ag as A,cN as M,j as t,r as k,cO as $,d as o,z as S,H as Y,E as L,v as B,c as D,V as U,R as _,bU as J,L as W,cP as X,x as O,f as q,h as K,a9 as Z,k as V,cQ as G,u as ee,C as z,ae as te,cR as se,a6 as T,a3 as ie,S as ne}from"./index-BsQN_SZU.js";import{n as oe,d as re,i as ae,c as ce,r as le,p as de,a as ue,b as me,P as I}from"./ProjectForm-DrdaiE90.js";import{g as E}from"./formFields-DzJouV_d.js";import{R as fe}from"./RenameHeader-BdCO5Nid.js";import{u as F}from"./projects-CczQ3aFg.js";import{U as j}from"./UsedByRow-DlstYIKs.js";import{H as ge}from"./HelpLink-BJF9zWZL.js";import{P as N}from"./ProjectRichChip-DZzjTfq6.js";import{F as pe}from"./FormFooterLayout-CcbL_-PB.js";import{F as he}from"./FormSubmitBtn-DEfKgZu7.js";import"./SshKeyForm-BNz7yPwa.js";import"./limits-yeXZOxhv.js";import"./AutoExpandingTextArea-Bd-45rZK.js";import"./scroll-Dc7Cgzms.js";import"./ConfigFieldDescription-CjXKAIpa.js";import"./snapshots-LtzKNDw1.js";import"./StoragePoolSelector-Bvqvds5t.js";import"./StoragePoolSize-BNbqTfwA.js";import"./Meter-cq8smrSm.js";import"./NetworkSelector-DuJmwRYk.js";import"./useNetworks-1j5RF-bH.js";import"./DiskSizeSelector-C9kWj54D.js";import"./useClusterGroups-BmTnhLw-.js";import"./UsedByItem-DYTdOZkC.js";import"./ExpandableList-DsGr0BpD.js";import"./formChangeCount-Kjdextdt.js";const _e=(e,s,n)=>({name:e.name,readOnly:!0,description:e.description,default_instance_storage_pool:s?A(s):"",default_project_network:s?Q(s):"",restricted:e.config.restricted==="true",features_images:e.config["features.images"]==="true",features_profiles:H(e),features_networks:e.config["features.networks"]==="true",features_networks_zones:e.config["features.networks.zones"]==="true",features_storage_buckets:e.config["features.storage.buckets"]==="true",features_storage_volumes:e.config["features.storage.volumes"]==="true",entityType:"project",limits_instances:e.config["limits.instances"]?parseInt(e.config["limits.instances"]):void 0,limits_containers:e.config["limits.containers"]?parseInt(e.config["limits.containers"]):void 0,limits_virtual_machines:e.config["limits.virtual-machines"]?parseInt(e.config["limits.virtual-machines"]):void 0,limits_disk:e.config["limits.disk"],limits_networks:e.config["limits.networks"]?parseInt(e.config["limits.networks"]):void 0,limits_cpu:e.config["limits.cpu"]?parseInt(e.config["limits.cpu"]):void 0,limits_memory:e.config["limits.memory"]?e.config["limits.memory"]:void 0,limits_processes:e.config["limits.processes"]?parseInt(e.config["limits.processes"]):void 0,restricted_cluster_groups:e.config["restricted.cluster.groups"],restricted_cluster_target:e.config["restricted.cluster.target"],restricted_virtual_machines_low_level:e.config["restricted.virtual-machines.lowlevel"],restricted_containers_low_level:e.config["restricted.containers.lowlevel"],restricted_containers_nesting:e.config["restricted.containers.nesting"],restricted_containers_privilege:e.config["restricted.containers.privilege"],restricted_container_interception:e.config["restricted.containers.interception"],restrict_backups:e.config["restricted.backups"],restrict_snapshots:e.config["restricted.snapshots"],restricted_idmap_uid:e.config["restricted.idmap.uid"],restricted_idmap_gid:e.config["restricted.idmap.gid"],restricted_devices_disk:e.config["restricted.devices.disk"],restricted_devices_disk_paths:e.config["restricted.devices.disk.paths"],restricted_devices_gpu:e.config["restricted.devices.gpu"],restricted_devices_infiniband:e.config["restricted.devices.infiniband"],restricted_devices_nic:e.config["restricted.devices.nic"],restricted_devices_pci:e.config["restricted.devices.pci"],restricted_devices_unix_block:e.config["restricted.devices.unix-block"],restricted_devices_unix_char:e.config["restricted.devices.unix-char"],restricted_devices_unix_hotplug:e.config["restricted.devices.unix-hotplug"],restricted_devices_usb:e.config["restricted.devices.usb"],restricted_network_access:e.config["restricted.networks.access"],restricted_network_subnets:e.config["restricted.networks.subnets"],restricted_network_uplinks:e.config["restricted.networks.uplinks"],restricted_network_zones:e.config["restricted.networks.zones"],editRestriction:n}),ye=(e,s)=>{const n=M(),a=new Set(["name","description","config"]);return{...ue(s),config:{...de(s),...le(s),...s.restricted?{...ce(s),...ae(s),...re(s),...oe(s)}:{},...E(e.config,n)},...E(e,a)}},xe=({project:e})=>{const s=e.used_by?.filter(n=>!n.includes("/1.0/profiles/default"));return t.jsx("table",{className:"p-main-table delete-project-table",children:t.jsxs("tbody",{children:[t.jsx(j,{entityType:"instance",usedBy:s}),t.jsx(j,{entityType:"profile",usedBy:s}),t.jsx(j,{entityType:"image",usedBy:s}),t.jsx(j,{entityType:"volume",usedBy:s})]})})},be=({project:e,handleDelete:s,isLoading:n,closePortal:a})=>{const[c,d]=k.useState(!0),u=$(e),r=i=>{d(i.target.value!==e.name)},l=i=>{i.key==="Enter"&&!c&&!n&&s()};return t.jsxs(o.Modal,{title:"Confirm delete",className:"delete-project-dialog",close:a,buttonRow:[t.jsx("span",{className:"u-float-left confirm-input",children:t.jsx(o.Input,{name:"confirm-delete-project-input",type:"text",onChange:r,onKeyDown:l,placeholder:e.name,className:"u-no-margin--bottom"})},"confirm-input"),t.jsx(o.ActionButton,{appearance:"negative",className:"u-no-margin--bottom",onClick:s,loading:n,disabled:c,children:"Permanently delete"},"confirm-action-button")],children:[t.jsx(o.NotificationConsumer,{}),t.jsxs("p",{children:["This will permanently delete project"," ",t.jsx(S,{type:"project",value:e.name,bold:!0}),".",t.jsx("br",{}),"This action cannot be undone, and can result in data loss."]}),!u&&t.jsxs(t.Fragment,{children:["The following items will also be deleted:",t.jsx(xe,{project:e})]}),t.jsx("p",{children:"To continue, please type the project name below."})]})},ve=(e,s,n,a,c)=>{if(!s)return"You do not have permission to delete this project";if(n)return"The default project cannot be deleted";if(a)return"Delete project";if(!c){const d={instance:{label:"Instances",link:`${_}/ui/project/${encodeURIComponent(e.name)}/instances`},profile:{label:"Profiles",link:`${_}/ui/project/${encodeURIComponent(e.name)}/profiles`},image:{label:"Images",link:`${_}/ui/project/${encodeURIComponent(e.name)}/images`},volume:{label:"Custom volumes",link:`${_}/ui/project/${encodeURIComponent(e.name)}/storage/volumes`}},u=Object.keys(d),r=[];for(const l of u){const i=J(l,e.used_by?.filter(m=>!m.includes("/1.0/profiles/default")));if(i.length>0){const m=d[l].label,f=d[l].link;r.push(t.jsxs("li",{className:"p-list__item is-dark u-no-margin--bottom",children:[t.jsx(W,{to:f,children:m})," (",i.length,")"]},l))}}return t.jsxs(t.Fragment,{children:["Cannot delete non-empty project.",t.jsx("br",{}),t.jsx("br",{}),"Project is used by:",t.jsx("ul",{className:"p-list u-no-margin--bottom",children:r}),t.jsx("br",{}),"Remove all resources first, or upgrade to LXD 6.6 or newer to use force deletion."]})}return"Delete project and all its resources"},Pe=({project:e})=>{const s=Y(),n=L(),a=o.useNotify(),c=o.useToastNotification(),d=B(),[u,r]=k.useState(!1),l=D(),{canDeleteProject:i}=F(),{openPortal:m,closePortal:f,isOpen:h,Portal:w}=o.usePortal(),{hasProjectForceDelete:y,hasProjectDeleteOperation:g}=U(),x=e.name==="default",b=$(e),p=()=>{a.clear(),f()},v=()=>{c.success(t.jsxs(t.Fragment,{children:["Project ",t.jsx(S,{bold:!0,type:"project",value:e.name})," ","deleted."]}))},C=()=>{r(!0),X(e,!b&&y).then(R=>{l(`${_}/ui/project/default/instances`),g?(c.info(t.jsxs(t.Fragment,{children:["Deletion of project"," ",t.jsx(S,{bold:!0,type:"project",value:e.name})," has started."]})),n.set(R.metadata.id,()=>{v()},P=>c.failure(`Deleting project ${e.name} failed`,new Error(P)))):v(),p()}).catch(R=>{r(!1),a.failure("Project deletion failed",R);const P=document.querySelector(".delete-project-dialog .p-modal__dialog");P&&P.scrollTo({top:0,behavior:"smooth"})}).finally(()=>{d.invalidateQueries({queryKey:[O.projects]})})};return t.jsxs(t.Fragment,{children:[t.jsx(o.Button,{onClick:m,hasIcon:!s,disabled:!i(e)||x||u||!b&&!y,className:"u-no-margin--bottom",children:t.jsxs(o.Tooltip,{message:ve(e,i(e),x,b,y),children:[!s&&t.jsx(o.Icon,{name:"delete"}),t.jsx("span",{children:"Delete project"})]})}),h&&t.jsx(w,{children:t.jsx(be,{project:e,handleDelete:C,isLoading:u,closePortal:p})})]})},je=({project:e})=>{const s=L(),n=D(),a=o.useToastNotification(),c=k.useState(null),{canEditProject:d}=F(),u=q().shape({name:K().test("deduplicate","A project with this name already exists",async i=>e.name===i||Z(i,"",c,"projects")).required("Project name is required")}),r=V({initialValues:{name:e.name,isRenaming:!1},validationSchema:u,onSubmit:i=>{if(e.name===i.name){r.setFieldValue("isRenaming",!1),r.setSubmitting(!1);return}const m=t.jsx(N,{projectName:e.name,urlSuffix:"/configuration"});G(e.name,i.name).then(f=>{s.set(f.metadata.id,()=>{const h=`${_}/ui/project/${encodeURIComponent(i.name)}/configuration`;n(h),a.success(t.jsxs(t.Fragment,{children:["Project ",t.jsx("strong",{children:e.name})," renamed to"," ",t.jsx(N,{projectName:i.name,urlSuffix:"/configuration"}),"."]})),r.setFieldValue("isRenaming",!1)},h=>a.failure(`Renaming project ${e.name} failed`,new Error(h),m),()=>{r.setSubmitting(!1)})}).catch(f=>{r.setSubmitting(!1),a.failure(`Renaming project ${e.name} failed`,f,m)})}}),l=()=>{if(!d(e))return"You do not have permission to rename this project";if(e.name==="default")return"Cannot rename the default project"};return t.jsx(fe,{name:e.name,parentItems:[t.jsx(ge,{docPath:"/reference/projects/",title:"Learn more about project configuration",children:"Project configuration"},"project-configuration")],renameDisabledReason:l(),controls:t.jsx(Pe,{project:e}),isLoaded:!!e,formik:r})},ke=({project:e})=>{const s=D(),{isRestricted:n}=ee(),a=o.useNotify(),c=o.useToastNotification(),d=B(),{section:u}=z(),{hasProjectsNetworksZones:r,hasStorageBuckets:l}=U(),{canEditProject:i}=F(),{data:m}=te("default",e.name),f=()=>{ie("form-contents","p-bottom-controls")};k.useEffect(f,[a.notification?.message,u]),o.useListener(window,f,"resize",!0);const h=q().shape({name:K().required()}),w=i(e)?void 0:"You do not have permission to edit this project",y=_e(e,m,w),g=V({initialValues:y,validationSchema:h,enableReinitialize:!0,onSubmit:p=>{r||(p.features_networks_zones=void 0),l||(p.features_storage_buckets=void 0);const v=ye(e,p);v.etag=e.etag,se(v).then(()=>{c.success(t.jsxs(t.Fragment,{children:["Project"," ",t.jsx(N,{projectName:e.name,urlSuffix:"/instances"})," ","updated."]})),g.setFieldValue("readOnly",!0)}).catch(C=>{a.failure("Project update failed",C)}).finally(()=>{g.setSubmitting(!1),d.invalidateQueries({queryKey:[O.projects]})})}}),x=`${_}/ui/project/${encodeURIComponent(e.name)}/configuration`,b=p=>{s(p===I?x:`${x}/${T(p)}`)};return t.jsxs(o.CustomLayout,{header:t.jsx(je,{project:e}),contentClassName:"edit-project",children:[t.jsx(me,{formik:g,project:e,section:u??T(I),updateSection:b,isEdit:!0}),!n&&t.jsx(pe,{children:g.values.readOnly?null:t.jsxs(t.Fragment,{children:[t.jsx(o.Button,{appearance:"base",onClick:async()=>g.setValues(y),children:"Cancel"}),t.jsx(he,{formik:g,baseUrl:x,disabled:!g.values.name})]})})]})},Ze=()=>{const{project:e}=z();if(!e)return t.jsx(t.Fragment,{children:"Missing project"});const{project:s,isLoading:n}=ne();return n?t.jsx(o.Spinner,{className:"u-loader",text:"Loading...",isMainComponent:!0}):s?t.jsx(ke,{project:s},s.name):t.jsx(t.Fragment,{children:"Loading project failed"})};export{Ze as default};