@spotify/backstage-plugin-rbac 0.7.3 → 0.7.4

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @spotify/backstage-plugin-rbac
2
2
 
3
+ ## 0.7.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Update to Backstage `v1.34.0`
8
+ - Fixed a bug that could cause a draft policy to be corrupted and lost while editing the policy or its roles.
9
+ - The UI has been optimized for the default Backstage theme and should better respect theme customizations.
10
+ - Fixed a bug with policy diffing that incorrectly identified changes to roles and permissions that were unchanged when exported and reimported.
11
+ - Updated dependencies
12
+ - @spotify/backstage-plugin-core@0.8.4
13
+ - @spotify/backstage-plugin-rbac-common@0.6.4
14
+
3
15
  ## 0.7.3
4
16
 
5
17
  ### Patch Changes
@@ -1,2 +1,2 @@
1
- import{makeStyles as g,Box as a,Card as f,CardContent as C,InputLabel as h,TextField as y,Typography as i,Popper as x,IconButton as b}from"@material-ui/core";import v from"@material-ui/icons/Delete";import{Autocomplete as B}from"@material-ui/lab";import e,{useCallback as F}from"react";import{useAggregatedRules as I}from"../../Permissions/PermissionsMetadataContext.esm.js";import{ParamsForm as k}from"../ParamsForm/ParamsForm.esm.js";const D=g(n=>({conditionCard:{minWidth:n.spacing(63)},conditionCardBar:{height:n.spacing(1),backgroundImage:"linear-gradient(90deg, #007DFF 0%, #0057B2 100%)"},autocomplete:{flex:1}}));function N({ruleName:n,parameters:p,resourceType:u,onChange:r,onDelete:d}){const o=D(),m=I()?.filter(t=>t.resourceType===u)??[],c=m.find(t=>t.name===n),s=t=>{r(t,{})},E=F(t=>{r(n,t)},[r,n]);return e.createElement(a,{display:"flex",alignItems:"center"},e.createElement(f,{className:o.conditionCard},e.createElement("div",{className:o.conditionCardBar}),e.createElement(C,null,e.createElement(a,null,e.createElement(a,null,e.createElement(B,{className:o.autocomplete,"data-testid":"rule-select",getOptionLabel:t=>t.name,getOptionSelected:(t,l)=>t.name===l.name,options:m,onChange:(t,l)=>s(l?l.name:null),renderInput:t=>e.createElement(e.Fragment,null,e.createElement(a,{marginBottom:2},e.createElement(h,null,"Rule")),e.createElement(y,{...t,placeholder:"Select",variant:"outlined",size:"small",name:"rule"})),renderOption:t=>e.createElement(a,null,e.createElement(i,{variant:"body2"},t.name),e.createElement(i,{noWrap:!0,variant:"caption"},t.description)),value:c||null,PopperComponent:t=>e.createElement(x,{...t,style:{width:"auto"},placement:"bottom-start"})})),e.createElement(a,{flex:"1"},e.createElement(a,{display:"flex",flexDirection:"column"},e.createElement(k,{rule:c,onChange:E,value:p})))))),e.createElement(a,{ml:1},e.createElement(b,{"aria-label":"delete",onClick:d,size:"small"},e.createElement(v,null))))}export{N as default};
1
+ import{makeStyles as g,Box as a,Card as f,CardContent as C,InputLabel as y,TextField as h,Typography as i,Popper as x,IconButton as b}from"@material-ui/core";import v from"@material-ui/icons/Delete";import{Autocomplete as B}from"@material-ui/lab";import e,{useCallback as N}from"react";import{useAggregatedRules as k}from"../../Permissions/PermissionsMetadataContext.esm.js";import{ParamsForm as I}from"../ParamsForm/ParamsForm.esm.js";const S=g(n=>({conditionCard:{minWidth:n.spacing(63)},conditionCardBar:{height:n.spacing(1),backgroundColor:n.palette.primary.main},autocomplete:{flex:1}}));function T({ruleName:n,parameters:p,resourceType:u,onChange:r,onDelete:s}){const o=S(),m=k()?.filter(t=>t.resourceType===u)??[],c=m.find(t=>t.name===n),d=t=>{r(t,{})},E=N(t=>{r(n,t)},[r,n]);return e.createElement(a,{display:"flex",alignItems:"center"},e.createElement(f,{className:o.conditionCard},e.createElement("div",{className:o.conditionCardBar}),e.createElement(C,null,e.createElement(a,null,e.createElement(a,null,e.createElement(B,{className:o.autocomplete,"data-testid":"rule-select",getOptionLabel:t=>t.name,getOptionSelected:(t,l)=>t.name===l.name,options:m,onChange:(t,l)=>d(l?l.name:null),renderInput:t=>e.createElement(e.Fragment,null,e.createElement(a,{marginBottom:2},e.createElement(y,null,"Rule")),e.createElement(h,{...t,placeholder:"Select",variant:"outlined",size:"small",name:"rule"})),renderOption:t=>e.createElement(a,null,e.createElement(i,{variant:"body2"},t.name),e.createElement(i,{noWrap:!0,variant:"caption"},t.description)),value:c||null,PopperComponent:t=>e.createElement(x,{...t,style:{width:"auto"},placement:"bottom-start"})})),e.createElement(a,{flex:"1"},e.createElement(a,{display:"flex",flexDirection:"column"},e.createElement(I,{rule:c,onChange:E,value:p})))))),e.createElement(a,{ml:1},e.createElement(b,{"aria-label":"delete",onClick:s,size:"small"},e.createElement(v,null))))}export{T as default};
2
2
  //# sourceMappingURL=ConditionCard.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as W,Dialog as A,DialogTitle as F,Typography as j,Button as x,DialogContent as k,Box as r,Divider as M,FormHelperText as V,Tooltip as G}from"@material-ui/core";import H from"@material-ui/icons/Close";import L from"@material-ui/icons/Info";import e,{useState as T,useMemo as y,useEffect as O}from"react";import{usePermissions as U,useAggregatedRules as Y,useResourceTypeInfo as q}from"../Permissions/PermissionsMetadataContext.esm.js";import z from"./computeMatchResult.esm.js";import J from"./ConditionalDecisionForm/ConditionalDecisionForm.esm.js";import{getInitialValues as K,validateCriteria as Q,toRolePermission as X,getConditions as Z}from"./decisionDataMappers.esm.js";import _ from"./MatchByActions.esm.js";import $ from"./MatchByName.esm.js";import ee from"./MatchByResourceType.esm.js";import C from"./ToggleButton.esm.js";import oe from"./ToggleButtonGroup.esm.js";import{VerticalSelection as ie}from"./VerticalSelection.esm.js";const ne=W(a=>({dialogTitle:{display:"flex",alignItems:"center",justifyContent:"space-between"},fullWidth:{width:"100%","& > *":{flexGrow:1}},infoIcon:{position:"absolute",right:a.spacing(3)},content:{padding:a.spacing(7)},saveButton:{paddingLeft:a.spacing(5),paddingRight:a.spacing(5)},contentContainerConditional:{display:"flex",gap:a.spacing(5),maxWidth:1480}})),te={specificPermission:"Choose a specific permission",filter:"Filter by permission properties",all:"Match all permissions"},R="Choose the name of a resource permission or filter by resource type to set a conditional decision.";function ae({rolePermission:a,readonly:t=!1,onClose:b,onSave:D}){const s=ne(),{permissions:c}=U(),v=Y(),f=q(),p=K(a),[o,d]=T(p.match),[l,g]=T(p.decisionType),[u,I]=T(p.criteria),i=y(()=>z(c,o),[c,o]),m=l==="conditional",w=m?"xl":"sm";O(()=>{m&&c&&!i.commonResourceType&&g("allow")},[m,c,i.commonResourceType,g]);const N=n=>{n!==null&&g(n)},h=y(()=>o.method==="specificPermission"&&!o.name||o.method==="filter"&&!o.resourceType&&!o.actions,[o]),P=y(()=>i.permissions.length===0?!1:!h,[i,h]),S=y(()=>l!=="conditional"?!0:!(!i.commonResourceType||!f?.[i.commonResourceType].pluginId||!Q(u,v)),[l,i,f,u,v]),B=()=>{D?.(X(p.id,o,l==="conditional"?{resourceType:i.commonResourceType,pluginId:f[i.commonResourceType].pluginId,conditions:Z(u)}:l))};return e.createElement(A,{open:!0,maxWidth:w,onClose:b,fullWidth:!0},e.createElement(F,{disableTypography:!0,className:s.dialogTitle},e.createElement(j,{variant:"h4",component:"h2"},"New Permission Decision"),e.createElement(x,{startIcon:e.createElement(H,null),onClick:b},"Close")),e.createElement(k,{dividers:!0,className:s.content},e.createElement(r,{className:m?s.contentContainerConditional:void 0},e.createElement(r,{mb:5,flex:1},e.createElement(ie,{options:Object.entries(te).map(([n,E])=>({id:n,displayText:E})),selected:o.method,onChange:n=>d({method:n}),readonly:t})),e.createElement(r,{mb:5,height:189,flex:1},o.method==="specificPermission"&&e.createElement($,{name:o.name,readonly:t,onNameChange:n=>d({...o,name:n})}),o.method==="filter"&&e.createElement(e.Fragment,null,e.createElement(ee,{resourceType:o.resourceType,readonly:t,onResourceTypeChange:n=>d({...o,resourceType:n})}),e.createElement(_,{actions:o.actions,readonly:t,onActionsChange:n=>d({...o,actions:n.length?n:void 0})}),h?null:e.createElement(e.Fragment,null,e.createElement(r,{marginY:2},e.createElement(M,{variant:"middle"})),e.createElement(V,null,`Matched ${i.permissions.length} ${i.permissions.length===1?"permission":"permissions"}`)))),e.createElement(r,{mb:5,flex:1},e.createElement(r,{display:"flex",alignItems:"center"},e.createElement(oe,{value:l,exclusive:!0,fullWidth:!0,"aria-label":"Decision result",onChange:(n,E)=>N(E)},e.createElement(C,{value:"allow","aria-label":"Decision allowed",disabled:t},"Allow"),e.createElement(C,{value:"deny","aria-label":"Decision denied",disabled:t},"Deny"),e.createElement(C,{value:"conditional","aria-label":"Decision conditionally allowed",disabled:!i.commonResourceType||t},"Conditional")),!m&&!t&&e.createElement(G,{title:R},e.createElement(L,{className:s.infoIcon,color:"primary","aria-label":R}))))),l==="conditional"&&!!i.commonResourceType&&e.createElement(J,{permissionCriteria:u,resourceType:i.commonResourceType,onUpdate:I,readonly:t}),!t&&e.createElement(r,{display:"flex",justifyContent:"flex-end"},e.createElement(x,{variant:"contained",color:"primary",className:s.saveButton,onClick:B,disabled:!P||!S},"Save"))))}export{ae as DecisionDialog};
