Skip to content

Commit 7f97f71

Browse files
authored
FE: Improve cluster's resources navigation (#1133)
1 parent 7073c72 commit 7f97f71

File tree

29 files changed

+164
-73
lines changed

29 files changed

+164
-73
lines changed

frontend/src/components/ACLPage/List/List.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from 'react';
22
import { ColumnDef, Row } from '@tanstack/react-table';
3-
import PageHeading from 'components/common/PageHeading/PageHeading';
43
import Table from 'components/common/NewTable';
54
import { useConfirm } from 'lib/hooks/useConfirm';
65
import useAppParams from 'lib/hooks/useAppParams';
@@ -20,6 +19,7 @@ import { useTheme } from 'styled-components';
2019
import ACLFormContext from 'components/ACLPage/Form/AclFormContext';
2120
import PlusIcon from 'components/common/Icons/PlusIcon';
2221
import ActionButton from 'components/common/ActionComponent/ActionButton/ActionButton';
22+
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
2323

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

@@ -149,7 +149,7 @@ const ACList: React.FC = () => {
149149

150150
return (
151151
<S.Container>
152-
<PageHeading text="Access Control List">
152+
<ResourcePageHeading text="Access Control List">
153153
<ActionButton
154154
buttonType="primary"
155155
buttonSize="M"
@@ -161,7 +161,7 @@ const ACList: React.FC = () => {
161161
>
162162
<PlusIcon /> Create ACL
163163
</ActionButton>
164-
</PageHeading>
164+
</ResourcePageHeading>
165165
<Table
166166
columns={columns}
167167
data={aclList ?? []}

frontend/src/components/Brokers/Broker/Broker.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { Suspense } from 'react';
2-
import PageHeading from 'components/common/PageHeading/PageHeading';
32
import * as Metrics from 'components/common/Metrics';
43
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
54
import useAppParams from 'lib/hooks/useAppParams';
@@ -21,6 +20,7 @@ import Navbar from 'components/common/Navigation/Navbar.styled';
2120
import PageLoader from 'components/common/PageLoader/PageLoader';
2221
import { ActionNavLink } from 'components/common/ActionComponent';
2322
import { Action, ResourceType } from 'generated-sources';
23+
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
2424

2525
import Configs from './Configs/Configs';
2626

@@ -38,7 +38,7 @@ const Broker: React.FC = () => {
3838
);
3939
return (
4040
<>
41-
<PageHeading
41+
<ResourcePageHeading
4242
text={`Broker ${brokerId}`}
4343
backTo={clusterBrokersPath(clusterName)}
4444
backText="Brokers"

frontend/src/components/Brokers/BrokersList/BrokersList.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import React, { useMemo } from 'react';
22
import { ClusterName } from 'lib/interfaces/cluster';
33
import { useNavigate } from 'react-router-dom';
4-
import PageHeading from 'components/common/PageHeading/PageHeading';
54
import useAppParams from 'lib/hooks/useAppParams';
65
import Table from 'components/common/NewTable';
76
import { clusterBrokerPath } from 'lib/paths';
87
import { useBrokers } from 'lib/hooks/api/brokers';
98
import { useClusterStats } from 'lib/hooks/api/clusters';
9+
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
1010

1111
import { BrokersMetrics } from './BrokersMetrics/BrokersMetrics';
1212
import { getBrokersTableColumns, getBrokersTableRows } from './lib';
@@ -45,7 +45,7 @@ const BrokersList: React.FC = () => {
4545

4646
return (
4747
<>
48-
<PageHeading text="Brokers" />
48+
<ResourcePageHeading text="Brokers" />
4949

5050
<BrokersMetrics
5151
brokerCount={brokerCount}

frontend/src/components/Connect/Details/DetailsPage.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import {
99
RouterParamsClusterConnectConnector,
1010
} from 'lib/paths';
1111
import Navbar from 'components/common/Navigation/Navbar.styled';
12-
import PageHeading from 'components/common/PageHeading/PageHeading';
1312
import PageLoader from 'components/common/PageLoader/PageLoader';
13+
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
1414

1515
import Overview from './Overview/Overview';
1616
import Tasks from './Tasks/Tasks';
@@ -23,13 +23,13 @@ const DetailsPage: React.FC = () => {
2323

2424
return (
2525
<div>
26-
<PageHeading
26+
<ResourcePageHeading
2727
text={connectorName}
2828
backTo={clusterConnectorsPath(clusterName)}
2929
backText="Connectors"
3030
>
3131
<Actions />
32-
</PageHeading>
32+
</ResourcePageHeading>
3333
<Overview />
3434
<Navbar role="navigation">
3535
<NavLink

frontend/src/components/Connect/List/ListPage.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import { ClusterNameRoute, clusterConnectorNewRelativePath } from 'lib/paths';
44
import ClusterContext from 'components/contexts/ClusterContext';
55
import Search from 'components/common/Search/Search';
66
import * as Metrics from 'components/common/Metrics';
7-
import PageHeading from 'components/common/PageHeading/PageHeading';
87
import Tooltip from 'components/common/Tooltip/Tooltip';
98
import { ControlPanelWrapper } from 'components/common/ControlPanel/ControlPanel.styled';
109
import PageLoader from 'components/common/PageLoader/PageLoader';
1110
import { ConnectorState, Action, ResourceType } from 'generated-sources';
1211
import { useConnectors, useConnects } from 'lib/hooks/api/kafkaConnect';
1312
import { ActionButton } from 'components/common/ActionComponent';
13+
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
1414

1515
import List from './List';
1616

@@ -33,7 +33,7 @@ const ListPage: React.FC = () => {
3333

3434
return (
3535
<>
36-
<PageHeading text="Connectors">
36+
<ResourcePageHeading text="Connectors">
3737
{!isReadOnly && (
3838
<Tooltip
3939
value={
@@ -55,7 +55,7 @@ const ListPage: React.FC = () => {
5555
placement="left"
5656
/>
5757
)}
58-
</PageHeading>
58+
</ResourcePageHeading>
5959
<Metrics.Wrapper>
6060
<Metrics.Section>
6161
<Metrics.Indicator

frontend/src/components/Connect/New/New.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ import Select from 'components/common/Select/Select';
1515
import { FormError } from 'components/common/Input/Input.styled';
1616
import Input from 'components/common/Input/Input';
1717
import { Button } from 'components/common/Button/Button';
18-
import PageHeading from 'components/common/PageHeading/PageHeading';
1918
import Heading from 'components/common/heading/Heading.styled';
2019
import { useConnects, useCreateConnector } from 'lib/hooks/api/kafkaConnect';
2120
import { Connect } from 'generated-sources';
21+
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
2222

2323
import * as S from './New.styled';
2424

@@ -94,7 +94,7 @@ const New: React.FC = () => {
9494

9595
return (
9696
<FormProvider {...methods}>
97-
<PageHeading
97+
<ResourcePageHeading
9898
text="Create new connector"
9999
backTo={clusterConnectorsPath(clusterName)}
100100
backText="Connectors"

frontend/src/components/ConsumerGroups/Details/Details.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
} from 'lib/paths';
99
import Search from 'components/common/Search/Search';
1010
import ClusterContext from 'components/contexts/ClusterContext';
11-
import PageHeading from 'components/common/PageHeading/PageHeading';
1211
import * as Metrics from 'components/common/Metrics';
1312
import { Tag } from 'components/common/Tag/Tag.styled';
1413
import groupBy from 'lib/functions/groupBy';
@@ -25,6 +24,7 @@ import {
2524
} from 'lib/hooks/api/consumers';
2625
import Tooltip from 'components/common/Tooltip/Tooltip';
2726
import { CONSUMER_GROUP_STATE_TOOLTIPS } from 'lib/constants';
27+
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
2828

2929
import ListItem from './ListItem';
3030

@@ -64,7 +64,7 @@ const Details: React.FC = () => {
6464
return (
6565
<div>
6666
<div>
67-
<PageHeading
67+
<ResourcePageHeading
6868
text={consumerGroupID}
6969
backTo={clusterConsumerGroupsPath(clusterName)}
7070
backText="Consumers"
@@ -96,7 +96,7 @@ const Details: React.FC = () => {
9696
</ActionDropdownItem>
9797
</Dropdown>
9898
)}
99-
</PageHeading>
99+
</ResourcePageHeading>
100100
</div>
101101
<Metrics.Wrapper>
102102
<Metrics.Section>

frontend/src/components/ConsumerGroups/Details/ResetOffsets/ResetOffsets.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react';
22
import { clusterConsumerGroupsPath, ClusterGroupParam } from 'lib/paths';
33
import 'react-datepicker/dist/react-datepicker.css';
4-
import PageHeading from 'components/common/PageHeading/PageHeading';
54
import useAppParams from 'lib/hooks/useAppParams';
65
import { useConsumerGroupDetails } from 'lib/hooks/api/consumers';
76
import PageLoader from 'components/common/PageLoader/PageLoader';
7+
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
88
import {
99
ConsumerGroupOffsetsReset,
1010
ConsumerGroupOffsetsResetType,
@@ -37,7 +37,7 @@ const ResetOffsets: React.FC = () => {
3737

3838
return (
3939
<>
40-
<PageHeading
40+
<ResourcePageHeading
4141
text={consumerGroupID}
4242
backTo={clusterConsumerGroupsPath(routerParams.clusterName)}
4343
backText="Consumers"

frontend/src/components/ConsumerGroups/List.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React from 'react';
2-
import PageHeading from 'components/common/PageHeading/PageHeading';
32
import Search from 'components/common/Search/Search';
43
import { ControlPanelWrapper } from 'components/common/ControlPanel/ControlPanel.styled';
54
import {
@@ -16,6 +15,7 @@ import { useNavigate, useSearchParams } from 'react-router-dom';
1615
import { CONSUMER_GROUP_STATE_TOOLTIPS, PER_PAGE } from 'lib/constants';
1716
import { useConsumerGroups } from 'lib/hooks/api/consumers';
1817
import Tooltip from 'components/common/Tooltip/Tooltip';
18+
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
1919

2020
const List = () => {
2121
const { clusterName } = useAppParams<ClusterNameRoute>();
@@ -92,7 +92,7 @@ const List = () => {
9292

9393
return (
9494
<>
95-
<PageHeading text="Consumers" />
95+
<ResourcePageHeading text="Consumers" />
9696
<ControlPanelWrapper hasInput>
9797
<Search placeholder="Search by Consumer Group ID" />
9898
</ControlPanelWrapper>

frontend/src/components/KsqlDb/KsqlDb.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import {
1010
clusterKsqlDbTablesRelativePath,
1111
ClusterNameRoute,
1212
} from 'lib/paths';
13-
import PageHeading from 'components/common/PageHeading/PageHeading';
1413
import { ActionButton } from 'components/common/ActionComponent';
1514
import Navbar from 'components/common/Navigation/Navbar.styled';
1615
import { Navigate, NavLink, Route, Routes } from 'react-router-dom';
1716
import { Action, ResourceType } from 'generated-sources';
1817
import { useKsqlkDb } from 'lib/hooks/api/ksqlDb';
1918
import 'ace-builds/src-noconflict/ace';
19+
import ResourcePageHeading from 'components/common/ResourcePageHeading/ResourcePageHeading';
2020

2121
import TableView from './TableView';
2222

@@ -29,7 +29,7 @@ const KsqlDb: React.FC = () => {
2929

3030
return (
3131
<>
32-
<PageHeading text="KSQL DB">
32+
<ResourcePageHeading text="KSQL DB">
3333
<ActionButton
3434
to={clusterKsqlDbQueryRelativePath}
3535
buttonType="primary"
@@ -41,7 +41,7 @@ const KsqlDb: React.FC = () => {
4141
>
4242
Execute KSQL Request
4343
</ActionButton>
44-
</PageHeading>
44+
</ResourcePageHeading>
4545
<Metrics.Wrapper>
4646
<Metrics.Section>
4747
<Metrics.Indicator

frontend/src/components/Nav/ClusterMenu/ClusterMenu.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import MenuTab from 'components/Nav/Menu/MenuTab';
55
import MenuItem from 'components/Nav/Menu/MenuItem';
66
import {
77
clusterACLPath,
8-
clusterBrokerPath,
98
clusterBrokersPath,
109
clusterConnectorsPath,
1110
clusterConsumerGroupsPath,
@@ -16,45 +15,50 @@ import {
1615
import { useLocation } from 'react-router-dom';
1716
import { useLocalStorage } from 'lib/hooks/useLocalStorage';
1817
import { ClusterColorKey } from 'theme/theme';
18+
import useScrollIntoView from 'lib/hooks/useScrollIntoView';
1919

2020
interface ClusterMenuProps {
2121
name: Cluster['name'];
2222
status: Cluster['status'];
2323
features: Cluster['features'];
24-
singleMode?: boolean;
24+
opened?: boolean;
2525
}
2626

2727
const ClusterMenu: FC<ClusterMenuProps> = ({
2828
name,
2929
status,
3030
features,
31-
singleMode,
31+
opened = false,
3232
}) => {
3333
const hasFeatureConfigured = (key: ClusterFeaturesEnum) =>
3434
features?.includes(key);
35-
const [isOpen, setIsOpen] = useState(!!singleMode);
35+
const [isOpen, setIsOpen] = useState(!!opened);
3636
const location = useLocation();
3737
const [colorKey, setColorKey] = useLocalStorage<ClusterColorKey>(
3838
`clusterColor-${name}`,
3939
'transparent'
4040
);
4141

42-
const getIsMenuItemActive = (path: string) =>
43-
location.pathname.includes(path);
42+
const getIsMenuItemActive = (path: string) => {
43+
return location.pathname.includes(path);
44+
};
45+
46+
const { ref } = useScrollIntoView<HTMLUListElement>(opened);
4447

4548
return (
46-
<S.ClusterList role="menu" $colorKey={colorKey}>
49+
<S.ClusterList role="menu" $colorKey={colorKey} ref={ref}>
4750
<MenuTab
4851
title={name}
4952
status={status}
5053
isOpen={isOpen}
5154
toggleClusterMenu={() => setIsOpen((prev) => !prev)}
5255
setColorKey={setColorKey}
56+
isActive={opened}
5357
/>
5458
{isOpen && (
5559
<S.List>
5660
<MenuItem
57-
isActive={getIsMenuItemActive(clusterBrokerPath(name))}
61+
isActive={getIsMenuItemActive(clusterBrokersPath(name))}
5862
to={clusterBrokersPath(name)}
5963
title="Brokers"
6064
/>

frontend/src/components/Nav/ClusterMenu/__tests__/ClusterMenu.spec.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,18 @@ import { clusterConnectorsPath } from 'lib/paths';
77
import { render } from 'lib/testHelpers';
88
import { onlineClusterPayload } from 'lib/fixtures/clusters';
99

10+
/*
11+
Due to jsdom doesnt know about scrollIntoView
12+
*/
13+
window.HTMLElement.prototype.scrollIntoView = jest.fn();
14+
1015
describe('ClusterMenu', () => {
11-
const setupComponent = (cluster: Cluster, singleMode?: boolean) => (
16+
const setupComponent = (cluster: Cluster, opened?: boolean) => (
1217
<ClusterMenu
1318
name={cluster.name}
1419
status={cluster.status}
1520
features={cluster.features}
16-
singleMode={singleMode}
21+
opened={opened}
1722
/>
1823
);
1924
const getMenuItems = () => screen.getAllByRole('menuitem');

frontend/src/components/Nav/Menu/MenuTab.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export interface MenuTabProps {
1111
isOpen: boolean;
1212
toggleClusterMenu: () => void;
1313
setColorKey: Dispatch<SetStateAction<ClusterColorKey>>;
14+
isActive?: boolean;
1415
}
1516

1617
const MenuTab: FC<MenuTabProps> = ({
@@ -19,8 +20,13 @@ const MenuTab: FC<MenuTabProps> = ({
1920
status,
2021
isOpen,
2122
setColorKey,
23+
isActive = false,
2224
}) => (
23-
<S.MenuItem $variant="primary" onClick={toggleClusterMenu}>
25+
<S.MenuItem
26+
$variant="primary"
27+
onClick={toggleClusterMenu}
28+
$isActive={isActive}
29+
>
2430
<S.ContentWrapper>
2531
<S.StatusIconWrapper>
2632
<S.StatusIcon status={status} aria-label="status">

0 commit comments

Comments
 (0)