Skip to content

Commit

Permalink
Merge pull request #2437 from headlamp-k8s/role-list-multi
Browse files Browse the repository at this point in the history
frontend: RoleList: Make multi cluster aware
  • Loading branch information
illume authored Oct 30, 2024
2 parents 3cef2b5 + 57d5722 commit 8ff7f60
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 39 deletions.
2 changes: 1 addition & 1 deletion frontend/src/components/common/Resource/ResourceTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export type ResourceTableColumn<RowItem> = {
}
);

type ColumnType = 'age' | 'name' | 'namespace' | 'type' | 'kind' | 'cluster';
export type ColumnType = 'age' | 'name' | 'namespace' | 'type' | 'kind' | 'cluster';

export interface ResourceTableProps<RowItem> {
/** The columns to be rendered, like used in Table, or by name. */
Expand Down
58 changes: 20 additions & 38 deletions frontend/src/components/role/List.tsx
Original file line number Diff line number Diff line change
@@ -1,66 +1,46 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useClusterGroup } from '../../lib/k8s';
import ClusterRole from '../../lib/k8s/clusterRole';
import Role from '../../lib/k8s/role';
import { useErrorState } from '../../lib/util';
import { combineClusterListErrors } from '../../lib/util';
import Link from '../common/Link';
import ResourceListView from '../common/Resource/ResourceListView';

interface RolesDict {
[kind: string]: Role[] | null;
}
import { ColumnType } from '../common/Resource/ResourceTable';

export default function RoleList() {
const [roles, setRoles] = React.useState<RolesDict | null>(null);
const [roleError, setRolesError] = useErrorState(setupRoles);
const [clusterRoleError, setClusterRolesError] = useErrorState(setupClusterRoles);
const { t } = useTranslation('glossary');
const { items: roles, clusterErrors: rolesErrors } = Role.useList();
const { items: clusterRoles, clusterErrors: clusterRolesErrors } = ClusterRole.useList();

function setupRolesWithKind(newRoles: Role[] | null, kind: string) {
setRoles(oldRoles => ({ ...(oldRoles || {}), [kind]: newRoles }));
}

function setupRoles(roles: Role[] | null) {
setupRolesWithKind(roles, 'Role');
}
const clusters = useClusterGroup();
const isMultiCluster = clusters.length > 1;

function setupClusterRoles(roles: ClusterRole[] | null) {
setupRolesWithKind(roles, 'ClusterRole');
}

function getJointItems() {
if (roles === null) {
const allRoles = React.useMemo(() => {
if (roles === null && clusterRoles === null) {
return null;
}

let joint: Role[] = [];
let hasItems = false;
return roles ? roles.concat(clusterRoles || []) : clusterRoles;
}, [roles, clusterRoles]);

for (const items of Object.values(roles)) {
if (items !== null) {
joint = joint.concat(items);
hasItems = true;
}
}

return hasItems ? joint : null;
}
const allErrors = React.useMemo(() => {
return combineClusterListErrors(rolesErrors || null, clusterRolesErrors || null);
}, [rolesErrors, clusterRolesErrors]);

function getErrorMessage() {
if (getJointItems() === null) {
return Role.getErrorMessage(roleError || clusterRoleError);
if (Object.values(allErrors || {}).length === clusters.length && clusters.length > 1) {
return Role.getErrorMessage(Object.values(allErrors!)[0]);
}

return null;
}

Role.useApiList(setupRoles, setRolesError);
ClusterRole.useApiList(setupClusterRoles, setClusterRolesError);

return (
<ResourceListView
title={t('Roles')}
errorMessage={getErrorMessage()}
clusterErrors={isMultiCluster ? allErrors : null}
columns={[
'type',
{
Expand All @@ -72,16 +52,18 @@ export default function RoleList() {
params={{
namespace: item.metadata.namespace || '',
name: item.metadata.name,
cluster: item.cluster,
}}
>
{item.metadata.name}
</Link>
),
},
'namespace',
...(isMultiCluster ? (['cluster'] as ColumnType[]) : ([] as ColumnType[])),
'age',
]}
data={getJointItems()}
data={allRoles}
id="headlamp-roles"
/>
);
Expand Down

0 comments on commit 8ff7f60

Please sign in to comment.