1
+ import{makeStyles as W,Dialog as A,DialogTitle as F,Typography as j,Button as x,DialogContent as k,Box as r,Divider as M,FormHelperText as V,Tooltip as G}from"@material-ui/core";import H from"@material-ui/icons/Close";import L from"@material-ui/icons/Info";import{ToggleButton as T}from"@material-ui/lab";import e,{useState as C,useMemo as g,useEffect as O}from"react";import{usePermissions as U,useAggregatedRules as Y,useResourceTypeInfo as q}from"../Permissions/PermissionsMetadataContext.esm.js";import z from"./computeMatchResult.esm.js";import J from"./ConditionalDecisionForm/ConditionalDecisionForm.esm.js";import{getInitialValues as K,validateCriteria as Q,toRolePermission as X,getConditions as Z}from"./decisionDataMappers.esm.js";import _ from"./MatchByActions.esm.js";import $ from"./MatchByName.esm.js";import ee from"./MatchByResourceType.esm.js";import oe from"./ToggleButtonGroup.esm.js";import{VerticalSelection as ne}from"./VerticalSelection.esm.js";const ie=W(a=>({dialogTitle:{display:"flex",alignItems:"center",justifyContent:"space-between"},fullWidth:{width:"100%","& > *":{flexGrow:1}},infoIcon:{position:"absolute",right:a.spacing(3)},content:{padding:a.spacing(7)},saveButton:{paddingLeft:a.spacing(5),paddingRight:a.spacing(5)},contentContainerConditional:{display:"flex",gap:a.spacing(5),maxWidth:1480}})),te={specificPermission:"Choose a specific permission",filter:"Filter by permission properties",all:"Match all permissions"},R="Choose the name of a resource permission or filter by resource type to set a conditional decision.";function ae({rolePermission:a,readonly:t=!1,onClose:b,onSave:D}){const s=ie(),{permissions:c}=U(),v=Y(),f=q(),p=K(a),[o,d]=C(p.match),[l,y]=C(p.decisionType),[u,I]=C(p.criteria),n=g(()=>z(c,o),[c,o]),m=l==="conditional",w=m?"xl":"sm";O(()=>{m&&c&&!n.commonResourceType&&y("allow")},[m,c,n.commonResourceType,y]);const N=i=>{i!==null&&y(i)},h=g(()=>o.method==="specificPermission"&&!o.name||o.method==="filter"&&!o.resourceType&&!o.actions,[o]),P=g(()=>n.permissions.length===0?!1:!h,[n,h]),B=g(()=>l!=="conditional"?!0:!(!n.commonResourceType||!f?.[n.commonResourceType].pluginId||!Q(u,v)),[l,n,f,u,v]),S=()=>{D?.(X(p.id,o,l==="conditional"?{resourceType:n.commonResourceType,pluginId:f[n.commonResourceType].pluginId,conditions:Z(u)}:l))};return e.createElement(A,{open:!0,maxWidth:w,onClose:b,fullWidth:!0},e.createElement(F,{disableTypography:!0,className:s.dialogTitle},e.createElement(j,{variant:"h4",component:"h2"},"New Permission Decision"),e.createElement(x,{startIcon:e.createElement(H,null),onClick:b},"Close")),e.createElement(k,{dividers:!0,className:s.content},e.createElement(r,{className:m?s.contentContainerConditional:void 0},e.createElement(r,{mb:5,flex:1},e.createElement(ne,{options:Object.entries(te).map(([i,E])=>({id:i,displayText:E})),selected:o.method,onChange:i=>d({method:i}),readonly:t})),e.createElement(r,{mb:5,height:189,flex:1},o.method==="specificPermission"&&e.createElement($,{name:o.name,readonly:t,onNameChange:i=>d({...o,name:i})}),o.method==="filter"&&e.createElement(e.Fragment,null,e.createElement(ee,{resourceType:o.resourceType,readonly:t,onResourceTypeChange:i=>d({...o,resourceType:i})}),e.createElement(_,{actions:o.actions,readonly:t,onActionsChange:i=>d({...o,actions:i.length?i:void 0})}),h?null:e.createElement(e.Fragment,null,e.createElement(r,{marginY:2},e.createElement(M,{variant:"middle"})),e.createElement(V,null,`Matched ${n.permissions.length} ${n.permissions.length===1?"permission":"permissions"}`)))),e.createElement(r,{mb:5,flex:1},e.createElement(r,{display:"flex",alignItems:"center"},e.createElement(oe,{value:l,exclusive:!0,fullWidth:!0,"aria-label":"Decision result",onChange:(i,E)=>N(E)},e.createElement(T,{value:"allow","aria-label":"Decision allowed",disabled:t},"Allow"),e.createElement(T,{value:"deny","aria-label":"Decision denied",disabled:t},"Deny"),e.createElement(T,{value:"conditional","aria-label":"Decision conditionally allowed",disabled:!n.commonResourceType||t},"Conditional")),!m&&!t&&e.createElement(G,{title:R},e.createElement(L,{className:s.infoIcon,"aria-label":R}))))),l==="conditional"&&!!n.commonResourceType&&e.createElement(J,{permissionCriteria:u,resourceType:n.commonResourceType,onUpdate:I,readonly:t}),!t&&e.createElement(r,{display:"flex",justifyContent:"flex-end"},e.createElement(x,{variant:"contained",color:"primary",className:s.saveButton,onClick:S,disabled:!P||!B},"Save"))))}export{ae as DecisionDialog};
2
2
  //# sourceMappingURL=DecisionDialog.esm.js.map
@@ -1,2 +1,2 @@
1
- import{IconButton as h,Box as s,FormControlLabel as I,Checkbox as B,Tooltip as F}from"@material-ui/core";import P from"@material-ui/icons/Add";import v from"@material-ui/icons/Remove";import{BackstageUserPlaceholder as u}from"@spotify/backstage-plugin-rbac-common";import e,{useCallback as w,useEffect as z}from"react";import{ParamsFormInputRouter as D}from"./ParamsFormInputRouter.esm.js";const O=[];function S(m){const{onChange:n,schema:f,name:g}=m,{description:d,items:c}=f,[y,p]=e.useState(!1),t=Array.isArray(m.value)?m.value:O,r=t.includes(u),E=(a,l)=>{if(!Array.isArray(l)){const o=[...t];o[a]=l||"",n(o)}},i=w(()=>{n([...t,""])},[n,t]),C=a=>{n(t.filter((l,o)=>o!==a))},k=()=>{n(r?[]:[u])},b=()=>{r&&p(!0)},x=()=>{p(!1)};return z(()=>{t.length?r&&t.length>1&&n([u]):i()},[i,n,t,r]),!c||!("type"in c)?null:e.createElement(e.Fragment,null,(t??[]).map((a,l,{length:o})=>e.createElement(D,{allowEmptyStrings:!0,key:l,onChange:A=>E(l,A),name:l===0?g:"",schema:{description:l===o-1?d:"",type:c.type},value:a,controls:e.createElement(h,{size:"small",onClick:()=>C(l)},e.createElement(v,null))})),!!t?.length&&e.createElement(s,{alignItems:"center",display:"flex",flexDirection:"row",justifyContent:"space-between"},e.createElement(s,null,e.createElement(I,{control:e.createElement(B,{checked:r,onChange:k,name:"checkedB",color:"primary"}),label:"Use the claims from the logged in users token"})),e.createElement(s,null,e.createElement(F,{onClose:x,onOpen:b,open:y,title:"To add additional entries you must uncheck using the claims from the logged in user."},e.createElement("span",null,e.createElement(h,{disabled:r,size:"small",onClick:i},e.createElement(P,null)))))))}export{S as ParamsFormArrayInput};
1
+ import{IconButton as h,Box as s,FormControlLabel as I,Checkbox as P,Tooltip as B}from"@material-ui/core";import F from"@material-ui/icons/Add";import v from"@material-ui/icons/Remove";import{BackstageUserPlaceholder as u}from"@spotify/backstage-plugin-rbac-common";import e,{useCallback as w,useEffect as z}from"react";import{ParamsFormInputRouter as O}from"./ParamsFormInputRouter.esm.js";const S=[];function T(m){const{onChange:n,schema:f,name:g}=m,{description:d,items:c}=f,[y,p]=e.useState(!1),t=Array.isArray(m.value)?m.value:S,r=t.includes(u),E=(a,l)=>{if(!Array.isArray(l)){const o=[...t];o[a]=l||"",n(o)}},i=w(()=>{n([...t,""])},[n,t]),C=a=>{n(t.filter((l,o)=>o!==a))},k=()=>{n(r?[]:[u])},b=()=>{r&&p(!0)},x=()=>{p(!1)};return z(()=>{t.length?r&&t.length>1&&n([u]):i()},[i,n,t,r]),!c||!("type"in c)?null:e.createElement(e.Fragment,null,(t??[]).map((a,l,{length:o})=>e.createElement(O,{allowEmptyStrings:!0,key:l,onChange:A=>E(l,A),name:l===0?g:"",schema:{description:l===o-1?d:"",type:c.type},value:a,controls:e.createElement(h,{size:"small",onClick:()=>C(l)},e.createElement(v,null))})),!!t?.length&&e.createElement(s,{alignItems:"center",display:"flex",flexDirection:"row",justifyContent:"space-between"},e.createElement(s,null,e.createElement(I,{control:e.createElement(P,{checked:r,onChange:k,name:"checkedB",color:"primary"}),label:"Use the claims from the logged in users token"})),e.createElement(s,null,e.createElement(B,{onClose:x,onOpen:b,open:y,title:"To add additional entries you must uncheck using the claims from the logged in user."},e.createElement("span",null,e.createElement(h,{disabled:r,size:"small",onClick:i},e.createElement(F,null)))))))}export{T as ParamsFormArrayInput};
2
2
  //# sourceMappingURL=ParamsFormArrayInput.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as c,Tabs as d,Tab as m}from"@material-ui/core";import o from"react";import{getSelectedColor as s}from"./utils.esm.js";const p=c(e=>({indicator:{right:"unset"},tab:{maxWidth:"none","&.Mui-selected":{backgroundColor:s(e),color:e.palette.primary.main}}}));function b({options:e,selected:r,onChange:i,readonly:n=!1}){const a=p();return o.createElement(d,{orientation:"vertical",value:e.map(({id:t})=>t).indexOf(r),onChange:(t,l)=>i(e[l].id),indicatorColor:"primary",TabIndicatorProps:{className:a.indicator}},e.map(t=>o.createElement(m,{key:t.id,label:t.displayText.toUpperCase(),className:a.tab,disabled:n})))}export{b as VerticalSelection};
1
+ import{makeStyles as c,Tabs as d,Tab as m}from"@material-ui/core";import a from"react";import{getSelectedColor as s}from"./utils.esm.js";const p=c(e=>({indicator:{right:"unset",backgroundColor:e.palette.text.primary},tab:{maxWidth:"none","&.Mui-selected":{backgroundColor:s(e)}}}));function b({options:e,selected:r,onChange:i,readonly:n=!1}){const o=p();return a.createElement(d,{orientation:"vertical",value:e.map(({id:t})=>t).indexOf(r),onChange:(t,l)=>i(e[l].id),indicatorColor:"primary",TabIndicatorProps:{className:o.indicator}},e.map(t=>a.createElement(m,{key:t.id,label:t.displayText.toUpperCase(),className:o.tab,disabled:n})))}export{b as VerticalSelection};
2
2
  //# sourceMappingURL=VerticalSelection.esm.js.map
