| Current Path : /proc/thread-self/root/snap/lxd/39313/share/lxd-ui/assets/ |
| Current File : //proc/thread-self/root/snap/lxd/39313/share/lxd-ui/assets/PermissionGroups-C3nVtEOe.js |
import{u as Oe,B as de,t as Z,d as a,r as C,b as be,j as e,U as F,y as ue,w as O,E as ze,dk as Q,e as ee,du as ye,dz as Y,R as te,az as qe,dA as He,dB as xe,H as Ke,K as Ue,ae as me,s as X,cf as Ye,x as je,f as Se,h as Ne,k as ve,p as ne,dp as ae,v as re,dm as Qe,b8 as Ve,O as We,M as Xe}from"./index-BFGypnt-.js";import{S as le}from"./SelectableMainTable-BZaSR8Vv.js";import{S as Je}from"./SelectedTableNotification-D7txT2Gz.js";import{u as ce}from"./useSortTableData-DMPSUVcX.js";import{u as H,p as oe}from"./usePanelParams-CV5ZHNeu.js";import{P as W}from"./PageHeader-DZVSTM6q.js";import{H as Ze}from"./HelpLink-l4aaXUp-.js";import{d as et,c as tt,r as nt,a as pe,u as st}from"./useAuthGroups-3GAYR02a.js";import{L as Ie,u as Ce,G as it,S as ot,A as at,Q as rt,i as lt,P as ct}from"./GroupOrIdentityChangesTable-C5GyT60U.js";import{A as dt}from"./AutoExpandingTextArea-WEdimI5c.js";import{F as he,B as ut}from"./FormLink-DYjWMIpw.js";import{g as mt}from"./images-C6WqBeZG.js";import{h as we}from"./useImages-DavKpFTt.js";import{P as pt}from"./PermissionGroupsFilter-BWepc9mD.js";import{u as ht,M as ft}from"./ModifiedStatusAction-BK_Bam7Z.js";import"./searchAndFilter-DtC_P-vv.js";import"./image-registries-YAuyq4CZ.js";const V=()=>{const{isFineGrained:t}=Oe();return{canDeleteGroup:o=>de(t,"can_delete",o?.access_entitlements),canEditGroup:o=>de(t,"can_edit",o?.access_entitlements)}},Ge=({groups:t,close:n})=>{const s=Z(),o=a.useNotify(),i=a.useToastNotification(),[u,b]=C.useState(!0),[r,l]=C.useState(!1),h="confirm-delete-group",{canDeleteGroup:j}=V(),{data:f}=be(),I=f?.auth_user_name??"",v=[],x=[];let c=!1;t.forEach(d=>{j(d)?(d.identities?.oidc?.includes(I)&&(c=!0),d.identities?.tls?.includes(I)&&(c=!0),x.push(d)):v.push(d)});const g=x.length===1,w=d=>{b(d.target.value!==h)},y=()=>{l(!0);const m=x.length===1?e.jsxs(e.Fragment,{children:["Group"," ",e.jsx(ue,{bold:!0,type:"auth-group",value:x[0].name})," ","deleted."]}):`${x.length} groups deleted.`;et(x.map(S=>S.name)).then(()=>{s.invalidateQueries({predicate:S=>[O.identities,O.authGroups].includes(S.queryKey[0])}),i.success(m),n()}).catch(S=>{o.failure(`Failed deleting ${x.length} ${F("group",x.length)}.`,S)}).finally(()=>{l(!1)})},G=()=>{const d=v.length?e.jsxs(e.Fragment,{children:[e.jsxs("li",{className:"p-list__item",children:["-"," ",`${x.length} ${F("group",x.length)} will be deleted.`]}),e.jsxs("li",{className:"p-list__item",children:["-"," ",`${v.length} ${F("group",v.length)} that you do not have permission to delete will be ignored.`]})]}):null,m=g?e.jsxs(e.Fragment,{children:[" ","the group"," ",e.jsx(ue,{type:"auth-group",value:x[0].name,bold:!0})]}):e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:x.length})," ",F("group",x.length)]});return e.jsxs(e.Fragment,{children:[d&&e.jsxs(e.Fragment,{children:[e.jsxs("p",{children:[e.jsx("b",{children:t.length})," ",F("group",t.length)," ","selected:"]}),e.jsx("ul",{className:"p-list",children:d})]}),e.jsxs("p",{className:"u-no-padding--top",children:["This will permanently delete ",m,".",`
`,"This action cannot be undone and may result in users losing access to LXD, including the possibility that all users lose admin access."]}),c&&e.jsx("div",{className:"u-sv1",children:e.jsx(Ie,{isVisible:c})}),e.jsx("p",{children:"To continue, please type the confirmation text below."}),e.jsx("p",{children:e.jsx("strong",{children:h})})]})};return e.jsx(a.Modal,{title:"Confirm group deletion",className:"delete-group-confirm-modal",close:n,buttonRow:[e.jsx("span",{className:"u-float-left confirm-input",children:e.jsx(a.Input,{id:"confirm-delete-group-input",name:"confirm-delete-group-input",type:"text",onChange:w,placeholder:h,className:"u-no-margin--bottom",disabled:!x.length})},"confirm-input"),e.jsxs(a.ActionButton,{appearance:"negative",className:"u-no-margin--bottom",onClick:y,loading:r,disabled:u||r,children:["Permanently delete ",x.length," ",F("group",x.length)]},"confirm-action-button")],children:G()})},q=t=>t?.name==="admins",Re=(t,n)=>["deduplicate","A group with this name already exists",async s=>n&&s===n||ze(s,"",t,"auth/groups")],gt=(t,n)=>{const s=t.length,o=[],i=[],u=[];for(const b of n){let r=0;const l=new Set(b.groups||[]);for(const f of t)l.has(f.name)&&r++;const h=r===s,j=!h&&r>0;if(h){o.push(b.id);continue}if(j){i.push(b.id);continue}u.push(b.id)}return{identityIdsInAllGroups:o,identityIdsInSomeGroups:i,identityIdsInNoGroups:u}},Pe=(t,n,s)=>t.filter(i=>n.has(i.id)||s.has(i.id)),Ee=(t,n,s,o)=>{const i=new Set(t),u=new Set(n),b=new Set(s.map(l=>l.name)),r={};for(const l of o){const h=l.groups||[],j=new Set(h);for(const f of h)u.has(l.id)&&b.has(f)&&j.delete(f);for(const f of s)i.has(l.id)&&j.add(f.name);r[l.id]=Array.from(j)}return r},bt=(t,n,s,o)=>{const i=Pe(t,s,o),u=Ee(s,o,n,i),b={};for(const r of i){const l=u[r.id];if(!l)continue;const h=new Set,j=new Set,f=new Set(r.groups);for(const v of l)f.has(v)||h.add(v);const I=new Set(l);for(const v of r.groups||[])I.has(v)||j.add(v);(h.size||j.size)&&(b[r.id]={added:h,removed:j,name:Q(r)})}return b},yt=({group:t})=>{const n=H(),{openPortal:s,closePortal:o,isOpen:i,Portal:u}=a.usePortal(),{canDeleteGroup:b,canEditGroup:r}=V(),l=()=>q(t)?"Admins group cannot be deleted":b(t)?"Delete group":"Delete group - You do not have permission to delete this group";return e.jsxs(e.Fragment,{children:[e.jsx(a.List,{inline:!0,className:"u-no-margin--bottom actions-list",items:[e.jsx(a.Button,{appearance:"base",dense:!0,hasIcon:!0,onClick:()=>{n.openEditGroup(t.name)},type:"button",title:r(t)?"Edit group":"Edit group - You do not have permission to edit this group",disabled:!r(t),children:e.jsx(a.Icon,{name:"edit"})},"edit"),e.jsx(a.Button,{appearance:"base",dense:!0,hasIcon:!0,onClick:s,type:"button",title:l(),disabled:q(t)||!b(t),children:e.jsx(a.Icon,{name:"delete"})},"delete")]}),i&&e.jsx(u,{children:e.jsx(Ge,{groups:[t],close:o})})]})},Ae=({formik:t,setSubForm:n,identityCount:s,identityModifyCount:o,permissionCount:i,permissionModifyCount:u,isEditing:b=!0,group:r})=>{const{canEditGroup:l}=V(),h=w=>({id:w,name:w,onBlur:t.handleBlur,onChange:t.handleChange,value:t.values[w]??"",error:t.touched[w]?t.errors[w]:null,placeholder:`Enter ${w.replaceAll("_"," ")}`}),j=!b||l(r)?"":"You do not have permission to modify this group",f=!t.values.name||!!t.errors.name,I=!!j||f,v=f,c=(()=>{if(j)return j;if(r&&q(r))return"Admins group cannot be modified";if(f)return"Enter a valid group name first"})(),g=()=>r&&!l(r)?"View ":b?"Edit ":"Add ";return e.jsxs(a.Form,{onSubmit:t.handleSubmit,children:[e.jsx(a.Input,{type:"submit",hidden:!0,value:"Hidden input"}),e.jsx(a.Input,{...h("name"),type:"text",label:"Name",required:!0,autoFocus:!0,disabled:!!j||q(r),title:j||c}),e.jsx(dt,{...h("description"),label:"Description",disabled:I||q(r),title:c}),e.jsx(he,{title:(b?"Edit ":"Add ")+F("identity",2),icon:"user-group",onClick:()=>{n("identity")},isModified:o>0,subText:s===0?`No ${F("identity",2)}`:`${s} ${F("identity",s)}`,disabled:I,onHoverText:c}),e.jsx(he,{title:g()+F("permission",2),icon:"lock-locked",onClick:()=>{n("permission")},isModified:u>0,subText:i===0?`No ${F("permission",2)}`:`${i} ${F("permission",i)}`,disabled:v,onHoverText:c})]})},Le=({selected:t,setSelected:n,groupName:s,group:o})=>{const i=a.useNotify(),[u,b]=C.useState(null),{data:r=[],error:l}=ee(),{canEditIdentity:h}=Ce(),j=r.filter(d=>!h(d)).map(d=>d.id);l&&i.failure("Loading details failed",l);const f=r.filter(d=>!ye(d)),I=new Set(Y(o)),v=I.size>0,x=d=>{if(j.includes(d))return;const m=t.find(S=>S.id===d);if(m){const S=t.filter(B=>B.id!==d),L={...m,isAdded:!m.isAdded,isRemoved:!m.isRemoved},M=m.groups?.includes(s);if(L.isRemoved&&!M){n(S);return}L.isAdded=!M,n([...S,L])}else{const S=r.find(L=>L.id===d);if(!S){i.failure("Selection failed",new Error("Identity not found"));return}n([...t,{...S,isAdded:!0,isRemoved:!1}])}},c=d=>{if(d.length===0){const S=[];t.forEach(L=>{L.groups?.includes(s)&&S.push({...L,isAdded:!1,isRemoved:!0})}),n(S);return}const m=r.filter(S=>d.includes(S.id)).map(S=>({...S,isAdded:!S.groups?.includes(s),isRemoved:!1}));n(m)},g=[{content:"Identity",sortKey:"name"},{content:"","aria-label":"Modified status",className:"modified-status"}],y=f.filter(d=>u?Q(d).toLowerCase().includes(u.toLowerCase()):!0).map(d=>{const m=()=>{x(d.id)},S=t.find(D=>D.id===d.id),L=S?.isAdded||S?.isRemoved,M=Q(d);return{key:d.id,name:d.id,className:"u-row u-truncate",columns:[{content:M,role:"rowheader","aria-label":"Identity",title:h(d)?M:"You do not have permission to allocate this identity to the group",onClick:m,className:"clickable-cell"},{content:L&&e.jsx(a.Icon,{name:"status-in-progress-small"}),role:"cell","aria-label":"Modified status",className:"modified-status u-align--right"}],sortData:{name:M.toLowerCase(),isPreselected:I.has(d.id)}}}),{rows:G}=ce({rows:y,defaultSort:v?"isPreselected":"name",defaultSortDirection:v?"descending":"ascending"});return e.jsxs(e.Fragment,{children:[e.jsx(a.SearchBox,{onChange:d=>{b(d)}}),e.jsx(a.ScrollableTable,{dependencies:[r,t,i.notification],tableId:"group-identities-table",belowIds:["panel-footer"],children:e.jsx(le,{id:"group-identities-table",headers:g,rows:G,sortable:!0,emptyStateMsg:"No identities found",itemName:"identity",parentName:"server",selectedNames:t.filter(d=>!d.isRemoved).map(d=>d.id),setSelectedNames:c,disabledNames:j,filteredNames:f.map(d=>d.id),indeterminateNames:[],onToggleRow:x,hideContextualMenu:!0,disableSelectAll:!!j.length})})]})},xt=async t=>{const n=new URLSearchParams;return n.set("entity-type",t),fetch(`${te}/1.0/auth/permissions?${n.toString()}`).then(qe).then(s=>s.metadata.sort((o,i)=>o.url===i.url?o.entitlement===i.entitlement?o.entity_type.localeCompare(i.entity_type):o.entitlement.localeCompare(i.entitlement):o.url.localeCompare(i.url)))},jt=({resource:t})=>{const s=De(t.type).map(o=>{let i=t[o]||"-";return Array.isArray(i)&&(i=i.join(", ")||"-"),e.jsx("span",{title:i,className:"resource u-truncate",children:i},o)});return e.jsx("div",{className:"label",children:s})},St=({entitlement:t,description:n})=>e.jsxs("div",{className:"label",children:[e.jsx("span",{title:t,className:"entitlement u-truncate",children:t}),e.jsx("span",{title:n,className:"entitlement-description u-truncate u-text--muted",children:n})]});var fe=He();const Nt={disabled:!0,label:"None available",value:""},Te=[{value:"server",label:"Server"},{value:"identity",label:"Identity"},{value:"group",label:"Group"},{value:"certificate",label:"Certificate"},{value:"project",label:"Project"},{value:"profile",label:"Profile"},{value:"instance",label:"Instance"},{value:"image",label:"Image"},{value:"image_alias",label:"Image alias"},{value:"storage_pool",label:"Storage pool"},{value:"storage_volume",label:"Storage volume"},{value:"storage_bucket",label:"Storage bucket"},{value:"network",label:"Network"},{value:"network_acl",label:"Network ACL"},{value:"network_zone",label:"Network zone"}],J=(t,n)=>{const s=fe.getOptionText(t)||t.value,o=fe.getOptionText(n)||n.value;return s.localeCompare(o)},vt=t=>{if(!t||!t.entities)return Te.sort(J);const n=[],s=Object.keys(t.entities);for(const o of s){const i=o.split("_");i[0]=Ke(i[0]),n.push({value:o,label:i.join(" ")})}return n},It=(t,n,s,o)=>{if(!n.length||!t)return[];const i=[],u=new Set;for(const b of n){const r=xe(t,b.url,s,o),l=ke(r);u.has(l)||(u.add(l),i.push({value:b.url,label:e.jsx(jt,{resource:r}),text:l}))}return i.sort(J),i},Ct=(t,n)=>{const s={},o=t.entities[n].entitlements;for(const i of o)s[i.name]=i.description;return s},wt=(t,n,s)=>{if(!n||!t)return[];const o=n[0].url,i=[],u=[];for(const r of n){if(r.url!==o)continue;const l={value:r.entitlement,label:r.entitlement};if(r.entitlement.includes("can_")){u.push({...l});continue}i.push({...l})}i.sort(J),u.sort(J),i.length>1&&u.length&&(i.unshift({disabled:!0,label:"Broad entitlement sets",value:"group"}),u.unshift({disabled:!0,label:"Granular entitlements",value:"group"}));const b=[...i,...u];if(s&&s.entities){const r=Ct(s,t);for(const l of b)l.value&&typeof l.value=="string"&&r[l.value]&&(l.text=l.value,l.label=e.jsx(St,{entitlement:l.value,description:r[l.value]})),l.value==="group"&&(l.label=e.jsx("div",{className:"header u-no-padding",children:e.jsx("span",{className:"u-no-margin",children:e.jsx("h5",{className:"u-no-margin u-no-padding",children:l.label})})}))}return[...i,...u]},ke=t=>{const n=t.project?` (project: ${t.project}) `:"",s=t.target?` (target: ${t.target}) `:"",o=t.pool?` (pool: ${t.pool}) `:"",i=t.aliases?` (aliases: ${t.aliases.join(", ")}) `:"",u=t.fingerprint?` (fingerprint: ${t.fingerprint}) `:"";return`${t.name}${s}${o}${n}${i}${u}`},se=t=>t.entity_type+t.url+t.entitlement,Gt=t=>t.map(n=>se(n)),Fe=(t,n,s)=>{const o=xe(t.entity_type,t.url,n,s);return ke(o)},Me=t=>{const n={};for(const s of t)n[s.fingerprint]={...s,name:`${mt(s)} (${s.type})`};return n},$e=t=>{const n={};for(const s of t)n[s.id]=Q(s);return n},Rt=()=>{const t={};return Te.forEach((n,s)=>{t[n.value]=s}),t},ge=Rt(),Pt=(t,n)=>{const s=ge[t.entity_type]-ge[n.entity_type],o=t.resourceLabel?.localeCompare(n.resourceLabel??""),i=t.entitlement.localeCompare(n.entitlement);return s||o||i},De=t=>{const n={image:["description","aliases","fingerprint","imageType","project"],image_alias:["name","project"],instance:["name","project"],network:["name","project"],network_acl:["name","project"],network_zone:["name","project"],profile:["name","project"],storage_bucket:["name","project"],storage_volume:["name","pool","project"],default:["name"]};return n[t]??n.default},Et=({resourceType:t})=>{const n=De(t);if(n.length<2)return null;const s=n.map(o=>e.jsx("span",{className:"resource u-no-margin--bottom",children:o==="imageType"?"image type":o},o));return e.jsx("div",{className:"header",children:s})},At=({onAddPermission:t,disableReason:n})=>{const s=a.useNotify(),[o,i]=C.useState(""),[u,b]=C.useState(""),[r,l]=C.useState(""),{hasMetadataConfiguration:h,hasEntityTypeMetadata:j}=Ue(),f=C.useRef(null),I=C.useRef(null),v=C.useRef(null),x=C.useRef(null),{data:c,isLoading:g,error:w}=me({queryKey:[O.permissions,o],queryFn:async()=>xt(o),enabled:!!o&&!n}),{data:y=[]}=we(),{data:G=[]}=ee(),d=Me(y),m=$e(G),{data:S,isLoading:L}=me({queryKey:[O.configOptions],queryFn:async()=>Ye(h)}),M=g||L;C.useEffect(()=>{setTimeout(()=>{f.current&&(f.current.focus(),f.current.tabIndex=-1)},100)},[]);const D=(E,p,P)=>{if(p==="server")return x.current?.open(),p;if(!E&&p||E&&p===E){if(P?.length)return v.current?.open(),p;I.current?.focus()}return p};C.useEffect(()=>{D("",o,c)},[o,c]);const B=E=>{const p=E;l(""),i(P=>D(P,p,c)),b(p==="server"?"/1.0":"")},R=E=>{b(E),x.current?.open()},K=E=>{l(E),document.getElementById("add-entitlement")?.focus()},_=()=>{const E={entity_type:o,url:u,entitlement:r};t({...E,id:se(E),resourceLabel:Fe(E,d,m)}),l("")};w&&s.failure("Loading permissions failed",w);const N=It(o,c??[],d,m),T=wt(o,c,j?S:null),k=o==="server",A=N.length;return e.jsxs("div",{className:X("permission-selector",{"dropdown-disabled":!!n}),tabIndex:0,ref:f,title:n,children:[e.jsx(a.CustomSelect,{id:"resourceType",name:"resourceType",label:e.jsx("strong",{children:"Resource type"}),options:vt(S),toggleClassName:"u-no-margin--bottom","aria-label":"Resource type",onChange:B,value:o,selectRef:I,searchable:"always",disabled:!!n}),e.jsx(a.CustomSelect,{id:"resource",name:"resource",label:e.jsx("strong",{children:"Resource"}),options:A?N:[Nt],toggleClassName:"u-no-margin--bottom","aria-label":"Resource",onChange:R,value:u,disabled:M||!o||k||!A,dropdownClassName:"permissions-select-dropdown",header:e.jsx(Et,{resourceType:o}),selectRef:v,searchable:"always"}),e.jsx(a.CustomSelect,{id:"entitlement",name:"entitlement",label:e.jsx("strong",{children:"Entitlement"}),options:T,toggleClassName:"u-no-margin--bottom","aria-label":"Entitlement",onChange:K,value:r,disabled:M||!u&&!k,dropdownClassName:"permissions-select-dropdown",selectRef:x,searchable:"always",initialPosition:"right"}),e.jsx("div",{className:"add-entitlement",children:e.jsx(a.Button,{id:"add-entitlement",appearance:"positive",onClick:_,className:"u-no-margin--bottom",disabled:!r,tabIndex:r?void 0:-1,children:"Add"})})]})},_e=({permissions:t,setPermissions:n,group:s})=>{const o=a.useNotify(),[i,u]=C.useState(""),{canViewPermissions:b}=je(),{canEditGroup:r}=V(),l=()=>s&&!r(s)?"You do not have permission to edit this group":b()?q(s)?"Permissions for this group cannot be modified":"":"You are not allowed to view permissions",h=c=>{const g=t.find(d=>d.id===c.id);if(g&&!g.isRemoved)return;const y=Gt(s?.permissions??[]).includes(c.id??""),G={...c,isAdded:!y,isRemoved:!1};if(g&&g.isRemoved){const d=t.map(m=>m.id===c.id?G:m);n(d);return}g||n([...t,G])},j=c=>{let g;s?.permissions?.some(y=>se(y)===c)?g=t.map(y=>y.id===c?{...y,isRemoved:!0,isAdded:!1}:y):g=t.filter(y=>y.id!==c),n(g)},f=i?t.filter(c=>c.entitlement.includes(i)||c.entity_type.includes(i)||c.resourceLabel?.toLowerCase().includes(i)):t,I=C.useMemo(()=>f.sort(Pt),[f]),v=[{content:"Resource type",sortKey:"resourceType",className:"resource-type"},{content:"Resource",sortKey:"resource",className:"resource"},{content:"Entitlement",sortKey:"entitlement",className:"entitlement"},{"aria-label":"Actions",className:"u-align--right actions"}],x=I.map(c=>{const g=c.isAdded||c.isRemoved;return{key:c.id,name:c.id,className:X("u-row",{strikeout:c.isRemoved}),columns:[{content:c.entity_type,title:c.entity_type,role:"rowheader","aria-label":"Resource type",className:"resource-type"},{content:c.resourceLabel,role:"cell","aria-label":"Resource",className:"u-truncate resource",title:c.resourceLabel},{content:c.entitlement,role:"cell","aria-label":"Entitlement",className:"u-truncate entitlement",title:c.entitlement},{className:"actions u-align--right",content:e.jsxs(e.Fragment,{children:[c.isRemoved?e.jsx(a.Button,{appearance:"base",hasIcon:!0,dense:!0,onClick:()=>{h(c)},type:"button","aria-label":"Restore permission",title:"Restore permission",className:"u-no-margin--right",children:e.jsx(a.Icon,{name:"restart"})}):e.jsx(a.Button,{appearance:"base",hasIcon:!0,dense:!0,onClick:()=>{j(c.id??"")},type:"button","aria-label":"Delete permission",title:l()??"Delete permission",className:"u-no-margin--right",disabled:!!l(),children:e.jsx(a.Icon,{name:"delete"})}),e.jsx(a.Icon,{name:"status-in-progress-small",className:X({"hide-modified-status":!g}),"aria-hidden":!g,"aria-label":"Permission modified"})]}),role:"cell","aria-label":"Delete permission"}],sortData:{resourceType:c.entity_type.toLowerCase(),resource:c.resourceLabel?.toLowerCase(),entitlement:c.entitlement.toLowerCase()}}});return e.jsxs(a.ScrollableContainer,{dependencies:[o.notification,t.length],belowIds:["panel-footer"],children:[e.jsxs(a.Card,{children:[e.jsx("strong",{children:e.jsx("p",{className:"u-no-margin--bottom",children:"Add permissions"})}),e.jsx("span",{children:"Entitlements need to be given in relation to a specific resource. Select the appropriate resource and entitlement below and add it to the list of permissions for this group."}),e.jsx(At,{onAddPermission:h,disableReason:l()})]}),e.jsx(a.SearchBox,{externallyControlled:!0,value:i,onChange:u}),t.length?e.jsx(a.MainTable,{id:"permissions-table",headers:v,sortable:!0,responsive:!0,emptyStateMsg:"No permissions match the search criteria.",rows:x,className:"permissions-table"}):e.jsx(a.EmptyState,{className:"empty-state empty-state__full-width",image:e.jsx(a.Icon,{name:"plans",className:"empty-state-icon"}),title:"No permissions",children:e.jsx("p",{children:"Select a permission above and add to the group"})})]})},Be=({subForm:t,setSubForm:n,group:s})=>{if(t===null)return s?`Edit auth group ${s?.name}`:"Create auth group";const o=s?"Edit":"Add";return e.jsx(ut,{linkText:s?"Edit auth group":"Create auth group",title:`${o} ${F(t,2)}`,onClick:()=>{n(null)}})},Lt=()=>{const t=H(),n=a.useNotify(),s=a.useToastNotification(),o=Z(),i=C.useState(null),[u,b]=C.useState([]),[r,l]=C.useState([]),h=t.subForm,j=g=>{t.openCreateGroup(g)},f=()=>{t.clear(),n.clear()},I=Se().shape({name:Ne().test(...Re(i)).required("Group name is required")}),v=g=>{s.success(e.jsxs(e.Fragment,{children:["Group"," ",e.jsx(re,{type:"auth-group",value:g,to:`${te}/ui/permissions/groups`})," ","created."]})),f()},x=g=>{if(u.length===0){v(g);return}const w=u.map(y=>{const G=y.groups||[];return y.groups=[...G,g],y});ae(w).then(()=>{v(g)}).catch(y=>{n.failure(`Group ${g} created, failed to add identities.`,y)}).finally(()=>{c.setSubmitting(!1),o.invalidateQueries({queryKey:[O.authGroups]})})},c=ve({initialValues:{name:"",description:""},validationSchema:I,onSubmit:g=>{tt({name:g.name,description:g.description,permissions:r.filter(w=>!w.isRemoved)}).then(()=>{x(g.name)}).catch(w=>{n.failure("Group creation failed",w)}).finally(()=>{c.setSubmitting(!1),o.invalidateQueries({queryKey:[O.authGroups]})})}});return e.jsx(e.Fragment,{children:e.jsxs(a.SidePanel,{className:X({"edit-permissions-panel":h==="permission"}),children:[e.jsx(a.SidePanel.Header,{children:e.jsx(a.SidePanel.HeaderTitle,{children:e.jsx(Be,{subForm:h,setSubForm:j})},h??"start")}),e.jsx(ne,{className:"u-no-padding"}),e.jsx(a.SidePanel.Content,{className:"u-no-padding",children:e.jsxs(a.ScrollableContainer,{dependencies:[n.notification,h],belowIds:["panel-footer"],children:[h===null&&e.jsx(Ae,{formik:c,setSubForm:j,identityCount:u.length,identityModifyCount:u.length,permissionCount:r.length,permissionModifyCount:r.length,isEditing:!1}),h==="identity"&&e.jsx(Le,{selected:u,setSelected:b,groupName:c.values.name}),h==="permission"&&e.jsx(_e,{permissions:r,setPermissions:l})]})}),e.jsxs(a.SidePanel.Footer,{className:"u-align--right",children:[e.jsx(a.Button,{appearance:"base",onClick:f,className:"u-no-margin--bottom",children:"Cancel"}),e.jsx(a.ActionButton,{appearance:"positive",loading:c.isSubmitting,onClick:()=>{c.submitForm()},className:"u-no-margin--bottom",disabled:!c.isValid||c.isSubmitting||!c.values.name,children:"Create group"})]})]})})},Tt=({group:t,onClose:n})=>{const s=H(),o=a.useNotify(),i=a.useToastNotification(),u=Z(),b=C.useState(null),[r,l]=C.useState(!1),[h,j]=C.useState(Y(t).map(N=>({id:N}))),[f,I]=C.useState(t.permissions??[]),{data:v}=be(),x=v?.auth_user_name??"",{canEditGroup:c}=V(),g=s.subForm,w=N=>{s.openEditGroup(s.group??"",N)},{data:y=[],isLoading:G,isError:d}=ee();C.useEffect(()=>{if(!G&&!d){const N=new Set(Y(t)),$=y.filter(T=>N.has(T.id));j($)}},[G,d,y,t]);const{data:m=[],isLoading:S,isError:L}=we();C.useEffect(()=>{if(!G&&!d&&!S&&!L){const N=Me(m),$=$e(y),T=(t.permissions??[]).map(k=>{const A=se(k),E=Fe(k,N,$);return{...k,resourceLabel:E,id:A}});I(T)}},[G,d,S,L,y,m,t]);const M=Se().shape({name:Ne().test(...Re(b,s.group??"")).required("Group name is required")}),D=async N=>{const $=h.filter(A=>A.isAdded),T=h.filter(A=>A.isRemoved);if($.length===0&&T.length===0)return;const k=[];return $.map(A=>{k.push({...A,groups:[...A.groups||[],R.values.name]})}),T.map(A=>{k.push({...A,groups:[...(A.groups||[]).filter(E=>E!==N)]})}),ae(k)},B=N=>{const $=N.name!==t?.name,T=t?.name??"",k={...t,name:N.name,description:N.description,permissions:f.filter(E=>!E.isRemoved)};(async()=>!c(t)||q(t)?D(T):$?nt(T,N.name).then(async()=>pe(k)).then(async()=>D(T)):pe(k).then(async()=>D(T)))().then(()=>{K(),i.success(e.jsxs(e.Fragment,{children:["Auth group"," ",e.jsx(re,{type:"auth-group",value:N.name,to:`${te}/ui/permissions/groups`})," ","updated."]}))}).catch(E=>{o.failure("Group update failed",E)}).finally(()=>{R.setSubmitting(!1),u.invalidateQueries({queryKey:[O.authGroups]})})},R=ve({initialValues:{name:t?.name??"",description:t?.description??""},enableReinitialize:!0,validationSchema:M,onSubmit:N=>{const $=Y(t).includes(x),T=h.find(A=>A.id===x)?.isRemoved,k=f.find(A=>A.isRemoved);T||$&&k?l(!0):B(N)}}),K=()=>{s.clear(),o.clear(),n?.()},_=h.filter(N=>N.isAdded||N.isRemoved).length+f.filter(N=>N.isAdded||N.isRemoved).length+(R.values.name!==t.name?1:0)+(R.values.description!==t.description?1:0);return e.jsxs(e.Fragment,{children:[e.jsxs(a.SidePanel,{className:X({"edit-permissions-panel":g==="permission"}),children:[e.jsx(a.SidePanel.Header,{children:e.jsx(a.SidePanel.HeaderTitle,{className:"u-truncate",children:e.jsx(Be,{subForm:g,setSubForm:w,group:t})},g??"start")}),e.jsx(ne,{className:"u-no-padding"}),e.jsxs(a.SidePanel.Content,{className:"u-no-padding",children:[g===null&&e.jsx(a.ScrollableContainer,{dependencies:[o.notification,g],belowIds:["panel-footer"],children:e.jsx(Ae,{formik:R,setSubForm:w,identityCount:h.filter(N=>!N.isRemoved).length,identityModifyCount:h.filter(N=>N.isAdded||N.isRemoved).length,permissionCount:f.filter(N=>!N.isRemoved).length,permissionModifyCount:f.filter(N=>N.isAdded||N.isRemoved).length,group:t})}),g==="identity"&&e.jsx(Le,{selected:h,setSelected:j,groupName:t.name,group:t}),g==="permission"&&e.jsx(_e,{permissions:f,setPermissions:I,group:t})]}),e.jsxs(a.SidePanel.Footer,{className:"u-align--right",children:[e.jsx(a.Button,{appearance:"base",onClick:K,className:"u-no-margin--bottom",children:"Cancel"}),e.jsx(a.ActionButton,{appearance:"positive",loading:R.isSubmitting,onClick:()=>{R.submitForm()},className:"u-no-margin--bottom",disabled:!R.isValid||R.isSubmitting||!R.values.name||_===0,children:_===0?"Save changes":`Save ${_} ${F("change",_)}`})]})]}),r&&e.jsx(a.ConfirmationModal,{confirmButtonLabel:"Confirm changes",confirmButtonAppearance:"positive",onConfirm:()=>{B(R.values)},close:()=>{l(!1),R.setSubmitting(!1)},title:"Confirm permission modification",className:"permission-confirm-modal",children:e.jsx(Ie,{isVisible:!0})})]})},kt=({groups:t,className:n})=>{const s=H();return e.jsx(e.Fragment,{children:e.jsxs(a.Button,{onClick:()=>{s.openGroupIdentities()},"aria-label":"Manage identities",title:"Manage identities",className:n,disabled:!t.length,hasIcon:!0,children:[e.jsx(a.Icon,{name:"user-group"}),e.jsx("span",{children:"Manage identities"})]})})},Ft=({onConfirm:t,close:n,addedIdentities:s,removedIdentities:o,selectedGroups:i,allIdentities:u})=>{const[b,r]=C.useState(!1),l=a.useNotify(),h=H(),j=Z(),f=a.useToastNotification(),I=bt(u,i,s,o),v=Qe(I),x=()=>{r(!0);const c=Pe(u,s,o),g=Ee(s,o,i,c),w=c.map(y=>({...y,groups:g[y.id]}));ae(w).then(()=>{j.invalidateQueries({predicate:d=>[O.identities,O.authGroups].includes(d.queryKey[0])});const y=Object.keys(v),G=y.length>1?`Updated identities for ${y.length} groups`:e.jsxs(e.Fragment,{children:["Updated identities for"," ",e.jsx(re,{type:"auth-group",value:y[0],to:`${te}/ui/permissions/groups`})]});f.success(G),h.clear(),l.clear()}).catch(y=>{l.failure("Update groups failed",y)}).finally(()=>{r(!1),t()})};return e.jsx(a.ConfirmationModal,{confirmButtonLabel:"Confirm changes",confirmButtonAppearance:"positive",onConfirm:x,close:n,title:"Confirm modification",className:"permission-confirm-modal",confirmButtonLoading:b,children:e.jsx(it,{identityGroupsChangeSummary:I,groupIdentitiesChangeSummary:v,identities:u,initialGroupBy:"group"})})},Mt=({groups:t})=>{const n=H(),[s]=Ve(),o=a.useNotify(),[i,u]=C.useState(!1),{data:b=[],error:r,isLoading:l}=ee(),{canEditIdentity:h}=Ce(),j=b.filter(p=>!h(p)),{desiredState:f,save:I,undo:v}=ht({initialState:{identitiesAdded:new Set,identitiesRemoved:new Set}});r&&o.failure("Loading panel details failed",r),C.useEffect(()=>{if(!t.length){n.clear();return}},[t]);const x=b.filter(p=>!ye(p)),{identityIdsInAllGroups:c,identityIdsInNoGroups:g,identityIdsInSomeGroups:w}=gt(t,x),y=new Set(f.identitiesAdded);for(const p of c)f.identitiesRemoved.has(p)||y.add(p);const G=new Set(w.filter(p=>!y.has(p)&&!f.identitiesRemoved.has(p))),d=new Set;t.forEach(p=>{Y(p).forEach(P=>d.add(P))});const m=d.size>0,S=()=>{const p=new Set;for(const P of c)y.has(P)||p.add(P);for(const P of w)G.has(P)||p.add(P);for(const P of g)y.has(P)&&p.add(P);return p},L=(p,P)=>{I(P?{identitiesAdded:new Set,identitiesRemoved:new Set(x.map(U=>U.id))}:{identitiesAdded:new Set(p),identitiesRemoved:new Set})},M=p=>{const P=y.has(p),U=G.has(p),z=new Set(f.identitiesAdded),ie=new Set(f.identitiesRemoved);P||U?(z.delete(p),ie.add(p)):(z.add(p),ie.delete(p)),I({identitiesAdded:z,identitiesRemoved:ie})},D=()=>{n.clear(),o.clear(),u(!1)},B=()=>{o.clear(),u(!1)},R=S(),K=[{content:"Identity",sortKey:"name"},{content:"","aria-label":"Modified status",className:"modified-status"}],_={queries:s.getAll(rt),authMethod:s.getAll(at),systemIdentities:s.get(ot)},$=x.filter(p=>!(_.systemIdentities==="hide"&<(p)||!_.queries.every(P=>Q(p).toLowerCase().includes(P)||p.id.toLowerCase().includes(P))||_.authMethod.length>0&&!_.authMethod.includes(p.authentication_method))).map(p=>{const P=t.length>1?"all selected groups":`group ${t[0].name}`,U=f.identitiesAdded.has(p.id)?`Identity will be added to ${P}`:f.identitiesRemoved.has(p.id)?`Identity will be removed from ${P}`:"",z=Q(p);return{key:p.id,name:p.id,className:"u-row",columns:[{content:z,role:"rowheader","aria-label":"Identity",title:h(p)?z:"You do not have permission to manage this identity"},{content:R.has(p.id)&&e.jsx(a.Icon,{name:"status-in-progress-small"}),role:"cell","aria-label":"Modified status",className:"modified-status u-align--right",title:U}],sortData:{name:z.toLowerCase(),isPreselected:d.has(p.id)}}}),{rows:T}=ce({rows:$,defaultSort:m?"isPreselected":"name",defaultSortDirection:m?"descending":"ascending"}),k=e.jsx(a.ScrollableTable,{dependencies:[b,R.size,o.notification],tableId:"group-identities-table",belowIds:["panel-footer"],children:e.jsx(le,{id:"group-identities-table",headers:K,rows:T,sortable:!0,emptyStateMsg:"No identities found",itemName:"identity",parentName:"server",selectedNames:Array.from(y),setSelectedNames:L,disabledNames:j.map(p=>p.id),filteredNames:x.map(p=>p.id),indeterminateNames:Array.from(G),onToggleRow:M,hideContextualMenu:!0,disableSelectAll:!!j.length})}),A=R.size?`Apply ${R.size} identity ${F("change",R.size)}`:"Modify identities",E=t.length>1?`Change identities for ${t.length} groups`:`Change identities for ${t[0]?.name}`;return e.jsxs(e.Fragment,{children:[e.jsxs(a.SidePanel,{loading:l,hasError:!b,children:[e.jsx(a.SidePanel.Header,{children:e.jsx(a.SidePanel.HeaderTitle,{children:E})}),e.jsx(ne,{className:"u-no-padding"}),e.jsx(ct,{}),e.jsx(a.SidePanel.Content,{className:"u-no-padding",children:e.jsx(a.ScrollableContainer,{dependencies:[R.size,o.notification],belowIds:["panel-footer"],children:k})}),e.jsxs(a.SidePanel.Footer,{className:"u-align--right",children:[R.size?e.jsx(ft,{modifiedCount:R.size,onUndoChange:v,itemName:"identity"}):null,e.jsx(a.Button,{appearance:"base",onClick:D,className:"u-no-margin--bottom",children:"Cancel"}),e.jsx(a.ActionButton,{appearance:"positive",onClick:()=>{u(!0)},className:"u-no-margin--bottom",disabled:R.size===0,children:A})]})]}),i&&e.jsx(Ft,{close:B,onConfirm:B,selectedGroups:t,addedIdentities:f.identitiesAdded,removedIdentities:f.identitiesRemoved,allIdentities:x})]})},$t=({groups:t,className:n,onDelete:s})=>{const[o,i]=C.useState(!1),{canDeleteGroup:u}=V(),b=t.filter(u),r=()=>{i(!0)},l=()=>{s(),i(!1)};return e.jsxs(e.Fragment,{children:[e.jsxs(a.Button,{onClick:r,title:b.length?"Delete groups":`You do not have permission to delete the selected ${F("group",t.length)}`,className:n,hasIcon:!0,disabled:!b.length,children:[e.jsx(a.Icon,{name:"delete"}),e.jsx("span",{children:`Delete ${t.length} ${F("group",t.length)}`})]}),o&&e.jsx(Ge,{groups:t,close:l})]})},tn=()=>{const t=a.useNotify(),{data:n=[],error:s,isLoading:o}=st(),i=H(),[u,b]=C.useState(""),[r,l]=C.useState([]),{canCreateGroups:h}=je(),j=We();s&&t.failure("Loading groups failed",s),C.useEffect(()=>{const m=r.filter(S=>n.some(L=>L.name===S));m.length!==r.length&&l(m)},[n]),C.useEffect(()=>{i.group&&l([i.group])},[i.group,n]);const f=[{content:"Name",className:"name",sortKey:"name"},{content:"Description",className:"description",sortKey:"description"},{content:"Identities",sortKey:"identities",className:"u-align--right identities"},{content:"Permissions",sortKey:"permissions",className:"u-align--right permissions"},{"aria-label":"Actions",className:"u-align--right actions"}],I=n.filter(m=>!u||m.name.toLowerCase().includes(u)||m.description.toLowerCase().includes(u)),v=n.filter(m=>r.includes(m.name)),x=n.find(m=>m.name===i.group),c=I.map(m=>{const S=Y(m);return{key:m.name,name:m.name,className:"u-row",columns:[{content:m.name,role:"rowheader","aria-label":"Name",className:"u-truncate name",title:m.name},{content:e.jsx("span",{children:m.description}),role:"cell","aria-label":"Description",className:"description",title:m.description},{content:e.jsx(a.Button,{appearance:"link",dense:!0,onClick:()=>{i.openEditGroup(m.name,"identity")},children:S.length}),role:"cell",className:"u-align--right identities","aria-label":"Identities in this group"},{content:e.jsx(a.Button,{appearance:"link",dense:!0,onClick:()=>{i.openEditGroup(m.name,"permission")},children:m.permissions?.length||0}),role:"cell",className:"u-align--right permissions","aria-label":"Permissions for this group"},{className:"actions u-align--right",content:e.jsx(yt,{group:m}),role:"cell","aria-label":"Actions"}],sortData:{name:m.name.toLowerCase(),description:m.description.toLowerCase(),permissions:m.permissions?.length||0,identities:S.length}}}),{rows:g,updateSort:w}=ce({rows:c,defaultSort:"name"});if(o)return e.jsx(a.Spinner,{className:"u-loader",text:"Loading...",isMainComponent:!0});const y=()=>r.length>0?e.jsx(Je,{totalCount:n.length??0,itemName:"group",parentName:"",selectedNames:r,setSelectedNames:l,filteredNames:I.map(m=>m.name),hideActions:!!i.panel}):null,G=n.length>0,d=G?e.jsx(a.ScrollableTable,{dependencies:[n],tableId:"groups-table",belowIds:["status-bar"],children:e.jsx(a.TablePagination,{data:g,id:"pagination",itemName:"group",className:"u-no-margin--top","aria-label":"Table pagination control",description:y(),children:e.jsx(le,{id:"groups-table",className:"groups-table",headers:f,rows:g,sortable:!0,emptyStateMsg:"No groups found matching this search",onUpdateSort:w,itemName:"group",parentName:"",selectedNames:r,setSelectedNames:l,disabledNames:[],filteredNames:I.map(m=>m.name),disableSelect:!!i.panel})})}):e.jsxs(a.EmptyState,{className:"empty-state",image:e.jsx(a.Icon,{name:"user-group",className:"empty-state-icon"}),title:"No groups",children:[e.jsx("p",{children:"Groups are an easy way to manage the structured assignment of permissions"}),e.jsx("p",{children:e.jsx(Xe,{docPath:"/explanation/authorization",hasExternalIcon:!0,children:"Learn more about permissions"})}),e.jsxs(a.Button,{className:"empty-state-button",appearance:"positive",onClick:()=>{i.openCreateGroup()},disabled:!h(),title:h()?"":"You do not have permission to create groups",hasIcon:!j,children:[!j&&e.jsx(a.Icon,{name:"plus",light:!0}),e.jsx("span",{children:"Create group"})]})]});return e.jsxs(e.Fragment,{children:[e.jsxs(a.CustomLayout,{mainClassName:"permission-groups-list",contentClassName:"u-no-padding--bottom",header:e.jsxs(W,{children:[e.jsxs(W.Left,{children:[e.jsx(W.Title,{children:e.jsx(Ze,{docPath:"/explanation/authorization",title:"Learn more about permissions",children:"Auth groups"})}),!r.length&&G&&e.jsx(W.Search,{children:e.jsx(pt,{onChange:b,value:u,disabled:!!i.group,className:"u-no-margin--bottom"})}),r.length>0&&!i.panel&&e.jsxs(e.Fragment,{children:[e.jsx(kt,{groups:v,className:"u-no-margin--bottom"}),e.jsx($t,{groups:v,className:"u-no-margin--bottom",onDelete:()=>{l([])}})]})]}),G&&e.jsx(W.BaseActions,{children:!r.length&&e.jsxs(a.Button,{appearance:"positive",className:"u-no-margin--bottom u-float-right",onClick:()=>{i.openCreateGroup()},disabled:!h(),title:h()?"":"You do not have permission to create groups",hasIcon:!j,children:[!j&&e.jsx(a.Icon,{name:"plus",light:!0}),e.jsx("span",{children:"Create group"})]})})]}),children:[!i.panel&&e.jsx(ne,{}),e.jsx(a.Row,{className:"permission-groups",children:d})]}),i.panel===oe.createGroup&&e.jsx(Lt,{}),i.panel===oe.editGroup&&x&&e.jsx(Tt,{group:x,onClose:()=>{l([])}}),i.panel===oe.groupIdentities&&!!v.length&&e.jsx(Mt,{groups:v})]})};export{tn as default};