@spotify/backstage-plugin-rbac 0.7.7 → 0.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/alpha/pages.esm.js +1 -1
  3. package/dist/alpha.d.ts +7 -6
  4. package/dist/components/Auth/Authorized.esm.js +1 -1
  5. package/dist/components/ConfirmationDialog/ConfirmationDialog.esm.js +1 -1
  6. package/dist/components/DecisionDialog/ConditionalDecisionForm/AddConditionSelector.esm.js +1 -1
  7. package/dist/components/DecisionDialog/ConditionalDecisionForm/ConditionCard.esm.js +1 -1
  8. package/dist/components/DecisionDialog/ConditionalDecisionForm/ConditionTree.esm.js +1 -1
  9. package/dist/components/DecisionDialog/ConditionalDecisionForm/ConditionTypeSelector.esm.js +1 -1
  10. package/dist/components/DecisionDialog/ConditionalDecisionForm/ConditionalDecisionForm.esm.js +1 -1
  11. package/dist/components/DecisionDialog/ConditionalDecisionForm/CriteriaSummary/ConditionLevelSummary.esm.js +1 -1
  12. package/dist/components/DecisionDialog/ConditionalDecisionForm/CriteriaSummary/ConditionSummary.esm.js +1 -1
  13. package/dist/components/DecisionDialog/ConditionalDecisionForm/CriteriaSummary/ConditionalDecisionBox.esm.js +1 -1
  14. package/dist/components/DecisionDialog/ConditionalDecisionForm/CriteriaSummary/CriteriaSummary.esm.js +1 -1
  15. package/dist/components/DecisionDialog/ConditionalDecisionForm/CriteriaSummary/Indent.esm.js +1 -1
  16. package/dist/components/DecisionDialog/ConditionalDecisionForm/CriteriaSummary/MonospaceText.esm.js +1 -1
  17. package/dist/components/DecisionDialog/DecisionDialog.esm.js +1 -1
  18. package/dist/components/DecisionDialog/MatchByActions.esm.js +1 -1
  19. package/dist/components/DecisionDialog/MatchByName.esm.js +1 -1
  20. package/dist/components/DecisionDialog/MatchByResourceType.esm.js +1 -1
  21. package/dist/components/DecisionDialog/ParamsForm/ParamsForm.esm.js +1 -1
  22. package/dist/components/DecisionDialog/ParamsForm/ParamsFormArrayInput.esm.js +1 -1
  23. package/dist/components/DecisionDialog/ParamsForm/ParamsFormBooleanInput.esm.js +1 -1
  24. package/dist/components/DecisionDialog/ParamsForm/ParamsFormInput.esm.js +1 -1
  25. package/dist/components/DecisionDialog/ParamsForm/ParamsFormInputRouter.esm.js +1 -1
  26. package/dist/components/DecisionDialog/ParamsForm/ParamsFormJSONEditor.esm.js +1 -1
  27. package/dist/components/DecisionDialog/ParamsForm/ParamsFormStandard.esm.js +1 -1
  28. package/dist/components/DecisionDialog/ToggleButtonGroup.esm.js +1 -1
  29. package/dist/components/DecisionDialog/VerticalSelection.esm.js +1 -1
  30. package/dist/components/Diffing/DiffBadge.esm.js +1 -1
  31. package/dist/components/Diffing/DiffSummary.esm.js +1 -1
  32. package/dist/components/EditableInput/EditableInput.esm.js +1 -1
  33. package/dist/components/Home/HomePage.esm.js +1 -1
  34. package/dist/components/Home/HomePageContent.esm.js +1 -1
  35. package/dist/components/Home/HomePageEmptyState.esm.js +1 -1
  36. package/dist/components/Layout/Breadcrumbs.esm.js +1 -1
  37. package/dist/components/Layout/EmptyStateImageWrapper.esm.js +1 -1
  38. package/dist/components/Layout/PageWrapper.esm.js +1 -1
  39. package/dist/components/Layout/Title.esm.js +1 -1
  40. package/dist/components/Members/MemberLabel.esm.js +1 -1
  41. package/dist/components/Members/MemberOptionsProvider.esm.js +1 -1
  42. package/dist/components/Members/MembersAutocomplete.esm.js +1 -1
  43. package/dist/components/Members/MembersAutocompleteListBox.esm.js +1 -1
  44. package/dist/components/Members/MembersTable.esm.js +1 -1
  45. package/dist/components/Members/MembersTableBody.esm.js +1 -1
  46. package/dist/components/Permission/PermissionName.esm.js +1 -1
  47. package/dist/components/Permissions/PermissionsMetadataContext.esm.js +1 -1
  48. package/dist/components/Permissions/PermissionsTable.esm.js +1 -1
  49. package/dist/components/Policies/PoliciesProvider.esm.js +1 -1
  50. package/dist/components/Policies/PoliciesTable.esm.js +1 -1
  51. package/dist/components/Policy/EmptyRolesCard.esm.js +1 -1
  52. package/dist/components/Policy/PolicyCard.esm.js +1 -1
  53. package/dist/components/Policy/PolicyConflictDialog.esm.js +1 -1
  54. package/dist/components/Policy/PolicyImportButton.esm.js +1 -1
  55. package/dist/components/Policy/PolicyInvalidDialog.esm.js +1 -1
  56. package/dist/components/Policy/PolicyMenu.esm.js +1 -1
  57. package/dist/components/Policy/PolicyOptionCard.esm.js +1 -1
  58. package/dist/components/Policy/PolicyOptionsPage.esm.js +1 -1
  59. package/dist/components/Policy/PolicyPage.esm.js +1 -1
  60. package/dist/components/Policy/PolicyProvider.esm.js +1 -1
  61. package/dist/components/Policy/PolicyPublishButton.esm.js +1 -1
  62. package/dist/components/Policy/PolicyPublishConfirmationDialog.esm.js +1 -1
  63. package/dist/components/Policy/PolicyPublishSuccessDialog.esm.js +1 -1
  64. package/dist/components/Policy/PolicyStatusChip.esm.js +1 -1
  65. package/dist/components/Policy/useDuplicatePolicy.esm.js +1 -1
  66. package/dist/components/PolicyTester/DecisionBreakdownTable/CellText.esm.js +1 -1
  67. package/dist/components/PolicyTester/DecisionBreakdownTable/DecidingRoleCell.esm.js +1 -1
  68. package/dist/components/PolicyTester/DecisionBreakdownTable/DecisionBreakdownTable.esm.js +1 -1
  69. package/dist/components/PolicyTester/DecisionBreakdownTable/DecisionCell.esm.js +1 -1
  70. package/dist/components/PolicyTester/DecisionBreakdownTable/PermissionNameCell.esm.js +1 -1
  71. package/dist/components/PolicyTester/DecisionBreakdownTable/RoleNameCell.esm.js +1 -1
  72. package/dist/components/PolicyTester/DecisionBreakdownTable/TableHeaderCell.esm.js +1 -1
  73. package/dist/components/PolicyTester/DecisionBreakdownTable/UserIconCell.esm.js +1 -1
  74. package/dist/components/PolicyTester/DecisionIcon.esm.js +1 -1
  75. package/dist/components/PolicyTester/DecisionInfo.esm.js +1 -1
  76. package/dist/components/PolicyTester/PolicyTestResultDetails.esm.js +1 -1
  77. package/dist/components/PolicyTester/PolicyTester.esm.js +1 -1
  78. package/dist/components/PolicyTester/PolicyTesterFieldset.esm.js +1 -1
  79. package/dist/components/PolicyTester/PolicyTesterPermissionSelect.esm.js +1 -1
  80. package/dist/components/PolicyTester/PolicyTesterResultRow.esm.js +1 -1
  81. package/dist/components/PolicyTester/PolicyTesterResults.esm.js +1 -1
  82. package/dist/components/PolicyTester/PolicyTesterRoleSelect.esm.js +1 -1
  83. package/dist/components/PolicyTester/StatusChip.esm.js +1 -1
  84. package/dist/components/RBACSidebarItem.esm.js +1 -1
  85. package/dist/components/RelativeTime/RelativeTime.esm.js +1 -1
  86. package/dist/components/ReorderControls/ReorderControls.esm.js +1 -1
  87. package/dist/components/ReorderControls/ReorderInfo.esm.js +1 -1
  88. package/dist/components/Role/RolePage.esm.js +1 -1
  89. package/dist/components/Roles/RolesTable.esm.js +1 -1
  90. package/dist/components/Root.esm.js +1 -1
  91. package/dist/hooks/useFeatureFlag.esm.js +2 -0
  92. package/dist/index.d.ts +1 -2
  93. package/package.json +19 -19
@@ -1,2 +1,2 @@
1
- import{parseEntityRef as E}from"@backstage/catalog-model";import{makeStyles as x,Box as R,Checkbox as C,TextField as k,CircularProgress as A}from"@material-ui/core";import{Autocomplete as S}from"@material-ui/lab";import t,{useState as O,useReducer as P,useEffect as F}from"react";import{MemberLabel as L}from"./MemberLabel.esm.js";import{MembersAutocompleteListBox as M}from"./MembersAutocompleteListBox.esm.js";const I=x({autocomplete:{display:"flex",flex:1}});function w({members:n,allOptions:r,memberDisplayNames:m,loading:o=!1,disabled:s=!1,placeholder:u,onTextChange:a,onToggleMember:d,onChange:f}){const b=I(),[l,i]=O(!1),[y,g]=P(e=>e+1,0),h=(e,c)=>{c&&(d(c),g())};return F(()=>{l&&a("")},[l,a]),t.createElement(R,{width:250},t.createElement(S,{key:`${y}`,open:l,onOpen:()=>{i(!0)},onClose:()=>{i(!1)},onChange:h,getOptionLabel:e=>m.get(e.entityRef)||e.entityRef,groupBy:B,ListboxComponent:M,renderOption:e=>t.createElement("div",{key:e.entityRef},t.createElement(C,{id:`checkbox-${e.entityRef}`,checked:n.includes(e.entityRef),color:"primary"}),t.createElement("label",{htmlFor:`checkbox-${e.entityRef}`},t.createElement(L,{member:e}))),options:r,openOnFocus:!0,disabled:s,loading:o,className:b.autocomplete,renderInput:e=>t.createElement(k,{...e,placeholder:u,variant:"standard",onChange:f,InputProps:{...e.InputProps,endAdornment:t.createElement(t.Fragment,null,o?t.createElement(A,{color:"inherit",size:20}):null,e.InputProps.endAdornment)}})}))}const p={user:"USERS",group:"GROUPS",namespace:"NAMESPACES"};function B(n){const{name:r,kind:m}=E(n.entityRef),o=r==="*"?"namespace":m;if(!p[o])throw new Error(`Group '${o}' is not supported for members in a policy`);return p[o]}export{w as MembersAutocomplete};
1
+ import{jsx as o,jsxs as a}from"react/jsx-runtime";import{parseEntityRef as R}from"@backstage/catalog-model";import{makeStyles as C,Box as A,Checkbox as S,TextField as k,CircularProgress as E}from"@material-ui/core";import{Autocomplete as O}from"@material-ui/lab";import{useState as P,useReducer as M,useEffect as w,Fragment as B}from"react";import{MemberLabel as F}from"./MemberLabel.esm.js";import{MembersAutocompleteListBox as I}from"./MembersAutocompleteListBox.esm.js";const L=C({autocomplete:{display:"flex",flex:1}});function $({members:n,allOptions:r,memberDisplayNames:i,loading:t=!1,disabled:d=!1,placeholder:u,onTextChange:s,onToggleMember:f,onChange:h}){const b=L(),[p,m]=P(!1),[g,y]=M(e=>e+1,0),x=(e,l)=>{l&&(f(l),y())};return w(()=>{p&&s("")},[p,s]),o(A,{width:250,children:o(O,{open:p,onOpen:()=>{m(!0)},onClose:()=>{m(!1)},onChange:x,getOptionLabel:e=>i.get(e.entityRef)||e.entityRef,groupBy:N,ListboxComponent:I,renderOption:e=>a("div",{children:[o(S,{id:`checkbox-${e.entityRef}`,checked:n.includes(e.entityRef),color:"primary"}),o("label",{htmlFor:`checkbox-${e.entityRef}`,children:o(F,{member:e})})]},e.entityRef),options:r,openOnFocus:!0,disabled:d,loading:t,className:b.autocomplete,renderInput:e=>o(k,{...e,placeholder:u,variant:"standard",onChange:h,InputProps:{...e.InputProps,endAdornment:a(B,{children:[t?o(E,{color:"inherit",size:20}):null,e.InputProps.endAdornment]})}})},`${g}`)})}const c={user:"USERS",group:"GROUPS",namespace:"NAMESPACES"};function N(n){const{name:r,kind:i}=R(n.entityRef),t=r==="*"?"namespace":i;if(!c[t])throw new Error(`Group '${t}' is not supported for members in a policy`);return c[t]}export{$ as MembersAutocomplete};
2
2
  //# sourceMappingURL=MembersAutocomplete.esm.js.map
@@ -1,2 +1,2 @@
1
- import r,{useMemo as f,Children as s,isValidElement as t}from"react";import{List as u}from"react-virtualized";const w=r.forwardRef(function({children:n,role:h,...p},d){const l=f(()=>{const e=[];return s.forEach(n,o=>{if(t(o)){const c=o.props.children[0];t(c)&&e.push(c);const i=o.props.children[1];if(t(i)){const a=s.toArray(i.props.children).filter(t);e.push(...a)}}}),e},[n]),m=l.length;return r.createElement("div",{ref:d},r.createElement("ul",{...p},r.createElement(u,{height:250,width:250,rowHeight:54,overscanCount:5,rowCount:m,rowRenderer:e=>r.cloneElement(l[e.index],{style:{...e.style,whiteSpace:"nowrap"}}),role:h})))});export{w as MembersAutocompleteListBox};
1
+ import{jsx as t}from"react/jsx-runtime";import{forwardRef as u,useMemo as a,Children as c,isValidElement as e,cloneElement as w}from"react";import{List as x}from"react-virtualized";const g=u(function({children:n,role:h,...p},d){const i=a(()=>{const r=[];return c.forEach(n,o=>{if(e(o)){const s=o.props.children[0];e(s)&&r.push(s);const l=o.props.children[1];if(e(l)){const m=c.toArray(l.props.children).filter(e);r.push(...m)}}}),r},[n]),f=i.length;return t("div",{ref:d,children:t("ul",{...p,children:t(x,{height:250,width:250,rowHeight:54,overscanCount:5,rowCount:f,rowRenderer:r=>w(i[r.index],{style:{...r.style,whiteSpace:"nowrap"}}),role:h})})})});export{g as MembersAutocompleteListBox};
2
2
  //# sourceMappingURL=MembersAutocompleteListBox.esm.js.map