@@ -1,2 +1,2 @@
1
- function t(e){return`${e.palette.primary.main}50`}export{t as getSelectedColor};
1
+ function t(e){return`${e.palette.textVerySubtle}`}export{t as getSelectedColor};
2
2
  //# sourceMappingURL=utils.esm.js.map
@@ -1,2 +1,2 @@
1
- import{Progress as l,ErrorPanel as n,ContentHeader as c}from"@backstage/core-components";import{Grid as p}from"@material-ui/core";import e from"react";import a from"react-use/lib/useMount";import{PageWrapper as s}from"../Layout/PageWrapper.esm.js";import{usePoliciesContext as f}from"../Policies/PoliciesProvider.esm.js";import{useFetchPolicies as E}from"../Policies/useFetchPolicies.esm.js";import{PolicyImportButton as P}from"../Policy/PolicyImportButton.esm.js";import u from"./HomePageContent.esm.js";import g from"./HomePageEmptyState.esm.js";function d(){const{policies:t}=f(),{loading:m,error:o,fetchPolicies:i}=E();a(()=>{t||i()});let r;return m?r=e.createElement(p,{item:!0,xs:12},e.createElement(l,null)):o?r=e.createElement(n,{error:o}):!t||t.length===0?r=e.createElement(g,null):r=e.createElement(u,{policies:t}),e.createElement(s,{pages:void 0,header:e.createElement(c,{title:"RBAC Policies"},e.createElement(P,null))},r)}export{d as HomePage};
1
+ import{Progress as l,ErrorPanel as n,ContentHeader as a}from"@backstage/core-components";import{Grid as c,Typography as p}from"@material-ui/core";import e from"react";import s from"react-use/lib/useMount";import{PageWrapper as f}from"../Layout/PageWrapper.esm.js";import{usePoliciesContext as E}from"../Policies/PoliciesProvider.esm.js";import{useFetchPolicies as P}from"../Policies/useFetchPolicies.esm.js";import{PolicyImportButton as g}from"../Policy/PolicyImportButton.esm.js";import u from"./HomePageContent.esm.js";import h from"./HomePageEmptyState.esm.js";function d(){const{policies:t}=E(),{loading:m,error:o,fetchPolicies:i}=P();s(()=>{t||i()});let r;return m?r=e.createElement(c,{item:!0,xs:12},e.createElement(l,null)):o?r=e.createElement(n,{error:o}):!t||t.length===0?r=e.createElement(h,null):r=e.createElement(u,{policies:t}),e.createElement(f,{pages:void 0,header:e.createElement(a,{titleComponent:e.createElement(p,{variant:"h2"},"RBAC Policies")},e.createElement(g,null))},r)}export{d as HomePage};
2
2
  //# sourceMappingURL=HomePage.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as o,Typography as a}from"@material-ui/core";import n from"react";const t=o(e=>({titleWrapper:{display:"flex",alignItems:"center",gap:e.spacing(2)}}));function p({children:e}){const r=t();return n.createElement(a,{noWrap:!0,variant:"h4",component:"h2",color:"textSecondary",className:r.titleWrapper},e)}export{p as Title,t as useStyles};
1
+ import{makeStyles as a,Typography as o}from"@material-ui/core";import n from"react";const t=a(e=>({titleWrapper:{display:"flex",alignItems:"center",gap:e.spacing(2)}}));function p({children:e}){const r=t();return n.createElement(o,{noWrap:!0,variant:"h2",color:"textSecondary",className:r.titleWrapper},e)}export{p as Title,t as useStyles};
2
2
  //# sourceMappingURL=Title.esm.js.map
@@ -1,2 +1,2 @@
1
- import{parseEntityRef as u,DEFAULT_NAMESPACE as A}from"@backstage/catalog-model";import{humanizeEntityRef as C}from"@backstage/plugin-catalog-react";import{makeStyles as S,Box as k,Checkbox as P,TextField as F,CircularProgress as M}from"@material-ui/core";import{Autocomplete as O}from"@material-ui/lab";import n,{useState as $,useReducer as L,useEffect as N}from"react";import{MembersAutocompleteListBox as w}from"./MembersAutocompleteListBox.esm.js";const I=S({autocomplete:{display:"flex",flex:1}});function T({members:o,options:r,namespaceOptions:t,loading:a=!1,disabled:f=!1,isMultiNamespaces:s=!1,onTextChange:i,onToggleMember:E,onChange:b}){const[c,l]=$(!1),g=I(),[h,y]=L(e=>e+1,0),x=(e,p)=>{p&&(E(p),y())};N(()=>{c&&i("")},[c,i]);const R=s?t.concat(r?.members||[]):r?.members||[];return n.createElement(k,{width:250},n.createElement(O,{key:`${h}`,open:c,onOpen:()=>{l(!0)},onClose:()=>{l(!1)},onChange:x,getOptionLabel:m,groupBy:B,ListboxComponent:w,renderOption:e=>n.createElement(n.Fragment,null,n.createElement(P,{id:`checkbox-${e.entityRef}`,checked:o.includes(e.entityRef),color:"primary"}),n.createElement("label",{htmlFor:`checkbox-${e.entityRef}`},s?m(e,!1):m(e))),options:R,openOnFocus:!0,disabled:f,loading:a,className:g.autocomplete,renderInput:e=>n.createElement(F,{...e,label:s?"Select members":"Select specific users/groups",variant:"standard",onChange:b,InputProps:{...e.InputProps,endAdornment:n.createElement(n.Fragment,null,a?n.createElement(M,{color:"inherit",size:20}):null,e.InputProps.endAdornment)}})}))}function m(o,r=!0){const t=u(o.entityRef);return t.name==="*"?`${t.kind}:${t.namespace}`:C({...t,name:o.name??t.name},{defaultKind:t.kind,defaultNamespace:r?A:!1})}const d={user:"USERS",group:"GROUPS",namespace:"NAMESPACES"};function B(o){const{name:r,kind:t}=u(o.entityRef),a=r==="*"?"namespace":t;if(!d[a])throw new Error(`Group '${a}' is not supported for members in a policy`);return d[a]}export{T as MembersAutocomplete,m as getLabel};
1
+ import{parseEntityRef as u,DEFAULT_NAMESPACE as A}from"@backstage/catalog-model";import{humanizeEntityRef as C}from"@backstage/plugin-catalog-react";import{makeStyles as S,Box as k,Checkbox as P,TextField as F,CircularProgress as M}from"@material-ui/core";import{Autocomplete as O}from"@material-ui/lab";import n,{useState as $,useReducer as L,useEffect as N}from"react";import{MembersAutocompleteListBox as w}from"./MembersAutocompleteListBox.esm.js";const I=S({autocomplete:{display:"flex",flex:1}});function T({members:o,options:r,namespaceOptions:t,loading:a=!1,disabled:f=!1,isMultiNamespaces:s=!1,onTextChange:i,onToggleMember:E,onChange:b}){const[c,l]=$(!1),g=I(),[h,y]=L(e=>e+1,0),x=(e,p)=>{p&&(E(p),y())};N(()=>{c&&i("")},[c,i]);const R=s?t.concat(r?.members||[]):r?.members||[];return n.createElement(k,{width:250},n.createElement(O,{key:`${h}`,open:c,onOpen:()=>{l(!0)},onClose:()=>{l(!1)},onChange:x,getOptionLabel:m,groupBy:B,ListboxComponent:w,renderOption:e=>n.createElement(n.Fragment,null,n.createElement(P,{id:`checkbox-${e.entityRef}`,checked:o.includes(e.entityRef),color:"primary"}),n.createElement("label",{htmlFor:`checkbox-${e.entityRef}`},s?m(e,!1):m(e))),options:R,openOnFocus:!0,disabled:f,loading:a,className:g.autocomplete,renderInput:e=>n.createElement(F,{...e,placeholder:s?"Select members":"Select specific users/groups",variant:"standard",onChange:b,InputProps:{...e.InputProps,endAdornment:n.createElement(n.Fragment,null,a?n.createElement(M,{color:"inherit",size:20}):null,e.InputProps.endAdornment)}})}))}function m(o,r=!0){const t=u(o.entityRef);return t.name==="*"?`${t.kind}:${t.namespace}`:C({...t,name:o.name??t.name},{defaultKind:t.kind,defaultNamespace:r?A:!1})}const d={user:"USERS",group:"GROUPS",namespace:"NAMESPACES"};function B(o){const{name:r,kind:t}=u(o.entityRef),a=r==="*"?"namespace":t;if(!d[a])throw new Error(`Group '${a}' is not supported for members in a policy`);return d[a]}export{T as MembersAutocomplete,m as getLabel};
2
2
  //# sourceMappingURL=MembersAutocomplete.esm.js.map
