From 3bfa1a7d1e4418c59f8d5e14ee8f41f83217086d Mon Sep 17 00:00:00 2001 From: Oleg Shuralev Date: Sun, 5 Jan 2020 14:40:18 +0300 Subject: [PATCH] [UI] Topics Ui --- frontend/src/components/App.tsx | 14 ++--- frontend/src/components/Nav/ClusterMenu.tsx | 5 +- .../src/components/Topics/Details/Details.tsx | 4 +- .../src/components/Topics/Details/Replica.tsx | 6 +- frontend/src/components/Topics/List/List.tsx | 60 +++++++------------ .../components/Topics/List/ListContainer.ts | 2 +- .../src/components/Topics/List/ListItem.tsx | 34 +++++++++++ frontend/src/components/Topics/Topics.tsx | 6 +- frontend/src/lib/api/topics.ts | 2 +- frontend/src/redux/reducers/topics/thunks.ts | 3 +- frontend/src/theme/index.scss | 2 - frontend/src/types/topic.ts | 9 ++- 12 files changed, 81 insertions(+), 66 deletions(-) create mode 100644 frontend/src/components/Topics/List/ListItem.tsx diff --git a/frontend/src/components/App.tsx b/frontend/src/components/App.tsx index 067a1b408a033ad60bcaf32bf22ff91fedfea00d..bc51b2106d7b56d9d9a729543477863353e9732e 100644 --- a/frontend/src/components/App.tsx +++ b/frontend/src/components/App.tsx @@ -31,14 +31,12 @@ const App: React.FC = ({
{isClusterListFetched ? ( -
- - - - Dashboard - - -
+ + + + Dashboard + + ) : ( )} diff --git a/frontend/src/components/Nav/ClusterMenu.tsx b/frontend/src/components/Nav/ClusterMenu.tsx index 63a2ffbcb9556ef0e5d48c3a6ffbbd96b6792147..1c533f5f7f48afd4ba1fe9282b1962aa5b29c8d6 100644 --- a/frontend/src/components/Nav/ClusterMenu.tsx +++ b/frontend/src/components/Nav/ClusterMenu.tsx @@ -31,7 +31,10 @@ const ClusterMenu: React.FC = ({ {name}
    - + + Brokers + + Topics
diff --git a/frontend/src/components/Topics/Details/Details.tsx b/frontend/src/components/Topics/Details/Details.tsx index a39be081cd745f7d48996bd0f8040d9b93edc2ab..5851cb8d2619f58c449b4fa362187b71a52ed75c 100644 --- a/frontend/src/components/Topics/Details/Details.tsx +++ b/frontend/src/components/Topics/Details/Details.tsx @@ -1,15 +1,15 @@ import React from 'react'; -import { Topic } from 'types'; +import { Topic, TopicConfigs } from 'types'; import ConfigRow from './ConfigRow'; import Partition from './Partition'; const Details: React.FC<{ topic: Topic }> = ({ topic: { name, - configs, partitions, } }) => { + const configs: TopicConfigs = {[ 'key-config']: '1' }; const configKeys = Object.keys(configs); return ( diff --git a/frontend/src/components/Topics/Details/Replica.tsx b/frontend/src/components/Topics/Details/Replica.tsx index 716d72855d3cc05ee9c62251c5a6a257139d3746..52e73b5966e1544da2088b61f6ef032ec7373694 100644 --- a/frontend/src/components/Topics/Details/Replica.tsx +++ b/frontend/src/components/Topics/Details/Replica.tsx @@ -7,7 +7,7 @@ interface Props extends TopicReplica { } const Replica: React.FC = ({ - in_sync, + inSync, leader, broker, index, @@ -22,8 +22,8 @@ const Replica: React.FC = ({ LEADER )} - - {in_sync ? 'IN SYNC' : 'OUT OF SYNC'} + + {inSync ? 'IN SYNC' : 'OUT OF SYNC'} diff --git a/frontend/src/components/Topics/List/List.tsx b/frontend/src/components/Topics/List/List.tsx index 486ef8852565a54c957e8200bb493a34a68f0f99..544ab7468b95973636d5f229d74d3b9567b59325 100644 --- a/frontend/src/components/Topics/List/List.tsx +++ b/frontend/src/components/Topics/List/List.tsx @@ -1,56 +1,36 @@ import React from 'react'; import { Topic } from 'types'; -import { NavLink } from 'react-router-dom'; - -const ListItem: React.FC = ({ - name, - partitions, -}) => { - return ( -
  • - - {name} - -

    Partitions: {partitions.length}

    -

    Replications: {partitions ? partitions[0].replicas.length : 0}

    -
  • - ); -} +import ListItem from './ListItem'; interface Props { topics: Topic[]; - totalBrokers?: number; } const List: React.FC = ({ topics, - totalBrokers, }) => { return ( <> -
    -
    -
    -
    -
    -

    Brokers

    -

    {totalBrokers}

    -
    -
    -
    -
    -

    Topics

    -

    {topics.length}

    -
    -
    -
    +
    +
    + + + + + + + + + + {topics.map((topic) => ( + + ))} + +
    Topic NameTotal PartitionsOut of sync replicas
    -
    - -
    -
      - {topics.map((topic) => )} -
    ); diff --git a/frontend/src/components/Topics/List/ListContainer.ts b/frontend/src/components/Topics/List/ListContainer.ts index 4a8cc324e8b82fa6b4fc59dee688ff77aa8482fe..fdf16e97c8d7a55a802e911239101c84e1335f9f 100644 --- a/frontend/src/components/Topics/List/ListContainer.ts +++ b/frontend/src/components/Topics/List/ListContainer.ts @@ -4,7 +4,6 @@ import { getTotalBrokers, } from 'redux/reducers/topics/selectors'; import { RootState } from 'types'; - import List from './List'; const mapStateToProps = (state: RootState) => ({ @@ -12,4 +11,5 @@ const mapStateToProps = (state: RootState) => ({ totalBrokers: getTotalBrokers(state), }); + export default connect(mapStateToProps)(List); diff --git a/frontend/src/components/Topics/List/ListItem.tsx b/frontend/src/components/Topics/List/ListItem.tsx new file mode 100644 index 0000000000000000000000000000000000000000..999648ee3701beb34e9061b626e8e921c3e733e3 --- /dev/null +++ b/frontend/src/components/Topics/List/ListItem.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { NavLink } from 'react-router-dom'; +import { Topic } from 'types'; + + +const ListItem: React.FC = ({ + name, + partitions, +}) => { + const outOfSyncReplicas = React.useMemo(() => { + if (partitions === undefined || partitions.length === 0) { + return 0; + } + + return partitions.reduce((memo: number, { replicas }) => { + const outOfSync = replicas.filter(({ inSync }) => !inSync) + return memo + outOfSync.length; + }, 0); + }, [partitions]) + + return ( + + + + {name} + + + {partitions.length} + {outOfSyncReplicas} + + ); +} + +export default ListItem; diff --git a/frontend/src/components/Topics/Topics.tsx b/frontend/src/components/Topics/Topics.tsx index 700727b50a734966ed1e939892a8d6d4db917359..5041596d591f880e41a424754c2ac4e06a698918 100644 --- a/frontend/src/components/Topics/Topics.tsx +++ b/frontend/src/components/Topics/Topics.tsx @@ -22,13 +22,13 @@ const Topics: React.FC = ({ fetchTopicList, }) => { React.useEffect(() => { fetchTopicList(clusterId); }, [fetchTopicList, clusterId]); - React.useEffect(() => { fetchBrokers(clusterId); }, [fetchBrokers, clusterId]); + // React.useEffect(() => { fetchBrokers(clusterId); }, [fetchBrokers, clusterId]); if (isFetched) { return ( - - + + ); } diff --git a/frontend/src/lib/api/topics.ts b/frontend/src/lib/api/topics.ts index 9507410b2e5e8f2aeee2e3fbb9edead0dea12c03..2347f1db05d789ce3bc9fee77bccc6c7d5913e81 100644 --- a/frontend/src/lib/api/topics.ts +++ b/frontend/src/lib/api/topics.ts @@ -13,7 +13,7 @@ export const getTopic = (name: TopicName): Promise => fetch(`${BASE_URL}/topics/${name}`, { ...BASE_PARAMS }) .then(res => res.json()); -export const getTopics = (clusterId: ClusterId): Promise => +export const getTopics = (clusterId: ClusterId): Promise => fetch(`${BASE_URL}/clusters/${clusterId}/topics`, { ...BASE_PARAMS }) .then(res => res.json()); diff --git a/frontend/src/redux/reducers/topics/thunks.ts b/frontend/src/redux/reducers/topics/thunks.ts index bdaf5e39c41ac863afd323fb3faa4a04b450f0a0..aa6d9ec1fa3bb6e83d161ac3641c2878909c7095 100644 --- a/frontend/src/redux/reducers/topics/thunks.ts +++ b/frontend/src/redux/reducers/topics/thunks.ts @@ -15,9 +15,8 @@ export const fetchTopicList = (clusterId: ClusterId): PromiseThunk => asyn try { const topics = await getTopics(clusterId); - const detailedList = await Promise.all(topics.map((topic: TopicName): Promise => getTopic(topic))); - dispatch(fetchTopicListAction.success(detailedList)); + dispatch(fetchTopicListAction.success(topics)); } catch (e) { dispatch(fetchTopicListAction.failure()); } diff --git a/frontend/src/theme/index.scss b/frontend/src/theme/index.scss index 8941cef62662ed9b606fb8f7fa41e113a671a214..f12b290336c5b3f66f78cac4c071ff9f7ae1f483 100644 --- a/frontend/src/theme/index.scss +++ b/frontend/src/theme/index.scss @@ -1,9 +1,7 @@ @import './bulma_overrides.scss'; #root, body, html { - height: 100%; width: 100%; - overflow: hidden; position: relative; margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', diff --git a/frontend/src/types/topic.ts b/frontend/src/types/topic.ts index 997666912fd4401fba8e044c3d5445abfd44a30c..4a2eb5f83d8d7ce162af81a7e8fe9f331b165c74 100644 --- a/frontend/src/types/topic.ts +++ b/frontend/src/types/topic.ts @@ -8,7 +8,7 @@ export interface TopicConfigs { export interface TopicReplica { broker: number; leader: boolean; - in_sync: true; + inSync: true; } export interface TopicPartition { @@ -19,7 +19,7 @@ export interface TopicPartition { export interface Topic { name: TopicName; - configs: TopicConfigs; + internal: boolean; partitions: TopicPartition[]; } @@ -29,4 +29,7 @@ export interface TopicsState { brokers?: Broker[]; } -export type Broker = number; +export interface Broker { + id: 1, + host: "broker", +};