@@ -1,2 +1,2 @@
1
- import{parseEntityRef as L}from"@backstage/catalog-model";import{useApi as k,useApiHolder as P}from"@backstage/core-plugin-api";import{catalogApiRef as j,entityPresentationApiRef as F}from"@backstage/plugin-catalog-react";import{makeStyles as V,debounce as q,Card as z,CardHeader as G,Box as J,CardContent as K,Table as Q,TableHead as U,TableRow as W,TableCell as c,TableBody as X}from"@material-ui/core";import a,{useState as Y,useRef as Z,useMemo as u}from"react";import v from"react-use/lib/useAsync";import{rbacApiRef as _}from"../../api.esm.js";import{useMemberOptions as ee}from"./MemberOptionsProvider.esm.js";import{MembersAutocomplete as te}from"./MembersAutocomplete.esm.js";import ae from"./MembersTableBody.esm.js";const re=V(()=>({header:{display:"flex",flexDirection:"row",justifyContent:"space-between",paddingLeft:"1rem",paddingRight:"1rem",gap:"1rem"},actionCol:{width:48},typeIconCol:{paddingRight:"0.4rem"},nameCol:{paddingLeft:0}}));function ne({diff:o,policyId:r,role:e,onToggleMember:n,readonly:i=!1,debounceTime:E=1e3}){const y=re(),D=k(_),R=k(j),C=P().get(F),[T,b]=Y(""),{current:p}=Z({}),$=u(()=>q(t=>{b(t.target.value.toLowerCase())},E),[b,E]),{value:g,loading:H}=ee(),{loading:h,value:s}=v(async()=>{const t=await R.getEntityFacets({facets:["metadata.namespace"],filter:{kind:["group","user"]}}).then(m=>m.facets["metadata.namespace"].map(l=>l.value));return me(t)},[R]),w=t=>{p[t.entityRef]=t,n(t.entityRef)},d=s?s?.length>2:!1,M=u(()=>s?s.filter(t=>t.entityRef.toLowerCase().includes(T)):[],[s,T]),f=u(()=>d?M.concat(g?.members||[]):g?.members||[],[g,M,d]),A=u(()=>x(f,C),[f,C]),N=t=>{if(p[t])return p[t];const m=f.find(O=>O.entityRef===t),l=L(t);return{entityRef:t,type:l.kind.toLowerCase(),name:l.name??t,namespace:l.namespace,description:m?.description,spec:m?.spec}},S=e.members==="*",{loading:B,error:I}=v(async()=>{e.members==="*"||e.members.length===0||(await D.getPolicy(r)).roles.find(t=>t.id===e.id)===void 0||e.members.forEach(t=>{const m=N(t);p[m.entityRef]=m})},[r,S]);return a.createElement(z,null,a.createElement(G,{title:"Members",action:a.createElement(J,{m:1,mt:1.25},a.createElement(te,{onToggleMember:w,members:e.members,disabled:i,allOptions:f,memberDisplayNames:A,loading:H||h,onTextChange:b,onChange:$,placeholder:d?"Select members":"Select specific users/groups"}))}),a.createElement(K,null,a.createElement(Q,{"data-testid":"membersTable"},a.createElement(U,null,a.createElement(W,null,a.createElement(c,{className:y.typeIconCol}),a.createElement(c,{className:y.nameCol},"Name"),a.createElement(c,null,"Type"),a.createElement(c,null),!i&&a.createElement(c,{className:y.actionCol}))),a.createElement(X,null,a.createElement(ae,{diff:o,loading:B||h,isMultiNamespaces:d,error:I,members:Array.isArray(e.members)?e.members.map(N):e.members,memberDisplayNames:A,onToggleMember:w,readonly:i})))))}function x(o,r){return new Map(o.map(e=>{const n=L(e.entityRef),i=n.name==="*"?`${n.kind}:${e.namespace||n.namespace}`:r?.forEntity({apiVersion:"",kind:e.type,metadata:{name:e.name||n.name,namespace:e.namespace||n.namespace,description:e.description},spec:e.spec})?.snapshot.primaryTitle||n.name;return[e.entityRef,i]}))}function me(o){return o.map(r=>[{name:"*",type:"user",entityRef:`user:${r}/*`},{name:"*",type:"group",entityRef:`group:${r}/*`}]).flat().sort((r,e)=>r.entityRef.toLowerCase().localeCompare(e.entityRef.toLowerCase()))}export{ne as MembersTable,x as getMemberDisplayNames};
1
+ import{jsxs as h,jsx as t}from"react/jsx-runtime";import{parseEntityRef as k}from"@backstage/catalog-model";import{useApi as v,useApiHolder as P}from"@backstage/core-plugin-api";import{catalogApiRef as F,entityPresentationApiRef as V}from"@backstage/plugin-catalog-react";import{makeStyles as q,debounce as z,Card as G,CardHeader as J,Box as K,CardContent as Q,Table as U,TableHead as W,TableRow as X,TableCell as p,TableBody as Y}from"@material-ui/core";import{useState as Z,useRef as _,useMemo as y}from"react";import E from"react-use/lib/useAsync";import{rbacApiRef as ee}from"../../api.esm.js";import{useMemberOptions as ae}from"./MemberOptionsProvider.esm.js";import{MembersAutocomplete as te}from"./MembersAutocomplete.esm.js";import re from"./MembersTableBody.esm.js";const ne=q(()=>({header:{display:"flex",flexDirection:"row",justifyContent:"space-between",paddingLeft:"1rem",paddingRight:"1rem",gap:"1rem"},actionCol:{width:48},typeIconCol:{paddingRight:"0.4rem"},nameCol:{paddingLeft:0}}));function oe({diff:i,policyId:r,role:e,onToggleMember:n,readonly:m=!1,debounceTime:C=1e3}){const b=ne(),S=v(ee),R=v(F),T=P().get(V),[w,u]=Z(""),{current:c}=_({}),D=y(()=>z(a=>{u(a.target.value.toLowerCase())},C),[u,C]),{value:g,loading:H}=ae(),{loading:M,value:s}=E(async()=>{const a=await R.getEntityFacets({facets:["metadata.namespace"],filter:{kind:["group","user"]}}).then(o=>o.facets["metadata.namespace"].map(l=>l.value));return ie(a)},[R]),A=a=>{c[a.entityRef]=a,n(a.entityRef)},d=s?s?.length>2:!1,N=y(()=>s?s.filter(a=>a.entityRef.toLowerCase().includes(w)):[],[s,w]),f=y(()=>d?N.concat(g?.members||[]):g?.members||[],[g,N,d]),L=y(()=>$(f,T),[f,T]),x=a=>{if(c[a])return c[a];const o=f.find(O=>O.entityRef===a),l=k(a);return{entityRef:a,type:l.kind.toLowerCase(),name:l.name??a,namespace:l.namespace,description:o?.description,spec:o?.spec}},j=e.members==="*",{loading:B,error:I}=E(async()=>{e.members==="*"||e.members.length===0||(await S.getPolicy(r)).roles.find(a=>a.id===e.id)===void 0||e.members.forEach(a=>{const o=x(a);c[o.entityRef]=o})},[r,j]);return h(G,{children:[t(J,{title:"Members",action:t(K,{m:1,mt:1.25,children:t(te,{onToggleMember:A,members:e.members,disabled:m,allOptions:f,memberDisplayNames:L,loading:H||M,onTextChange:u,onChange:D,placeholder:d?"Select members":"Select specific users/groups"})})}),t(Q,{children:h(U,{"data-testid":"membersTable",children:[t(W,{children:h(X,{children:[t(p,{className:b.typeIconCol}),t(p,{className:b.nameCol,children:"Name"}),t(p,{children:"Type"}),t(p,{}),!m&&t(p,{className:b.actionCol})]})}),t(Y,{children:t(re,{diff:i,loading:B||M,isMultiNamespaces:d,error:I,members:Array.isArray(e.members)?e.members.map(x):e.members,memberDisplayNames:L,onToggleMember:A,readonly:m})})]})})]})}function $(i,r){return new Map(i.map(e=>{const n=k(e.entityRef),m=n.name==="*"?`${n.kind}:${e.namespace||n.namespace}`:r?.forEntity({apiVersion:"",kind:e.type,metadata:{name:e.name||n.name,namespace:e.namespace||n.namespace,description:e.description},spec:e.spec})?.snapshot.primaryTitle||n.name;return[e.entityRef,m]}))}function ie(i){return i.map(r=>[{name:"*",type:"user",entityRef:`user:${r}/*`},{name:"*",type:"group",entityRef:`group:${r}/*`}]).flat().sort((r,e)=>r.entityRef.toLowerCase().localeCompare(e.entityRef.toLowerCase()))}export{oe as MembersTable,$ as getMemberDisplayNames};
2
2
  //# sourceMappingURL=MembersTable.esm.js.map
@@ -1,2 +1,2 @@
1
- import{parseEntityRef as p}from"@backstage/catalog-model";import{Progress as I}from"@backstage/core-components";import{makeStyles as S,TableRow as i,TableCell as r,IconButton as h}from"@material-ui/core";import k from"@material-ui/icons/Delete";import B from"@material-ui/icons/Group";import M from"@material-ui/icons/GroupWork";import T from"@material-ui/icons/Person";import e from"react";import{DiffBadge as g}from"../Diffing/DiffBadge.esm.js";import{MemberLabel as v}from"./MemberLabel.esm.js";const A=S(m=>({actionCol:{width:48},typeIconCol:{paddingRight:"0.4rem"},nameCol:{paddingLeft:0},typeIcon:{color:m.palette.grey[500]}}));function D({diff:m,loading:d,isMultiNamespaces:o,members:f,memberDisplayNames:u,error:y,onToggleMember:b,readonly:l=!1}){const a=A();if(d)return e.createElement(i,null,e.createElement(r,{scope:"row",colSpan:l?4:5},e.createElement(I,null)));if(y&&y.message,f==="*")return e.createElement(i,null,e.createElement(r,{colSpan:2,height:80},"All"),e.createElement(r,{colSpan:l?2:3},e.createElement(g,{operation:m?.members["*"].operation})));if(f.length===0)return e.createElement(i,null,e.createElement(r,{scope:"row",colSpan:l?4:5},"Select users or groups using the drop-down menu above."));const C=f.sort((t,n)=>{const c=u.get(t.entityRef)||p(t.entityRef).name,s=u.get(n.entityRef)||p(n.entityRef).name;let E=0;o&&n.name==="*"&&t.name!=="*"?E=1:o&&t.name==="*"&&n.name!=="*"&&(E=-1);const R=t.type.localeCompare(n.type),w=p(t.entityRef).namespace.localeCompare(p(n.entityRef).namespace),N=c.localeCompare(s);return E||R||w||N});return e.createElement(e.Fragment,null,C.map(t=>{const{name:n,type:c,entityRef:s}=t;return e.createElement(i,{key:s},e.createElement(r,{className:a.typeIconCol},o&&n==="*"&&e.createElement(M,{className:a.typeIcon})||c==="group"&&e.createElement(B,{className:a.typeIcon})||e.createElement(T,{className:a.typeIcon})),e.createElement(r,{scope:"row",className:a.nameCol},e.createElement(v,{member:t})),e.createElement(r,{scope:"row"},n==="*"&&o?"namespace":c),e.createElement(r,null,n&&e.createElement(g,{operation:m?.members[s].operation})),!l&&e.createElement(r,{scope:"row",className:a.actionCol},e.createElement(h,{"aria-label":"Remove member",onClick:()=>b(t),size:"small"},e.createElement(k,null))))}))}export{D as default};
1
+ import{jsx as e,jsxs as g,Fragment as S}from"react/jsx-runtime";import{parseEntityRef as p}from"@backstage/catalog-model";import{Progress as T}from"@backstage/core-components";import{makeStyles as k,TableRow as s,TableCell as n,IconButton as x}from"@material-ui/core";import B from"@material-ui/icons/Delete";import M from"@material-ui/icons/Group";import j from"@material-ui/icons/GroupWork";import v from"@material-ui/icons/Person";import{DiffBadge as u}from"../Diffing/DiffBadge.esm.js";import{MemberLabel as A}from"./MemberLabel.esm.js";const D=k(a=>({actionCol:{width:48},typeIconCol:{paddingRight:"0.4rem"},nameCol:{paddingLeft:0},typeIcon:{color:a.palette.grey[500]}}));function E({diff:a,loading:b,isMultiNamespaces:m,members:d,memberDisplayNames:h,error:y,onToggleMember:R,readonly:c=!1}){const t=D();if(b)return e(s,{children:e(n,{scope:"row",colSpan:c?4:5,children:e(T,{})})});if(y&&y.message,d==="*")return g(s,{children:[e(n,{colSpan:2,height:80,children:"All"}),e(n,{colSpan:c?2:3,children:e(u,{operation:a?.members["*"].operation})})]});if(d.length===0)return e(s,{children:e(n,{scope:"row",colSpan:c?4:5,children:"Select users or groups using the drop-down menu above."})});const C=d.sort((o,r)=>{const i=h.get(o.entityRef)||p(o.entityRef).name,l=h.get(r.entityRef)||p(r.entityRef).name;let f=0;m&&r.name==="*"&&o.name!=="*"?f=1:m&&o.name==="*"&&r.name!=="*"&&(f=-1);const w=o.type.localeCompare(r.type),I=p(o.entityRef).namespace.localeCompare(p(r.entityRef).namespace),N=i.localeCompare(l);return f||w||I||N});return e(S,{children:C.map(o=>{const{name:r,type:i,entityRef:l}=o;return g(s,{children:[e(n,{className:t.typeIconCol,children:m&&r==="*"&&e(j,{className:t.typeIcon})||i==="group"&&e(M,{className:t.typeIcon})||e(v,{className:t.typeIcon})}),e(n,{scope:"row",className:t.nameCol,children:e(A,{member:o})}),e(n,{scope:"row",children:r==="*"&&m?"namespace":i}),e(n,{children:r&&e(u,{operation:a?.members[l].operation})}),!c&&e(n,{scope:"row",className:t.actionCol,children:e(x,{"aria-label":"Remove member",onClick:()=>R(o),size:"small",children:e(B,{})})})]},l)})})}export{E as default};
2
2
  //# sourceMappingURL=MembersTableBody.esm.js.map
@@ -1,2 +1,2 @@
1
- import e,{useMemo as a}from"react";const l=({name:t})=>{const m=a(()=>t.includes(".")?t.split(/(\.)/g).flatMap(n=>[n,e.createElement("wbr",null)]):[t],[t]);return e.createElement(e.Fragment,null,m.map((n,r)=>e.createElement(e.Fragment,{key:r},n)))};export{l as PermissionName};
1
+ import{jsx as n,Fragment as a}from"react/jsx-runtime";import{useMemo as o,Fragment as s}from"react";const i=({name:e})=>{const r=o(()=>e.includes(".")?e.split(/(\.)/g).flatMap(m=>[m,n("wbr",{})]):[e],[e]);return n(a,{children:r.map((m,t)=>n(s,{children:m},t))})};export{i as PermissionName};
2
2
  //# sourceMappingURL=PermissionName.esm.js.map
@@ -1,2 +1,2 @@
1
- import{useApi as a,configApiRef as g,alertApiRef as y}from"@backstage/core-plugin-api";import{isResourcePermission as h}from"@backstage/plugin-permission-common";import{forEach as P,mapValues as A,groupBy as R,uniq as T}from"lodash";import v,{createContext as M,useState as b,useCallback as x,useMemo as w,useContext as C}from"react";import I from"react-use/lib/useAsync";import{rbacApiRef as S}from"../../api.esm.js";const l=M(null),L=({children:e})=>{const t=a(g),r=a(S),n=a(y),[s,o]=b(null),c=x(async()=>{if(!s){const p=await r.fetchAllPermissionMetadata(t.getOptionalStringArray("permission.permissionedPlugins")??[]),m=O(p.rules);P(m,u=>{u.length!==1&&n.post({message:`The plugin(s) ${u.slice(1).join(", ")} expose rules which are conflicting with rules exposed by the ${u[0]} plugin. These rules will not be available for use. Please contact RBAC support if you need assistance resolving this issue.`,severity:"error"})});const d=j(p,m);return o(d),d}return s},[n,s,r,t]);return v.createElement(l.Provider,{value:w(()=>({getMetadata:c}),[c])},e)};function i(){const e=C(l),{value:t,loading:r}=I(async()=>e?.getMetadata(),[e]);return{metadata:t,isLoading:r}}function $(){const{metadata:e}=i();return e?.rules??null}function B(){const{metadata:e,isLoading:t}=i();return{permissions:e?.permissions??null,isLoading:t}}function f(){const{metadata:e}=i();return e?[...new Set(e.permissions.filter(t=>h(t)).map(({resourceType:t})=>t))]:null}function E(){const{metadata:e}=i(),t=f();return!e||!t?null:t.reduce((r,n)=>{const s=e.rules.find(o=>o.resourceType===n);return s&&(r[n]={pluginId:s.pluginId}),r},{})}function O(e){return A(R(e,"resourceType"),t=>T(t.map(({pluginId:r})=>r)))}function j(e,t){return{...e,rules:e.rules.filter(({resourceType:r,pluginId:n})=>{const s=t[r];return n===s[0]})}}export{L as PermissionMetadataProvider,l as PermissionsMetadataContext,$ as useAggregatedRules,i as usePermissionMetadata,B as usePermissions,E as useResourceTypeInfo,f as useResourceTypeOptions};
1
+ import{jsx as g}from"react/jsx-runtime";import{useApi as a,configApiRef as y,alertApiRef as h}from"@backstage/core-plugin-api";import{isResourcePermission as P}from"@backstage/plugin-permission-common";import{forEach as v,mapValues as A,groupBy as R,uniq as T}from"lodash";import{createContext as x,useState as M,useCallback as b,useMemo as w,useContext as C}from"react";import I from"react-use/lib/useAsync";import{rbacApiRef as L}from"../../api.esm.js";const l=x(null),S=({children:e})=>{const r=a(y),t=a(L),n=a(h),[s,o]=M(null),c=b(async()=>{if(!s){const p=await t.fetchAllPermissionMetadata(r.getOptionalStringArray("permission.permissionedPlugins")??[]),m=O(p.rules);v(m,u=>{u.length!==1&&n.post({message:`The plugin(s) ${u.slice(1).join(", ")} expose rules which are conflicting with rules exposed by the ${u[0]} plugin. These rules will not be available for use. Please contact RBAC support if you need assistance resolving this issue.`,severity:"error"})});const d=k(p,m);return o(d),d}return s},[n,s,t,r]);return g(l.Provider,{value:w(()=>({getMetadata:c}),[c]),children:e})};function i(){const e=C(l),{value:r,loading:t}=I(async()=>e?.getMetadata(),[e]);return{metadata:r,isLoading:t}}function $(){const{metadata:e}=i();return e?.rules??null}function j(){const{metadata:e,isLoading:r}=i();return{permissions:e?.permissions??null,isLoading:r}}function f(){const{metadata:e}=i();return e?[...new Set(e.permissions.filter(r=>P(r)).map(({resourceType:r})=>r))]:null}function B(){const{metadata:e}=i(),r=f();return!e||!r?null:r.reduce((t,n)=>{const s=e.rules.find(o=>o.resourceType===n);return s&&(t[n]={pluginId:s.pluginId}),t},{})}function O(e){return A(R(e,"resourceType"),r=>T(r.map(({pluginId:t})=>t)))}function k(e,r){return{...e,rules:e.rules.filter(({resourceType:t,pluginId:n})=>{const s=r[t];return n===s[0]})}}export{S as PermissionMetadataProvider,l as PermissionsMetadataContext,$ as useAggregatedRules,i as usePermissionMetadata,j as usePermissions,B as useResourceTypeInfo,f as useResourceTypeOptions};
2
2
  //# sourceMappingURL=PermissionsMetadataContext.esm.js.map