@@ -1,2 +1,2 @@
1
- import{parseEntityRef as I}from"@backstage/catalog-model";import{useApi as E}from"@backstage/core-plugin-api";import{catalogApiRef as S}from"@backstage/plugin-catalog-react";import{makeStyles as F,debounce as O,Table as j,TableHead as B,TableRow as D,TableCell as m,TableBody as H}from"@material-ui/core";import t,{useState as P,useRef as U,useMemo as V}from"react";import C from"react-use/lib/useAsync";import{rbacApiRef as q}from"../../api.esm.js";import{useMemberOptions as z}from"./MemberOptionsProvider.esm.js";import{MembersAutocomplete as G}from"./MembersAutocomplete.esm.js";import J from"./MembersTableBody.esm.js";const K=F(()=>({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 Q({diff:s,policyId:r,role:a,onToggleMember:R,readonly:c=!1,debounceTime:f=1e3}){const h=E(q),d=E(S),o=K(),T=a.members==="*",[w,p]=P(""),{current:l}=U({}),u=e=>{l[e.entityRef]=e,R(e.entityRef)},g=e=>{if(l[e])return l[e];const n=I(e);return{entityRef:e,type:n.kind.toLowerCase(),name:n.name??e}},{value:M,loading:N}=z(),{loading:y,value:i}=C(async()=>{const e=await d.getEntityFacets({facets:["metadata.namespace"],filter:{kind:["group","user"]}}).then(n=>n.facets["metadata.namespace"].map(k=>k.value));return W(e)},[d]),b=i?i?.length>2:!1,L=i?i.filter(e=>e.entityRef.toLowerCase().includes(w)):[],v=V(()=>O(e=>{p(e.target.value.toLowerCase())},f),[p,f]),{loading:A,error:x}=C(async()=>{a.members==="*"||a.members.length===0||(await h.getPolicy(r)).roles.find(e=>e.id===a.id)===void 0||a.members.forEach(e=>{const n=g(e);l[n.entityRef]=n})},[r,T]);return t.createElement(t.Fragment,null,t.createElement("div",{className:o.header},t.createElement("h2",null,"Members"),t.createElement(G,{onToggleMember:u,members:a.members,disabled:c,options:M,namespaceOptions:L,isMultiNamespaces:b,loading:N||y,onTextChange:p,onChange:v})),t.createElement(j,{"data-testid":"membersTable"},t.createElement(B,null,t.createElement(D,null,t.createElement(m,{className:o.typeIconCol}),t.createElement(m,{className:o.nameCol},"Name"),t.createElement(m,null,"Type"),t.createElement(m,null),!c&&t.createElement(m,{className:o.actionCol}))),t.createElement(H,null,t.createElement(J,{diff:s,loading:A||y,isMultiNamespaces:b,error:x,members:Array.isArray(a.members)?a.members.map(g):a.members,onToggleMember:u,readonly:c}))))}function W(s){return s.map(r=>[{name:"*",type:"user",entityRef:`user:${r}/*`},{name:"*",type:"group",entityRef:`group:${r}/*`}]).flat().sort((r,a)=>r.entityRef.toLowerCase().localeCompare(a.entityRef.toLowerCase()))}export{Q as MembersTable};
1
+ import{parseEntityRef as I}from"@backstage/catalog-model";import{useApi as C}from"@backstage/core-plugin-api";import{catalogApiRef as S}from"@backstage/plugin-catalog-react";import{makeStyles as $,debounce as B,Card as H,CardHeader as O,Box as j,CardContent as D,Table as F,TableHead as P,TableRow as Y,TableCell as m,TableBody as Z}from"@material-ui/core";import t,{useState as q,useRef as z,useMemo as G}from"react";import E from"react-use/lib/useAsync";import{rbacApiRef as J}from"../../api.esm.js";import{useMemberOptions as K}from"./MemberOptionsProvider.esm.js";import{MembersAutocomplete as Q}from"./MembersAutocomplete.esm.js";import U from"./MembersTableBody.esm.js";const 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 W({diff:i,policyId:r,role:a,onToggleMember:R,readonly:s=!1,debounceTime:d=1e3}){const T=C(J),f=C(S),c=V(),w=a.members==="*",[h,p]=q(""),{current:o}=z({}),u=e=>{o[e.entityRef]=e,R(e.entityRef)},b=e=>{if(o[e])return o[e];const n=I(e);return{entityRef:e,type:n.kind.toLowerCase(),name:n.name??e}},{value:M,loading:L}=K(),{loading:g,value:l}=E(async()=>{const e=await f.getEntityFacets({facets:["metadata.namespace"],filter:{kind:["group","user"]}}).then(n=>n.facets["metadata.namespace"].map(k=>k.value));return X(e)},[f]),y=l?l?.length>2:!1,N=l?l.filter(e=>e.entityRef.toLowerCase().includes(h)):[],A=G(()=>B(e=>{p(e.target.value.toLowerCase())},d),[p,d]),{loading:v,error:x}=E(async()=>{a.members==="*"||a.members.length===0||(await T.getPolicy(r)).roles.find(e=>e.id===a.id)===void 0||a.members.forEach(e=>{const n=b(e);o[n.entityRef]=n})},[r,w]);return t.createElement(H,null,t.createElement(O,{title:"Members",action:t.createElement(j,{m:1,mt:1.25},t.createElement(Q,{onToggleMember:u,members:a.members,disabled:s,options:M,namespaceOptions:N,isMultiNamespaces:y,loading:L||g,onTextChange:p,onChange:A}))}),t.createElement(D,null,t.createElement(F,{"data-testid":"membersTable"},t.createElement(P,null,t.createElement(Y,null,t.createElement(m,{className:c.typeIconCol}),t.createElement(m,{className:c.nameCol},"Name"),t.createElement(m,null,"Type"),t.createElement(m,null),!s&&t.createElement(m,{className:c.actionCol}))),t.createElement(Z,null,t.createElement(U,{diff:i,loading:v||g,isMultiNamespaces:y,error:x,members:Array.isArray(a.members)?a.members.map(b):a.members,onToggleMember:u,readonly:s})))))}function X(i){return i.map(r=>[{name:"*",type:"user",entityRef:`user:${r}/*`},{name:"*",type:"group",entityRef:`group:${r}/*`}]).flat().sort((r,a)=>r.entityRef.toLowerCase().localeCompare(a.entityRef.toLowerCase()))}export{W as MembersTable};
2
2
  //# sourceMappingURL=MembersTable.esm.js.map
@@ -1,2 +1,2 @@
1
- import{parseEntityRef as s}from"@backstage/catalog-model";import{Progress as R}from"@backstage/core-components";import{makeStyles as b,TableRow as i,TableCell as a,IconButton as N}from"@material-ui/core";import h from"@material-ui/icons/Delete";import S from"@material-ui/icons/Group";import k from"@material-ui/icons/GroupWork";import B from"@material-ui/icons/Person";import e from"react";import{DiffBadge as u}from"../Diffing/DiffBadge.esm.js";import{getLabel as y}from"./MembersAutocomplete.esm.js";const M=b(m=>({actionCol:{width:48},typeIconCol:{paddingRight:"0.4rem"},nameCol:{paddingLeft:0},typeIcon:{color:m.palette.grey[500]}}));function T({diff:m,loading:g,isMultiNamespaces:l,members:f,error:E,onToggleMember:d,readonly:c=!1}){const r=M();if(g)return e.createElement(i,null,e.createElement(a,{scope:"row",colSpan:c?4:5},e.createElement(R,null)));if(E&&E.message,f==="*")return e.createElement(i,null,e.createElement(a,{colSpan:2,height:80},"All"),e.createElement(a,{colSpan:c?2:3},e.createElement(u,{operation:m?.members["*"].operation})));if(f.length===0)return e.createElement(i,null,e.createElement(a,{scope:"row",colSpan:c?4:5},"Select users or groups using the drop-down menu above."));const C=f.sort((t,n)=>{let o=0;l&&n.name==="*"&&t.name!=="*"?o=1:l&&t.name==="*"&&n.name!=="*"&&(o=-1);const p=t.type.localeCompare(n.type),w=s(t.entityRef).namespace.localeCompare(s(n.entityRef).namespace),I=s(t.entityRef).name.localeCompare(s(n.entityRef).name);return o||p||w||I});return e.createElement(e.Fragment,null,C.map(t=>{const{name:n,type:o,entityRef:p}=t;return e.createElement(i,{key:p},e.createElement(a,{className:r.typeIconCol},l&&n==="*"&&e.createElement(k,{className:r.typeIcon})||o==="group"&&e.createElement(S,{className:r.typeIcon})||e.createElement(B,{className:r.typeIcon})),e.createElement(a,{scope:"row",className:r.nameCol},(l?y(t,!1):y(t))??"Unknown"),e.createElement(a,{scope:"row"},n==="*"&&l?"namespace":o),e.createElement(a,null,n&&e.createElement(u,{operation:m?.members[p].operation})),!c&&e.createElement(a,{scope:"row",className:r.actionCol},e.createElement(N,{"aria-label":"Remove member",onClick:()=>d(t),size:"small"},e.createElement(h,null))))}))}export{T as default};
1
+ import{parseEntityRef as s}from"@backstage/catalog-model";import{Progress as R}from"@backstage/core-components";import{makeStyles as b,TableRow as i,TableCell as a,IconButton as I}from"@material-ui/core";import h from"@material-ui/icons/Delete";import S from"@material-ui/icons/Group";import k from"@material-ui/icons/GroupWork";import B from"@material-ui/icons/Person";import e from"react";import{DiffBadge as u}from"../Diffing/DiffBadge.esm.js";import{getLabel as y}from"./MembersAutocomplete.esm.js";const M=b(m=>({actionCol:{width:48},typeIconCol:{paddingRight:"0.4rem"},nameCol:{paddingLeft:0},typeIcon:{color:m.palette.grey[500]}}));function T({diff:m,loading:g,isMultiNamespaces:l,members:f,error:E,onToggleMember:d,readonly:c=!1}){const r=M();if(g)return e.createElement(i,null,e.createElement(a,{scope:"row",colSpan:c?4:5},e.createElement(R,null)));if(E&&E.message,f==="*")return e.createElement(i,null,e.createElement(a,{colSpan:2,height:80},"All"),e.createElement(a,{colSpan:c?2:3},e.createElement(u,{operation:m?.members["*"].operation})));if(f.length===0)return e.createElement(i,null,e.createElement(a,{scope:"row",colSpan:c?4:5},"Select users or groups using the drop-down menu above."));const C=f.sort((t,n)=>{let o=0;l&&n.name==="*"&&t.name!=="*"?o=1:l&&t.name==="*"&&n.name!=="*"&&(o=-1);const p=t.type.localeCompare(n.type),w=s(t.entityRef).namespace.localeCompare(s(n.entityRef).namespace),N=s(t.entityRef).name.localeCompare(s(n.entityRef).name);return o||p||w||N});return e.createElement(e.Fragment,null,C.map(t=>{const{name:n,type:o,entityRef:p}=t;return e.createElement(i,{key:p},e.createElement(a,{className:r.typeIconCol},l&&n==="*"&&e.createElement(k,{className:r.typeIcon})||o==="group"&&e.createElement(S,{className:r.typeIcon})||e.createElement(B,{className:r.typeIcon})),e.createElement(a,{scope:"row",className:r.nameCol},(l?y(t,!1):y(t))??"Unknown"),e.createElement(a,{scope:"row"},n==="*"&&l?"namespace":o),e.createElement(a,null,n&&e.createElement(u,{operation:m?.members[p].operation})),!c&&e.createElement(a,{scope:"row",className:r.actionCol},e.createElement(I,{"aria-label":"Remove member",onClick:()=>d(t),size:"small"},e.createElement(h,null))))}))}export{T as default};
2
2
  //# sourceMappingURL=MembersTableBody.esm.js.map
@@ -1,2 +1,2 @@
1
- import{EmptyState as y}from"@backstage/core-components";import{Box as h,Typography as s,Button as c,Table as g,TableHead as b,TableRow as l,TableCell as t,TableBody as w,ButtonBase as C,IconButton as v}from"@material-ui/core";import B from"@material-ui/icons/Add";import R from"@material-ui/icons/Delete";import e from"react";import T from"../../images/no-permissions.svg";import{ConfirmationDialog as k}from"../ConfirmationDialog/ConfirmationDialog.esm.js";import{DiffBadge as D}from"../Diffing/DiffBadge.esm.js";import{EmptyStateImageWrapper as I}from"../Layout/EmptyStateImageWrapper.esm.js";import{ReorderControls as x}from"../ReorderControls/ReorderControls.esm.js";import{ReorderInfo as N}from"../ReorderControls/ReorderInfo.esm.js";import{getMatchBy as P,getDecisionDescription as S}from"./utils.esm.js";const A="Use the arrows to change the order in which permission decisions are evaluated.";function M({diff:p,permissions:n,onReorderPermissions:E,onNewPermissionClick:a,onOpenPermission:d,onRemovePermissionClick:u,anyAllow:m,readonly:r=!1}){return e.createElement(e.Fragment,null,e.createElement(h,{display:"flex",justifyContent:"space-between",padding:2},e.createElement(s,{variant:"h5"},"Permission Decisions"),!r&&n.length!==0&&e.createElement(c,{color:"primary",variant:"outlined",startIcon:e.createElement(B,null),onClick:a},"New")),e.createElement(g,{"data-testid":"permissionsTable"},e.createElement(b,null,e.createElement(l,null,!r&&!m&&e.createElement(t,{style:{width:0}},e.createElement(N,{helpText:A})),e.createElement(t,null,"Match by"),e.createElement(t,null,"Decision"),e.createElement(t,null),!r&&e.createElement(t,null))),e.createElement(w,null,n.length===0&&e.createElement(l,null,e.createElement(t,{colSpan:5},e.createElement(y,{title:"No permission decisions set",description:"Click the button below to create your first permission.",missing:{customImage:e.createElement(I,{src:T,alt:"No permission placeholder"})},action:e.createElement(c,{variant:"contained",color:"primary",onClick:a},"New permission decision")}))),n.map((i,o)=>e.createElement(l,{key:o},!r&&!m&&e.createElement(t,null,e.createElement(x,{array:n,index:o,onReorder:E})),e.createElement(t,null,e.createElement(C,{onClick:()=>d(o)},e.createElement(s,{variant:"body2",color:"primary"},P(i)))),e.createElement(t,null,S(i)),e.createElement(t,null,e.createElement(D,{operation:p?.permissions[i.id].operation})),!r&&e.createElement(t,{align:"right"},e.createElement(k,{message:"Are you sure you want to remove this permission decision?",onConfirm:()=>u(o),title:"Remove?"},f=>e.createElement(v,{...f,"aria-label":"Remove permission decision",size:"small"},e.createElement(R,null)))))))))}export{M as default};
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 v,ButtonBase as B,Typography as R,IconButton as T}from"@material-ui/core";import k from"@material-ui/icons/Add";import D from"@material-ui/icons/Delete";import e from"react";import N from"../../images/no-permissions.svg";import{ConfirmationDialog as P}from"../ConfirmationDialog/ConfirmationDialog.esm.js";import{DiffBadge as I}from"../Diffing/DiffBadge.esm.js";import{EmptyStateImageWrapper as x}from"../Layout/EmptyStateImageWrapper.esm.js";import{ReorderControls as S}from"../ReorderControls/ReorderControls.esm.js";import{ReorderInfo as z}from"../ReorderControls/ReorderInfo.esm.js";import{getMatchBy as A,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(k,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(z,{helpText:M})),e.createElement(t,null,"Match by"),e.createElement(t,null,"Decision"),e.createElement(t,null),!r&&e.createElement(t,null))),e.createElement(v,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(x,{src:N,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(S,{array:n,index:o,onReorder:p})),e.createElement(t,null,e.createElement(B,{onClick:()=>E(o)},e.createElement(R,{variant:"body2",color:"primary"},A(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(P,{message:"Are you sure you want to remove this permission decision?",onConfirm:()=>d(o),title:"Remove?"},u=>e.createElement(T,{...u,"aria-label":"Remove permission decision",size:"small"},e.createElement(D,null))))))))))}export{O as default};
2
2
  //# sourceMappingURL=PermissionsTable.esm.js.map
