diff --git a/plugins/rbac/src/components/RoleOverview/MembersCard.test.tsx b/plugins/rbac/src/components/RoleOverview/MembersCard.test.tsx
index 1c54640567..d15d1c00d5 100644
--- a/plugins/rbac/src/components/RoleOverview/MembersCard.test.tsx
+++ b/plugins/rbac/src/components/RoleOverview/MembersCard.test.tsx
@@ -70,7 +70,7 @@ describe('MembersCard', () => {
loading: false,
data: useMembersMockData,
error: undefined,
- retry: () => {},
+ retry: { roleRetry: jest.fn(), membersRetry: jest.fn() },
});
const { queryByText } = await renderInTestApp(
,
@@ -87,7 +87,7 @@ describe('MembersCard', () => {
loading: false,
data: [],
error: undefined,
- retry: () => {},
+ retry: { roleRetry: jest.fn(), membersRetry: jest.fn() },
});
const { queryByText } = await renderInTestApp(
,
@@ -102,7 +102,7 @@ describe('MembersCard', () => {
loading: false,
data: [],
error: { message: 'xyz' },
- retry: () => {},
+ retry: { roleRetry: jest.fn(), membersRetry: jest.fn() },
});
const { queryByText } = await renderInTestApp(
,
@@ -122,7 +122,7 @@ describe('MembersCard', () => {
loading: false,
data: useMembersMockData,
error: undefined,
- retry: () => {},
+ retry: { roleRetry: jest.fn(), membersRetry: jest.fn() },
});
const { getByTestId } = await renderInTestApp(
,
@@ -136,7 +136,7 @@ describe('MembersCard', () => {
loading: false,
data: useMembersMockData,
error: undefined,
- retry: () => {},
+ retry: { roleRetry: jest.fn(), membersRetry: jest.fn() },
});
const { queryByTestId } = await renderInTestApp(
,
diff --git a/plugins/rbac/src/components/RoleOverview/MembersCard.tsx b/plugins/rbac/src/components/RoleOverview/MembersCard.tsx
index 1215516cb4..725cef017a 100644
--- a/plugins/rbac/src/components/RoleOverview/MembersCard.tsx
+++ b/plugins/rbac/src/components/RoleOverview/MembersCard.tsx
@@ -59,7 +59,10 @@ export const MembersCard = ({ roleName }: MembersCardProps) => {
icon: getRefreshIcon,
tooltip: 'Refresh',
isFreeAction: true,
- onClick: () => retry(),
+ onClick: () => {
+ retry.roleRetry();
+ retry.membersRetry();
+ },
},
{
icon: () =>
diff --git a/plugins/rbac/src/components/RoleOverview/PermissionsCard.test.tsx b/plugins/rbac/src/components/RoleOverview/PermissionsCard.test.tsx
index 3801f613d4..bc37bbc855 100644
--- a/plugins/rbac/src/components/RoleOverview/PermissionsCard.test.tsx
+++ b/plugins/rbac/src/components/RoleOverview/PermissionsCard.test.tsx
@@ -50,7 +50,7 @@ describe('PermissionsCard', () => {
mockPermissionPolicies.mockReturnValue({
loading: false,
data: usePermissionPoliciesMockData,
- retry: () => {},
+ retry: { policiesRetry: jest.fn(), permissionPoliciesRetry: jest.fn() },
error: new Error(''),
});
const { queryByText } = await renderInTestApp(
@@ -65,7 +65,7 @@ describe('PermissionsCard', () => {
mockPermissionPolicies.mockReturnValue({
loading: false,
data: [],
- retry: () => {},
+ retry: { policiesRetry: jest.fn(), permissionPoliciesRetry: jest.fn() },
error: new Error(''),
});
const { queryByText } = await renderInTestApp(
@@ -79,7 +79,7 @@ describe('PermissionsCard', () => {
mockPermissionPolicies.mockReturnValue({
loading: false,
data: [],
- retry: () => {},
+ retry: { policiesRetry: jest.fn(), permissionPoliciesRetry: jest.fn() },
error: { message: '404', name: 'Not Found' },
});
const { queryByText } = await renderInTestApp(
@@ -99,7 +99,7 @@ describe('PermissionsCard', () => {
loading: false,
data: [],
error: new Error(''),
- retry: () => {},
+ retry: { policiesRetry: jest.fn(), permissionPoliciesRetry: jest.fn() },
});
const { getByTestId } = await renderInTestApp(
,
@@ -113,7 +113,7 @@ describe('PermissionsCard', () => {
loading: false,
data: [],
error: new Error(''),
- retry: () => {},
+ retry: { policiesRetry: jest.fn(), permissionPoliciesRetry: jest.fn() },
});
const { queryByTestId } = await renderInTestApp(
,
diff --git a/plugins/rbac/src/components/RoleOverview/PermissionsCard.tsx b/plugins/rbac/src/components/RoleOverview/PermissionsCard.tsx
index e106c15e3b..82b348a071 100644
--- a/plugins/rbac/src/components/RoleOverview/PermissionsCard.tsx
+++ b/plugins/rbac/src/components/RoleOverview/PermissionsCard.tsx
@@ -65,7 +65,10 @@ export const PermissionsCard = ({ entityReference }: PermissionsCardProps) => {
icon: getRefreshIcon,
tooltip: 'Refresh',
isFreeAction: true,
- onClick: () => retry(),
+ onClick: () => {
+ retry.permissionPoliciesRetry();
+ retry.policiesRetry();
+ },
},
{
icon: () => getEditIcon(permissionResult.allowed, entityReference),
diff --git a/plugins/rbac/src/hooks/useMembers.ts b/plugins/rbac/src/hooks/useMembers.ts
index a92edfd887..7c5eb57533 100644
--- a/plugins/rbac/src/hooks/useMembers.ts
+++ b/plugins/rbac/src/hooks/useMembers.ts
@@ -1,11 +1,11 @@
import React from 'react';
-import { useAsync, useAsyncRetry } from 'react-use';
+import { useAsyncRetry, useInterval } from 'react-use';
import { stringifyEntityRef } from '@backstage/catalog-model';
import { useApi } from '@backstage/core-plugin-api';
import { rbacApiRef } from '../api/RBACBackendClient';
-import { MembersData } from '../types';
+import { MemberEntity, MembersData } from '../types';
import { getKindNamespaceName, getMembersFromGroup } from '../utils/rbac-utils';
const getErrorText = (
@@ -24,74 +24,90 @@ const getErrorText = (
return undefined;
};
-export const useMembers = (roleName: string) => {
+const getMemberData = (
+ memberResource: MemberEntity | undefined,
+ ref: string,
+) => {
+ if (memberResource) {
+ return {
+ name:
+ memberResource.spec.profile?.displayName ??
+ memberResource.metadata.name,
+ type: memberResource.kind,
+ ref: {
+ namespace: memberResource.metadata.namespace as string,
+ kind: memberResource.kind.toLowerCase(),
+ name: memberResource.metadata.name,
+ },
+ members:
+ memberResource.kind === 'Group'
+ ? getMembersFromGroup(memberResource)
+ : 0,
+ };
+ }
+ const { kind, namespace, name } = getKindNamespaceName(ref);
+ return {
+ name,
+ type: kind === 'user' ? 'User' : ('Group' as 'User' | 'Group'),
+ ref: {
+ namespace,
+ kind,
+ name,
+ },
+ members: 0,
+ };
+};
+
+export const useMembers = (roleName: string, pollInterval?: number) => {
const rbacApi = useApi(rbacApiRef);
let data: MembersData[] = [];
const {
- loading: rolesLoading,
value: role,
- retry,
+ retry: roleRetry,
error: roleError,
} = useAsyncRetry(async () => {
return await rbacApi.getRole(roleName);
});
const {
- loading: membersLoading,
value: members,
+ retry: membersRetry,
error: membersError,
- } = useAsync(async () => {
+ } = useAsyncRetry(async () => {
return await rbacApi.getMembers();
});
- const loading = rolesLoading && membersLoading;
+ const loading = !roleError && !membersError && !role && !members;
data = React.useMemo(
() =>
Array.isArray(role)
? role[0].memberReferences.reduce((acc: MembersData[], ref: string) => {
- const memberResource =
- Array.isArray(members) &&
- members.find(member => stringifyEntityRef(member) === ref);
- if (memberResource) {
- acc.push({
- name:
- memberResource.spec.profile?.displayName ??
- memberResource.metadata.name,
- type: memberResource.kind,
- ref: {
- namespace: memberResource.metadata.namespace as string,
- kind: memberResource.kind.toLowerCase(),
- name: memberResource.metadata.name,
- },
- members:
- memberResource.kind === 'Group'
- ? getMembersFromGroup(memberResource)
- : 0,
- });
- } else {
- const { kind, namespace, name } = getKindNamespaceName(ref);
- acc.push({
- name,
- type: kind === 'user' ? 'User' : 'Group',
- ref: {
- namespace,
- kind,
- name,
- },
- members: 0,
- });
- }
+ const memberResource: MemberEntity | undefined = Array.isArray(
+ members,
+ )
+ ? members.find(member => stringifyEntityRef(member) === ref)
+ : undefined;
+ const memberData = getMemberData(memberResource, ref);
+ acc.push(memberData);
return acc;
}, [])
: [],
[role, members],
);
+ useInterval(
+ () => {
+ roleRetry();
+ membersRetry();
+ },
+ loading ? null : pollInterval || 10000,
+ );
+
return {
loading,
data,
- retry,
+ retry: { roleRetry, membersRetry },
error: getErrorText(role, members) || roleError || membersError,
};
};
diff --git a/plugins/rbac/src/hooks/usePermissionPolicies.ts b/plugins/rbac/src/hooks/usePermissionPolicies.ts
index d85fd02e5f..87660f6dcd 100644
--- a/plugins/rbac/src/hooks/usePermissionPolicies.ts
+++ b/plugins/rbac/src/hooks/usePermissionPolicies.ts
@@ -1,50 +1,80 @@
import React from 'react';
-import { useAsync, useAsyncRetry } from 'react-use';
+import { useAsyncRetry, useInterval } from 'react-use';
import { useApi } from '@backstage/core-plugin-api';
import { rbacApiRef } from '../api/RBACBackendClient';
import { getPermissionsData } from '../utils/rbac-utils';
-export const usePermissionPolicies = (entityReference: string) => {
+const getErrorText = (
+ policies: any,
+ permissionPolicies: any,
+): { name: number; message: string } | undefined => {
+ if (!Array.isArray(policies) && (policies as Response)?.statusText) {
+ return {
+ name: (policies as Response).status,
+ message: `Error fetching policies. ${(policies as Response).statusText}`,
+ };
+ } else if (
+ !Array.isArray(permissionPolicies) &&
+ (permissionPolicies as Response)?.statusText
+ ) {
+ return {
+ name: (permissionPolicies as Response).status,
+ message: `Error fetching the plugins. ${
+ (permissionPolicies as Response).statusText
+ }`,
+ };
+ }
+ return undefined;
+};
+
+export const usePermissionPolicies = (
+ entityReference: string,
+ pollInterval?: number,
+) => {
const rbacApi = useApi(rbacApiRef);
const {
- loading: policiesLoading,
value: policies,
- retry,
- error,
+ retry: policiesRetry,
+ error: policiesError,
} = useAsyncRetry(async () => {
return await rbacApi.getAssociatedPolicies(entityReference);
});
const {
value: permissionPolicies,
- loading: permissionPoliciesLoading,
error: permissionPoliciesError,
- } = useAsync(async () => {
+ retry: permissionPoliciesRetry,
+ } = useAsyncRetry(async () => {
return await rbacApi.listPermissions();
});
- const loading = policiesLoading || permissionPoliciesLoading;
+ const loading =
+ !permissionPoliciesError &&
+ !policiesError &&
+ !policies &&
+ !permissionPolicies;
const data = React.useMemo(() => {
const pp = Array.isArray(permissionPolicies) ? permissionPolicies : [];
return Array.isArray(policies) ? getPermissionsData(policies, pp) : [];
}, [policies, permissionPolicies]);
+
+ useInterval(
+ () => {
+ policiesRetry();
+ permissionPoliciesRetry();
+ },
+ loading ? null : pollInterval || 10000,
+ );
return {
loading,
data,
- retry,
- error: (error as Error) ||
- (permissionPoliciesError as Error) || {
- name: (policies as Response)?.status,
- message: `Error fetching policies. ${(policies as Response)
- ?.statusText}`,
- } || {
- name: (permissionPolicies as Response)?.status,
- message: `Error fetching permission policies. ${(
- permissionPolicies as Response
- )?.statusText}`,
- },
+ retry: { policiesRetry, permissionPoliciesRetry },
+ error:
+ policiesError ||
+ permissionPoliciesError ||
+ getErrorText(policies, permissionPolicies),
};
};