@@ -1,2 +1,2 @@
1
- import{EmptyState as f}from"@backstage/core-components";import{Card as y,CardHeader as h,Box as g,Button as c,CardContent as C,Table as b,TableHead as w,TableRow as i,TableCell as t,TableBody as k,Link as v,IconButton as R}from"@material-ui/core";import T from"@material-ui/icons/Add";import B from"@material-ui/icons/Delete";import e from"react";import D from"../../images/no-permissions.svg";import{ConfirmationDialog as N}from"../ConfirmationDialog/ConfirmationDialog.esm.js";import{DiffBadge as I}from"../Diffing/DiffBadge.esm.js";import{EmptyStateImageWrapper as P}from"../Layout/EmptyStateImageWrapper.esm.js";import{ReorderControls as x}from"../ReorderControls/ReorderControls.esm.js";import{ReorderInfo as A}from"../ReorderControls/ReorderInfo.esm.js";import{getMatchBy as S,getDecisionDescription as H}from"./utils.esm.js";const M="Use the arrows to change the order in which permission decisions are evaluated.";function O({diff:s,permissions:n,onReorderPermissions:p,onNewPermissionClick:a,onOpenPermission:E,onRemovePermissionClick:d,anyAllow:m,readonly:r=!1}){return e.createElement(y,null,e.createElement(h,{title:"Permission Decisions",action:!r&&n.length!==0&&e.createElement(g,{m:1,mt:1.25},e.createElement(c,{color:"primary",variant:"outlined",startIcon:e.createElement(T,null),onClick:a},"New"))}),e.createElement(C,null,e.createElement(b,{"data-testid":"permissionsTable"},e.createElement(w,null,e.createElement(i,null,!r&&!m&&e.createElement(t,{style:{width:0}},e.createElement(A,{helpText:M})),e.createElement(t,null,"Match by"),e.createElement(t,null,"Decision"),e.createElement(t,null),!r&&e.createElement(t,null))),e.createElement(k,null,n.length===0&&e.createElement(i,null,e.createElement(t,{colSpan:5},e.createElement(f,{title:"No permission decisions set",description:"Click the button below to create your first permission.",missing:{customImage:e.createElement(P,{src:D,alt:"No permission placeholder"})},action:e.createElement(c,{variant:"contained",color:"primary",onClick:a},"New decision")}))),n.map((l,o)=>e.createElement(i,{key:o},!r&&!m&&e.createElement(t,null,e.createElement(x,{array:n,index:o,onReorder:p})),e.createElement(t,null,e.createElement(v,{component:"button",color:"primary",variant:"body2",align:"left",onClick:()=>E(o)},S(l))),e.createElement(t,null,H(l)),e.createElement(t,null,e.createElement(I,{operation:s?.permissions[l.id].operation})),!r&&e.createElement(t,{align:"right"},e.createElement(N,{message:"Are you sure you want to remove this permission decision?",onConfirm:()=>d(o),title:"Remove?"},u=>e.createElement(R,{...u,"aria-label":"Remove permission decision",size:"small"},e.createElement(B,null))))))))))}export{O as default};
1
+ import{jsxs as r,jsx as e}from"react/jsx-runtime";import{EmptyState as g}from"@backstage/core-components";import{Card as u,CardHeader as C,Box as b,Button as m,CardContent as w,Table as k,TableHead as v,TableRow as l,TableCell as i,TableBody as R,Link as T,IconButton as x}from"@material-ui/core";import B from"@material-ui/icons/Add";import D from"@material-ui/icons/Delete";import I from"../../images/no-permissions.svg";import{ConfirmationDialog as N}from"../ConfirmationDialog/ConfirmationDialog.esm.js";import{DiffBadge as P}from"../Diffing/DiffBadge.esm.js";import{EmptyStateImageWrapper as A}from"../Layout/EmptyStateImageWrapper.esm.js";import{ReorderControls as S}from"../ReorderControls/ReorderControls.esm.js";import{ReorderInfo as j}from"../ReorderControls/ReorderInfo.esm.js";import{getMatchBy as E,getDecisionDescription as H}from"./utils.esm.js";const M="Use the arrows to change the order in which permission decisions are evaluated.";function O({diff:d,permissions:n,onReorderPermissions:p,onNewPermissionClick:a,onOpenPermission:h,onRemovePermissionClick:f,anyAllow:c,readonly:o=!1}){return r(u,{children:[e(C,{title:"Permission Decisions",action:!o&&n.length!==0&&e(b,{m:1,mt:1.25,children:e(m,{color:"primary",variant:"outlined",startIcon:e(B,{}),onClick:a,children:"New"})})}),e(w,{children:r(k,{"data-testid":"permissionsTable",children:[e(v,{children:r(l,{children:[!o&&!c&&e(i,{style:{width:0},children:e(j,{helpText:M})}),e(i,{children:"Match by"}),e(i,{children:"Decision"}),e(i,{}),!o&&e(i,{})]})}),r(R,{children:[n.length===0&&e(l,{children:e(i,{colSpan:5,children:e(g,{title:"No permission decisions set",description:"Click the button below to create your first permission.",missing:{customImage:e(A,{src:I,alt:"No permission placeholder"})},action:e(m,{variant:"contained",color:"primary",onClick:a,children:"New decision"})})})}),n.map((s,t)=>r(l,{children:[!o&&!c&&e(i,{children:e(S,{array:n,index:t,onReorder:p})}),e(i,{children:e(T,{component:"button",color:"primary",variant:"body2",align:"left",onClick:()=>h(t),children:E(s)})}),e(i,{children:H(s)}),e(i,{children:e(P,{operation:d?.permissions[s.id].operation})}),!o&&e(i,{align:"right",children:e(N,{message:"Are you sure you want to remove this permission decision?",onConfirm:()=>f(t),title:"Remove?",children:y=>e(x,{...y,"aria-label":"Remove permission decision",size:"small",children:e(D,{})})})})]},t))]})]})})]})}export{O as default};
2
2
  //# sourceMappingURL=PermissionsTable.esm.js.map
@@ -1,2 +1,2 @@
1
- import h,{createContext as u,useState as v,useCallback as l,useMemo as p,useContext as b}from"react";const s=u({hasDraftPolicy:!1,policies:void 0,fallbackPolicy:void 0,setPolicies:()=>{},setFallbackPolicy:()=>{},setPolicy:()=>{},getPolicy:()=>{},removePolicy:()=>{}}),k=()=>b(s);function m({children:a,initialState:t={policies:void 0,fallbackPolicy:void 0,cache:{}}}){const[c,o]=v(t),P=l(i=>{o(e=>({...e,policies:i,cache:d(e.cache,i)}))},[]),r=l(i=>c.cache[i],[c.cache]),y=l(i=>o(e=>({...e,cache:{...e.cache,[i]:void 0},policies:void 0})),[]),n=l(i=>o(e=>({...e,policies:void 0,cache:d(e.cache,[i])})),[]),f=l(i=>o(e=>({...e,fallbackPolicy:i})),[]);return h.createElement(s.Provider,{value:p(()=>({hasDraftPolicy:c.policies?.some(({status:i})=>i==="draft")||!1,policies:c.policies,fallbackPolicy:c.fallbackPolicy,setPolicies:P,setFallbackPolicy:f,setPolicy:n,getPolicy:r,removePolicy:y}),[c.policies,P,c.fallbackPolicy,f,n,r,y])},a)}function d(a,t){if(!t)return a;const c={...a};return t.forEach(o=>{c[o.id]=o}),c}export{s as PoliciesContext,m as PoliciesProvider,k as usePoliciesContext};
1
+ import{jsx as h}from"react/jsx-runtime";import{createContext as p,useState as u,useCallback as l,useMemo as v,useContext as b}from"react";const s=p({hasDraftPolicy:!1,policies:void 0,fallbackPolicy:void 0,setPolicies:()=>{},setFallbackPolicy:()=>{},setPolicy:()=>{},getPolicy:()=>{},removePolicy:()=>{}}),k=()=>b(s);function m({children:a,initialState:t={policies:void 0,fallbackPolicy:void 0,cache:{}}}){const[c,o]=u(t),r=l(i=>{o(e=>({...e,policies:i,cache:d(e.cache,i)}))},[]),P=l(i=>c.cache[i],[c.cache]),y=l(i=>o(e=>({...e,cache:{...e.cache,[i]:void 0},policies:void 0})),[]),n=l(i=>o(e=>({...e,policies:void 0,cache:d(e.cache,[i])})),[]),f=l(i=>o(e=>({...e,fallbackPolicy:i})),[]);return h(s.Provider,{value:v(()=>({hasDraftPolicy:c.policies?.some(({status:i})=>i==="draft")||!1,policies:c.policies,fallbackPolicy:c.fallbackPolicy,setPolicies:r,setFallbackPolicy:f,setPolicy:n,getPolicy:P,removePolicy:y}),[c.policies,r,c.fallbackPolicy,f,n,P,y]),children:a})}function d(a,t){if(!t)return a;const c={...a};return t.forEach(o=>{c[o.id]=o}),c}export{s as PoliciesContext,m as PoliciesProvider,k as usePoliciesContext};
2
2
  //# sourceMappingURL=PoliciesProvider.esm.js.map
@@ -1,2 +1,2 @@
1
- import{Table as y,Link as S}from"@backstage/core-components";import E from"@material-ui/icons/FilterNone";import C from"@material-ui/icons/Publish";import{DateTime as c}from"luxon";import t,{useState as m}from"react";import{assertNever as T}from"../../utils/assert.esm.js";import{PolicyPublishConfirmationDialog as A}from"../Policy/PolicyPublishConfirmationDialog.esm.js";import{PolicyPublishSuccessDialog as I}from"../Policy/PolicyPublishSuccessDialog.esm.js";import{useDuplicatePolicy as O}from"../Policy/useDuplicatePolicy.esm.js";import{usePublishPolicy as k}from"../Policy/usePublishPolicy.esm.js";import{useFetchPolicies as N}from"./useFetchPolicies.esm.js";const _=[{title:"Name",field:"name",render:e=>t.createElement(S,{to:`versions/${e.id}`},e.name)},{title:"Status",field:"status",render:e=>{switch(e.status){case"active":return"Active";case"draft":return"Draft";case"inactive":return"Inactive";default:return T(e.status)}}},{title:"Publish date",field:"lastPublishedAt",render:e=>e.lastPublishedAt?c.fromISO(e.lastPublishedAt).toLocaleString(c.DATETIME_MED_WITH_SECONDS):"",type:"datetime",defaultSort:"desc"},{title:"Published by",field:"lastPublishedBy"}];function w(e){const u=e.data.length>3,{fetchPolicies:d}=N(),[{loading:p},f]=O(),[{loading:b,value:s},P]=k(),[o,l]=m(void 0),[h,a]=m(!1),g=()=>{l(void 0),d()},n=o?.id===s?.id?s:void 0,v=[i=>{const{tableData:D,...r}=i;return{icon:C,tooltip:"Republish",onClick:()=>{l(r),a(!0)},disabled:b}},i=>{const{tableData:D,...r}=i;return{icon:E,tooltip:"Duplicate",disabled:p||!e.canDuplicate,onClick:()=>f(r)}}];return t.createElement(t.Fragment,null,t.createElement(y,{title:"Previous Versions",columns:_,data:e.data,options:{paging:u,pageSize:3,pageSizeOptions:[3,5,10,20],actionsColumnIndex:-1,loadingType:"linear"},actions:v}),o&&t.createElement(A,{open:h,onPublish:i=>{P(o,i),a(!1)},onClose:()=>{l(void 0),a(!1)},policy:o}),n&&t.createElement(I,{isOpen:!0,policy:n,onClose:g}))}export{w as PoliciesTable};
1
+ import{jsxs as y,Fragment as S,jsx as o}from"react/jsx-runtime";import{Table as C,Link as T}from"@backstage/core-components";import A from"@material-ui/icons/FilterNone";import I from"@material-ui/icons/Publish";import{DateTime as c}from"luxon";import{useState as d}from"react";import{assertNever as k}from"../../utils/assert.esm.js";import{PolicyPublishConfirmationDialog as x}from"../Policy/PolicyPublishConfirmationDialog.esm.js";import{PolicyPublishSuccessDialog as E}from"../Policy/PolicyPublishSuccessDialog.esm.js";import{useDuplicatePolicy as O}from"../Policy/useDuplicatePolicy.esm.js";import{usePublishPolicy as N}from"../Policy/usePublishPolicy.esm.js";import{useFetchPolicies as _}from"./useFetchPolicies.esm.js";const j=[{title:"Name",field:"name",render:t=>o(T,{to:`versions/${t.id}`,children:t.name})},{title:"Status",field:"status",render:t=>{switch(t.status){case"active":return"Active";case"draft":return"Draft";case"inactive":return"Inactive";default:return k(t.status)}}},{title:"Publish date",field:"lastPublishedAt",render:t=>t.lastPublishedAt?c.fromISO(t.lastPublishedAt).toLocaleString(c.DATETIME_MED_WITH_SECONDS):"",type:"datetime",defaultSort:"desc"},{title:"Published by",field:"lastPublishedBy"}];function z(t){const u=t.data.length>3,{fetchPolicies:m}=_(),[{loading:p},f]=O(),[{loading:b,value:r},P]=N(),[e,l]=d(void 0),[h,a]=d(!1),g=()=>{l(void 0),m()},n=e?.id===r?.id?r:void 0,v=[i=>{const{tableData:D,...s}=i;return{icon:I,tooltip:"Republish",onClick:()=>{l(s),a(!0)},disabled:b}},i=>{const{tableData:D,...s}=i;return{icon:A,tooltip:"Duplicate",disabled:p||!t.canDuplicate,onClick:()=>f(s)}}];return y(S,{children:[o(C,{title:"Previous Versions",columns:j,data:t.data,options:{paging:u,pageSize:3,pageSizeOptions:[3,5,10,20],actionsColumnIndex:-1,loadingType:"linear"},actions:v}),e&&o(x,{open:h,onPublish:i=>{P(e,i),a(!1)},onClose:()=>{l(void 0),a(!1)},policy:e}),n&&o(E,{isOpen:!0,policy:n,onClose:g})]})}export{z as PoliciesTable};
2
2
  //# sourceMappingURL=PoliciesTable.esm.js.map
@@ -1,2 +1,2 @@
1
- import{EmptyState as o}from"@backstage/core-components";import{makeStyles as m,Card as c,CardHeader as s,CardContent as d,Button as p}from"@material-ui/core";import e from"react";import{useNavigate as f}from"react-router-dom";import g from"../../images/no-roles.svg";import{EmptyStateImageWrapper as u}from"../Layout/EmptyStateImageWrapper.esm.js";import{usePolicyContext as C}from"./PolicyProvider.esm.js";const y=m(t=>({cardHeader:{padding:t.spacing(3,3),borderBottom:`1px solid ${t.palette.border}`},cardContent:{padding:t.spacing(6,3),"& > *":{background:"transparent"}},emptyStateImage:{width:"95%",zIndex:2,position:"relative",left:"50%",top:"50%",transform:"translate(-50%, 15%)"}}));function E({readonly:t}){const r=y(),a=f(),{createNewRole:n}=C(),l=()=>{const i=n();a(`./roles/${i}`)};return e.createElement(c,null,e.createElement(s,{title:"Roles",className:r.cardHeader}),e.createElement(d,{className:r.cardContent},t?e.createElement(o,{title:"No roles configured",missing:"content"}):e.createElement(o,{title:"No roles yet",description:"Click the button below to create your first role.",missing:{customImage:e.createElement(u,{src:g,alt:"No roles placeholder"})},action:e.createElement(p,{variant:"contained",color:"primary",onClick:()=>l()},"New role")})))}export{E as default};
1
+ import{jsxs as l,jsx as t}from"react/jsx-runtime";import{EmptyState as r}from"@backstage/core-components";import{makeStyles as c,Card as d,CardHeader as m,CardContent as p,Button as f}from"@material-ui/core";import{useNavigate as g}from"react-router-dom";import u from"../../images/no-roles.svg";import{EmptyStateImageWrapper as y}from"../Layout/EmptyStateImageWrapper.esm.js";import{usePolicyContext as C}from"./PolicyProvider.esm.js";const N=c(e=>({cardHeader:{padding:e.spacing(3,3),borderBottom:`1px solid ${e.palette.border}`},cardContent:{padding:e.spacing(6,3),"& > *":{background:"transparent"}},emptyStateImage:{width:"95%",zIndex:2,position:"relative",left:"50%",top:"50%",transform:"translate(-50%, 15%)"}}));function h({readonly:e}){const o=N(),a=g(),{createNewRole:n}=C(),i=()=>{const s=n();a(`./roles/${s}`)};return l(d,{children:[t(m,{title:"Roles",className:o.cardHeader}),t(p,{className:o.cardContent,children:e?t(r,{title:"No roles configured",missing:"content"}):t(r,{title:"No roles yet",description:"Click the button below to create your first role.",missing:{customImage:t(y,{src:u,alt:"No roles placeholder"})},action:t(f,{variant:"contained",color:"primary",onClick:()=>i(),children:"New role"})})})]})}export{h as default};
2
2
  //# sourceMappingURL=EmptyRolesCard.esm.js.map
