Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions frontend/src/components/ACLPage/List/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import {
createPatternCell,
} from 'components/ACLPage/Table/TableCells';
import useDeleteKafkaAcl from 'components/ACLPage/lib/useDeleteAcl';
import PageLoader from 'components/common/PageLoader/PageLoader';
import ErrorPage from 'components/ErrorPage/ErrorPage';

import * as S from './List.styled';

Expand All @@ -36,7 +38,7 @@ const ACList: React.FC = () => {
const { clusterName } = useAppParams<{ clusterName: ClusterName }>();
const [searchParams, setSearchParams] = useSearchParams();
const { isFtsEnabled } = useFts('acl');
const { data: aclList } = useAcls({
const acls = useAcls({
clusterName,
search: searchParams.get('q') ?? '',
fts: isFtsEnabled,
Expand Down Expand Up @@ -94,7 +96,22 @@ const ACList: React.FC = () => {
extraActions={<Fts resourceName="acl" />}
/>
</ControlPanelWrapper>
<AclsTable acls={aclList ?? EMPTY_ACLS} columns={columns} />

{(acls.isLoading || acls.isRefetching) && <PageLoader offsetY={300} />}

{acls.error && (
<ErrorPage
offsetY={300}
status={acls.error.status}
onClick={acls.refetch}
text={acls.error.message}
/>
)}

{acls.isSuccess && (
<AclsTable acls={acls.data ?? EMPTY_ACLS} columns={columns} />
)}

<ACLFormContext.Provider
value={{
close: closeForm,
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/components/ACLPage/List/__test__/List.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ describe('ACLList Component', () => {
beforeEach(() => {
(useAcls as jest.Mock).mockImplementation(() => ({
data: aclPayload,
isSuccess: true,
}));
(useDeleteAcl as jest.Mock).mockImplementation(() => ({
deleteResource: jest.fn(),
Expand Down Expand Up @@ -82,6 +83,7 @@ describe('ACLList Component', () => {
beforeEach(() => {
(useAcls as jest.Mock).mockImplementation(() => ({
data: [],
isSuccess: true,
}));
(useDeleteAcl as jest.Mock).mockImplementation(() => ({
deleteResource: jest.fn(),
Expand Down
140 changes: 83 additions & 57 deletions frontend/src/components/Brokers/Broker/Broker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,82 +21,108 @@ import PageLoader from 'components/common/PageLoader/PageLoader';
import { ActionNavLink } from 'components/common/ActionComponent';
import { Action, ResourceType } from 'generated-sources';
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
import ErrorPage from 'components/ErrorPage/ErrorPage';

import Configs from './Configs/Configs';

const Broker: React.FC = () => {
const { clusterName, brokerId } = useAppParams<ClusterBrokerParam>();

const { data: clusterStats } = useClusterStats(clusterName);
const { data: brokers } = useBrokers(clusterName);

if (!clusterStats) return null;
const {
data: brokers,
error,
isSuccess,
refetch,
isLoading,
isRefetching,
} = useBrokers(clusterName);

const brokerItem = brokers?.find(({ id }) => id === Number(brokerId));
const brokerDiskUsage = clusterStats.diskUsage?.find(
const brokerDiskUsage = clusterStats?.diskUsage?.find(
(item) => item.brokerId === Number(brokerId)
);

return (
<>
<ResourcePageHeading
text={`Broker ${brokerId}`}
backTo={clusterBrokersPath(clusterName)}
backText="Brokers"
/>
<Metrics.Wrapper>
<Metrics.Section>
<Metrics.Indicator label="Segment Size">
<BytesFormatted
value={brokerDiskUsage?.segmentSize}
precision={2}
/>
</Metrics.Indicator>
<Metrics.Indicator label="Segment Count">
{brokerDiskUsage?.segmentCount}
</Metrics.Indicator>
<Metrics.Indicator label="Port">{brokerItem?.port}</Metrics.Indicator>
<Metrics.Indicator label="Host">{brokerItem?.host}</Metrics.Indicator>
</Metrics.Section>
</Metrics.Wrapper>

<Navbar role="navigation">
<NavLink
to={clusterBrokerPath(clusterName, brokerId)}
className={({ isActive }) => (isActive ? 'is-active' : '')}
end
>
Log directories
</NavLink>
<NavLink
to={clusterBrokerConfigsPath(clusterName, brokerId)}
className={({ isActive }) => (isActive ? 'is-active' : '')}
>
Configs
</NavLink>
<ActionNavLink
to={clusterBrokerMetricsPath(clusterName, brokerId)}
className={({ isActive }) => (isActive ? 'is-active' : '')}
permission={{
resource: ResourceType.CLUSTERCONFIG,
action: Action.VIEW,
}}
>
Metrics
</ActionNavLink>
</Navbar>
<Suspense fallback={<PageLoader />}>
<Routes>
<Route index element={<BrokerLogdir />} />
<Route
path={clusterBrokerConfigsRelativePath}
element={<Configs />}
/>
<Route
path={clusterBrokerMetricsRelativePath}
element={<BrokerMetrics />}
/>
</Routes>
</Suspense>
{(isLoading || isRefetching) && <PageLoader />}

{(error || brokerItem === undefined) && (
<ErrorPage
status={error?.status || 404}
onClick={refetch}
resourceName={`Broker ${brokerId}`}
/>
)}

{isSuccess && brokerItem !== undefined && (
<>
<Metrics.Wrapper>
<Metrics.Section>
<Metrics.Indicator label="Segment Size">
<BytesFormatted
value={brokerDiskUsage?.segmentSize}
precision={2}
/>
</Metrics.Indicator>
<Metrics.Indicator label="Segment Count">
{brokerDiskUsage?.segmentCount}
</Metrics.Indicator>
<Metrics.Indicator label="Port">
{brokerItem?.port}
</Metrics.Indicator>
<Metrics.Indicator label="Host">
{brokerItem?.host}
</Metrics.Indicator>
</Metrics.Section>
</Metrics.Wrapper>

<Navbar role="navigation">
<NavLink
to={clusterBrokerPath(clusterName, brokerId)}
className={({ isActive }) => (isActive ? 'is-active' : '')}
end
>
Log directories
</NavLink>
<NavLink
to={clusterBrokerConfigsPath(clusterName, brokerId)}
className={({ isActive }) => (isActive ? 'is-active' : '')}
>
Configs
</NavLink>
<ActionNavLink
to={clusterBrokerMetricsPath(clusterName, brokerId)}
className={({ isActive }) => (isActive ? 'is-active' : '')}
permission={{
resource: ResourceType.CLUSTERCONFIG,
action: Action.VIEW,
}}
>
Metrics
</ActionNavLink>
</Navbar>
<Suspense fallback={<PageLoader />}>
<Routes>
<Route index element={<BrokerLogdir />} />
<Route
path={clusterBrokerConfigsRelativePath}
element={<Configs />}
/>
<Route
path={clusterBrokerMetricsRelativePath}
element={<BrokerMetrics />}
/>
</Routes>
</Suspense>
</>
)}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ describe('Broker Component', () => {
beforeEach(() => {
(useBrokers as jest.Mock).mockImplementation(() => ({
data: brokersPayload,
isSuccess: true,
}));
(useClusterStats as jest.Mock).mockImplementation(() => ({
data: clusterStatsPayload,
isSuccess: true,
}));
});
const renderComponent = (path = clusterBrokerPath(clusterName, brokerId)) =>
Expand Down
10 changes: 1 addition & 9 deletions frontend/src/components/Brokers/Brokers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,11 @@ import { Route, Routes } from 'react-router-dom';
import { getNonExactPath, RouteParams } from 'lib/paths';
import BrokersList from 'components/Brokers/BrokersList/BrokersList';
import Broker from 'components/Brokers/Broker/Broker';
import SuspenseQueryComponent from 'components/common/SuspenseQueryComponent/SuspenseQueryComponent';

const Brokers: React.FC = () => (
<Routes>
<Route index element={<BrokersList />} />
<Route
path={getNonExactPath(RouteParams.brokerId)}
element={
<SuspenseQueryComponent>
<Broker />
</SuspenseQueryComponent>
}
/>
<Route path={getNonExactPath(RouteParams.brokerId)} element={<Broker />} />
</Routes>
);

Expand Down
42 changes: 32 additions & 10 deletions frontend/src/components/Brokers/BrokersList/BrokersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { useClusters, useClusterStats } from 'lib/hooks/api/clusters';
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
import { Button } from 'components/common/Button/Button';
import ExportIcon from 'components/common/Icons/ExportIcon';
import PageLoader from 'components/common/PageLoader/PageLoader';
import ErrorPage from 'components/ErrorPage/ErrorPage';

import { getBrokersTableColumns, getBrokersTableRows } from './lib';
import { BrokersMetrics } from './BrokersMetrics/BrokersMetrics';
Expand All @@ -22,7 +24,14 @@ const BrokersList: React.FC = () => {
const { data: clusterData } = useClusters();
const cluster = clusterData?.find(({ name }) => name === clusterName);
const { data: clusterStats = {} } = useClusterStats(clusterName);
const { data: brokers } = useBrokers(clusterName);
const {
data: brokers,
error,
refetch,
isLoading,
isRefetching,
isSuccess,
} = useBrokers(clusterName);

const {
brokerCount,
Expand Down Expand Up @@ -81,15 +90,28 @@ const BrokersList: React.FC = () => {
controller={cluster?.controller}
/>

<Table
columns={columns}
data={rows}
enableSorting
onRowClick={({ original: { brokerId } }) =>
navigate(clusterBrokerPath(clusterName, brokerId))
}
emptyMessage="No clusters are online"
/>
{(isLoading || isRefetching) && <PageLoader offsetY={300} />}

{error && (
<ErrorPage
offsetY={300}
status={error.status}
onClick={refetch}
text={error.message}
/>
)}

{isSuccess && (
<Table
columns={columns}
data={rows}
enableSorting
onRowClick={({ original: { brokerId } }) =>
navigate(clusterBrokerPath(clusterName, brokerId))
}
emptyMessage="No clusters are online"
/>
)}
</>
);
}}
Expand Down
Loading
Loading