@@ -1,2 +1,2 @@
1
- import{Link as f}from"@backstage/core-components";import{makeStyles as b,Card as h,CardContent as v,Typography as i,List as C,ListItem as o,ListItemIcon as c,ListItemText as l,Box as m,CardActions as x}from"@material-ui/core";import D from"@material-ui/icons/CalendarToday";import L from"@material-ui/icons/Person";import e from"react";import{DiffSummary as k}from"../Diffing/DiffSummary.esm.js";import{RelativeTime as I}from"../RelativeTime/RelativeTime.esm.js";import{getActivityDescription as S}from"./getActivityDescriptions.esm.js";import{PolicyStatusChip as N}from"./PolicyStatusChip.esm.js";const T=b(t=>({card:a=>({backgroundImage:a.policy.status==="active"?"linear-gradient(256.15deg, #00782A 19.77%, #1DB954 100%)":"linear-gradient(256.15deg, #BDBDBD 19.77%, #EEEEEE 100%)",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 B(t){const a=T(t),{policy:r,to:s,withChangeSummary:d}=t,n=`${r.name} ${r.status==="draft"?"- Draft":""}`,p={created:"Created: ",published:"Published: ",updated:"Updated: "},u={created:"Created by ",published:"Published by ",updated:"Updated by "},{activityDateText:y,activityUser:E,timestamp:g}=S(r,p,u);return e.createElement(h,{className:a.card},e.createElement(v,null,e.createElement("div",{className:a.header},s?e.createElement(f,{to:`versions/${r.id}`},e.createElement(i,{variant:"h5",component:"h1"},n)):e.createElement(i,{variant:"h5",component:"h1"},n),r.status==="active"?e.createElement(N,{status:"active",size:"small"}):null),r.description?e.createElement(i,{variant:"body1",color:"textSecondary"},'"',r.description,'"'):null,e.createElement(i,{component:"h2",className:a.detailsHeader},"Details"),e.createElement(C,{className:a.activityList},e.createElement(o,{className:a.activityListItem},e.createElement(c,null,e.createElement(D,null)),e.createElement(l,{primary:e.createElement(I,{timestamp:g,description:y})})),e.createElement(o,{className:a.activityListItem},e.createElement(c,null,e.createElement(L,null)),e.createElement(l,{primary:E}))),d&&e.createElement(m,{paddingTop:2},e.createElement(i,{gutterBottom:!0,variant:"subtitle2"},"What's changed"),e.createElement(m,{className:a.diffSummaryContainer},e.createElement(k,{policy:r})))),t.actions?e.createElement(x,{className:a.actions},t.actions):null)}export{B as PolicyCard};
1
+ import{Link as E}from"@backstage/core-components";import{makeStyles as b,Card as h,CardContent as v,Typography as i,List as C,ListItem as c,ListItemIcon as o,ListItemText as l,Box as s,CardActions as x}from"@material-ui/core";import L from"@material-ui/icons/CalendarToday";import k from"@material-ui/icons/Person";import e from"react";import{DiffSummary as I}from"../Diffing/DiffSummary.esm.js";import{RelativeTime as S}from"../RelativeTime/RelativeTime.esm.js";import{getActivityDescription as N}from"./getActivityDescriptions.esm.js";import{PolicyStatusChip as $}from"./PolicyStatusChip.esm.js";const T=b(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 P(t){const a=T(t),{policy:r,to:m,withChangeSummary:d}=t,n=`${r.name} ${r.status==="draft"?"- Draft":""}`,p={created:"Created: ",published:"Published: ",updated:"Updated: "},u={created:"Created by ",published:"Published by ",updated:"Updated by "},{activityDateText:y,activityUser:g,timestamp:f}=N(r,p,u);return e.createElement(h,{className:a.card},e.createElement(v,null,e.createElement("div",{className:a.header},m?e.createElement(E,{to:`versions/${r.id}`},e.createElement(i,{variant:"h2"},n)):e.createElement(i,{variant:"h2"},n),r.status==="active"?e.createElement($,{status:"active",size:"small"}):null),r.description?e.createElement(i,{variant:"body1",color:"textSecondary"},'"',r.description,'"'):null,e.createElement(i,{component:"h2",className:a.detailsHeader},"Details"),e.createElement(C,{className:a.activityList},e.createElement(c,{className:a.activityListItem},e.createElement(o,null,e.createElement(L,null)),e.createElement(l,{primary:e.createElement(S,{timestamp:f,description:y})})),e.createElement(c,{className:a.activityListItem},e.createElement(o,null,e.createElement(k,null)),e.createElement(l,{primary:g}))),d&&e.createElement(s,{paddingTop:2},e.createElement(i,{gutterBottom:!0,variant:"subtitle2"},"What's changed"),e.createElement(s,{className:a.diffSummaryContainer},e.createElement(I,{policy:r})))),t.actions?e.createElement(x,{className:a.actions},t.actions):null)}export{P as PolicyCard};
2
2
  //# sourceMappingURL=PolicyCard.esm.js.map
@@ -1,2 +1,2 @@
1
- import{useApi as n,alertApiRef as g}from"@backstage/core-plugin-api";import{Button as v}from"@material-ui/core";import{PolicyConfigParser as P}from"@spotify/backstage-plugin-rbac-common";import A from"js-yaml";import c from"react";import{useNavigate as w}from"react-router-dom";import{rbacApiRef as b}from"../../api.esm.js";function h(){const t=n(b),l=w(),e=n(g);function m(p){const r=p.target?.files?.[0],o=new FileReader;r&&(o.readAsText(r,"utf-8"),o.onload=async f=>{const i=f.target?.result?.toString();if(i){let s=null;try{s=A.load(i)}catch{e.post({message:"YAML file is invalid",severity:"error"});return}const a=P.safeParse(s);if(!a.success){e.post({message:"Imported policy is invalid",severity:"error"});return}const u=a.data;if((await t.getPolicies()).items.some(d=>d.status==="draft")){e.post({message:"Unable to import new policy due to existing draft policy",severity:"error"});return}const y=await t.createDraft(u);l(`./versions/${y.id}`),e.post({message:"Policy imported successfully",severity:"success"})}})}return c.createElement(v,{variant:"outlined",color:"primary",component:"label"},"Import",c.createElement("input",{role:"input",type:"file",hidden:!0,onChange:m,accept:".yaml"}))}export{h as PolicyImportButton};
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};
2
2
  //# sourceMappingURL=PolicyImportButton.esm.js.map
@@ -1,2 +1,2 @@
1
- import{ButtonGroup as S,Button as l,Menu as D,MenuList as c,MenuItem as n,ListItemIcon as r,ListItemText as o,Typography as x,Divider as u}from"@material-ui/core";import z from"@material-ui/icons/MoreHoriz";import L 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 w}from"./PolicyProvider.esm.js";import{useDuplicatePolicy as F}from"./useDuplicatePolicy.esm.js";function G(){const[m,s]=B(null),{hasDraftPolicy:E}=O(),{isValid:a,discardLocalDraft:p,exportPolicy:d,hasChanges:i,policy:t,saveLocalDraftToServer:f,saveAndPublish:h,publish:y}=w(),C=A(),[v,g]=F(),b=k=>{s(k.currentTarget)},P=()=>{s(null)};return e.createElement(e.Fragment,null,e.createElement(S,{variant:"contained",color:"primary"},t.status==="draft"&&e.createElement(l,{disabled:!a,onClick:()=>f()},"Save"),t.status==="inactive"&&e.createElement(l,{onClick:()=>y()},"Republish"),t.status==="active"&&e.createElement(l,{disabled:E||v.loading,onClick:()=>g(t)},"Duplicate"),e.createElement(l,{color:"primary",title:"options",size:"small",onClick:b},e.createElement(z,null))),e.createElement(D,{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:!a,onClick:()=>h()},e.createElement(r,null,e.createElement(L,{fontSize:"small"})),e.createElement(o,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(o,null,e.createElement(x,{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(o,null,"Export"))),e.createElement(u,null),e.createElement(c,null,e.createElement(n,{disabled:!a,onClick:()=>C("./options")},e.createElement(r,null,e.createElement(I,{fontSize:"small"})),e.createElement(o,null,"Options")))))}export{G as PolicyMenu};
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};
2
2
  //# sourceMappingURL=PolicyMenu.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as s,Card as m,CardActionArea as p,CardContent as g,CardHeader as h,Radio as f,Typography as u,Chip as C}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 E(e){const a=y(e),{title:r,description:i,active:l,changeResolutionStrategy:o,defaultOption:c,readonly:n}=e,d=()=>{n||o()};return t.createElement(m,{className:`${a.card}`,onClick:d},t.createElement(p,{disabled:n},t.createElement(g,null,t.createElement(h,{className:a.cardHeader,avatar:t.createElement(f,{checked:l,color:"primary",disabled:n}),title:t.createElement("div",{className:a.title},t.createElement(u,{variant:"h6",component:"h2"},r),c?t.createElement(C,{label:"Default",size:"small",className:a.defaultChip}):null),subheader:i}))))}export{E as PolicyOptionCard};
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};
2
2
  //# sourceMappingURL=PolicyOptionCard.esm.js.map
@@ -1,2 +1,2 @@
1
- import{ContentHeader as m}from"@backstage/core-components";import{makeStyles as d,Button as h,Grid as y,Typography as a,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,{title:"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{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};
2
2
  //# sourceMappingURL=PolicyOptionsPage.esm.js.map
@@ -1,2 +1,2 @@
1
- import{ContentHeader as p}from"@backstage/core-components";import{Grid as m,Typography as i}from"@material-ui/core";import{invariant as s}from"@spotify/backstage-plugin-core";import{UpdateDraftRequestParser as u}from"@spotify/backstage-plugin-rbac-common";import e from"react";import{useParams as f}from"react-router-dom";import{getZodValidationToKeyMap as d}from"../../utils/getZodValidationToKeyMap.esm.js";import y from"../EditableInput/EditableInput.esm.js";import{PageWrapper as E}from"../Layout/PageWrapper.esm.js";import{Title as P}from"../Layout/Title.esm.js";import{PolicyTester as g}from"../PolicyTester/PolicyTester.esm.js";import{RelativeTime as v}from"../RelativeTime/RelativeTime.esm.js";import{RolesTable as T}from"../Roles/RolesTable.esm.js";import b from"./EmptyRolesCard.esm.js";import{getActivityDescription as h}from"./getActivityDescriptions.esm.js";import{PolicyMenu as C}from"./PolicyMenu.esm.js";import{PolicyProvider as x,usePolicyContext as D}from"./PolicyProvider.esm.js";import{PolicyStatusChip as $}from"./PolicyStatusChip.esm.js";function L(){const{versionId:t}=f();return s(t),e.createElement(x,{policyId:t},e.createElement(l,null))}function l(){const{policy:t,updateLocalDraft:a}=D(),o=c=>{a({...t,name:c})},n=d(u.safeParse(t)).name,r=t.status!=="draft";return e.createElement(E,{pages:[{title:t.name}],header:e.createElement(p,{title:t.name,titleComponent:e.createElement(e.Fragment,null,e.createElement(P,null,r?t.name:e.createElement(y,{invalid:n,name:"Policy name",value:t.name,onTextChange:o}),e.createElement($,{status:t.status})),R(t))},e.createElement(C,null))},e.createElement(m,{container:!0,spacing:4},e.createElement(m,{item:!0,xs:12},t.roles.length>0?e.createElement(T,null):e.createElement(b,{readonly:r})),e.createElement(m,{item:!0,xs:12},e.createElement(g,null))))}function R(t){const a={created:"Created by ",published:"Last published by ",updated:"Last updated by "},{activityDateText:o,activityUser:n,timestamp:r}=h(t,a);return e.createElement(i,{variant:"body2"},e.createElement(i,{component:"span",display:"inline",variant:"body2"},`${o} ${n} `),e.createElement(v,{timestamp:r}))}export{L as PolicyPage,l as PolicyPageContent};
1
+ import{ContentHeader as P}from"@backstage/core-components";import{useApi as g,alertApiRef as v}from"@backstage/core-plugin-api";import{Grid as p,Typography as f}from"@material-ui/core";import{invariant as h}from"@spotify/backstage-plugin-core";import{UpdateDraftRequestParser as T}from"@spotify/backstage-plugin-rbac-common";import e,{useState as b}from"react";import{useParams as x}from"react-router-dom";import{getZodValidationToKeyMap as C}from"../../utils/getZodValidationToKeyMap.esm.js";import D from"../EditableInput/EditableInput.esm.js";import{PageWrapper as R}from"../Layout/PageWrapper.esm.js";import{Title as A}from"../Layout/Title.esm.js";import{PolicyTester as L}from"../PolicyTester/PolicyTester.esm.js";import{RelativeTime as I}from"../RelativeTime/RelativeTime.esm.js";import{RolesTable as M}from"../Roles/RolesTable.esm.js";import S from"./EmptyRolesCard.esm.js";import{getActivityDescription as U}from"./getActivityDescriptions.esm.js";import{PolicyMenu as W}from"./PolicyMenu.esm.js";import{PolicyProvider as $,usePolicyContext as q}from"./PolicyProvider.esm.js";import{PolicyStatusChip as F}from"./PolicyStatusChip.esm.js";function G(){const{versionId:t}=x();return h(t),e.createElement($,{policyId:t},e.createElement(d,null))}function d(){const{policy:t,updateLocalDraft:n}=q(),m=g(v),[i,l]=b(!1),y=r=>{let a;const o=T.safeParse({...t,name:r}),s=C(o).name;return s&&(a=o.error?.issues.find(u=>u.path.length===1&&u.path[0]==="name")?.message),l(s),{result:!s,helperText:a}},E=r=>{const{result:a,helperText:o}=y(r);a?n({...t,name:r}):m.post({display:"transient",severity:"error",message:o||"Please specify a valid policy name."})},c=t.status!=="draft";return e.createElement(R,{pages:[{title:t.name}],header:e.createElement(P,{title:t.name,titleComponent:e.createElement(e.Fragment,null,e.createElement(A,null,c?t.name:e.createElement(D,{invalid:i,name:"Policy name",value:t.name,onTextChange:E}),e.createElement(F,{status:t.status})),H(t))},e.createElement(W,null))},e.createElement(p,{container:!0,spacing:4},e.createElement(p,{item:!0,xs:12},t.roles.length>0?e.createElement(M,null):e.createElement(S,{readonly:c})),e.createElement(p,{item:!0,xs:12},e.createElement(L,null))))}function H(t){const n={created:"Created by ",published:"Last published by ",updated:"Last updated by "},{activityDateText:m,activityUser:i,timestamp:l}=U(t,n);return e.createElement(f,{variant:"body2"},e.createElement(f,{component:"span",display:"inline",variant:"body2"},`${m} ${i} `),e.createElement(I,{timestamp:l}))}export{G as PolicyPage,d as PolicyPageContent};
2
2
  //# sourceMappingURL=PolicyPage.esm.js.map
@@ -1,3 +1,3 @@
1
- import{saveAs as l}from"file-saver";import{dump as c}from"js-yaml";import t from"lodash/omit";import d from"lodash/pickBy";function f(o){const e=new Blob([n(o)],{type:"text/yaml"});l(e,`${(o.name||"policy").toLocaleLowerCase().replace(/\W/g,"-")}.yaml`)}function n(o){const{name:e,roles:r,options:m,description:p}=o;return`# this is an autogenerated file, do not edit
2
- ${c(d({name:e,description:p,options:m,roles:r.map(({permissions:i,...s})=>({...t(s,["id"]),permissions:i.map(a=>t(a,["id"]))}))},i=>i!==null||i!==void 0))}`}export{f as exportPolicy,n as policyToYaml};
1
+ import{saveAs as p}from"file-saver";import{dump as a}from"js-yaml";import m from"lodash/pickBy";function s(o){const e=new Blob([i(o)],{type:"text/yaml"});p(e,`${(o.name||"policy").toLocaleLowerCase().replace(/\W/g,"-")}.yaml`)}function i(o){const{name:e,roles:n,options:r,description:l}=o;return`# this is an autogenerated file, do not edit
2
+ ${a(m({name:e,description:l,options:r,roles:n},t=>t!==null||t!==void 0))}`}export{s as exportPolicy,i as policyToYaml};
3
3
  //# sourceMappingURL=exportPolicy.esm.js.map
@@ -1,2 +1,2 @@
1
- import{makeStyles as N,Paper as b,Box as n,Typography as d,Button as f}from"@material-ui/core";import B from"@material-ui/icons/Clear";import e,{useMemo as h,useRef as I,useState as k,useEffect as L}from"react";import{usePermissions as M}from"../Permissions/PermissionsMetadataContext.esm.js";import{usePolicyContext as U}from"../Policy/PolicyProvider.esm.js";import{PolicyTesterFieldset as g}from"./PolicyTesterFieldset.esm.js";import{PolicyTesterPermissionSelect as W}from"./PolicyTesterPermissionSelect.esm.js";import{PolicyTesterResults as j}from"./PolicyTesterResults.esm.js";import{PolicyTesterRoleSelect as F}from"./PolicyTesterRoleSelect.esm.js";import{usePolicyTesterLocalStorageStrings as P}from"./usePolicyTesterLocalStorageStrings.esm.js";import{usePolicyTestResult as G}from"./usePolicyTestResult.esm.js";const $=N(t=>({bodyText:{margin:`${t.spacing(1)}px 0`},clearButton:{marginLeft:t.spacing(1)}}));function q(){const{policy:t}=U(),{permissions:a,isLoading:E}=M(),T=h(()=>t.roles.map(o=>o.id),[t.roles]),S=h(()=>a?.map(o=>o.name)||[],[a]),c=I(null),[m,p]=P("roleIds",T),[r,u]=P("permissionNames",S,E),[x,s]=k(""),[l,v,i]=G();L(()=>{i()},[t.roles,t.options,i]);const C=()=>{r.length===0?(c.current?.firstChild?.focus(),s("Please select at least one permission.")):v(m,r)},R=()=>{p([]),u([]),i(),s("")},y=$(),w=o=>{u(o),o.length>0&&s("")};return e.createElement(b,null,e.createElement(n,{justifyContent:"space-between",padding:2},e.createElement(d,{variant:"h3"},"Policy Tester"),e.createElement(d,{variant:"body1",component:"p",className:y.bodyText},"Use the policy tester to check if your changes will provide the access you intended for a user that has the roles you select below."),e.createElement(g,{title:"Which permissions do you want to test?"},e.createElement(W,{selectedPermissionNames:r,setSelectedPermissionNames:w,ref:c,errorMessage:x})),e.createElement(g,{title:"Which roles should the simulated user have?"},e.createElement(F,{selectedRoleIds:m,setSelectedRoleIds:p})),e.createElement(n,{marginTop:3,component:"section"},e.createElement(f,{onClick:C,variant:"contained",color:"primary"},"Run tests"),e.createElement(f,{className:y.clearButton,color:"primary",variant:"outlined",startIcon:e.createElement(B,null),onClick:R},"Clear")),l&&l.length?e.createElement(n,{sx:{flexGrow:1},marginTop:4},e.createElement(j,{results:l,resolutionStrategy:t.options.resolutionStrategy})):null))}export{q as PolicyTester};
1
+ import{makeStyles as w,Card as x,CardHeader as B,CardContent as N,Typography as k,Box as p,Button as d}from"@material-ui/core";import I from"@material-ui/icons/Clear";import e,{useMemo as y,useRef as L,useState as b,useEffect as M}from"react";import{usePermissions as W}from"../Permissions/PermissionsMetadataContext.esm.js";import{usePolicyContext as q}from"../Policy/PolicyProvider.esm.js";import{PolicyTesterFieldset as f}from"./PolicyTesterFieldset.esm.js";import{PolicyTesterPermissionSelect as F}from"./PolicyTesterPermissionSelect.esm.js";import{PolicyTesterResults as G}from"./PolicyTesterResults.esm.js";import{PolicyTesterRoleSelect as H}from"./PolicyTesterRoleSelect.esm.js";import{usePolicyTesterLocalStorageStrings as h}from"./usePolicyTesterLocalStorageStrings.esm.js";import{usePolicyTestResult as U}from"./usePolicyTestResult.esm.js";const j=w(t=>({clearButton:{marginLeft:t.spacing(1)}}));function z(){const{policy:t}=q(),{permissions:n,isLoading:g}=W(),E=y(()=>t.roles.map(o=>o.id),[t.roles]),P=y(()=>n?.map(o=>o.name)||[],[n]),a=L(null),[c,m]=h("roleIds",E),[r,u]=h("permissionNames",P,g),[T,s]=b(""),[l,S,i]=U();M(()=>{i()},[t.roles,t.options,i]);const C=()=>{r.length===0?(a.current?.firstChild?.focus(),s("Please select at least one permission.")):S(c,r)},R=()=>{m([]),u([]),i(),s("")},v=j();return e.createElement(x,null,e.createElement(B,{title:"Policy Tester"}),e.createElement(N,null,e.createElement(k,{variant:"body1",component:"p"},"Use the policy tester to check if your changes will provide the access you intended for a user that has the roles you select below."),e.createElement(f,{title:"Which permissions do you want to test?"},e.createElement(F,{selectedPermissionNames:r,setSelectedPermissionNames:o=>{u(o),o.length>0&&s("")},ref:a,errorMessage:T})),e.createElement(f,{title:"Which roles should the simulated user have?"},e.createElement(H,{selectedRoleIds:c,setSelectedRoleIds:m})),e.createElement(p,{marginTop:3,component:"section"},e.createElement(d,{onClick:C,variant:"contained",color:"primary"},"Run tests"),e.createElement(d,{className:v.clearButton,color:"primary",variant:"outlined",startIcon:e.createElement(I,null),onClick:R},"Clear")),l&&l.length?e.createElement(p,{sx:{flexGrow:1},marginTop:4},e.createElement(G,{results:l,resolutionStrategy:t.options.resolutionStrategy})):null))}export{z as PolicyTester};
2
2
  //# sourceMappingURL=PolicyTester.esm.js.map
@@ -1,2 +1,2 @@
1
- import{ContentHeader as M}from"@backstage/core-components";import{useApp as F}from"@backstage/core-plugin-api";import{makeStyles as $,Button as z,Grid as g,Card as y}from"@material-ui/core";import{invariant as P}from"@spotify/backstage-plugin-core";import{RoleParser as G}from"@spotify/backstage-plugin-rbac-common";import o,{useState as C}from"react";import{useParams as H,useNavigate as K}from"react-router-dom";import{getZodValidationToKeyMap as L}from"../../utils/getZodValidationToKeyMap.esm.js";import{DecisionDialog as O}from"../DecisionDialog/DecisionDialog.esm.js";import{DiffBadge as U}from"../Diffing/DiffBadge.esm.js";import V from"../EditableInput/EditableInput.esm.js";import{PageWrapper as W}from"../Layout/PageWrapper.esm.js";import{Title as Z}from"../Layout/Title.esm.js";import{MembersTable as j}from"../Members/MembersTable.esm.js";import q from"../Permissions/PermissionsTable.esm.js";import{PolicyProvider as J,usePolicyContext as Q}from"../Policy/PolicyProvider.esm.js";function X({roleId:m}){const{versionId:s,roleId:d}=H(),n=m??d;return P(n),P(s),o.createElement(J,{policyId:s},o.createElement(v,{roleId:n}))}const Y=$(m=>({cardContainer:{margin:m.spacing(0)}}));function v({roleId:m}){const{diff:s,updateLocalDraft:d,policy:n}=Q(),e=n.roles.find(r=>r.id===m),f=s?.roles[m],[a,E]=C(null),[b,c]=C(!1),x=F(),{NotFoundErrorPage:I}=x.getComponents(),T=K(),h=Y();if(!e)return o.createElement(I,null);const u=e.name,i=r=>{const t=n.roles.findIndex(B=>B.id===r.id),l=[...n.roles];l.splice(t,1,r),d({...n,roles:l})},k=r=>{i({...e,name:r})},R=r=>{if(a===null)i({...e,permissions:[r,...e.permissions]});else{const t=[...e.permissions];t.splice(a,1,r),i({...e,permissions:t})}c(!1)},w=r=>{if(r==="*")i({...e,members:e.members==="*"?[]:"*"});else if(e.members==="*")i({...e,members:[r]});else{const t=e.members.includes(r)?e.members.filter(l=>l!==r):[...e.members,r];i({...e,members:t.length===0?"*":t})}},A=r=>{i({...e,permissions:e.permissions.filter((t,l)=>r!==l)})},D=r=>{i({...e,permissions:r})},N=L(G.safeParse(e)).name,p=n.status!=="draft",S=n.options.resolutionStrategy==="any-allow";return o.createElement(o.Fragment,null,o.createElement(W,{pages:[{title:n.name,path:`../../../${n.id}`},{title:u}],header:o.createElement(M,{titleComponent:o.createElement(Z,null,n.name," \xA0\u01C0",p?o.createElement(o.Fragment,null,"\xA0",u):o.createElement(V,{invalid:N,value:u,name:"Role name",onTextChange:k}),o.createElement(U,{operation:f?.role.operation,size:"medium"})),description:n.description||void 0},o.createElement(z,{variant:"outlined",color:"primary",onClick:()=>T("../..",{relative:"path"})},"Back to policy"))},o.createElement(g,{container:!0,className:h.cardContainer,spacing:4,direction:"row"},o.createElement(g,{item:!0,xs:6},o.createElement(y,null,o.createElement(j,{diff:f||null,role:e,policyId:n.id,onToggleMember:w,readonly:p}))),o.createElement(g,{item:!0,xs:6},o.createElement(y,null,o.createElement(q,{diff:f||null,permissions:e.permissions,onNewPermissionClick:()=>{E(null),c(!0)},onOpenPermission:r=>{E(r),c(!0)},onReorderPermissions:D,onRemovePermissionClick:A,anyAllow:S,readonly:p}))))),b&&o.createElement(O,{rolePermission:a!==null?e.permissions[a]:void 0,onClose:()=>c(!1),onSave:R,readonly:p}))}export{X as RolePage,v as RolePageContent};
1
+ import{ContentHeader as $}from"@backstage/core-components";import{useApi as K,alertApiRef as L,useApp as V}from"@backstage/core-plugin-api";import{makeStyles as W,Button as Z,Grid as P}from"@material-ui/core";import{invariant as x}from"@spotify/backstage-plugin-core";import{RoleParser as j,RolesParser as q}from"@spotify/backstage-plugin-rbac-common";import o,{useState as y}from"react";import{useParams as J,useNavigate as Q}from"react-router-dom";import{getZodValidationToKeyMap as U}from"../../utils/getZodValidationToKeyMap.esm.js";import{DecisionDialog as X}from"../DecisionDialog/DecisionDialog.esm.js";import{DiffBadge as Y}from"../Diffing/DiffBadge.esm.js";import _ from"../EditableInput/EditableInput.esm.js";import{PageWrapper as ee}from"../Layout/PageWrapper.esm.js";import{Title as re}from"../Layout/Title.esm.js";import{MembersTable as oe}from"../Members/MembersTable.esm.js";import ne from"../Permissions/PermissionsTable.esm.js";import{PolicyProvider as ie,usePolicyContext as te}from"../Policy/PolicyProvider.esm.js";function se({roleId:l}){const{versionId:m,roleId:d}=J(),n=l??d;return x(n),x(m),o.createElement(ie,{policyId:m},o.createElement(I,{roleId:n}))}const le=W(l=>({cardContainer:{margin:l.spacing(0)}}));function I({roleId:l}){const{diff:m,updateLocalDraft:d,policy:n}=te(),[R,T]=y(!1),h=K(L),r=n.roles.find(e=>e.id===l),f=m?.roles[l],[a,v]=y(null),[A,p]=y(!1),k=V(),{NotFoundErrorPage:w}=k.getComponents(),D=Q(),N=le();if(!r)return o.createElement(w,null);const u=r.name,s=e=>{const i=n.roles.findIndex(g=>g.id===e.id),t=[...n.roles];t.splice(i,1,e),d({...n,roles:t})},S=e=>{let i;const t=U(j.safeParse({...r,name:e})).name,g=n.roles.findIndex(O=>O.id===r.id),C=[...n.roles];C.splice(g,1,{...r,name:e});const b=q.safeParse(C),E=!b.success;return E&&(i=b.error.issues[0].message),T(t||E),{result:!(t||E),helperText:i}},B=e=>{const{result:i,helperText:t}=S(e);i?s({...r,name:e}):h.post({display:"transient",severity:"error",message:t||"Please specify a valid role name."})},M=e=>{if(a===null)s({...r,permissions:[e,...r.permissions]});else{const i=[...r.permissions];i.splice(a,1,e),s({...r,permissions:i})}p(!1)},F=e=>{if(e==="*")s({...r,members:r.members==="*"?[]:"*"});else if(r.members==="*")s({...r,members:[e]});else{const i=r.members.includes(e)?r.members.filter(t=>t!==e):[...r.members,e];s({...r,members:i.length===0?"*":i})}},z=e=>{s({...r,permissions:r.permissions.filter((i,t)=>e!==t)})},G=e=>{s({...r,permissions:e})},c=n.status!=="draft",H=n.options.resolutionStrategy==="any-allow";return o.createElement(o.Fragment,null,o.createElement(ee,{pages:[{title:n.name,path:`../../../${n.id}`},{title:u}],header:o.createElement($,{titleComponent:o.createElement(re,null,n.name," \xA0\u01C0",c?o.createElement(o.Fragment,null,"\xA0",u):o.createElement(_,{invalid:R,value:u,name:"Role name",onTextChange:B}),o.createElement(Y,{operation:f?.role.operation,size:"medium"})),description:n.description||void 0},o.createElement(Z,{variant:"outlined",color:"primary",onClick:()=>D("../..",{relative:"path"})},"Back to policy"))},o.createElement(P,{container:!0,className:N.cardContainer,spacing:4,direction:"row"},o.createElement(P,{item:!0,xs:6},o.createElement(oe,{diff:f||null,role:r,policyId:n.id,onToggleMember:F,readonly:c})),o.createElement(P,{item:!0,xs:6},o.createElement(ne,{diff:f||null,permissions:r.permissions,onNewPermissionClick:()=>{v(null),p(!0)},onOpenPermission:e=>{v(e),p(!0)},onReorderPermissions:G,onRemovePermissionClick:z,anyAllow:H,readonly:c})))),A&&o.createElement(X,{rolePermission:a!==null?r.permissions[a]:void 0,onClose:()=>p(!1),onSave:M,readonly:c}))}export{se as RolePage,I as RolePageContent};
2
2
  //# sourceMappingURL=RolePage.esm.js.map
@@ -1,2 +1,2 @@
1
- import{Link as h}from"@backstage/core-components";import{Paper as b,Box as c,Typography as C,Button as w,Table as T,TableHead as R,TableRow as u,TableCell as l,TableBody as v,IconButton as x}from"@material-ui/core";import A from"@material-ui/icons/Add";import B from"@material-ui/icons/Delete";import e from"react";import{useNavigate as I}from"react-router-dom";import{ConfirmationDialog as D}from"../ConfirmationDialog/ConfirmationDialog.esm.js";import{DiffBadge as N}from"../Diffing/DiffBadge.esm.js";import{usePolicyContext as k}from"../Policy/PolicyProvider.esm.js";import{ReorderControls as G}from"../ReorderControls/ReorderControls.esm.js";import{ReorderInfo as $}from"../ReorderControls/ReorderInfo.esm.js";const L="Use the arrows to change the order in which roles are evaluated.";function P({}){const{diff:m,policy:t,createNewRole:o,updateLocalDraft:i}=k(),p=I(),d=U(t),a=t.status!=="draft",s=t.options.resolutionStrategy==="any-allow",f=r=>{i({...t,roles:r})},E=r=>{i({...t,roles:t.roles.filter(({id:n})=>n!==r)})},y=()=>{p(`./roles/${o()}`)};return e.createElement(b,null,e.createElement(c,{display:"flex",justifyContent:"space-between",padding:2},e.createElement(C,{variant:"h3"},"Roles"),!a&&e.createElement(w,{color:"primary",variant:"outlined",startIcon:e.createElement(A,null),onClick:()=>y()},"New role")),e.createElement(T,{"data-testid":"rolesTable"},e.createElement(R,null,e.createElement(u,null,!a&&!s&&e.createElement(l,{style:{width:0}},e.createElement($,{helpText:L})),e.createElement(l,null,"Name"),e.createElement(l,null,"Users"),e.createElement(l,null,"Groups"),!a&&e.createElement(l,{style:{width:0}}))),e.createElement(v,null,d.map((r,n)=>e.createElement(u,{key:n},!a&&!s&&e.createElement(l,null,e.createElement(G,{array:t.roles,index:n,onReorder:f})),e.createElement(l,null,e.createElement(c,{alignItems:"center",display:"flex",gridGap:8},e.createElement(h,{to:`roles/${r.id}`},r.name),e.createElement(N,{operation:m?.roles[r.id].role.operation}))),e.createElement(l,null,r.userCount),e.createElement(l,null,r.groupCount),!a&&e.createElement(l,{align:"right"},e.createElement(D,{message:"Are you sure you want to remove this role?",title:"Remove role?",onConfirm:()=>E(r.id)},g=>e.createElement(x,{...g,"aria-label":"Remove role",size:"small"},e.createElement(B,null)))))))))}function U(m){return m.roles.map(t=>({id:t.id,name:t.name,userCount:Array.isArray(t.members)?t.members.filter(o=>o.startsWith("user:")).length:t.members,groupCount:Array.isArray(t.members)?t.members.filter(o=>o.startsWith("group:")).length:t.members}))}export{P as RolesTable};
1
+ import{Link as C}from"@backstage/core-components";import{Card as b,CardHeader as h,Box as c,Button as w,CardContent as R,Table as T,TableHead as v,TableRow as u,TableCell as l,TableBody as x,IconButton as A}from"@material-ui/core";import B from"@material-ui/icons/Add";import N from"@material-ui/icons/Delete";import e from"react";import{useNavigate as I}from"react-router-dom";import{ConfirmationDialog as k}from"../ConfirmationDialog/ConfirmationDialog.esm.js";import{DiffBadge as D}from"../Diffing/DiffBadge.esm.js";import{usePolicyContext as U}from"../Policy/PolicyProvider.esm.js";import{ReorderControls as W}from"../ReorderControls/ReorderControls.esm.js";import{ReorderInfo as G}from"../ReorderControls/ReorderInfo.esm.js";const H="Use the arrows to change the order in which roles are evaluated.";function L({}){const{diff:m,policy:t,createNewRole:o,updateLocalDraft:i}=U(),d=I(),E=P(t),a=t.status!=="draft",s=t.options.resolutionStrategy==="any-allow",p=r=>{i({...t,roles:r})},f=r=>{i({...t,roles:t.roles.filter(({id:n})=>n!==r)})},y=()=>{d(`./roles/${o()}`)};return e.createElement(b,null,e.createElement(h,{title:"Roles",action:!a&&e.createElement(c,{m:1,mt:1.25},e.createElement(w,{color:"primary",variant:"outlined",startIcon:e.createElement(B,null),onClick:()=>y()},"New role"))}),e.createElement(R,null,e.createElement(T,{"data-testid":"rolesTable"},e.createElement(v,null,e.createElement(u,null,!a&&!s&&e.createElement(l,{style:{width:0}},e.createElement(G,{helpText:H})),e.createElement(l,null,"Name"),e.createElement(l,null,"Users"),e.createElement(l,null,"Groups"),!a&&e.createElement(l,{style:{width:0}}))),e.createElement(x,null,E.map((r,n)=>e.createElement(u,{key:n},!a&&!s&&e.createElement(l,null,e.createElement(W,{array:t.roles,index:n,onReorder:p})),e.createElement(l,null,e.createElement(c,{alignItems:"center",display:"flex",gridGap:8},e.createElement(C,{to:`roles/${r.id}`},r.name),e.createElement(D,{operation:m?.roles[r.id].role.operation}))),e.createElement(l,null,r.userCount),e.createElement(l,null,r.groupCount),!a&&e.createElement(l,{align:"right"},e.createElement(k,{message:"Are you sure you want to remove this role?",title:"Remove role?",onConfirm:()=>f(r.id)},g=>e.createElement(A,{...g,"aria-label":"Remove role",size:"small"},e.createElement(N,null))))))))))}function P(m){return m.roles.map(t=>({id:t.id,name:t.name,userCount:Array.isArray(t.members)?t.members.filter(o=>o.startsWith("user:")).length:t.members,groupCount:Array.isArray(t.members)?t.members.filter(o=>o.startsWith("group:")).length:t.members}))}export{L as RolesTable};
2
2
  //# sourceMappingURL=RolesTable.esm.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spotify/backstage-plugin-rbac",
3
3
  "description": "Control access to actions and data in Backstage with ease.",
4
- "version": "0.7.3",
4
+ "version": "0.7.4",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "homepage": "https://backstage.spotify.com",
7
7
  "main": "./dist/index.esm.js",
@@ -53,22 +53,22 @@
53
53
  "a11y": "yarn dlx @lhci/cli@0.13.x --config ./.lighthouserc.js autorun"
54
54
  },
55
55
  "dependencies": {
56
- "@backstage/catalog-model": "^1.7.1",
57
- "@backstage/core-compat-api": "^0.3.3",
58
- "@backstage/core-components": "^0.16.1",
59
- "@backstage/core-plugin-api": "^1.10.1",
60
- "@backstage/errors": "^1.2.5",
61
- "@backstage/frontend-plugin-api": "^0.9.2",
62
- "@backstage/plugin-catalog-react": "^1.14.2",
63
- "@backstage/plugin-permission-common": "^0.8.2",
64
- "@backstage/plugin-permission-react": "^0.4.28",
65
- "@backstage/theme": "^0.6.2",
56
+ "@backstage/catalog-model": "^1.7.2",
57
+ "@backstage/core-compat-api": "^0.3.4",
58
+ "@backstage/core-components": "^0.16.2",
59
+ "@backstage/core-plugin-api": "^1.10.2",
60
+ "@backstage/errors": "^1.2.6",
61
+ "@backstage/frontend-plugin-api": "^0.9.3",
62
+ "@backstage/plugin-catalog-react": "^1.15.0",
63
+ "@backstage/plugin-permission-common": "^0.8.3",
64
+ "@backstage/plugin-permission-react": "^0.4.29",
65
+ "@backstage/theme": "^0.6.3",
66
66
  "@backstage/types": "^1.2.0",
67
67
  "@material-ui/core": "^4.12.2",
68
68
  "@material-ui/icons": "^4.9.1",
69
69
  "@material-ui/lab": "4.0.0-alpha.61",
70
- "@spotify/backstage-plugin-core": "^0.8.3",
71
- "@spotify/backstage-plugin-rbac-common": "^0.6.3",
70
+ "@spotify/backstage-plugin-core": "^0.8.4",
71
+ "@spotify/backstage-plugin-rbac-common": "^0.6.4",
72
72
  "ajv": "^8.11.2",
73
73
  "file-saver": "^2.0.5",
74
74
  "js-yaml": "^4.1.0",
@@ -87,14 +87,14 @@
87
87
  "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
88
88
  },
89
89
  "devDependencies": {
90
- "@backstage/cli": "^0.29.2",
91
- "@backstage/core-app-api": "^1.15.2",
92
- "@backstage/dev-utils": "^1.1.4",
90
+ "@backstage/cli": "^0.29.4",
91
+ "@backstage/core-app-api": "^1.15.3",
92
+ "@backstage/dev-utils": "^1.1.5",
93
93
  "@backstage/e2e-test-utils": "^0.1.1",
94
- "@backstage/frontend-test-utils": "^0.2.3",
95
- "@backstage/test-utils": "^1.7.2",
94
+ "@backstage/frontend-test-utils": "^0.2.4",
95
+ "@backstage/test-utils": "^1.7.3",
96
96
  "@playwright/test": "^1.32.3",
97
- "@sp4b-dev/test-utils": "^0.0.9",
97
+ "@sp4b-dev/test-utils": "^0.0.10",
98
98
  "@testing-library/jest-dom": "^6.0.0",
99
99
  "@testing-library/react": "^14.0.0",
100
100
  "@testing-library/user-event": "^14.0.0",
@@ -1,2 +0,0 @@
1
- import{makeStyles as r}from"@material-ui/core";import{ToggleButton as a}from"@material-ui/lab";import l from"react";import{getSelectedColor as m}from"./utils.esm.js";const i=r(e=>({toggleButton:{"&.Mui-selected":{backgroundColor:m(e),color:e.palette.primary.main},"&.Mui-selected:hover":{backgroundColor:"#97BBE8"},color:e.palette.primary.main,border:`1px solid ${e.palette.primary.main}`}}));function n({className:e,...o}){const t=i();return l.createElement(a,{className:`${t.toggleButton} ${e}`,...o})}export{n as default};
2
- //# sourceMappingURL=ToggleButton.esm.js.map