@@ -1,2 +1,2 @@
1
- import{Link as g}from"@backstage/core-components";import{EntityDisplayName as b}from"@backstage/plugin-catalog-react";import{makeStyles as h,Card as v,CardContent as C,Typography as n,List as x,ListItem as o,ListItemIcon as c,ListItemText as m,Box as s,CardActions as I}from"@material-ui/core";import L from"@material-ui/icons/CalendarToday";import N from"@material-ui/icons/Person";import e from"react";import{DiffSummary as S}from"../Diffing/DiffSummary.esm.js";import{RelativeTime as $}from"../RelativeTime/RelativeTime.esm.js";import{getActivityDetails as k}from"./getActivityDetails.esm.js";import{PolicyStatusChip as P}from"./PolicyStatusChip.esm.js";const T=h(t=>({card:a=>({backgroundImage:a.policy.status==="active"?`linear-gradient(${t.palette.success.main}, ${t.palette.success.main})`:`linear-gradient(${t.palette.text.secondary}, ${t.palette.text.secondary})`,backgroundPosition:"top",backgroundSize:"100% 8px",backgroundRepeat:"no-repeat",paddingTop:"8px",height:"100%"}),diffSummaryContainer:{backgroundColor:t.palette.background.default,padding:t.spacing(2),borderWidth:"1px",borderStyle:"solid",borderColor:t.palette.divider,borderRadius:t.shape.borderRadius},header:{display:"flex",justifyContent:"space-between",alignItems:"center"},detailsHeader:{...t.typography.body1,paddingTop:t.spacing(2),color:t.palette.text.secondary},activityList:{color:t.palette.text.secondary},activityListItem:{padding:0},actions:{justifyContent:"flex-start"}}));function D(t){const a=T(t),{policy:r,to:d,withChangeSummary:p}=t,i=`${r.name} ${r.status==="draft"?"- Draft":""}`,u={created:"Created: ",published:"Published: ",updated:"Updated: "},y={created:"Created by",published:"Published by",updated:"Updated by"},{type:l,user:E,timestamp:f}=k(r);return e.createElement(v,{className:a.card},e.createElement(C,null,e.createElement("div",{className:a.header},d?e.createElement(g,{to:`versions/${r.id}`},e.createElement(n,{variant:"h2"},i)):e.createElement(n,{variant:"h2"},i),r.status==="active"?e.createElement(P,{status:"active",size:"small"}):null),r.description?e.createElement(n,{variant:"body1",color:"textSecondary"},'"',r.description,'"'):null,e.createElement(n,{component:"h2",className:a.detailsHeader},"Details"),e.createElement(x,{className:a.activityList},e.createElement(o,{className:a.activityListItem},e.createElement(c,null,e.createElement(L,null)),e.createElement(m,{primary:e.createElement($,{timestamp:f,description:u[l]})})),e.createElement(o,{className:a.activityListItem},e.createElement(c,null,e.createElement(N,null)),e.createElement(m,{primary:e.createElement(e.Fragment,null,y[l]," ",e.createElement(b,{hideIcon:!0,entityRef:E}))}))),p&&e.createElement(s,{paddingTop:2},e.createElement(n,{gutterBottom:!0,variant:"subtitle2"},"What's changed"),e.createElement(s,{className:a.diffSummaryContainer},e.createElement(S,{policy:r})))),t.actions?e.createElement(I,{className:a.actions},t.actions):null)}export{D as PolicyCard};
1
+ import{jsxs as a,jsx as t,Fragment as b}from"react/jsx-runtime";import{Link as v}from"@backstage/core-components";import{EntityDisplayName as C}from"@backstage/plugin-catalog-react";import{makeStyles as x,Card as I,CardContent as L,Typography as d,List as N,ListItem as s,ListItemIcon as c,ListItemText as l,Box as p,CardActions as S}from"@material-ui/core";import k from"@material-ui/icons/CalendarToday";import $ from"@material-ui/icons/Person";import{DiffSummary as T}from"../Diffing/DiffSummary.esm.js";import{RelativeTime as D}from"../RelativeTime/RelativeTime.esm.js";import{getActivityDetails as P}from"./getActivityDetails.esm.js";import{PolicyStatusChip as R}from"./PolicyStatusChip.esm.js";const j=x(e=>({card:i=>({backgroundImage:i.policy.status==="active"?`linear-gradient(${e.palette.success.main}, ${e.palette.success.main})`:`linear-gradient(${e.palette.text.secondary}, ${e.palette.text.secondary})`,backgroundPosition:"top",backgroundSize:"100% 8px",backgroundRepeat:"no-repeat",paddingTop:"8px",height:"100%"}),diffSummaryContainer:{backgroundColor:e.palette.background.default,padding:e.spacing(2),borderWidth:"1px",borderStyle:"solid",borderColor:e.palette.divider,borderRadius:e.shape.borderRadius},header:{display:"flex",justifyContent:"space-between",alignItems:"center"},detailsHeader:{...e.typography.body1,paddingTop:e.spacing(2),color:e.palette.text.secondary},activityList:{color:e.palette.text.secondary},activityListItem:{padding:0},actions:{justifyContent:"flex-start"}}));function w(e){const i=j(e),{policy:r,to:m,withChangeSummary:y}=e,o=`${r.name} ${r.status==="draft"?"- Draft":""}`,h={created:"Created: ",published:"Published: ",updated:"Updated: "},u={created:"Created by",published:"Published by",updated:"Updated by"},{type:n,user:f,timestamp:g}=P(r);return a(I,{className:i.card,children:[a(L,{children:[a("div",{className:i.header,children:[m?t(v,{to:`versions/${r.id}`,children:t(d,{variant:"h2",children:o})}):t(d,{variant:"h2",children:o}),r.status==="active"?t(R,{status:"active",size:"small"}):null]}),r.description?a(d,{variant:"body1",color:"textSecondary",children:['"',r.description,'"']}):null,t(d,{component:"h2",className:i.detailsHeader,children:"Details"}),a(N,{className:i.activityList,children:[a(s,{className:i.activityListItem,children:[t(c,{children:t(k,{})}),t(l,{primary:t(D,{timestamp:g,description:h[n]})})]}),a(s,{className:i.activityListItem,children:[t(c,{children:t($,{})}),t(l,{primary:a(b,{children:[u[n]," ",t(C,{hideIcon:!0,entityRef:f})]})})]})]}),y&&a(p,{paddingTop:2,children:[t(d,{gutterBottom:!0,variant:"subtitle2",children:"What's changed"}),t(p,{className:i.diffSummaryContainer,children:t(T,{policy:r})})]})]}),e.actions?t(S,{className:i.actions,children:e.actions}):null]})}export{w as PolicyCard};
2
2
  //# sourceMappingURL=PolicyCard.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as s,Dialog as p,DialogContent as y,Box as n,Typography as l,Button as r}from"@material-ui/core";import d from"@material-ui/icons/ReportProblemOutlined";import e from"react";import{PolicyCard as o}from"./PolicyCard.esm.js";const g=s(t=>({icon:{color:t.palette.warning.main,width:"2rem",height:"2rem"},label:{align:"center",display:"block",marginBottom:t.spacing(1),color:t.palette.text.secondary,fontSize:t.typography.caption.fontSize},policiesContainer:{display:"flex",gap:t.spacing(4),marginTop:t.spacing(4),marginBottom:t.spacing(4)},button:{marginTop:t.spacing(4)}})),f=({localPolicy:t,onSelectLocalPolicy:c,onSelectServerPolicy:i,serverPolicy:m})=>{const a=g();return e.createElement(p,{open:!0,maxWidth:"md"},e.createElement(y,null,e.createElement(n,{display:"flex",flexDirection:"column",gridGap:8},e.createElement(n,{display:"flex",justifyContent:"center"},e.createElement(d,{className:a.icon})),e.createElement(l,{align:"center",variant:"h6"},"There is a conflict with your drafts"),e.createElement(n,null,e.createElement(l,{align:"center"},"A newer version of the draft you are trying to edit has been recently saved."),e.createElement(l,{align:"center"},"Please review the changes and decide on a version to keep."))),e.createElement(n,{className:a.policiesContainer},e.createElement(n,{alignItems:"center",display:"flex",flexDirection:"column",flex:"1 1 0%"},e.createElement(l,{className:a.label,variant:"button"},"Your local draft"),e.createElement(o,{policy:t,withChangeSummary:!0}),e.createElement(r,{className:a.button,color:"primary",onClick:c,variant:"outlined"},"Keep local draft")),e.createElement(n,{alignItems:"center",display:"flex",flexDirection:"column",flex:"1 1 0%"},e.createElement(l,{className:a.label,variant:"button"},"Recently saved draft"),e.createElement(o,{policy:m,withChangeSummary:!0}),e.createElement(r,{className:a.button,color:"primary",onClick:i,variant:"outlined"},"Keep recently saved draft")))))};export{f as PolicyConflictDialog};
1
+ import{jsx as e,jsxs as l}from"react/jsx-runtime";import{makeStyles as m,Dialog as p,DialogContent as h,Box as o,Typography as t,Button as r}from"@material-ui/core";import y from"@material-ui/icons/ReportProblemOutlined";import{PolicyCard as a}from"./PolicyCard.esm.js";const g=m(i=>({icon:{color:i.palette.warning.main,width:"2rem",height:"2rem"},label:{align:"center",display:"block",marginBottom:i.spacing(1),color:i.palette.text.secondary,fontSize:i.typography.caption.fontSize},policiesContainer:{display:"flex",gap:i.spacing(4),marginTop:i.spacing(4),marginBottom:i.spacing(4)},button:{marginTop:i.spacing(4)}})),f=({localPolicy:i,onSelectLocalPolicy:c,onSelectServerPolicy:s,serverPolicy:d})=>{const n=g();return e(p,{open:!0,maxWidth:"md",children:l(h,{children:[l(o,{display:"flex",flexDirection:"column",gridGap:8,children:[e(o,{display:"flex",justifyContent:"center",children:e(y,{className:n.icon})}),e(t,{align:"center",variant:"h6",children:"There is a conflict with your drafts"}),l(o,{children:[e(t,{align:"center",children:"A newer version of the draft you are trying to edit has been recently saved."}),e(t,{align:"center",children:"Please review the changes and decide on a version to keep."})]})]}),l(o,{className:n.policiesContainer,children:[l(o,{alignItems:"center",display:"flex",flexDirection:"column",flex:"1 1 0%",children:[e(t,{className:n.label,variant:"button",children:"Your local draft"}),e(a,{policy:i,withChangeSummary:!0}),e(r,{className:n.button,color:"primary",onClick:c,variant:"outlined",children:"Keep local draft"})]}),l(o,{alignItems:"center",display:"flex",flexDirection:"column",flex:"1 1 0%",children:[e(t,{className:n.label,variant:"button",children:"Recently saved draft"}),e(a,{policy:d,withChangeSummary:!0}),e(r,{className:n.button,color:"primary",onClick:s,variant:"outlined",children:"Keep recently saved draft"})]})]})]})})};export{f as PolicyConflictDialog};
2
2
  //# sourceMappingURL=PolicyConflictDialog.esm.js.map
@@ -1,2 +1,2 @@
1
- import{useApi as n,alertApiRef as v}from"@backstage/core-plugin-api";import{makeStyles as P,Button as h}from"@material-ui/core";import{PolicyConfigParser as A}from"@spotify/backstage-plugin-rbac-common";import B from"js-yaml";import m from"react";import{useNavigate as b}from"react-router-dom";import{rbacApiRef as w}from"../../api.esm.js";const x=P({importButton:{"&:hover":{transformOrigin:"top right"}}});function I(){const c=x(),e=n(w),l=b(),t=n(v);function p(f){const r=f.target?.files?.[0],o=new FileReader;r&&(o.readAsText(r,"utf-8"),o.onload=async u=>{const i=u.target?.result?.toString();if(i){let s=null;try{s=B.load(i)}catch{t.post({message:"YAML file is invalid",severity:"error"});return}const a=A.safeParse(s);if(!a.success){t.post({message:"Imported policy is invalid",severity:"error"});return}const y=a.data;if((await e.getPolicies()).items.some(g=>g.status==="draft")){t.post({message:"Unable to import new policy due to existing draft policy",severity:"error"});return}const d=await e.createDraft(y);l(`./versions/${d.id}`),t.post({message:"Policy imported successfully",severity:"success"})}})}return m.createElement(h,{variant:"outlined",color:"primary",component:"label",className:c.importButton},"Import",m.createElement("input",{role:"input",type:"file",hidden:!0,onChange:p,accept:".yaml"}))}export{I as PolicyImportButton};
1
+ import{jsxs as A,jsx as h}from"react/jsx-runtime";import{useApi as c,alertApiRef as F,useAnalytics as P}from"@backstage/core-plugin-api";import{makeStyles as b,Button as x}from"@material-ui/core";import{PolicyConfigParser as w}from"@spotify/backstage-plugin-rbac-common";import B from"js-yaml";import{useNavigate as I}from"react-router-dom";import{rbacApiRef as j}from"../../api.esm.js";import{useFeatureFlags as R}from"../../hooks/useFeatureFlag.esm.js";const C=b({importButton:{"&:hover":{transformOrigin:"top right"}}});function D(){const p=C(),e=c(j),m=I(),t=c(F),l=P(),u=R();function f(d){const r=d.target?.files?.[0],o=new FileReader;r&&(o.readAsText(r,"utf-8"),o.onload=async y=>{const i=y.target?.result?.toString();if(i){let s=null;try{s=B.load(i)}catch{t.post({message:"YAML file is invalid",severity:"error"});return}const a=w.safeParse(s);if(!a.success){t.post({message:"Imported policy is invalid",severity:"error"});return}const g=a.data;if((await e.getPolicies()).items.some(v=>v.status==="draft")){t.post({message:"Unable to import new policy due to existing draft policy",severity:"error"});return}const n=await e.createDraft(g);l.captureEvent("resource_action","import",{attributes:{resourceType:"policy",resourceAction:"import",resourceId:n.id,rbacFeatureFlags:u.join(",")}}),m(`./versions/${n.id}`),t.post({message:"Policy imported successfully",severity:"success"})}})}return A(x,{variant:"outlined",color:"primary",component:"label",className:p.importButton,children:["Import",h("input",{role:"input",type:"file",hidden:!0,onChange:f,accept:".yaml"})]})}export{D as PolicyImportButton};
2
2
  //# sourceMappingURL=PolicyImportButton.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as c,Dialog as m,DialogContent as p,Box as t,Typography as n,Button as r}from"@material-ui/core";import d from"@material-ui/icons/ReportProblemOutlined";import e from"react";import{exportPolicy as f}from"./exportPolicy.esm.js";const s=c(o=>({icon:{color:o.palette.warning.main,width:"2rem",height:"2rem"}})),g=({onConfirm:o,policy:a})=>{const i=s(),l=()=>{f(a)};return e.createElement(m,{open:!0},e.createElement(p,null,e.createElement(t,{display:"flex",flexDirection:"column",gridGap:16},e.createElement(t,{display:"flex",flexDirection:"column",gridGap:4},e.createElement(t,{display:"flex",justifyContent:"center"},e.createElement(d,{className:i.icon})),e.createElement(n,{align:"center",variant:"h6"},"Invalid local draft")),e.createElement(t,{display:"flex",flexDirection:"column",gridGap:8},e.createElement(n,{align:"center"},"You have a local draft that is no longer compatible or has become corrupted."),e.createElement(n,{align:"center"},"Click export to download your draft. You can attempt to restore your draft by importing this file on the RBAC home page."),e.createElement(n,{align:"center"},"Clicking continue will discard your draft."," ",e.createElement(t,{component:"span",fontWeight:"fontWeightBold"},"This action cannot be undone."))),e.createElement(t,{display:"flex",justifyContent:"center",gridGap:8,marginY:3},e.createElement(r,{color:"primary",onClick:l,variant:"outlined"},"Export"),e.createElement(r,{color:"primary",onClick:o,variant:"contained"},"Discard and continue")))))};export{g as PolicyInvalidDialog};
