* Migrate Topic Overview to the new version of table #2684 * changed Dropdown Toggle visibility to disabled and fixed test * changed drop down button disabled rule * deleted cleanUpPolicy form the some tests Co-authored-by: davitbejanyan <dbejanyan@provectus.com> Co-authored-by: Oleg Shur <workshur@gmail.com>
This commit is contained in:
parent
0e4a314082
commit
6581ee605b
3 changed files with 109 additions and 85 deletions
|
@ -0,0 +1,35 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Partition } from 'generated-sources';
|
||||||
|
import { CellContext } from '@tanstack/react-table';
|
||||||
|
import { useAppDispatch } from 'lib/hooks/redux';
|
||||||
|
import ClusterContext from 'components/contexts/ClusterContext';
|
||||||
|
import { RouteParamsClusterTopic } from 'lib/paths';
|
||||||
|
import useAppParams from 'lib/hooks/useAppParams';
|
||||||
|
import { clearTopicMessages } from 'redux/reducers/topicMessages/topicMessagesSlice';
|
||||||
|
import { Dropdown, DropdownItem } from 'components/common/Dropdown';
|
||||||
|
import { useTopicDetails } from 'lib/hooks/api/topics';
|
||||||
|
|
||||||
|
const ActionsCell: React.FC<CellContext<Partition, unknown>> = ({ row }) => {
|
||||||
|
const { clusterName, topicName } = useAppParams<RouteParamsClusterTopic>();
|
||||||
|
const { data } = useTopicDetails({ clusterName, topicName });
|
||||||
|
const { isReadOnly } = React.useContext(ClusterContext);
|
||||||
|
const { partition } = row.original;
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const clearTopicMessagesHandler = async () => {
|
||||||
|
await dispatch(
|
||||||
|
clearTopicMessages({ clusterName, topicName, partitions: [partition] })
|
||||||
|
).unwrap();
|
||||||
|
};
|
||||||
|
const disabled =
|
||||||
|
data?.internal || isReadOnly || data?.cleanUpPolicy !== 'DELETE';
|
||||||
|
return (
|
||||||
|
<Dropdown disabled={disabled}>
|
||||||
|
<DropdownItem onClick={clearTopicMessagesHandler} danger>
|
||||||
|
Clear Messages
|
||||||
|
</DropdownItem>
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ActionsCell;
|
|
@ -1,25 +1,20 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Partition, Replica } from 'generated-sources';
|
import { Partition, Replica } from 'generated-sources';
|
||||||
import ClusterContext from 'components/contexts/ClusterContext';
|
|
||||||
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
|
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
|
||||||
import { Table } from 'components/common/table/Table/Table.styled';
|
import Table from 'components/common/NewTable';
|
||||||
import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell';
|
|
||||||
import * as Metrics from 'components/common/Metrics';
|
import * as Metrics from 'components/common/Metrics';
|
||||||
import { Tag } from 'components/common/Tag/Tag.styled';
|
import { Tag } from 'components/common/Tag/Tag.styled';
|
||||||
import { useAppDispatch } from 'lib/hooks/redux';
|
|
||||||
import { RouteParamsClusterTopic } from 'lib/paths';
|
import { RouteParamsClusterTopic } from 'lib/paths';
|
||||||
import useAppParams from 'lib/hooks/useAppParams';
|
import useAppParams from 'lib/hooks/useAppParams';
|
||||||
import { Dropdown, DropdownItem } from 'components/common/Dropdown';
|
|
||||||
import { clearTopicMessages } from 'redux/reducers/topicMessages/topicMessagesSlice';
|
|
||||||
import { useTopicDetails } from 'lib/hooks/api/topics';
|
import { useTopicDetails } from 'lib/hooks/api/topics';
|
||||||
|
import { ColumnDef } from '@tanstack/react-table';
|
||||||
|
|
||||||
import * as S from './Overview.styled';
|
import * as S from './Overview.styled';
|
||||||
|
import ActionsCell from './ActionsCell';
|
||||||
|
|
||||||
const Overview: React.FC = () => {
|
const Overview: React.FC = () => {
|
||||||
const { clusterName, topicName } = useAppParams<RouteParamsClusterTopic>();
|
const { clusterName, topicName } = useAppParams<RouteParamsClusterTopic>();
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const { data } = useTopicDetails({ clusterName, topicName });
|
const { data } = useTopicDetails({ clusterName, topicName });
|
||||||
const { isReadOnly } = React.useContext(ClusterContext);
|
|
||||||
|
|
||||||
const messageCount = React.useMemo(
|
const messageCount = React.useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
@ -28,7 +23,65 @@ const Overview: React.FC = () => {
|
||||||
}, 0),
|
}, 0),
|
||||||
[data]
|
[data]
|
||||||
);
|
);
|
||||||
|
const newData = React.useMemo(() => {
|
||||||
|
if (!data?.partitions) return [];
|
||||||
|
|
||||||
|
return data.partitions.map((items: Partition) => {
|
||||||
|
return {
|
||||||
|
...items,
|
||||||
|
messageCount: items.offsetMax - items.offsetMin,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}, [data?.partitions]);
|
||||||
|
|
||||||
|
const columns = React.useMemo<ColumnDef<Partition>[]>(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
header: 'Partition ID',
|
||||||
|
enableSorting: false,
|
||||||
|
accessorKey: 'partition',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: 'Replicas',
|
||||||
|
enableSorting: false,
|
||||||
|
|
||||||
|
accessorKey: 'replicas',
|
||||||
|
cell: ({ getValue }) => {
|
||||||
|
const replicas = getValue<Partition['replicas']>();
|
||||||
|
if (replicas === undefined || replicas.length === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return replicas?.map(({ broker, leader }: Replica) => (
|
||||||
|
<S.Replica
|
||||||
|
leader={leader}
|
||||||
|
key={broker}
|
||||||
|
title={leader ? 'Leader' : ''}
|
||||||
|
>
|
||||||
|
{broker}
|
||||||
|
</S.Replica>
|
||||||
|
));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: 'First Offset',
|
||||||
|
enableSorting: false,
|
||||||
|
accessorKey: 'offsetMin',
|
||||||
|
},
|
||||||
|
{ header: 'Next Offset', enableSorting: false, accessorKey: 'offsetMax' },
|
||||||
|
{
|
||||||
|
header: 'Message Count',
|
||||||
|
enableSorting: false,
|
||||||
|
accessorKey: `messageCount`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: '',
|
||||||
|
enableSorting: false,
|
||||||
|
accessorKey: 'actions',
|
||||||
|
cell: ActionsCell,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Metrics.Wrapper>
|
<Metrics.Wrapper>
|
||||||
|
@ -90,66 +143,12 @@ const Overview: React.FC = () => {
|
||||||
</Metrics.Indicator>
|
</Metrics.Indicator>
|
||||||
</Metrics.Section>
|
</Metrics.Section>
|
||||||
</Metrics.Wrapper>
|
</Metrics.Wrapper>
|
||||||
<Table isFullwidth>
|
<Table
|
||||||
<thead>
|
columns={columns}
|
||||||
<tr>
|
data={newData}
|
||||||
<TableHeaderCell title="Partition ID" />
|
enableSorting
|
||||||
<TableHeaderCell title="Replicas" />
|
emptyMessage="No Partitions found "
|
||||||
<TableHeaderCell title="First Offset" />
|
/>
|
||||||
<TableHeaderCell title="Next Offset" />
|
|
||||||
<TableHeaderCell title="Message Count" />
|
|
||||||
<TableHeaderCell title=" " />
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{data?.partitions?.map((partition: Partition) => (
|
|
||||||
<tr key={`partition-list-item-key-${partition.partition}`}>
|
|
||||||
<td>{partition.partition}</td>
|
|
||||||
<td>
|
|
||||||
{partition.replicas?.map(({ broker, leader }: Replica) => (
|
|
||||||
<S.Replica
|
|
||||||
leader={leader}
|
|
||||||
key={broker}
|
|
||||||
title={leader ? 'Leader' : ''}
|
|
||||||
>
|
|
||||||
{broker}
|
|
||||||
</S.Replica>
|
|
||||||
))}
|
|
||||||
</td>
|
|
||||||
<td>{partition.offsetMin}</td>
|
|
||||||
<td>{partition.offsetMax}</td>
|
|
||||||
<td>{partition.offsetMax - partition.offsetMin}</td>
|
|
||||||
<td style={{ width: '5%' }}>
|
|
||||||
{!data?.internal &&
|
|
||||||
!isReadOnly &&
|
|
||||||
data?.cleanUpPolicy === 'DELETE' ? (
|
|
||||||
<Dropdown>
|
|
||||||
<DropdownItem
|
|
||||||
onClick={() =>
|
|
||||||
dispatch(
|
|
||||||
clearTopicMessages({
|
|
||||||
clusterName,
|
|
||||||
topicName,
|
|
||||||
partitions: [partition.partition],
|
|
||||||
})
|
|
||||||
).unwrap()
|
|
||||||
}
|
|
||||||
danger
|
|
||||||
>
|
|
||||||
Clear Messages
|
|
||||||
</DropdownItem>
|
|
||||||
</Dropdown>
|
|
||||||
) : null}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
{data?.partitions?.length === 0 && (
|
|
||||||
<tr>
|
|
||||||
<td colSpan={10}>No Partitions found</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</Table>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -122,39 +122,29 @@ describe('Overview', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when the table partition dropdown appearance', () => {
|
describe('when the table partition dropdown appearance', () => {
|
||||||
it('should check if the dropdown is not present when it is readOnly', () => {
|
it('should check if the dropdown is disabled when it is readOnly', () => {
|
||||||
renderComponent(
|
renderComponent(
|
||||||
{
|
{
|
||||||
...internalTopicPayload,
|
...externalTopicPayload,
|
||||||
cleanUpPolicy: CleanUpPolicy.DELETE,
|
|
||||||
},
|
},
|
||||||
{ ...defaultContextValues, isReadOnly: true }
|
{ ...defaultContextValues, isReadOnly: true }
|
||||||
);
|
);
|
||||||
expect(screen.queryByText('Clear Messages')).not.toBeInTheDocument();
|
expect(screen.getByLabelText('Dropdown Toggle')).toBeDisabled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check if the dropdown is not present when it is internal', () => {
|
it('should check if the dropdown is disabled when it is internal', () => {
|
||||||
renderComponent({
|
renderComponent({
|
||||||
...internalTopicPayload,
|
...internalTopicPayload,
|
||||||
cleanUpPolicy: CleanUpPolicy.DELETE,
|
|
||||||
});
|
});
|
||||||
expect(screen.queryByText('Clear Messages')).not.toBeInTheDocument();
|
expect(screen.getByLabelText('Dropdown Toggle')).toBeDisabled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check if the dropdown is not present when cleanUpPolicy is not DELETE', () => {
|
it('should check if the dropdown is disabled when cleanUpPolicy is not DELETE', () => {
|
||||||
renderComponent({
|
renderComponent({
|
||||||
...externalTopicPayload,
|
...externalTopicPayload,
|
||||||
cleanUpPolicy: CleanUpPolicy.COMPACT,
|
cleanUpPolicy: CleanUpPolicy.COMPACT,
|
||||||
});
|
});
|
||||||
expect(screen.queryByText('Clear Messages')).not.toBeInTheDocument();
|
expect(screen.getByLabelText('Dropdown Toggle')).toBeDisabled();
|
||||||
});
|
|
||||||
|
|
||||||
it('should check if the dropdown action to be in visible', () => {
|
|
||||||
renderComponent({
|
|
||||||
...externalTopicPayload,
|
|
||||||
cleanUpPolicy: CleanUpPolicy.DELETE,
|
|
||||||
});
|
|
||||||
expect(screen.getByText('Clear Messages')).toBeInTheDocument();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue