Cleanup styling (#365)
This commit is contained in:
parent
6e8226298f
commit
d471759b79
27 changed files with 1033 additions and 504 deletions
|
@ -17,7 +17,7 @@ $navbar-width: 250px;
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__navbar {
|
&__sidebar{
|
||||||
width: $navbar-width;
|
width: $navbar-width;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -28,6 +28,19 @@ $navbar-width: 250px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
padding: 20px 20px;
|
padding: 20px 20px;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
transition: width .25s,opacity .25s,transform .25s,-webkit-transform .25s;
|
||||||
|
|
||||||
|
&Overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
height: 120vh;
|
||||||
|
z-index: 99;
|
||||||
|
display: block;
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transition: all .5s ease;
|
||||||
|
transition: all .5s ease;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__alerts {
|
&__alerts {
|
||||||
|
@ -47,3 +60,35 @@ $navbar-width: 250px;
|
||||||
.react-datepicker-popper {
|
.react-datepicker-popper {
|
||||||
z-index: 30 !important;
|
z-index: 30 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1023px) {
|
||||||
|
.Layout {
|
||||||
|
&__container {
|
||||||
|
margin-left: initial;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__sidebar {
|
||||||
|
left: -$navbar-width;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__alerts {
|
||||||
|
max-width: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--sidebarVisible {
|
||||||
|
.Layout__sidebar {
|
||||||
|
transform: translate3d($navbar-width,0,0);
|
||||||
|
|
||||||
|
&Overlay {
|
||||||
|
background-color: rgba(34,41,47,.5);
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,51 +1,97 @@
|
||||||
import './App.scss';
|
import './App.scss';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Switch, Route } from 'react-router-dom';
|
import cx from 'classnames';
|
||||||
|
import { Cluster } from 'generated-sources';
|
||||||
|
import { Switch, Route, useLocation } from 'react-router-dom';
|
||||||
import { GIT_TAG, GIT_COMMIT } from 'lib/constants';
|
import { GIT_TAG, GIT_COMMIT } from 'lib/constants';
|
||||||
import { Alerts } from 'redux/interfaces';
|
import { Alerts } from 'redux/interfaces';
|
||||||
import NavContainer from './Nav/NavContainer';
|
import Nav from './Nav/Nav';
|
||||||
import PageLoader from './common/PageLoader/PageLoader';
|
import PageLoader from './common/PageLoader/PageLoader';
|
||||||
import Dashboard from './Dashboard/Dashboard';
|
import Dashboard from './Dashboard/Dashboard';
|
||||||
import Cluster from './Cluster/Cluster';
|
import ClusterPage from './Cluster/Cluster';
|
||||||
import Version from './Version/Version';
|
import Version from './Version/Version';
|
||||||
import Alert from './Alert/Alert';
|
import Alert from './Alert/Alert';
|
||||||
|
|
||||||
export interface AppProps {
|
export interface AppProps {
|
||||||
isClusterListFetched?: boolean;
|
isClusterListFetched?: boolean;
|
||||||
alerts: Alerts;
|
alerts: Alerts;
|
||||||
|
clusters: Cluster[];
|
||||||
fetchClustersList: () => void;
|
fetchClustersList: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const App: React.FC<AppProps> = ({
|
const App: React.FC<AppProps> = ({
|
||||||
isClusterListFetched,
|
isClusterListFetched,
|
||||||
alerts,
|
alerts,
|
||||||
|
clusters,
|
||||||
fetchClustersList,
|
fetchClustersList,
|
||||||
}) => {
|
}) => {
|
||||||
|
const [isSidebarVisible, setIsSidebarVisible] = React.useState(false);
|
||||||
|
|
||||||
|
const onBurgerClick = React.useCallback(
|
||||||
|
() => setIsSidebarVisible(!isSidebarVisible),
|
||||||
|
[isSidebarVisible]
|
||||||
|
);
|
||||||
|
|
||||||
|
const closeSidebar = React.useCallback(() => setIsSidebarVisible(false), []);
|
||||||
|
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
closeSidebar();
|
||||||
|
}, [location]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
fetchClustersList();
|
fetchClustersList();
|
||||||
}, [fetchClustersList]);
|
}, [fetchClustersList]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="Layout">
|
<div
|
||||||
|
className={cx('Layout', { 'Layout--sidebarVisible': isSidebarVisible })}
|
||||||
|
>
|
||||||
<nav
|
<nav
|
||||||
className="navbar is-fixed-top is-white Layout__header"
|
className="navbar is-fixed-top is-white Layout__header"
|
||||||
role="navigation"
|
role="navigation"
|
||||||
aria-label="main navigation"
|
aria-label="main navigation"
|
||||||
>
|
>
|
||||||
<div className="navbar-brand">
|
<div className="navbar-brand">
|
||||||
|
<div
|
||||||
|
className={cx('navbar-burger', 'ml-0', {
|
||||||
|
'is-active': isSidebarVisible,
|
||||||
|
})}
|
||||||
|
onClick={onBurgerClick}
|
||||||
|
onKeyDown={onBurgerClick}
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
>
|
||||||
|
<span />
|
||||||
|
<span />
|
||||||
|
<span />
|
||||||
|
</div>
|
||||||
|
|
||||||
<a className="navbar-item title is-5 is-marginless" href="/ui">
|
<a className="navbar-item title is-5 is-marginless" href="/ui">
|
||||||
Kafka UI
|
Kafka UI
|
||||||
</a>
|
</a>
|
||||||
</div>
|
|
||||||
<div className="navbar-end">
|
<div className="navbar-item">
|
||||||
<div className="navbar-item mr-2">
|
|
||||||
<Version tag={GIT_TAG} commit={GIT_COMMIT} />
|
<Version tag={GIT_TAG} commit={GIT_COMMIT} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<main className="Layout__container">
|
<main className="Layout__container">
|
||||||
<NavContainer className="Layout__navbar" />
|
<div className="Layout__sidebar has-shadow has-background-white">
|
||||||
|
<Nav
|
||||||
|
clusters={clusters}
|
||||||
|
isClusterListFetched={isClusterListFetched}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="Layout__sidebarOverlay is-overlay"
|
||||||
|
onClick={closeSidebar}
|
||||||
|
onKeyDown={closeSidebar}
|
||||||
|
tabIndex={-1}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
{isClusterListFetched ? (
|
{isClusterListFetched ? (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route
|
<Route
|
||||||
|
@ -53,7 +99,7 @@ const App: React.FC<AppProps> = ({
|
||||||
path={['/', '/ui', '/ui/clusters']}
|
path={['/', '/ui', '/ui/clusters']}
|
||||||
component={Dashboard}
|
component={Dashboard}
|
||||||
/>
|
/>
|
||||||
<Route path="/ui/clusters/:clusterName" component={Cluster} />
|
<Route path="/ui/clusters/:clusterName" component={ClusterPage} />
|
||||||
</Switch>
|
</Switch>
|
||||||
) : (
|
) : (
|
||||||
<PageLoader fullHeight />
|
<PageLoader fullHeight />
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { fetchClustersList } from 'redux/actions';
|
import { fetchClustersList } from 'redux/actions';
|
||||||
import { getIsClusterListFetched } from 'redux/reducers/clusters/selectors';
|
import {
|
||||||
|
getClusterList,
|
||||||
|
getIsClusterListFetched,
|
||||||
|
} from 'redux/reducers/clusters/selectors';
|
||||||
import { getAlerts } from 'redux/reducers/alerts/selectors';
|
import { getAlerts } from 'redux/reducers/alerts/selectors';
|
||||||
import { RootState } from 'redux/interfaces';
|
import { RootState } from 'redux/interfaces';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
|
@ -8,6 +11,7 @@ import App from './App';
|
||||||
const mapStateToProps = (state: RootState) => ({
|
const mapStateToProps = (state: RootState) => ({
|
||||||
isClusterListFetched: getIsClusterListFetched(state),
|
isClusterListFetched: getIsClusterListFetched(state),
|
||||||
alerts: getAlerts(state),
|
alerts: getAlerts(state),
|
||||||
|
clusters: getClusterList(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
|
|
|
@ -7,16 +7,15 @@ import MetricsWrapper from 'components/common/Dashboard/MetricsWrapper';
|
||||||
import Indicator from 'components/common/Dashboard/Indicator';
|
import Indicator from 'components/common/Dashboard/Indicator';
|
||||||
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
|
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
|
||||||
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
|
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
|
||||||
|
import { useParams } from 'react-router';
|
||||||
|
|
||||||
interface Props extends ClusterStats {
|
interface Props extends ClusterStats {
|
||||||
clusterName: ClusterName;
|
|
||||||
isFetched: boolean;
|
isFetched: boolean;
|
||||||
fetchClusterStats: (clusterName: ClusterName) => void;
|
fetchClusterStats: (clusterName: ClusterName) => void;
|
||||||
fetchBrokers: (clusterName: ClusterName) => void;
|
fetchBrokers: (clusterName: ClusterName) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Brokers: React.FC<Props> = ({
|
const Brokers: React.FC<Props> = ({
|
||||||
clusterName,
|
|
||||||
brokerCount,
|
brokerCount,
|
||||||
activeControllers,
|
activeControllers,
|
||||||
zooKeeperStatus,
|
zooKeeperStatus,
|
||||||
|
@ -29,6 +28,8 @@ const Brokers: React.FC<Props> = ({
|
||||||
fetchClusterStats,
|
fetchClusterStats,
|
||||||
fetchBrokers,
|
fetchBrokers,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { clusterName } = useParams<{ clusterName: ClusterName }>();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
fetchClusterStats(clusterName);
|
fetchClusterStats(clusterName);
|
||||||
fetchBrokers(clusterName);
|
fetchBrokers(clusterName);
|
||||||
|
@ -44,9 +45,13 @@ const Brokers: React.FC<Props> = ({
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<Breadcrumb>Brokers overview</Breadcrumb>
|
<Breadcrumb>Brokers overview</Breadcrumb>
|
||||||
<MetricsWrapper title="Uptime">
|
<MetricsWrapper title="Uptime">
|
||||||
<Indicator label="Total Brokers">{brokerCount}</Indicator>
|
<Indicator className="is-one-third" label="Total Brokers">
|
||||||
<Indicator label="Active Controllers">{activeControllers}</Indicator>
|
{brokerCount}
|
||||||
<Indicator label="Zookeeper Status">
|
</Indicator>
|
||||||
|
<Indicator className="is-one-third" label="Active Controllers">
|
||||||
|
{activeControllers}
|
||||||
|
</Indicator>
|
||||||
|
<Indicator className="is-one-third" label="Zookeeper Status">
|
||||||
<span className={cx('tag', zkOnline ? 'is-primary' : 'is-danger')}>
|
<span className={cx('tag', zkOnline ? 'is-primary' : 'is-danger')}>
|
||||||
{zkOnline ? 'Online' : 'Offline'}
|
{zkOnline ? 'Online' : 'Offline'}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,43 +1,36 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { fetchClusterStats, fetchBrokers } from 'redux/actions';
|
import { fetchClusterStats, fetchBrokers } from 'redux/actions';
|
||||||
import * as brokerSelectors from 'redux/reducers/brokers/selectors';
|
import { RootState } from 'redux/interfaces';
|
||||||
import { RootState, ClusterName } from 'redux/interfaces';
|
import {
|
||||||
import { RouteComponentProps } from 'react-router-dom';
|
getIsBrokerListFetched,
|
||||||
|
getBrokerCount,
|
||||||
|
getZooKeeperStatus,
|
||||||
|
getActiveControllers,
|
||||||
|
getOnlinePartitionCount,
|
||||||
|
getOfflinePartitionCount,
|
||||||
|
getInSyncReplicasCount,
|
||||||
|
getOutOfSyncReplicasCount,
|
||||||
|
getUnderReplicatedPartitionCount,
|
||||||
|
getDiskUsage,
|
||||||
|
} from 'redux/reducers/brokers/selectors';
|
||||||
import Brokers from './Brokers';
|
import Brokers from './Brokers';
|
||||||
|
|
||||||
interface RouteProps {
|
const mapStateToProps = (state: RootState) => ({
|
||||||
clusterName: ClusterName;
|
isFetched: getIsBrokerListFetched(state),
|
||||||
}
|
brokerCount: getBrokerCount(state),
|
||||||
|
zooKeeperStatus: getZooKeeperStatus(state),
|
||||||
type OwnProps = RouteComponentProps<RouteProps>;
|
activeControllers: getActiveControllers(state),
|
||||||
|
onlinePartitionCount: getOnlinePartitionCount(state),
|
||||||
const mapStateToProps = (
|
offlinePartitionCount: getOfflinePartitionCount(state),
|
||||||
state: RootState,
|
inSyncReplicasCount: getInSyncReplicasCount(state),
|
||||||
{
|
outOfSyncReplicasCount: getOutOfSyncReplicasCount(state),
|
||||||
match: {
|
underReplicatedPartitionCount: getUnderReplicatedPartitionCount(state),
|
||||||
params: { clusterName },
|
diskUsage: getDiskUsage(state),
|
||||||
},
|
|
||||||
}: OwnProps
|
|
||||||
) => ({
|
|
||||||
isFetched: brokerSelectors.getIsBrokerListFetched(state),
|
|
||||||
clusterName,
|
|
||||||
brokerCount: brokerSelectors.getBrokerCount(state),
|
|
||||||
zooKeeperStatus: brokerSelectors.getZooKeeperStatus(state),
|
|
||||||
activeControllers: brokerSelectors.getActiveControllers(state),
|
|
||||||
onlinePartitionCount: brokerSelectors.getOnlinePartitionCount(state),
|
|
||||||
offlinePartitionCount: brokerSelectors.getOfflinePartitionCount(state),
|
|
||||||
inSyncReplicasCount: brokerSelectors.getInSyncReplicasCount(state),
|
|
||||||
outOfSyncReplicasCount: brokerSelectors.getOutOfSyncReplicasCount(state),
|
|
||||||
underReplicatedPartitionCount: brokerSelectors.getUnderReplicatedPartitionCount(
|
|
||||||
state
|
|
||||||
),
|
|
||||||
diskUsage: brokerSelectors.getDiskUsage(state),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
fetchClusterStats: (clusterName: ClusterName) =>
|
fetchClusterStats,
|
||||||
fetchClusterStats(clusterName),
|
fetchBrokers,
|
||||||
fetchBrokers: (clusterName: ClusterName) => fetchBrokers(clusterName),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(Brokers);
|
export default connect(mapStateToProps, mapDispatchToProps)(Brokers);
|
||||||
|
|
|
@ -57,6 +57,7 @@ const List: React.FC<ListProps> = ({
|
||||||
<PageLoader />
|
<PageLoader />
|
||||||
) : (
|
) : (
|
||||||
<div className="box">
|
<div className="box">
|
||||||
|
<div className="table-container">
|
||||||
<table className="table is-fullwidth">
|
<table className="table is-fullwidth">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -79,6 +80,7 @@ const List: React.FC<ListProps> = ({
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -54,6 +54,7 @@ const Details: React.FC<Props> = ({
|
||||||
|
|
||||||
{isFetched ? (
|
{isFetched ? (
|
||||||
<div className="box">
|
<div className="box">
|
||||||
|
<div className="table-container">
|
||||||
<table className="table is-striped is-fullwidth">
|
<table className="table is-striped is-fullwidth">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -77,6 +78,7 @@ const Details: React.FC<Props> = ({
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<PageLoader />
|
<PageLoader />
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -36,6 +36,7 @@ const List: React.FC<Props> = ({ consumerGroups }) => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="table-container">
|
||||||
<table className="table is-striped is-fullwidth is-hoverable">
|
<table className="table is-striped is-fullwidth is-hoverable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -60,6 +61,7 @@ const List: React.FC<Props> = ({ consumerGroups }) => {
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
'No active consumer groups'
|
'No active consumer groups'
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { Cluster } from 'generated-sources';
|
||||||
import ClusterMenu from './ClusterMenu';
|
import ClusterMenu from './ClusterMenu';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isClusterListFetched: boolean;
|
isClusterListFetched?: boolean;
|
||||||
clusters: Cluster[];
|
clusters: Cluster[];
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import {
|
|
||||||
getIsClusterListFetched,
|
|
||||||
getClusterList,
|
|
||||||
} from 'redux/reducers/clusters/selectors';
|
|
||||||
import { RootState } from 'redux/interfaces';
|
|
||||||
import Nav from './Nav';
|
|
||||||
|
|
||||||
const mapStateToProps = (state: RootState) => ({
|
|
||||||
isClusterListFetched: getIsClusterListFetched(state),
|
|
||||||
clusters: getClusterList(state),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(Nav);
|
|
21
kafka-ui-react-app/src/components/Nav/__tests__/Nav.spec.tsx
Normal file
21
kafka-ui-react-app/src/components/Nav/__tests__/Nav.spec.tsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import { onlineClusterPayload } from 'redux/reducers/clusters/__test__/fixtures';
|
||||||
|
import Nav from '../Nav';
|
||||||
|
|
||||||
|
describe('Nav', () => {
|
||||||
|
it('renders loader', () => {
|
||||||
|
const wrapper = shallow(<Nav clusters={[]} />);
|
||||||
|
expect(wrapper.find('.loader')).toBeTruthy();
|
||||||
|
expect(wrapper.exists('ClusterMenu')).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders ClusterMenu', () => {
|
||||||
|
const wrapper = shallow(
|
||||||
|
<Nav clusters={[onlineClusterPayload]} isClusterListFetched />
|
||||||
|
);
|
||||||
|
expect(wrapper.exists('.loader')).toBeFalsy();
|
||||||
|
expect(wrapper.exists('ClusterMenu')).toBeTruthy();
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Nav renders ClusterMenu 1`] = `
|
||||||
|
<aside
|
||||||
|
className="menu has-shadow has-background-white"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
className="menu-label"
|
||||||
|
>
|
||||||
|
General
|
||||||
|
</p>
|
||||||
|
<ul
|
||||||
|
className="menu-list"
|
||||||
|
>
|
||||||
|
<li>
|
||||||
|
<NavLink
|
||||||
|
activeClassName="is-active"
|
||||||
|
exact={true}
|
||||||
|
title="Dashboard"
|
||||||
|
to="/ui"
|
||||||
|
>
|
||||||
|
Dashboard
|
||||||
|
</NavLink>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p
|
||||||
|
className="menu-label"
|
||||||
|
>
|
||||||
|
Clusters
|
||||||
|
</p>
|
||||||
|
<ClusterMenu
|
||||||
|
cluster={
|
||||||
|
Object {
|
||||||
|
"brokerCount": 1,
|
||||||
|
"bytesInPerSec": 1.55,
|
||||||
|
"bytesOutPerSec": 9.314,
|
||||||
|
"defaultCluster": true,
|
||||||
|
"features": Array [],
|
||||||
|
"name": "secondLocal",
|
||||||
|
"onlinePartitionCount": 6,
|
||||||
|
"status": "online",
|
||||||
|
"topicCount": 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
key="secondLocal"
|
||||||
|
/>
|
||||||
|
</aside>
|
||||||
|
`;
|
|
@ -85,6 +85,7 @@ const Details: React.FC<DetailsProps> = ({
|
||||||
<LatestVersionItem schema={schema} />
|
<LatestVersionItem schema={schema} />
|
||||||
</div>
|
</div>
|
||||||
<div className="box">
|
<div className="box">
|
||||||
|
<div className="table-container">
|
||||||
<table className="table is-striped is-fullwidth">
|
<table className="table is-striped is-fullwidth">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -100,6 +101,7 @@ const Details: React.FC<DetailsProps> = ({
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<PageLoader />
|
<PageLoader />
|
||||||
|
|
|
@ -12,6 +12,7 @@ const LatestVersionItem: React.FC<LatestVersionProps> = ({
|
||||||
<div className="tile is-ancestor mt-1">
|
<div className="tile is-ancestor mt-1">
|
||||||
<div className="tile is-4 is-parent">
|
<div className="tile is-4 is-parent">
|
||||||
<div className="tile is-child">
|
<div className="tile is-child">
|
||||||
|
<div className="table-container">
|
||||||
<table className="table is-fullwidth">
|
<table className="table is-fullwidth">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -30,6 +31,7 @@ const LatestVersionItem: React.FC<LatestVersionProps> = ({
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div className="tile is-parent">
|
<div className="tile is-parent">
|
||||||
<div className="tile is-child box py-1">
|
<div className="tile is-child box py-1">
|
||||||
<JSONViewer data={JSON.parse(schema)} />
|
<JSONViewer data={JSON.parse(schema)} />
|
||||||
|
|
|
@ -84,6 +84,9 @@ exports[`Details View Initial state matches snapshot 1`] = `
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="box"
|
className="box"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="table-container"
|
||||||
>
|
>
|
||||||
<table
|
<table
|
||||||
className="table is-striped is-fullwidth"
|
className="table is-striped is-fullwidth"
|
||||||
|
@ -105,6 +108,7 @@ exports[`Details View Initial state matches snapshot 1`] = `
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Details View when page with schema versions is loading matches snapshot 1`] = `
|
exports[`Details View when page with schema versions is loading matches snapshot 1`] = `
|
||||||
|
@ -215,6 +219,9 @@ exports[`Details View when page with schema versions loaded when schema has vers
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="box"
|
className="box"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="table-container"
|
||||||
>
|
>
|
||||||
<table
|
<table
|
||||||
className="table is-striped is-fullwidth"
|
className="table is-striped is-fullwidth"
|
||||||
|
@ -263,6 +270,7 @@ exports[`Details View when page with schema versions loaded when schema has vers
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Details View when page with schema versions loaded when versions are empty matches snapshot 1`] = `
|
exports[`Details View when page with schema versions loaded when versions are empty matches snapshot 1`] = `
|
||||||
|
@ -349,6 +357,9 @@ exports[`Details View when page with schema versions loaded when versions are em
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="box"
|
className="box"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="table-container"
|
||||||
>
|
>
|
||||||
<table
|
<table
|
||||||
className="table is-striped is-fullwidth"
|
className="table is-striped is-fullwidth"
|
||||||
|
@ -370,4 +381,5 @@ exports[`Details View when page with schema versions loaded when versions are em
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -9,6 +9,9 @@ exports[`LatestVersionItem matches snapshot 1`] = `
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="tile is-child"
|
className="tile is-child"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="table-container"
|
||||||
>
|
>
|
||||||
<table
|
<table
|
||||||
className="table is-fullwidth"
|
className="table is-fullwidth"
|
||||||
|
@ -42,6 +45,7 @@ exports[`LatestVersionItem matches snapshot 1`] = `
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
className="tile is-parent"
|
className="tile is-parent"
|
||||||
>
|
>
|
||||||
|
|
|
@ -48,6 +48,7 @@ const List: React.FC<ListProps> = ({
|
||||||
<PageLoader />
|
<PageLoader />
|
||||||
) : (
|
) : (
|
||||||
<div className="box">
|
<div className="box">
|
||||||
|
<div className="table-container">
|
||||||
<table className="table is-striped is-fullwidth">
|
<table className="table is-striped is-fullwidth">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -68,6 +69,7 @@ const List: React.FC<ListProps> = ({
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -81,6 +81,7 @@ const List: React.FC<Props> = ({
|
||||||
<PageLoader />
|
<PageLoader />
|
||||||
) : (
|
) : (
|
||||||
<div className="box">
|
<div className="box">
|
||||||
|
<div className="table-container">
|
||||||
<table className="table is-fullwidth">
|
<table className="table is-fullwidth">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -109,6 +110,7 @@ const List: React.FC<Props> = ({
|
||||||
</table>
|
</table>
|
||||||
<Pagination totalPages={totalPages} />
|
<Pagination totalPages={totalPages} />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -37,7 +37,7 @@ const ListItem: React.FC<ListItemProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td className="has-text-overflow-ellipsis">
|
||||||
<NavLink
|
<NavLink
|
||||||
exact
|
exact
|
||||||
to={`topics/${name}`}
|
to={`topics/${name}`}
|
||||||
|
|
|
@ -15,6 +15,7 @@ const MessagesTable: React.FC<MessagesTableProp> = ({ messages, onNext }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<div className="table-container">
|
||||||
<table className="table is-fullwidth">
|
<table className="table is-fullwidth">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -39,6 +40,7 @@ const MessagesTable: React.FC<MessagesTableProp> = ({ messages, onNext }) => {
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
<div className="columns">
|
<div className="columns">
|
||||||
<div className="column is-full">
|
<div className="column is-full">
|
||||||
<CustomParamButton
|
<CustomParamButton
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
exports[`MessagesTable when topic contains messages matches snapshot 1`] = `
|
exports[`MessagesTable when topic contains messages matches snapshot 1`] = `
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
<div
|
||||||
|
className="table-container"
|
||||||
|
>
|
||||||
<table
|
<table
|
||||||
className="table is-fullwidth"
|
className="table is-fullwidth"
|
||||||
>
|
>
|
||||||
|
@ -45,6 +48,7 @@ exports[`MessagesTable when topic contains messages matches snapshot 1`] = `
|
||||||
/>
|
/>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
className="columns"
|
className="columns"
|
||||||
>
|
>
|
||||||
|
|
|
@ -43,6 +43,7 @@ const Overview: React.FC<Props> = ({
|
||||||
<Indicator label="Segment count">{segmentCount}</Indicator>
|
<Indicator label="Segment count">{segmentCount}</Indicator>
|
||||||
</MetricsWrapper>
|
</MetricsWrapper>
|
||||||
<div className="box">
|
<div className="box">
|
||||||
|
<div className="table-container">
|
||||||
<table className="table is-striped is-fullwidth">
|
<table className="table is-striped is-fullwidth">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -64,6 +65,7 @@ const Overview: React.FC<Props> = ({
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ const Settings: React.FC<Props> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="box">
|
<div className="box">
|
||||||
|
<div className="table-container">
|
||||||
<table className="table is-striped is-fullwidth">
|
<table className="table is-striped is-fullwidth">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -62,6 +63,7 @@ const Settings: React.FC<Props> = ({
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,61 +1,79 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount, shallow } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { StaticRouter } from 'react-router-dom';
|
import { StaticRouter } from 'react-router-dom';
|
||||||
|
import { Alert } from 'redux/interfaces';
|
||||||
import configureStore from 'redux/store/configureStore';
|
import configureStore from 'redux/store/configureStore';
|
||||||
import App, { AppProps } from '../App';
|
import App, { AppProps } from 'components/App';
|
||||||
|
import AppContainer from 'components/AppContainer';
|
||||||
|
|
||||||
const fetchClustersList = jest.fn();
|
const fetchClustersList = jest.fn();
|
||||||
const store = configureStore();
|
const store = configureStore();
|
||||||
|
|
||||||
describe('App', () => {
|
describe('App', () => {
|
||||||
|
describe('container', () => {
|
||||||
|
it('renders view', () => {
|
||||||
|
const wrapper = mount(
|
||||||
|
<Provider store={store}>
|
||||||
|
<StaticRouter>
|
||||||
|
<AppContainer />
|
||||||
|
</StaticRouter>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
expect(wrapper.exists('App')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('view', () => {
|
||||||
const setupComponent = (props: Partial<AppProps> = {}) => (
|
const setupComponent = (props: Partial<AppProps> = {}) => (
|
||||||
|
<Provider store={store}>
|
||||||
|
<StaticRouter>
|
||||||
<App
|
<App
|
||||||
isClusterListFetched
|
isClusterListFetched
|
||||||
alerts={[]}
|
alerts={[]}
|
||||||
|
clusters={[]}
|
||||||
fetchClustersList={fetchClustersList}
|
fetchClustersList={fetchClustersList}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
</StaticRouter>
|
||||||
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
||||||
it('handles fetchClustersList', () => {
|
it('handles fetchClustersList', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mount(setupComponent());
|
||||||
<Provider store={store}>
|
|
||||||
<StaticRouter>{setupComponent()}</StaticRouter>
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
expect(wrapper.exists()).toBeTruthy();
|
expect(wrapper.exists()).toBeTruthy();
|
||||||
expect(fetchClustersList).toHaveBeenCalledTimes(1);
|
expect(fetchClustersList).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows PageLoader until cluster list is fetched', () => {
|
it('shows PageLoader until cluster list is fetched', () => {
|
||||||
const component = shallow(setupComponent({ isClusterListFetched: false }));
|
let component = mount(setupComponent({ isClusterListFetched: false }));
|
||||||
expect(component.exists('.Layout__container PageLoader')).toBeTruthy();
|
expect(component.exists('.Layout__container PageLoader')).toBeTruthy();
|
||||||
expect(component.exists('.Layout__container Switch')).toBeFalsy();
|
expect(component.exists('.Layout__container Switch')).toBeFalsy();
|
||||||
component.setProps({ isClusterListFetched: true });
|
|
||||||
|
component = mount(setupComponent({ isClusterListFetched: true }));
|
||||||
expect(component.exists('.Layout__container PageLoader')).toBeFalsy();
|
expect(component.exists('.Layout__container PageLoader')).toBeFalsy();
|
||||||
expect(component.exists('.Layout__container Switch')).toBeTruthy();
|
expect(component.exists('.Layout__container Switch')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('correctly renders alerts', () => {
|
it('correctly renders alerts', () => {
|
||||||
const alert = {
|
const alert: Alert = {
|
||||||
id: 'alert-id',
|
id: 'alert-id',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
title: 'My Custom Title',
|
title: 'My Custom Title',
|
||||||
message: 'My Custom Message',
|
message: 'My Custom Message',
|
||||||
createdAt: 1234567890,
|
createdAt: 1234567890,
|
||||||
};
|
};
|
||||||
const wrapper = shallow(setupComponent());
|
let wrapper = mount(setupComponent());
|
||||||
expect(wrapper.exists('.Layout__alerts')).toBeTruthy();
|
expect(wrapper.exists('.Layout__alerts')).toBeTruthy();
|
||||||
expect(wrapper.exists('Alert')).toBeFalsy();
|
expect(wrapper.exists('Alert')).toBeFalsy();
|
||||||
|
|
||||||
wrapper.setProps({ alerts: [alert] });
|
wrapper = mount(setupComponent({ alerts: [alert] }));
|
||||||
expect(wrapper.exists('Alert')).toBeTruthy();
|
expect(wrapper.exists('Alert')).toBeTruthy();
|
||||||
expect(wrapper.find('Alert').length).toEqual(1);
|
expect(wrapper.find('Alert').length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('matches snapshot', () => {
|
it('matches snapshot', () => {
|
||||||
const component = shallow(setupComponent());
|
const wrapper = mount(setupComponent());
|
||||||
expect(component).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,58 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`App matches snapshot 1`] = `
|
exports[`App view matches snapshot 1`] = `
|
||||||
|
<Provider
|
||||||
|
store={
|
||||||
|
Object {
|
||||||
|
"dispatch": [Function],
|
||||||
|
"getState": [Function],
|
||||||
|
"replaceReducer": [Function],
|
||||||
|
"subscribe": [Function],
|
||||||
|
Symbol(observable): [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<StaticRouter>
|
||||||
|
<Router
|
||||||
|
history={
|
||||||
|
Object {
|
||||||
|
"action": "POP",
|
||||||
|
"block": [Function],
|
||||||
|
"createHref": [Function],
|
||||||
|
"go": [Function],
|
||||||
|
"goBack": [Function],
|
||||||
|
"goForward": [Function],
|
||||||
|
"listen": [Function],
|
||||||
|
"location": Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/",
|
||||||
|
"search": "",
|
||||||
|
"state": undefined,
|
||||||
|
},
|
||||||
|
"push": [Function],
|
||||||
|
"replace": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
staticContext={Object {}}
|
||||||
|
>
|
||||||
|
<App
|
||||||
|
alerts={Array []}
|
||||||
|
clusters={Array []}
|
||||||
|
fetchClustersList={
|
||||||
|
[MockFunction] {
|
||||||
|
"calls": Array [
|
||||||
|
Array [],
|
||||||
|
],
|
||||||
|
"results": Array [
|
||||||
|
Object {
|
||||||
|
"type": "return",
|
||||||
|
"value": undefined,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isClusterListFetched={true}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
className="Layout"
|
className="Layout"
|
||||||
>
|
>
|
||||||
|
@ -12,18 +64,25 @@ exports[`App matches snapshot 1`] = `
|
||||||
<div
|
<div
|
||||||
className="navbar-brand"
|
className="navbar-brand"
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
className="navbar-burger ml-0"
|
||||||
|
onClick={[Function]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
>
|
||||||
|
<span />
|
||||||
|
<span />
|
||||||
|
<span />
|
||||||
|
</div>
|
||||||
<a
|
<a
|
||||||
className="navbar-item title is-5 is-marginless"
|
className="navbar-item title is-5 is-marginless"
|
||||||
href="/ui"
|
href="/ui"
|
||||||
>
|
>
|
||||||
Kafka UI
|
Kafka UI
|
||||||
</a>
|
</a>
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
className="navbar-end"
|
className="navbar-item"
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="navbar-item mr-2"
|
|
||||||
>
|
>
|
||||||
<Version />
|
<Version />
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,13 +91,97 @@ exports[`App matches snapshot 1`] = `
|
||||||
<main
|
<main
|
||||||
className="Layout__container"
|
className="Layout__container"
|
||||||
>
|
>
|
||||||
<Connect(Nav)
|
<div
|
||||||
className="Layout__navbar"
|
className="Layout__sidebar has-shadow has-background-white"
|
||||||
|
>
|
||||||
|
<Nav
|
||||||
|
clusters={Array []}
|
||||||
|
isClusterListFetched={true}
|
||||||
|
>
|
||||||
|
<aside
|
||||||
|
className="menu has-shadow has-background-white"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
className="menu-label"
|
||||||
|
>
|
||||||
|
General
|
||||||
|
</p>
|
||||||
|
<ul
|
||||||
|
className="menu-list"
|
||||||
|
>
|
||||||
|
<li>
|
||||||
|
<NavLink
|
||||||
|
activeClassName="is-active"
|
||||||
|
exact={true}
|
||||||
|
title="Dashboard"
|
||||||
|
to="/ui"
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
aria-current={null}
|
||||||
|
title="Dashboard"
|
||||||
|
to={
|
||||||
|
Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/ui",
|
||||||
|
"search": "",
|
||||||
|
"state": null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<LinkAnchor
|
||||||
|
aria-current={null}
|
||||||
|
href="/ui"
|
||||||
|
navigate={[Function]}
|
||||||
|
title="Dashboard"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
aria-current={null}
|
||||||
|
href="/ui"
|
||||||
|
onClick={[Function]}
|
||||||
|
title="Dashboard"
|
||||||
|
>
|
||||||
|
Dashboard
|
||||||
|
</a>
|
||||||
|
</LinkAnchor>
|
||||||
|
</Link>
|
||||||
|
</NavLink>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p
|
||||||
|
className="menu-label"
|
||||||
|
>
|
||||||
|
Clusters
|
||||||
|
</p>
|
||||||
|
</aside>
|
||||||
|
</Nav>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
aria-hidden="true"
|
||||||
|
className="Layout__sidebarOverlay is-overlay"
|
||||||
|
onClick={[Function]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
tabIndex={-1}
|
||||||
/>
|
/>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route
|
<Route
|
||||||
component={[Function]}
|
component={[Function]}
|
||||||
|
computedMatch={
|
||||||
|
Object {
|
||||||
|
"isExact": true,
|
||||||
|
"params": Object {},
|
||||||
|
"path": "/",
|
||||||
|
"url": "/",
|
||||||
|
}
|
||||||
|
}
|
||||||
exact={true}
|
exact={true}
|
||||||
|
location={
|
||||||
|
Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/",
|
||||||
|
"search": "",
|
||||||
|
"state": undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
path={
|
path={
|
||||||
Array [
|
Array [
|
||||||
"/",
|
"/",
|
||||||
|
@ -46,15 +189,195 @@ exports[`App matches snapshot 1`] = `
|
||||||
"/ui/clusters",
|
"/ui/clusters",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
>
|
||||||
|
<Dashboard
|
||||||
|
history={
|
||||||
|
Object {
|
||||||
|
"action": "POP",
|
||||||
|
"block": [Function],
|
||||||
|
"createHref": [Function],
|
||||||
|
"go": [Function],
|
||||||
|
"goBack": [Function],
|
||||||
|
"goForward": [Function],
|
||||||
|
"listen": [Function],
|
||||||
|
"location": Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/",
|
||||||
|
"search": "",
|
||||||
|
"state": undefined,
|
||||||
|
},
|
||||||
|
"push": [Function],
|
||||||
|
"replace": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
location={
|
||||||
|
Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/",
|
||||||
|
"search": "",
|
||||||
|
"state": undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match={
|
||||||
|
Object {
|
||||||
|
"isExact": true,
|
||||||
|
"params": Object {},
|
||||||
|
"path": "/",
|
||||||
|
"url": "/",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
staticContext={Object {}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="section"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="level"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="level-item level-left"
|
||||||
|
>
|
||||||
|
<Breadcrumb>
|
||||||
|
<nav
|
||||||
|
aria-label="breadcrumbs"
|
||||||
|
className="breadcrumb"
|
||||||
|
>
|
||||||
|
<ul>
|
||||||
|
<li
|
||||||
|
className="is-active"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
Dashboard
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</Breadcrumb>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Connect(ClustersWidget)>
|
||||||
|
<ClustersWidget
|
||||||
|
clusters={Array []}
|
||||||
|
dispatch={[Function]}
|
||||||
|
offlineClusters={Array []}
|
||||||
|
onlineClusters={Array []}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<h5
|
||||||
|
className="title is-5"
|
||||||
|
>
|
||||||
|
Clusters
|
||||||
|
</h5>
|
||||||
|
<MetricsWrapper>
|
||||||
|
<div
|
||||||
|
className="box"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="level"
|
||||||
|
>
|
||||||
|
<Indicator
|
||||||
|
label="Online Clusters"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="level-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
title="Online Clusters"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
className="heading"
|
||||||
|
>
|
||||||
|
Online Clusters
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
className="title has-text-centered"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="tag is-primary"
|
||||||
|
>
|
||||||
|
0
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Indicator>
|
||||||
|
<Indicator
|
||||||
|
label="Offline Clusters"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="level-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
title="Offline Clusters"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
className="heading"
|
||||||
|
>
|
||||||
|
Offline Clusters
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
className="title has-text-centered"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="tag is-danger"
|
||||||
|
>
|
||||||
|
0
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Indicator>
|
||||||
|
<Indicator
|
||||||
|
label="Hide online clusters"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="level-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
title="Hide online clusters"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
className="heading"
|
||||||
|
>
|
||||||
|
Hide online clusters
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
className="title has-text-centered"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
checked={false}
|
||||||
|
className="switch is-rounded"
|
||||||
|
id="switchRoundedDefault"
|
||||||
|
name="switchRoundedDefault"
|
||||||
|
onChange={[Function]}
|
||||||
|
type="checkbox"
|
||||||
/>
|
/>
|
||||||
<Route
|
<label
|
||||||
component={[Function]}
|
htmlFor="switchRoundedDefault"
|
||||||
path="/ui/clusters/:clusterName"
|
|
||||||
/>
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Indicator>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</MetricsWrapper>
|
||||||
|
</div>
|
||||||
|
</ClustersWidget>
|
||||||
|
</Connect(ClustersWidget)>
|
||||||
|
</div>
|
||||||
|
</Dashboard>
|
||||||
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
</main>
|
</main>
|
||||||
<div
|
<div
|
||||||
className="Layout__alerts"
|
className="Layout__alerts"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</App>
|
||||||
|
</Router>
|
||||||
|
</StaticRouter>
|
||||||
|
</Provider>
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -16,7 +16,7 @@ const Indicator: React.FC<Props> = ({
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className={cx('level-item', 'level-left', className)}>
|
<div className={cx('level-item', className)}>
|
||||||
<div title={title || label}>
|
<div title={title || label}>
|
||||||
<p className="heading">{label}</p>
|
<p className="heading">{label}</p>
|
||||||
<p className="title has-text-centered">
|
<p className="title has-text-centered">
|
||||||
|
|
|
@ -6,7 +6,7 @@ exports[`Indicator matches the snapshot 1`] = `
|
||||||
title="title"
|
title="title"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="level-item level-left"
|
className="level-item"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
title="title"
|
title="title"
|
||||||
|
|
Loading…
Add table
Reference in a new issue