1
+ import{jsx as i,jsxs as o}from"react/jsx-runtime";import{makeStyles as d,Dialog as p,DialogContent as h,Box as n,Typography as e,Button as t}from"@material-ui/core";import m from"@material-ui/icons/ReportProblemOutlined";import{exportPolicy as s}from"./exportPolicy.esm.js";const f=d(r=>({icon:{color:r.palette.warning.main,width:"2rem",height:"2rem"}})),g=({onConfirm:r,policy:l})=>{const a=f(),c=()=>{s(l)};return i(p,{open:!0,children:i(h,{children:o(n,{display:"flex",flexDirection:"column",gridGap:16,children:[o(n,{display:"flex",flexDirection:"column",gridGap:4,children:[i(n,{display:"flex",justifyContent:"center",children:i(m,{className:a.icon})}),i(e,{align:"center",variant:"h6",children:"Invalid local draft"})]}),o(n,{display:"flex",flexDirection:"column",gridGap:8,children:[i(e,{align:"center",children:"You have a local draft that is no longer compatible or has become corrupted."}),i(e,{align:"center",children:"Click export to download your draft. You can attempt to restore your draft by importing this file on the RBAC home page."}),o(e,{align:"center",children:["Clicking continue will discard your draft."," ",i(n,{component:"span",fontWeight:"fontWeightBold",children:"This action cannot be undone."})]})]}),o(n,{display:"flex",justifyContent:"center",gridGap:8,marginY:3,children:[i(t,{color:"primary",onClick:c,variant:"outlined",children:"Export"}),i(t,{color:"primary",onClick:r,variant:"contained",children:"Discard and continue"})]})]})})})};export{g as PolicyInvalidDialog};
2
2
  //# sourceMappingURL=PolicyInvalidDialog.esm.js.map
@@ -1,2 +1,2 @@
1
- import{Box as S,Button as l,Menu as x,MenuList as c,MenuItem as n,ListItemIcon as r,ListItemText as a,Typography as D,Divider as u}from"@material-ui/core";import L from"@material-ui/icons/MoreHoriz";import z from"@material-ui/icons/Save";import I from"@material-ui/icons/Settings";import M from"@material-ui/icons/Undo";import T from"@material-ui/icons/VerticalAlignTop";import e,{useState as B}from"react";import{useNavigate as A}from"react-router-dom";import{usePoliciesContext as O}from"../Policies/PoliciesProvider.esm.js";import{usePolicyContext as R}from"./PolicyProvider.esm.js";import{useDuplicatePolicy as w}from"./useDuplicatePolicy.esm.js";function F(){const[m,s]=B(null),{hasDraftPolicy:E}=O(),{isValid:o,discardLocalDraft:p,exportPolicy:d,hasChanges:i,policy:t,saveLocalDraftToServer:f,saveAndPublish:h,publish:y}=R(),v=A(),[C,b]=w(),g=k=>{s(k.currentTarget)},P=()=>{s(null)};return e.createElement(e.Fragment,null,e.createElement(S,null,t.status==="draft"&&e.createElement(l,{variant:"contained",color:"primary",disabled:!o,onClick:()=>f()},"Save"),t.status==="inactive"&&e.createElement(l,{variant:"contained",color:"primary",onClick:()=>y()},"Republish"),t.status==="active"&&e.createElement(l,{variant:"contained",color:"primary",disabled:E||C.loading,onClick:()=>b(t)},"Duplicate"),e.createElement(l,{color:"primary",title:"options",onClick:g,disableRipple:!0},e.createElement(L,null))),e.createElement(x,{getContentAnchorEl:null,anchorEl:m,anchorOrigin:{vertical:"bottom",horizontal:"right"},open:!!m,onClose:P,PaperProps:{style:{width:240}}},t.status==="draft"&&e.createElement(c,null,e.createElement(n,{disabled:!o,onClick:()=>h()},e.createElement(r,null,e.createElement(z,{fontSize:"small"})),e.createElement(a,null,"Save & Publish")),e.createElement(n,{disabled:!i,onClick:()=>p()},e.createElement(r,null,e.createElement(M,{color:i?"secondary":"inherit",fontSize:"small"})),e.createElement(a,null,e.createElement(D,{color:i?"secondary":"inherit"},"Discard changes"))),e.createElement(u,null)),e.createElement(c,null,e.createElement(n,{onClick:()=>d()},e.createElement(r,null,e.createElement(T,{fontSize:"small"})),e.createElement(a,null,"Export"))),e.createElement(u,null),e.createElement(c,null,e.createElement(n,{disabled:!o,onClick:()=>v("./options")},e.createElement(r,null,e.createElement(I,{fontSize:"small"})),e.createElement(a,null,"Options")))))}export{F as PolicyMenu};
1
+ import{jsxs as r,Fragment as S,jsx as i}from"react/jsx-runtime";import{Box as z,Button as e,Menu as L,MenuList as s,MenuItem as l,ListItemIcon as n,ListItemText as t,Typography as I,Divider as m}from"@material-ui/core";import M from"@material-ui/icons/MoreHoriz";import E from"@material-ui/icons/Save";import T from"@material-ui/icons/Settings";import B from"@material-ui/icons/Undo";import j from"@material-ui/icons/VerticalAlignTop";import{useState as A}from"react";import{useNavigate as O}from"react-router-dom";import{usePoliciesContext as R}from"../Policies/PoliciesProvider.esm.js";import{usePolicyContext as w}from"./PolicyProvider.esm.js";import{useDuplicatePolicy as F}from"./useDuplicatePolicy.esm.js";function N(){const[d,h]=A(null),{hasDraftPolicy:p}=R(),{isValid:c,discardLocalDraft:u,exportPolicy:f,hasChanges:a,policy:o,saveLocalDraftToServer:y,saveAndPublish:v,publish:C}=w(),b=O(),[g,x]=F(),P=D=>{h(D.currentTarget)},k=()=>{h(null)};return r(S,{children:[r(z,{children:[o.status==="draft"&&i(e,{variant:"contained",color:"primary",disabled:!c,onClick:()=>y(),children:"Save"}),o.status==="inactive"&&i(e,{variant:"contained",color:"primary",onClick:()=>C(),children:"Republish"}),o.status==="active"&&i(e,{variant:"contained",color:"primary",disabled:p||g.loading,onClick:()=>x(o),children:"Duplicate"}),i(e,{color:"primary",title:"options",onClick:P,disableRipple:!0,children:i(M,{})})]}),r(L,{getContentAnchorEl:null,anchorEl:d,anchorOrigin:{vertical:"bottom",horizontal:"right"},open:!!d,onClose:k,PaperProps:{style:{width:240}},children:[o.status==="draft"&&r(s,{children:[r(l,{disabled:!c,onClick:()=>v(),children:[i(n,{children:i(E,{fontSize:"small"})}),i(t,{children:"Save & Publish"})]}),r(l,{disabled:!a,onClick:()=>u(),children:[i(n,{children:i(B,{color:a?"secondary":"inherit",fontSize:"small"})}),i(t,{children:i(I,{color:a?"secondary":"inherit",children:"Discard changes"})})]}),i(m,{})]}),i(s,{children:r(l,{onClick:()=>f(),children:[i(n,{children:i(j,{fontSize:"small"})}),i(t,{children:"Export"})]})}),i(m,{}),i(s,{children:r(l,{disabled:!c,onClick:()=>b("./options"),children:[i(n,{children:i(T,{fontSize:"small"})}),i(t,{children:"Options"})]})})]})]})}export{N as PolicyMenu};
2
2
  //# sourceMappingURL=PolicyMenu.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as s,Card as m,CardActionArea as p,CardHeader as g,Radio as h,Typography as f,Chip as u}from"@material-ui/core";import t from"react";const y=s(e=>({card:a=>({marginTop:e.spacing(3),height:"100%","&:hover":a.readonly?{pointerEvents:"none"}:{}}),cardHeader:{paddingBottom:e.spacing(2),alignItems:"flex-start"},defaultChip:{marginLeft:e.spacing(1),marginBottom:0},title:{display:"flex",alignItems:"center",paddingTop:e.spacing(.5),paddingBottom:e.spacing(1)}}));function C(e){const a=y(e),{title:n,description:i,active:l,changeResolutionStrategy:o,defaultOption:c,readonly:r}=e,d=()=>{r||o()};return t.createElement(m,{className:`${a.card}`,onClick:d},t.createElement(p,{disabled:r},t.createElement(g,{className:a.cardHeader,avatar:t.createElement(h,{checked:l,color:"primary",disabled:r}),title:t.createElement("div",{className:a.title},t.createElement(f,{variant:"h6",component:"h2"},n),c?t.createElement(u,{label:"Default",size:"small",className:a.defaultChip}):null),subheader:i})))}export{C as PolicyOptionCard};
1
+ import{jsx as i,jsxs as s}from"react/jsx-runtime";import{makeStyles as p,Card as m,CardActionArea as g,CardHeader as h,Radio as f,Typography as u,Chip as y}from"@material-ui/core";const C=p(e=>({card:a=>({marginTop:e.spacing(3),height:"100%","&:hover":a.readonly?{pointerEvents:"none"}:{}}),cardHeader:{paddingBottom:e.spacing(2),alignItems:"flex-start"},defaultChip:{marginLeft:e.spacing(1),marginBottom:0},title:{display:"flex",alignItems:"center",paddingTop:e.spacing(.5),paddingBottom:e.spacing(1)}}));function v(e){const a=C(e),{title:r,description:n,active:d,changeResolutionStrategy:l,defaultOption:o,readonly:t}=e,c=()=>{t||l()};return i(m,{className:`${a.card}`,onClick:c,children:i(g,{disabled:t,children:i(h,{className:a.cardHeader,avatar:i(f,{checked:d,color:"primary",disabled:t}),title:s("div",{className:a.title,children:[i(u,{variant:"h6",component:"h2",children:r}),o?i(y,{label:"Default",size:"small",className:a.defaultChip}):null]}),subheader:n})})})}export{v as PolicyOptionCard};
2
2
  //# sourceMappingURL=PolicyOptionCard.esm.js.map
@@ -1,2 +1,2 @@
1
- import{ContentHeader as m}from"@backstage/core-components";import{makeStyles as d,Typography as a,Button as h,Grid as y,Chip as g}from"@material-ui/core";import{invariant as u}from"@spotify/backstage-plugin-core";import e from"react";import{useParams as f,useNavigate as E}from"react-router-dom";import{PageWrapper as v}from"../Layout/PageWrapper.esm.js";import{PolicyOptionCard as r}from"./PolicyOptionCard.esm.js";import{PolicyProvider as w,usePolicyContext as x}from"./PolicyProvider.esm.js";const P=d(t=>({title:{display:"flex",alignItems:"center",paddingBottom:t.spacing(2)},maxWidthWrapper:{maxWidth:"800px"},readOnlyChip:{marginLeft:t.spacing(1)},paragraph:{paddingBottom:t.spacing(1)}}));function b(){const{versionId:t}=f();return u(t),e.createElement(w,{policyId:t},e.createElement(l,null))}function l(){const t=P(),{policy:o,updateLocalDraft:s}=x(),c=E(),i=o.status!=="draft",n=p=>{s({...o,options:{...o.options,resolutionStrategy:p}})};return e.createElement(v,{pages:[{title:o.name,path:".."},{title:"Options"}],header:e.createElement(m,{titleComponent:e.createElement(a,{variant:"h2"},"Options")},e.createElement(h,{variant:"outlined",color:"primary",onClick:()=>c("..",{relative:"path"})},"Back to policy"))},e.createElement(y,{item:!0,xs:12,className:t.maxWidthWrapper},e.createElement("div",null,e.createElement("div",{className:t.title},e.createElement(a,{variant:"h5",component:"h1"},"Decision resolution strategy"),i?e.createElement(g,{label:"Read only",className:t.readOnlyChip}):null),e.createElement(a,{variant:"body2",component:"p",className:t.paragraph},"Multiple decisions from multiple roles could be applicable to a single user when authorizing a permission request. Please select the decision resolution strategy that makes sense for your policy."),e.createElement(a,{variant:"body2",component:"p",className:t.paragraph},"Please note this strategy will be applied to the whole policy and greatly affects the outcome of permission decisions."),e.createElement(r,{title:"Any-allow",changeResolutionStrategy:()=>n("any-allow"),readonly:i,defaultOption:!0,description:e.createElement(e.Fragment,null,e.createElement(a,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"The first allow decision from all of the roles and decisions is the final result. A single explicit allow or an allow as a result of a conditional decision would result in a final allow decision, otherwise the decision is deny."),e.createElement(a,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"With this option, the order of roles and decisions does not matter.")),active:o.options.resolutionStrategy==="any-allow"}),e.createElement(r,{title:"First match",changeResolutionStrategy:()=>n("first-match"),readonly:i,description:e.createElement(e.Fragment,null,e.createElement(a,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"The first matching decision from the first matching role that is applicable to the user is the final result, regardless if that decision is an allow, deny or conditional."),e.createElement(a,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"With this option, the order in which you define roles and decisions matters.")),active:o.options.resolutionStrategy==="first-match"}))))}export{b as PolicyOptionsPage,l as PolicyOptionsPageContent};
1
+ import{jsx as e,jsxs as a,Fragment as l}from"react/jsx-runtime";import{ContentHeader as m}from"@backstage/core-components";import{makeStyles as y,Typography as o,Button as g,Grid as f,Chip as u}from"@material-ui/core";import{invariant as v}from"@spotify/backstage-plugin-core";import{useParams as x,useNavigate as w}from"react-router-dom";import{PageWrapper as b}from"../Layout/PageWrapper.esm.js";import{PolicyOptionCard as s}from"./PolicyOptionCard.esm.js";import{PolicyProvider as P,usePolicyContext as N}from"./PolicyProvider.esm.js";const S=y(t=>({title:{display:"flex",alignItems:"center",paddingBottom:t.spacing(2)},maxWidthWrapper:{maxWidth:"800px"},readOnlyChip:{marginLeft:t.spacing(1)},paragraph:{paddingBottom:t.spacing(1)}}));function C(){const{versionId:t}=x();return v(t),e(P,{policyId:t,children:e(c,{})})}function c(){const t=S(),{policy:i,updateLocalDraft:p}=N(),d=w(),r=i.status!=="draft",n=h=>{p({...i,options:{...i.options,resolutionStrategy:h}})};return e(b,{pages:[{title:i.name,path:".."},{title:"Options"}],header:e(m,{titleComponent:e(o,{variant:"h2",children:"Options"}),children:e(g,{variant:"outlined",color:"primary",onClick:()=>d("..",{relative:"path"}),children:"Back to policy"})}),children:e(f,{item:!0,xs:12,className:t.maxWidthWrapper,children:a("div",{children:[a("div",{className:t.title,children:[e(o,{variant:"h5",component:"h1",children:"Decision resolution strategy"}),r?e(u,{label:"Read only",className:t.readOnlyChip}):null]}),e(o,{variant:"body2",component:"p",className:t.paragraph,children:"Multiple decisions from multiple roles could be applicable to a single user when authorizing a permission request. Please select the decision resolution strategy that makes sense for your policy."}),e(o,{variant:"body2",component:"p",className:t.paragraph,children:"Please note this strategy will be applied to the whole policy and greatly affects the outcome of permission decisions."}),e(s,{title:"Any-allow",changeResolutionStrategy:()=>n("any-allow"),readonly:r,defaultOption:!0,description:a(l,{children:[e(o,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph,children:"The first allow decision from all of the roles and decisions is the final result. A single explicit allow or an allow as a result of a conditional decision would result in a final allow decision, otherwise the decision is deny."}),e(o,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph,children:"With this option, the order of roles and decisions does not matter."})]}),active:i.options.resolutionStrategy==="any-allow"}),e(s,{title:"First match",changeResolutionStrategy:()=>n("first-match"),readonly:r,description:a(l,{children:[e(o,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph,children:"The first matching decision from the first matching role that is applicable to the user is the final result, regardless if that decision is an allow, deny or conditional."}),e(o,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph,children:"With this option, the order in which you define roles and decisions matters."})]}),active:i.options.resolutionStrategy==="first-match"})]})})})}export{C as PolicyOptionsPage,c as PolicyOptionsPageContent};
2
2
  //# sourceMappingURL=PolicyOptionsPage.esm.js.map
@@ -1,2 +1,2 @@
1
- import{ContentHeader as P}from"@backstage/core-components";import{useApi as g,alertApiRef as h}from"@backstage/core-plugin-api";import{EntityDisplayName as v}from"@backstage/plugin-catalog-react";import{Grid as s,Typography as f}from"@material-ui/core";import{invariant as T}from"@spotify/backstage-plugin-core";import{UpdateDraftRequestParser as b}from"@spotify/backstage-plugin-rbac-common";import e,{useState as x}from"react";import{useParams as C}from"react-router-dom";import{getZodValidationToKeyMap as R}from"../../utils/getZodValidationToKeyMap.esm.js";import D from"../EditableInput/EditableInput.esm.js";import{PageWrapper as A}from"../Layout/PageWrapper.esm.js";import{Title as I}from"../Layout/Title.esm.js";import{PolicyTester as L}from"../PolicyTester/PolicyTester.esm.js";import{RelativeTime as q}from"../RelativeTime/RelativeTime.esm.js";import{RolesTable as M}from"../Roles/RolesTable.esm.js";import N from"./EmptyRolesCard.esm.js";import{getActivityDetails as S}from"./getActivityDetails.esm.js";import{PolicyMenu as F}from"./PolicyMenu.esm.js";import{PolicyProvider as G,usePolicyContext as H}from"./PolicyProvider.esm.js";import{PolicyStatusChip as K}from"./PolicyStatusChip.esm.js";function U(){const{versionId:t}=C();return T(t),e.createElement(G,{policyId:t},e.createElement(d,null))}function d(){const{policy:t,updateLocalDraft:o}=H(),m=g(h),[i,l]=x(!1),y=r=>{let a;const n=b.safeParse({...t,name:r}),p=R(n).name;return p&&(a=n.error?.issues.find(u=>u.path.length===1&&u.path[0]==="name")?.message),l(p),{result:!p,helperText:a}},E=r=>{const{result:a,helperText:n}=y(r);a?o({...t,name:r}):m.post({display:"transient",severity:"error",message:n||"Please specify a valid policy name."})},c=t.status!=="draft";return e.createElement(A,{pages:[{title:t.name}],header:e.createElement(P,{title:t.name,titleComponent:e.createElement(e.Fragment,null,e.createElement(I,null,c?t.name:e.createElement(D,{invalid:i,name:"Policy name",value:t.name,onTextChange:E}),e.createElement(K,{status:t.status})),V(t))},e.createElement(F,null))},e.createElement(s,{container:!0,spacing:4},e.createElement(s,{item:!0,xs:12},t.roles.length>0?e.createElement(M,null):e.createElement(N,{readonly:c})),e.createElement(s,{item:!0,xs:12},e.createElement(L,null))))}function V(t){const o={created:"Created by ",published:"Last published by ",updated:"Last updated by "},{type:m,user:i,timestamp:l}=S(t);return e.createElement(f,{variant:"body2"},e.createElement(f,{component:"span",display:"inline",variant:"body2"},o[m],e.createElement(v,{hideIcon:!0,entityRef:i})," "),e.createElement(q,{timestamp:l}))}export{U as PolicyPage,d as PolicyPageContent};
1
+ import{jsx as t,jsxs as r,Fragment as g}from"react/jsx-runtime";import{ContentHeader as v}from"@backstage/core-components";import{useApi as x,alertApiRef as T}from"@backstage/core-plugin-api";import{EntityDisplayName as b}from"@backstage/plugin-catalog-react";import{Grid as c,Typography as u}from"@material-ui/core";import{invariant as C}from"@spotify/backstage-plugin-core";import{UpdateDraftRequestParser as R}from"@spotify/backstage-plugin-rbac-common";import{useState as D}from"react";import{useParams as A}from"react-router-dom";import{getZodValidationToKeyMap as I}from"../../utils/getZodValidationToKeyMap.esm.js";import L from"../EditableInput/EditableInput.esm.js";import{PageWrapper as j}from"../Layout/PageWrapper.esm.js";import{Title as q}from"../Layout/Title.esm.js";import{PolicyTester as M}from"../PolicyTester/PolicyTester.esm.js";import{RelativeTime as N}from"../RelativeTime/RelativeTime.esm.js";import{RolesTable as S}from"../Roles/RolesTable.esm.js";import E from"./EmptyRolesCard.esm.js";import{getActivityDetails as F}from"./getActivityDetails.esm.js";import{PolicyMenu as G}from"./PolicyMenu.esm.js";import{PolicyProvider as H,usePolicyContext as K}from"./PolicyProvider.esm.js";import{PolicyStatusChip as U}from"./PolicyStatusChip.esm.js";function V(){const{versionId:e}=A();return C(e),t(H,{policyId:e,children:t(y,{})})}function y(){const{policy:e,updateLocalDraft:n}=K(),m=x(T),[s,p]=D(!1),h=i=>{let o;const a=R.safeParse({...e,name:i}),l=I(a).name;return l&&(o=a.error?.issues.find(f=>f.path.length===1&&f.path[0]==="name")?.message),p(l),{result:!l,helperText:o}},P=i=>{const{result:o,helperText:a}=h(i);o?n({...e,name:i}):m.post({display:"transient",severity:"error",message:a||"Please specify a valid policy name."})},d=e.status!=="draft";return t(j,{pages:[{title:e.name}],header:t(v,{title:e.name,titleComponent:r(g,{children:[r(q,{children:[d?e.name:t(L,{invalid:s,name:"Policy name",value:e.name,onTextChange:P}),t(U,{status:e.status})]}),W(e)]}),children:t(G,{})}),children:r(c,{container:!0,spacing:4,children:[t(c,{item:!0,xs:12,children:e.roles.length>0?t(S,{}):t(E,{readonly:d})}),t(c,{item:!0,xs:12,children:t(M,{})})]})})}function W(e){const n={created:"Created by ",published:"Last published by ",updated:"Last updated by "},{type:m,user:s,timestamp:p}=F(e);return r(u,{variant:"body2",children:[r(u,{component:"span",display:"inline",variant:"body2",children:[n[m],t(b,{hideIcon:!0,entityRef:s})," "]}),t(N,{timestamp:p})]})}export{V as PolicyPage,y as PolicyPageContent};
2
2
  //# sourceMappingURL=PolicyPage.esm.js.map
@@ -1,2 +1,2 @@
1
- import{Progress as Z,ErrorPanel as _}from"@backstage/core-components";import{useApi as D,alertApiRef as ee,useApp as oe}from"@backstage/core-plugin-api";import{PolicyConfigParser as x}from"@spotify/backstage-plugin-rbac-common";import t,{createContext as re,useContext as te,useState as A,useCallback as f,useEffect as L}from"react";import{useNavigate as ie}from"react-router-dom";import le from"react-use/lib/useAsyncFn";import{v4 as ae}from"uuid";import{rbacApiRef as ce}from"../../api.esm.js";import{isNotFoundError as se}from"../../utils/errors.esm.js";import{usePolicyDiff as ne}from"../Diffing/usePolicyDiff.esm.js";import{usePoliciesContext as pe}from"../Policies/PoliciesProvider.esm.js";import{exportPolicy as me}from"./exportPolicy.esm.js";import{getLatestPolicy as ue}from"./getLatestPolicy.esm.js";import{PolicyConflictDialog as fe}from"./PolicyConflictDialog.esm.js";import{PolicyInvalidDialog as Pe}from"./PolicyInvalidDialog.esm.js";import{PolicyPublishConfirmationDialog as ye}from"./PolicyPublishConfirmationDialog.esm.js";import{PolicyPublishSuccessDialog as de}from"./PolicyPublishSuccessDialog.esm.js";import{useLocalDraftPolicy as ve}from"./useLocalDraftPolicy.esm.js";import{usePublishPolicy as he}from"./usePublishPolicy.esm.js";const S={canPublish:!1,diff:null,hasChanges:!1,isValid:!1,policy:void 0,createNewRole:()=>"",discardLocalDraft:()=>{},exportPolicy:()=>{},publish:()=>{},saveLocalDraftToServer:()=>Promise.reject(),saveAndPublish:()=>Promise.reject(),refetchPolicy:()=>Promise.reject(),updateLocalDraft:()=>{}},N=re(S),ge=()=>te(N);function Ce({children:R,policyId:P}){const j=ie(),y=D(ee),n=D(ce),{getPolicy:$,setPolicy:h}=pe(),k=oe(),{NotFoundErrorPage:F}=k.getComponents(),[d,l]=A({active:!1,update:!1}),[I,g]=A(!1),[{loading:T,value:p},C]=he(),r=$(P),[m,u,a]=ve(),E=!m||x.safeParse(m).success,c=E?m:void 0,{policy:e,policyConflict:V}=ue({serverPolicy:r,localPolicy:c}),O=ne(e),b=x.safeParse(e).success,U=b&&!c&&!T,[{loading:q,error:v},w]=le(()=>n.getPolicy(P),[n,P],r?{loading:!1,value:r}:{loading:!0}),z=()=>{l({active:!0,update:!1})},B=()=>{l({active:!0,update:!0})},i=f(async()=>{const o=await w();h(o)},[w,h]),G=f(async o=>{await C(e,o,d.update?e:void 0),l({active:!1,update:!1}),i?.()},[e,d,C,l,i]),H=async()=>{g(!1)},J=()=>{u(o=>o&&r&&{...o,updatedAt:r.updatedAt})},K=f(async()=>{if(!e)throw new Error("No policy to save");try{await n.updateDraft(e.id,{name:e.name,roles:e.roles,options:e.options}),y.post({message:"Policy saved",severity:"success"}),a(),i?.()}catch(o){y.post({message:o?.message||"An error occurred while updating the policy",severity:"error"})}},[y,n,e,i,a]),M=f(()=>{if(!e)throw new Error("No policy to create a new role");const o=new Set(e.roles.map(Y=>Y.id));let s;do s=ae().split("-")[0];while(o.has(s));const X={name:`Role ${s}`,permissions:[],members:"*",id:s};return u({...e,roles:[...e.roles,X]}),s},[e,u]),Q=()=>{a(),j("/rbac")},W=()=>{e&&me(e)};return L(()=>{r||i()},[i,r]),L(()=>{p&&g(!0)},[p]),E?e?t.createElement(N.Provider,{value:{canPublish:U,diff:O,hasChanges:!!c,isValid:b,policy:e,createNewRole:M,discardLocalDraft:a,exportPolicy:W,publish:z,saveLocalDraftToServer:K,refetchPolicy:i,updateLocalDraft:u,saveAndPublish:B}},V&&c&&r&&t.createElement(fe,{localPolicy:c,onSelectLocalPolicy:J,onSelectServerPolicy:a,serverPolicy:r}),t.createElement(ye,{open:d.active,onClose:()=>l({active:!1,update:!1}),onPublish:G,policy:e}),p&&t.createElement(de,{isOpen:I,onClose:H,policy:p}),R):q?t.createElement(Z,null):v?se(v)?t.createElement(F,null):t.createElement(_,{error:v??new Error("Unknown")}):null:t.createElement(Pe,{onConfirm:Q,policy:m})}export{Ce as PolicyProvider,S as defaultContext,ge as usePolicyContext};
1
+ import{jsxs as ee,jsx as t}from"react/jsx-runtime";import{Progress as oe,ErrorPanel as re}from"@backstage/core-components";import{useAnalytics as ie,useApi as E,alertApiRef as te,useApp as ae}from"@backstage/core-plugin-api";import{PolicyConfigParser as F}from"@spotify/backstage-plugin-rbac-common";import{createContext as ce,useContext as se,useState as j,useCallback as y,useEffect as L}from"react";import{useNavigate as le}from"react-router-dom";import ne from"react-use/lib/useAsyncFn";import{v4 as pe}from"uuid";import{rbacApiRef as ue}from"../../api.esm.js";import{useFeatureFlags as me}from"../../hooks/useFeatureFlag.esm.js";import{isNotFoundError as fe}from"../../utils/errors.esm.js";import{usePolicyDiff as de}from"../Diffing/usePolicyDiff.esm.js";import{usePoliciesContext as ye}from"../Policies/PoliciesProvider.esm.js";import{exportPolicy as Pe}from"./exportPolicy.esm.js";import{getLatestPolicy as ve}from"./getLatestPolicy.esm.js";import{PolicyConflictDialog as he}from"./PolicyConflictDialog.esm.js";import{PolicyInvalidDialog as ge}from"./PolicyInvalidDialog.esm.js";import{PolicyPublishConfirmationDialog as be}from"./PolicyPublishConfirmationDialog.esm.js";import{PolicyPublishSuccessDialog as we}from"./PolicyPublishSuccessDialog.esm.js";import{useLocalDraftPolicy as Ce}from"./useLocalDraftPolicy.esm.js";import{usePublishPolicy as xe}from"./usePublishPolicy.esm.js";const S={canPublish:!1,diff:null,hasChanges:!1,isValid:!1,policy:void 0,createNewRole:()=>"",discardLocalDraft:()=>{},exportPolicy:()=>{},publish:()=>{},saveLocalDraftToServer:()=>Promise.reject(),saveAndPublish:()=>Promise.reject(),refetchPolicy:()=>Promise.reject(),updateLocalDraft:()=>{}},N=ce(S),Ae=()=>se(N);function De({children:I,policyId:P}){const R=le(),c=ie(),s=me(),v=E(te),u=E(ue),{getPolicy:T,setPolicy:b}=ye(),_=ae(),{NotFoundErrorPage:k}=_.getComponents(),[h,l]=j({active:!1,update:!1}),[V,w]=j(!1),[{loading:$,value:m},C]=xe(),r=T(P),[f,d,n]=Ce(),x=!f||F.safeParse(f).success,p=x?f:void 0,{policy:e,policyConflict:O}=ve({serverPolicy:r,localPolicy:p}),U=de(e),A=F.safeParse(e).success,q=A&&!p&&!$,[{loading:z,error:g},D]=ne(()=>u.getPolicy(P),[u,P],r?{loading:!1,value:r}:{loading:!0}),B=()=>{l({active:!0,update:!1})},G=()=>{l({active:!0,update:!0})},i=y(async()=>{const o=await D();b(o)},[D,b]),H=y(async o=>{e&&(await C(e,o,h.update?e:void 0),l({active:!1,update:!1}),await i(),c.captureEvent("resource_action","publish",{attributes:{resourceType:"policy",resourceAction:"publish",resourceId:e.id,rbacFeatureFlags:s.join(",")}}))},[e,c,s,h,C,l,i]),J=async()=>{w(!1)},K=()=>{d(o=>o&&r&&{...o,updatedAt:r.updatedAt})},M=y(async()=>{if(!e)throw new Error("No policy to save");try{await u.updateDraft(e.id,{name:e.name,roles:e.roles,options:e.options}),v.post({message:"Policy saved",severity:"success"}),n(),i?.()}catch(o){v.post({message:o?.message||"An error occurred while updating the policy",severity:"error"})}},[v,u,e,i,n]),Q=y(()=>{if(!e)throw new Error("No policy to create a new role");const o=new Set(e.roles.map(Z=>Z.id));let a;do a=pe().split("-")[0];while(o.has(a));const Y={name:`Role ${a}`,permissions:[],members:"*",id:a};return d({...e,roles:[...e.roles,Y]}),c.captureEvent("resource_action","create",{attributes:{resourceType:"role",resourceAction:"create",resourceId:a,rbacFeatureFlags:s.join(",")}}),a},[e,c,s,d]),W=()=>{n(),R("/rbac")},X=()=>{e&&(Pe(e),c.captureEvent("resource_action","export",{attributes:{resourceType:"policy",resourceAction:"export",resourceId:e.id,rbacFeatureFlags:s.join(",")}}))};return L(()=>{r||i()},[i,r]),L(()=>{m&&w(!0)},[m]),x?e?ee(N.Provider,{value:{canPublish:q,diff:U,hasChanges:!!p,isValid:A,policy:e,createNewRole:Q,discardLocalDraft:n,exportPolicy:X,publish:B,saveLocalDraftToServer:M,refetchPolicy:i,updateLocalDraft:d,saveAndPublish:G},children:[O&&p&&r&&t(he,{localPolicy:p,onSelectLocalPolicy:K,onSelectServerPolicy:n,serverPolicy:r}),t(be,{open:h.active,onClose:()=>l({active:!1,update:!1}),onPublish:H,policy:e}),m&&t(we,{isOpen:V,onClose:J,policy:m}),I]}):z?t(oe,{}):g?fe(g)?t(k,{}):t(re,{error:g??new Error("Unknown")}):null:t(ge,{onConfirm:W,policy:f})}export{De as PolicyProvider,S as defaultContext,Ae as usePolicyContext};
2
2
  //# sourceMappingURL=PolicyProvider.esm.js.map
@@ -1,2 +1,2 @@
1
- import{Button as h}from"@material-ui/core";import{PolicyConfigParser as y}from"@spotify/backstage-plugin-rbac-common";import o,{useState as b}from"react";import{useFetchPolicies as C}from"../Policies/useFetchPolicies.esm.js";import{usePolicyContext as g}from"./PolicyProvider.esm.js";import{PolicyPublishConfirmationDialog as E}from"./PolicyPublishConfirmationDialog.esm.js";import{PolicyPublishSuccessDialog as d}from"./PolicyPublishSuccessDialog.esm.js";import{usePublishPolicy as x}from"./usePublishPolicy.esm.js";const B=l=>{const[s,e]=b(!1),{fetchPolicies:r}=C(),[{loading:c,value:t},n]=x(),{policy:i,hasChanges:m}=g(),a=y.safeParse(i).success,u=!m&&a,P=async f=>{await n(i,f),e(!1)},p=()=>{r()};return o.createElement(o.Fragment,null,o.createElement(h,{...l,onClick:()=>e(!0),disabled:!u||c},"Publish"),o.createElement(E,{open:s,onClose:()=>e(!1),onPublish:P,policy:i}),t&&o.createElement(d,{isOpen:!0,onClose:p,policy:t}))};export{B as PolicyPublishButton};
1
+ import{jsxs as h,Fragment as y,jsx as s}from"react/jsx-runtime";import{Button as b}from"@material-ui/core";import{PolicyConfigParser as C}from"@spotify/backstage-plugin-rbac-common";import{useState as g}from"react";import{useFetchPolicies as d}from"../Policies/useFetchPolicies.esm.js";import{usePolicyContext as x}from"./PolicyProvider.esm.js";import{PolicyPublishConfirmationDialog as j}from"./PolicyPublishConfirmationDialog.esm.js";import{PolicyPublishSuccessDialog as B}from"./PolicyPublishSuccessDialog.esm.js";import{usePublishPolicy as D}from"./usePublishPolicy.esm.js";const F=e=>{const[l,o]=g(!1),{fetchPolicies:t}=d(),[{loading:c,value:r},m]=D(),{policy:i,hasChanges:n}=x(),a=C.safeParse(i).success,u=!n&&a,P=async f=>{await m(i,f),o(!1)},p=()=>{t()};return h(y,{children:[s(b,{...e,onClick:()=>o(!0),disabled:!u||c,children:"Publish"}),s(j,{open:l,onClose:()=>o(!1),onPublish:P,policy:i}),r&&s(B,{isOpen:!0,onClose:p,policy:r})]})};export{F as PolicyPublishButton};
2
2
  //# sourceMappingURL=PolicyPublishButton.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as p,Dialog as f,DialogTitle as y,Box as d,Button as r,Typography as h,DialogContent as s,TextField as g,DialogActions as E,CircularProgress as b}from"@material-ui/core";import C from"@material-ui/icons/Close";import e,{useState as k,useRef as v}from"react";import{DiffSummary as D}from"../Diffing/DiffSummary.esm.js";const B=p(t=>({closeButton:{color:t.palette.text.secondary},diffSummaryContainer:{backgroundColor:t.palette.background.default,marginBottom:t.spacing(2)}}));function P({open:t,onPublish:c,onClose:l,policy:m}){const[o,n]=k(!1),a=B(),i=v(null),u=async()=>{n(!0),await c(i.current?.value??""),n(!1)};return e.createElement(f,{open:t,onClose:l,fullWidth:!0},e.createElement(y,null,e.createElement(d,{display:"flex",justifyContent:"space-between",alignItems:"center"},"Ready to publish?",e.createElement(r,{startIcon:e.createElement(C,null),onClick:l,className:a.closeButton},"Close")),e.createElement(h,null,"Double check your changes, then click Publish to activate this version of your policy. This will immediately apply the permissions defined in this version across Backstage.")),e.createElement(s,{className:a.diffSummaryContainer,dividers:!0},e.createElement(D,{policy:m})),e.createElement(s,null,e.createElement(g,{variant:"outlined",fullWidth:!0,label:"Summary (optional)",placeholder:"Briefly describe this version (or changes from a previous version)",inputRef:i})),e.createElement(E,null,e.createElement(r,{color:"primary",onClick:u,disabled:o},o?e.createElement(b,{size:20}):"Publish")))}export{P as PolicyPublishConfirmationDialog};
1
+ import{jsxs as i,jsx as e}from"react/jsx-runtime";import{makeStyles as h,Dialog as p,DialogTitle as f,Box as y,Button as s,Typography as g,DialogContent as c,TextField as b,DialogActions as C,CircularProgress as v}from"@material-ui/core";import k from"@material-ui/icons/Close";import{useState as B,useRef as x}from"react";import{DiffSummary as D}from"../Diffing/DiffSummary.esm.js";const S=h(o=>({closeButton:{color:o.palette.text.secondary},diffSummaryContainer:{backgroundColor:o.palette.background.default,marginBottom:o.spacing(2)}}));function P({open:o,onPublish:u,onClose:l,policy:d}){const[r,n]=B(!1),t=S(),a=x(null),m=async()=>{n(!0),await u(a.current?.value??""),n(!1)};return i(p,{open:o,onClose:l,fullWidth:!0,children:[i(f,{children:[i(y,{display:"flex",justifyContent:"space-between",alignItems:"center",children:["Ready to publish?",e(s,{startIcon:e(k,{}),onClick:l,className:t.closeButton,children:"Close"})]}),e(g,{children:"Double check your changes, then click Publish to activate this version of your policy. This will immediately apply the permissions defined in this version across Backstage."})]}),e(c,{className:t.diffSummaryContainer,dividers:!0,children:e(D,{policy:d})}),e(c,{children:e(b,{variant:"outlined",fullWidth:!0,label:"Summary (optional)",placeholder:"Briefly describe this version (or changes from a previous version)",inputRef:a})}),e(C,{children:e(s,{color:"primary",onClick:m,disabled:r,children:r?e(v,{size:20}):"Publish"})})]})}export{P as PolicyPublishConfirmationDialog};
2
2
  //# sourceMappingURL=PolicyPublishConfirmationDialog.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as a,Dialog as c,DialogTitle as m,Box as l,Typography as r,IconButton as s,DialogContent as p,DialogActions as u,Button as y}from"@material-ui/core";import E from"@material-ui/icons/Close";import e from"react";import{Link as f}from"react-router-dom";import{PolicyCard as g}from"./PolicyCard.esm.js";const d=a(t=>({paper:{padding:t.spacing(2,2,0,2)}})),x=({isOpen:t,onClose:o,policy:n})=>{const i=d();return e.createElement(c,{classes:{...i},open:t,onClose:o},e.createElement(m,{disableTypography:!0},e.createElement(l,{display:"flex",flexDirection:"row"},e.createElement(l,null,e.createElement(r,{variant:"h4",component:"h2"},"Success!"),e.createElement(r,null,n.name," has been published and is now your active policy.")),e.createElement(l,null,e.createElement(s,{onClick:o,title:"Close dialog"},e.createElement(E,null))))),e.createElement(p,null,e.createElement(g,{policy:n})),e.createElement(u,null,e.createElement(l,{display:"flex",flexDirection:"row",flexGrow:1,justifyContent:"flex-start"},e.createElement(y,{component:f,color:"primary",onClick:o,role:"link",to:"/rbac"},"View all versions"))))};export{x as PolicyPublishSuccessDialog};
1
+ import{jsxs as i,jsx as o}from"react/jsx-runtime";import{makeStyles as t,Dialog as a,DialogTitle as p,Box as e,Typography as c,IconButton as d,DialogContent as h,DialogActions as m,Button as y}from"@material-ui/core";import f from"@material-ui/icons/Close";import{Link as x}from"react-router-dom";import{PolicyCard as g}from"./PolicyCard.esm.js";const u=t(l=>({paper:{padding:l.spacing(2,2,0,2)}})),C=({isOpen:l,onClose:n,policy:r})=>{const s=u();return i(a,{classes:{...s},open:l,onClose:n,children:[o(p,{disableTypography:!0,children:i(e,{display:"flex",flexDirection:"row",children:[i(e,{children:[o(c,{variant:"h4",component:"h2",children:"Success!"}),i(c,{children:[r.name," has been published and is now your active policy."]})]}),o(e,{children:o(d,{onClick:n,title:"Close dialog",children:o(f,{})})})]})}),o(h,{children:o(g,{policy:r})}),o(m,{children:o(e,{display:"flex",flexDirection:"row",flexGrow:1,justifyContent:"flex-start",children:o(y,{component:x,color:"primary",onClick:n,role:"link",to:"/rbac",children:"View all versions"})})})]})};export{C as PolicyPublishSuccessDialog};
2
2
  //# sourceMappingURL=PolicyPublishSuccessDialog.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as a,Chip as s}from"@material-ui/core";import i from"@material-ui/icons/FiberManualRecord";import c from"react";const o=a(e=>({chip:{margin:0},icon:{color:e.palette.success.main}}));function l(e){const t=o();return e.status==="inactive"?null:e.status==="draft"?c.createElement(s,{className:t.chip,label:"Draft",size:e.size}):c.createElement(s,{className:t.chip,classes:{icon:t.icon},label:"Active",icon:c.createElement(i,null),size:e.size})}export{l as PolicyStatusChip};
1
+ import{jsx as i}from"react/jsx-runtime";import{makeStyles as a,Chip as c}from"@material-ui/core";import e from"@material-ui/icons/FiberManualRecord";const o=a(s=>({chip:{margin:0},icon:{color:s.palette.success.main}}));function l(s){const t=o();return s.status==="inactive"?null:s.status==="draft"?i(c,{className:t.chip,label:"Draft",size:s.size}):i(c,{className:t.chip,classes:{icon:t.icon},label:"Active",icon:i(e,{}),size:s.size})}export{l as PolicyStatusChip};
2
2
  //# sourceMappingURL=PolicyStatusChip.esm.js.map
@@ -1,2 +1,2 @@
1
- import{useApi as a,alertApiRef as f}from"@backstage/core-plugin-api";import{useNavigate as p}from"react-router-dom";import u from"react-use/lib/useAsyncFn";import{rbacApiRef as l}from"../../api.esm.js";import{useFetchPolicies as h}from"../Policies/useFetchPolicies.esm.js";function y(){const e=a(l),o=a(f),t=p(),{fetchPolicies:i}=h();return u(async s=>{if(!s)return;const{roles:c,name:n,options:m}=s;try{const r=await e.createDraft({roles:c,options:m,name:n});return await i(),t(`/rbac/versions/${r.id}`),r}catch(r){throw r instanceof Error&&o.post({message:r.message,severity:"error"}),r}},[t,e,o,i])}export{y as useDuplicatePolicy};
1
+ import{useApi as a,alertApiRef as f,useAnalytics as l}from"@backstage/core-plugin-api";import{useNavigate as y}from"react-router-dom";import d from"react-use/lib/useAsyncFn";import{rbacApiRef as g}from"../../api.esm.js";import{useFeatureFlags as A}from"../../hooks/useFeatureFlag.esm.js";import{useFetchPolicies as F}from"../Policies/useFetchPolicies.esm.js";function b(){const r=a(g),t=a(f),c=l(),n=A(),o=y(),{fetchPolicies:i}=F();return d(async s=>{if(!s)return;const{roles:u,name:p,options:m}=s;try{const e=await r.createDraft({roles:u,options:m,name:p});return await i(),c.captureEvent("resource_action","duplicate",{attributes:{resourceType:"policy",resourceAction:"duplicate",resourceId:e.id,rbacFeatureFlags:n.join(",")}}),o(`/rbac/versions/${e.id}`),e}catch(e){throw e instanceof Error&&t.post({message:e.message,severity:"error"}),e}},[o,r,t,i])}export{b as useDuplicatePolicy};
2
2
  //# sourceMappingURL=useDuplicatePolicy.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as n,Typography as r}from"@material-ui/core";import i from"react";const c=n(()=>({decisionRowCell:{fontWeight:"bold"}})),s=({children:o,ledToDecision:e,color:t})=>{const l=c();return i.createElement(r,{variant:"body1",component:"span",classes:{root:e?l.decisionRowCell:void 0},color:t},o)};export{s as CellText};
1
+ import{jsx as n}from"react/jsx-runtime";import{makeStyles as r,Typography as i}from"@material-ui/core";const s=r(()=>({decisionRowCell:{fontWeight:"bold"}})),c=({children:o,ledToDecision:e,color:t})=>{const l=s();return n(i,{variant:"body1",component:"span",classes:{root:e?l.decisionRowCell:void 0},color:t,children:o})};export{c as CellText};
2
2
  //# sourceMappingURL=CellText.esm.js.map
@@ -1,2 +1,2 @@
1
- import e from"react";import{CellText as i}from"./CellText.esm.js";const l=({ledToDecision:o})=>e.createElement(i,{ledToDecision:o,color:o===!1?"textSecondary":void 0},o?"Yes":"No");export{l as DecidingRoleCell};
1
+ import{jsx as e}from"react/jsx-runtime";import{CellText as i}from"./CellText.esm.js";const l=({ledToDecision:o})=>e(i,{ledToDecision:o,color:o===!1?"textSecondary":void 0,children:o?"Yes":"No"});export{l as DecidingRoleCell};
2
2
  //# sourceMappingURL=DecidingRoleCell.esm.js.map
@@ -1,2 +1,2 @@
1
- import{AuthorizeResult as c}from"@backstage/plugin-permission-common";import{makeStyles as p,Box as E,TableContainer as T,Table as b,TableHead as f,TableRow as u,TableBody as h,TableCell as a}from"@material-ui/core";import{getMatchingRolePermissions as D,isConditionalDecision as R}from"@spotify/backstage-plugin-rbac-common";import e,{useMemo as w}from"react";import{DecidingRoleCell as g}from"./DecidingRoleCell.esm.js";import{DecisionCell as C}from"./DecisionCell.esm.js";import{PermissionNameCell as k}from"./PermissionNameCell.esm.js";import{RoleNameCell as z}from"./RoleNameCell.esm.js";import{TableHeaderCell as s}from"./TableHeaderCell.esm.js";import{UserIconCell as y}from"./UserIconCell.esm.js";const N=p(o=>({tableContainer:{border:`1px solid ${o.palette.border}`,borderRadius:o.shape.borderRadius},tableRow:{"&, &:nth-child(odd)":{background:o.palette.background.paper}},decisionTableRow:{"&, &:nth-child(odd)":{background:o.palette.type==="light"?o.palette.infoBackground:o.palette.grey[900]}}})),I=o=>{if(R(o))return c.CONDITIONAL;if(typeof o=="string")switch(o){case"allow":return c.ALLOW;case"deny":return c.DENY;default:throw new Error(`Unknown decision: ${o}`)}throw new Error("Unknown decision type found.")},B=(o,t)=>t.some(r=>r.rolePermissionId===o.id),P=o=>w(()=>{const{roles:t,permission:r,decisionOrigin:l}=o,n=[];for(const i of t){const m=D(i,r);if(m.length>0)for(const d of m)n.push({role:i,permission:r,authorizeResult:I(d.decision),ledToDecision:B(d,l)});else n.push({role:i,permission:r,authorizeResult:null,ledToDecision:!1})}return n},[o]),O=({resultRow:o})=>{const t=N(),r=P(o);return e.createElement(E,{marginTop:3,marginBottom:3},e.createElement(T,{classes:{root:t.tableContainer}},e.createElement(b,null,e.createElement(f,null,e.createElement(u,{classes:{root:t.tableRow}},e.createElement(s,null),e.createElement(s,null,"Role"),e.createElement(s,null,"Permission"),e.createElement(s,null,"Decision"),e.createElement(s,null,"Is deciding role"))),e.createElement(h,null,r.map((l,n)=>{const i=n===0;return e.createElement(u,{key:n,classes:{root:l.ledToDecision?t.decisionTableRow:t.tableRow}},i?e.createElement(y,{rowCount:r.length}):null,e.createElement(a,{size:"small"},e.createElement(z,{role:l.role,ledToDecision:l.ledToDecision})),e.createElement(a,{size:"small"},e.createElement(k,{permissionName:l.permission.name,ledToDecision:l.ledToDecision})),e.createElement(a,{size:"small"},e.createElement(C,{authorizeResult:l.authorizeResult,ledToDecision:l.ledToDecision})),e.createElement(a,{size:"small"},e.createElement(g,{ledToDecision:l.ledToDecision})))})))))};export{O as DecisionBreakdownTable};
1
+ import{jsx as o,jsxs as c}from"react/jsx-runtime";import{AuthorizeResult as a}from"@backstage/plugin-permission-common";import{makeStyles as u,Box as T,TableContainer as b,Table as f,TableHead as D,TableRow as p,TableBody as R,TableCell as d}from"@material-ui/core";import{getMatchingRolePermissions as w,isConditionalDecision as g}from"@spotify/backstage-plugin-rbac-common";import{useMemo as C}from"react";import{DecidingRoleCell as z}from"./DecidingRoleCell.esm.js";import{DecisionCell as k}from"./DecisionCell.esm.js";import{PermissionNameCell as y}from"./PermissionNameCell.esm.js";import{RoleNameCell as N}from"./RoleNameCell.esm.js";import{TableHeaderCell as t}from"./TableHeaderCell.esm.js";import{UserIconCell as I}from"./UserIconCell.esm.js";const x=u(e=>({tableContainer:{border:`1px solid ${e.palette.border}`,borderRadius:e.shape.borderRadius},tableRow:{"&, &:nth-child(odd)":{background:e.palette.background.paper}},decisionTableRow:{"&, &:nth-child(odd)":{background:e.palette.type==="light"?e.palette.infoBackground:e.palette.grey[900]}}})),B=e=>{if(g(e))return a.CONDITIONAL;if(typeof e=="string")switch(e){case"allow":return a.ALLOW;case"deny":return a.DENY;default:throw new Error(`Unknown decision: ${e}`)}throw new Error("Unknown decision type found.")},A=(e,r)=>r.some(n=>n.rolePermissionId===e.id),O=e=>C(()=>{const{roles:r,permission:n,decisionOrigin:i}=e,l=[];for(const s of r){const m=w(s,n);if(m.length>0)for(const h of m)l.push({role:s,permission:n,authorizeResult:B(h.decision),ledToDecision:A(h,i)});else l.push({role:s,permission:n,authorizeResult:null,ledToDecision:!1})}return l},[e]),P=({resultRow:e})=>{const r=x(),n=O(e);return o(T,{marginTop:3,marginBottom:3,children:o(b,{classes:{root:r.tableContainer},children:c(f,{children:[o(D,{children:c(p,{classes:{root:r.tableRow},children:[o(t,{}),o(t,{children:"Role"}),o(t,{children:"Permission"}),o(t,{children:"Decision"}),o(t,{children:"Is deciding role"})]})}),o(R,{children:n.map((i,l)=>{const s=l===0;return c(p,{classes:{root:i.ledToDecision?r.decisionTableRow:r.tableRow},children:[s?o(I,{rowCount:n.length}):null,o(d,{size:"small",children:o(N,{role:i.role,ledToDecision:i.ledToDecision})}),o(d,{size:"small",children:o(y,{permissionName:i.permission.name,ledToDecision:i.ledToDecision})}),o(d,{size:"small",children:o(k,{authorizeResult:i.authorizeResult,ledToDecision:i.ledToDecision})}),o(d,{size:"small",children:o(z,{ledToDecision:i.ledToDecision})})]},l)})})]})})})};export{P as DecisionBreakdownTable};
2
2
  //# sourceMappingURL=DecisionBreakdownTable.esm.js.map
@@ -1,2 +1,2 @@
1
- import{AuthorizeResult as n}from"@backstage/plugin-permission-common";import{makeStyles as r}from"@material-ui/core";import t from"react";import{DecisionIcon as c}from"../DecisionIcon.esm.js";import{CellText as l}from"./CellText.esm.js";const s=r(e=>({decisionCell:{display:"flex",justifyItems:"center"},decisionIconContainer:{display:"flex",alignItems:"center",marginRight:e.spacing(1)},decisionIconAllow:{color:e.palette.success.main},decisionIconDeny:{color:e.palette.error.main},decisionIconConditional:{color:e.palette.info.main}})),a=e=>{switch(e){case n.ALLOW:return"Allow";case n.DENY:return"Deny";case n.CONDITIONAL:return"Conditional";default:return"Permission not found in role"}},m=(e,o)=>{let i;switch(e){case n.ALLOW:i=o.decisionIconAllow;break;case n.DENY:i=o.decisionIconDeny;break;case n.CONDITIONAL:i=o.decisionIconConditional;break;default:return}return`${o.decisionIconContainer} ${i}`},d=({ledToDecision:e,authorizeResult:o})=>{const i=s();return t.createElement("div",{className:i.decisionCell},o!==null&&t.createElement("span",{className:m(o,i)},t.createElement(c,{authorizeResult:o,size:"small"})),t.createElement(l,{ledToDecision:e,color:e===!1?"textSecondary":void 0},a(o)))};export{d as DecisionCell};
1
+ import{jsxs as s,jsx as r}from"react/jsx-runtime";import{AuthorizeResult as n}from"@backstage/plugin-permission-common";import{makeStyles as c}from"@material-ui/core";import{DecisionIcon as t}from"../DecisionIcon.esm.js";import{CellText as l}from"./CellText.esm.js";const a=c(e=>({decisionCell:{display:"flex",justifyItems:"center"},decisionIconContainer:{display:"flex",alignItems:"center",marginRight:e.spacing(1)},decisionIconAllow:{color:e.palette.success.main},decisionIconDeny:{color:e.palette.error.main},decisionIconConditional:{color:e.palette.info.main}})),d=e=>{switch(e){case n.ALLOW:return"Allow";case n.DENY:return"Deny";case n.CONDITIONAL:return"Conditional";default:return"Permission not found in role"}},m=(e,o)=>{let i;switch(e){case n.ALLOW:i=o.decisionIconAllow;break;case n.DENY:i=o.decisionIconDeny;break;case n.CONDITIONAL:i=o.decisionIconConditional;break;default:return}return`${o.decisionIconContainer} ${i}`},u=({ledToDecision:e,authorizeResult:o})=>{const i=a();return s("div",{className:i.decisionCell,children:[o!==null&&r("span",{className:m(o,i),children:r(t,{authorizeResult:o,size:"small"})}),r(l,{ledToDecision:e,color:e===!1?"textSecondary":void 0,children:d(o)})]})};export{u as DecisionCell};
2
2
  //# sourceMappingURL=DecisionCell.esm.js.map
@@ -1,2 +1,2 @@
1
- import o from"react";import{PermissionName as i}from"../../Permission/PermissionName.esm.js";import{CellText as r}from"./CellText.esm.js";const t=({permissionName:m,ledToDecision:e})=>o.createElement(r,{ledToDecision:e,color:e===!1?"textSecondary":void 0},o.createElement(i,{name:m}));export{t as PermissionNameCell};
1
+ import{jsx as e}from"react/jsx-runtime";import{PermissionName as m}from"../../Permission/PermissionName.esm.js";import{CellText as r}from"./CellText.esm.js";const s=({permissionName:i,ledToDecision:o})=>e(r,{ledToDecision:o,color:o===!1?"textSecondary":void 0,children:e(m,{name:i})});export{s as PermissionNameCell};
2
2
  //# sourceMappingURL=PermissionNameCell.esm.js.map
@@ -1,2 +1,2 @@
1
- import{Link as l}from"@backstage/core-components";import o from"react";import{CellText as m}from"./CellText.esm.js";const t=({role:e,ledToDecision:r})=>o.createElement(l,{to:`roles/${e.id}`},o.createElement(m,{ledToDecision:r,color:"primary"},e.name));export{t as RoleNameCell};
1
+ import{jsx as e}from"react/jsx-runtime";import{Link as i}from"@backstage/core-components";import{CellText as l}from"./CellText.esm.js";const m=({role:o,ledToDecision:r})=>e(i,{to:`roles/${o.id}`,children:e(l,{ledToDecision:r,color:"primary",children:o.name})});export{m as RoleNameCell};
2
2
  //# sourceMappingURL=RoleNameCell.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as r,TableCell as t}from"@material-ui/core";import o from"react";const a=r(e=>({tableHeader:{borderBottom:`1px solid ${e.palette.border}`}})),s=({children:e})=>{const l=a();return o.createElement(t,{size:"small",classes:{root:l.tableHeader}},e)};export{s as TableHeaderCell};
1
+ import{jsx as r}from"react/jsx-runtime";import{makeStyles as t,TableCell as o}from"@material-ui/core";const a=t(e=>({tableHeader:{borderBottom:`1px solid ${e.palette.border}`}})),s=({children:e})=>{const l=a();return r(o,{size:"small",classes:{root:l.tableHeader},children:e})};export{s as TableHeaderCell};
2
2
  //# sourceMappingURL=TableHeaderCell.esm.js.map
@@ -1,2 +1,2 @@
1
- import{UserIcon as t}from"@backstage/core-components";import{makeStyles as l,TableCell as n}from"@material-ui/core";import o from"react";const a=l(e=>({userCell:{borderRight:`1px solid ${e.palette.border}`,color:e.palette.text.secondary,background:e.palette.background.paper}})),s=({rowCount:e})=>{const r=a();return o.createElement(n,{size:"small",padding:"none",align:"center",rowSpan:e,classes:{root:r.userCell}},o.createElement(t,null))};export{s as UserIconCell};
1
+ import{jsx as o}from"react/jsx-runtime";import{UserIcon as t}from"@backstage/core-components";import{makeStyles as l,TableCell as n}from"@material-ui/core";const s=l(e=>({userCell:{borderRight:`1px solid ${e.palette.border}`,color:e.palette.text.secondary,background:e.palette.background.paper}})),a=({rowCount:e})=>{const r=s();return o(n,{size:"small",padding:"none",align:"center",rowSpan:e,classes:{root:r.userCell},children:o(t,{})})};export{a as UserIconCell};
2
2
  //# sourceMappingURL=UserIconCell.esm.js.map
@@ -1,2 +1,2 @@
1
- import{AuthorizeResult as t}from"@backstage/plugin-permission-common";import i from"@material-ui/icons/AccountTreeOutlined";import n from"@material-ui/icons/CheckSharp";import m from"@material-ui/icons/NotInterested";import r from"react";const u=({authorizeResult:o,size:e})=>{switch(o){case t.ALLOW:return r.createElement(n,{fontSize:e});case t.DENY:return r.createElement(m,{fontSize:e});case t.CONDITIONAL:return r.createElement(i,{fontSize:e});default:return null}};export{u as DecisionIcon};
1
+ import{jsx as t}from"react/jsx-runtime";import{AuthorizeResult as e}from"@backstage/plugin-permission-common";import i from"@material-ui/icons/AccountTreeOutlined";import n from"@material-ui/icons/CheckSharp";import m from"@material-ui/icons/NotInterested";const s=({authorizeResult:o,size:r})=>{switch(o){case e.ALLOW:return t(n,{fontSize:r});case e.DENY:return t(m,{fontSize:r});case e.CONDITIONAL:return t(i,{fontSize:r});default:return null}};export{s as DecisionIcon};
2
2
  //# sourceMappingURL=DecisionIcon.esm.js.map
@@ -1,2 +1,2 @@
1
- import{AuthorizeResult as c}from"@backstage/plugin-permission-common";import{makeStyles as u,Typography as p}from"@material-ui/core";import h from"@material-ui/icons/InfoOutlined";import{getMatchingRolePermissions as g}from"@spotify/backstage-plugin-rbac-common";import e from"react";import{PermissionName as i}from"../Permission/PermissionName.esm.js";import{usePolicyContext as f}from"../Policy/PolicyProvider.esm.js";const E=u(t=>({container:{display:"flex",flexDirection:"row",gap:t.spacing(1)},infoIcon:{color:t.palette.textSubtle}})),d=({policy:t,roles:o,permission:l})=>{const s=o.flatMap(n=>g(n,l));let r;if(o.length===0)r=e.createElement(e.Fragment,null,"A user with no assigned roles will be denied access to"," ",e.createElement("strong",null,e.createElement(i,{name:l.name})),".");else if(!s.length)r=e.createElement(e.Fragment,null,"None of the roles explicitly sets a rule for the permission"," ",e.createElement("strong",null,e.createElement(i,{name:l.name})),", which means that a user who has all of these roles will be denied access to"," ",e.createElement("strong",null,e.createElement(i,{name:l.name})),".");else if(t.options.resolutionStrategy==="any-allow")r=e.createElement(e.Fragment,null,"None of the roles explicitly sets an allow or conditional rule for the permission"," ",e.createElement("strong",null,e.createElement(i,{name:l.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", a user who has all of these roles will be denied access to"," ",e.createElement("strong",null,e.createElement(i,{name:l.name})),".");else throw t.options.resolutionStrategy==="first-match"?new Error("Trying to render ImplicitDecisionInfo for a first-match policy that has matching role permission. This should not happen, since the decision should be explicit by the matching role permission."):new Error(`Unknown resolution strategy ${t.options.resolutionStrategy}. Cannot render ImplicitDecisionInfo.`);return e.createElement(e.Fragment,null,e.createElement("strong",null,"Implicit decision")," \u2013 ",r)},y=({policy:t,permission:o,roles:l,decision:s,decisionOrigin:r})=>{const n=l.find(m=>m.id===r[0].roleId);let a;if(t.options.resolutionStrategy==="first-match"){if(!n)throw new Error("Expected decision origin role for first-match explicit decision but found none.");a=e.createElement(e.Fragment,null,"The role ",e.createElement("strong",null,n.name)," explicitly sets a rule for the permission"," ",e.createElement("strong",null,e.createElement(i,{name:o.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"first-match"),", no other roles are applied.")}else if(t.options.resolutionStrategy==="any-allow"){if(s.result===c.ALLOW){if(!n)throw new Error("Expected decision origin role for any-allow explicit allow decision but found none.");a=e.createElement(e.Fragment,null,"The role ",e.createElement("strong",null,n.name)," is the first role that explicitly sets an allow decision for the permission"," ",e.createElement("strong",null,e.createElement(i,{name:o.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", this decides the outcome.")}else if(s.result===c.CONDITIONAL)if(r.length===1){if(!n)throw new Error("Expected decision origin role for any-allow explicit allow decision but found none.");a=e.createElement(e.Fragment,null,"The role ",e.createElement("strong",null,n.name)," is the first role that explicitly sets a decision for the permission"," ",e.createElement("strong",null,e.createElement(i,{name:o.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", this decides the outcome.")}else a=e.createElement(e.Fragment,null,"Multiple roles explicitly set a rule for the permission"," ",e.createElement("strong",null,e.createElement(i,{name:o.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", these decide the outcome.")}else throw new Error(`Unknown resolution strategy ${t.options.resolutionStrategy}. Cannot render ExplicitDecisionInfo.`);return e.createElement(e.Fragment,null,e.createElement("strong",null,"Explicit decision")," \u2013 ",a)},w=({roles:t,permission:o,decision:l,decisionOrigin:s})=>{const{policy:r}=f(),n=E();return e.createElement("div",{className:n.container},e.createElement(h,{fontSize:"small",titleAccess:"",className:n.infoIcon}),e.createElement(p,{variant:"body1",component:"p"},s.length===0?e.createElement(d,{policy:r,roles:t,permission:o}):e.createElement(y,{policy:r,permission:o,roles:t,decision:l,decisionOrigin:s})))};export{w as DecisionInfo};
1
+ import{jsxs as s,jsx as e,Fragment as l}from"react/jsx-runtime";import{AuthorizeResult as d}from"@backstage/plugin-permission-common";import{makeStyles as p,Typography as f}from"@material-ui/core";import g from"@material-ui/icons/InfoOutlined";import{getMatchingRolePermissions as y}from"@spotify/backstage-plugin-rbac-common";import{PermissionName as c}from"../Permission/PermissionName.esm.js";import{usePolicyContext as u}from"../Policy/PolicyProvider.esm.js";const w=p(i=>({container:{display:"flex",flexDirection:"row",gap:i.spacing(1)},infoIcon:{color:i.palette.textSubtle}})),x=({policy:i,roles:n,permission:r})=>{const a=n.flatMap(o=>y(o,r));let t;if(n.length===0)t=s(l,{children:["A user with no assigned roles will be denied access to"," ",e("strong",{children:e(c,{name:r.name})}),"."]});else if(!a.length)t=s(l,{children:["None of the roles explicitly sets a rule for the permission"," ",e("strong",{children:e(c,{name:r.name})}),", which means that a user who has all of these roles will be denied access to"," ",e("strong",{children:e(c,{name:r.name})}),"."]});else if(i.options.resolutionStrategy==="any-allow")t=s(l,{children:["None of the roles explicitly sets an allow or conditional rule for the permission"," ",e("strong",{children:e(c,{name:r.name})}),". Since the resolution strategy for this policy is"," ",e("strong",{children:"any-allow"}),", a user who has all of these roles will be denied access to"," ",e("strong",{children:e(c,{name:r.name})}),"."]});else throw i.options.resolutionStrategy==="first-match"?new Error("Trying to render ImplicitDecisionInfo for a first-match policy that has matching role permission. This should not happen, since the decision should be explicit by the matching role permission."):new Error(`Unknown resolution strategy ${i.options.resolutionStrategy}. Cannot render ImplicitDecisionInfo.`);return s(l,{children:[e("strong",{children:"Implicit decision"})," \u2013 ",t]})},S=({policy:i,permission:n,roles:r,decision:a,decisionOrigin:t})=>{const o=r.find(m=>m.id===t[0].roleId);let h;if(i.options.resolutionStrategy==="first-match"){if(!o)throw new Error("Expected decision origin role for first-match explicit decision but found none.");h=s(l,{children:["The role ",e("strong",{children:o.name})," explicitly sets a rule for the permission"," ",e("strong",{children:e(c,{name:n.name})}),". Since the resolution strategy for this policy is"," ",e("strong",{children:"first-match"}),", no other roles are applied."]})}else if(i.options.resolutionStrategy==="any-allow"){if(a.result===d.ALLOW){if(!o)throw new Error("Expected decision origin role for any-allow explicit allow decision but found none.");h=s(l,{children:["The role ",e("strong",{children:o.name})," is the first role that explicitly sets an allow decision for the permission"," ",e("strong",{children:e(c,{name:n.name})}),". Since the resolution strategy for this policy is"," ",e("strong",{children:"any-allow"}),", this decides the outcome."]})}else if(a.result===d.CONDITIONAL)if(t.length===1){if(!o)throw new Error("Expected decision origin role for any-allow explicit allow decision but found none.");h=s(l,{children:["The role ",e("strong",{children:o.name})," is the first role that explicitly sets a decision for the permission"," ",e("strong",{children:e(c,{name:n.name})}),". Since the resolution strategy for this policy is"," ",e("strong",{children:"any-allow"}),", this decides the outcome."]})}else h=s(l,{children:["Multiple roles explicitly set a rule for the permission"," ",e("strong",{children:e(c,{name:n.name})}),". Since the resolution strategy for this policy is"," ",e("strong",{children:"any-allow"}),", these decide the outcome."]})}else throw new Error(`Unknown resolution strategy ${i.options.resolutionStrategy}. Cannot render ExplicitDecisionInfo.`);return s(l,{children:[e("strong",{children:"Explicit decision"})," \u2013 ",h]})},I=({roles:i,permission:n,decision:r,decisionOrigin:a})=>{const{policy:t}=u(),o=w();return s("div",{className:o.container,children:[e(g,{fontSize:"small",titleAccess:"",className:o.infoIcon}),e(f,{variant:"body1",component:"p",children:a.length===0?e(x,{policy:t,roles:i,permission:n}):e(S,{policy:t,permission:n,roles:i,decision:r,decisionOrigin:a})})]})};export{I as DecisionInfo};
2
2
  //# sourceMappingURL=DecisionInfo.esm.js.map