Skip to content

Commit

Permalink
[Stack Monitoring] Migrate Index Views to React (#113660) (#113784)
Browse files Browse the repository at this point in the history
* index views

* fix type

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Sandra G <neptunian@users.noreply.github.com>
  • Loading branch information
kibanamachine and neptunian authored Oct 4, 2021
1 parent cef53a9 commit 9f685ef
Show file tree
Hide file tree
Showing 7 changed files with 335 additions and 32 deletions.
17 changes: 17 additions & 0 deletions x-pack/plugins/monitoring/public/application/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import { KibanaOverviewPage } from './pages/kibana/overview';
import { CODE_PATH_ELASTICSEARCH, CODE_PATH_BEATS, CODE_PATH_KIBANA } from '../../common/constants';
import { ElasticsearchNodesPage } from './pages/elasticsearch/nodes_page';
import { ElasticsearchIndicesPage } from './pages/elasticsearch/indices_page';
import { ElasticsearchIndexPage } from './pages/elasticsearch/index_page';
import { ElasticsearchIndexAdvancedPage } from './pages/elasticsearch/index_advanced_page';
import { ElasticsearchNodePage } from './pages/elasticsearch/node_page';
import { MonitoringTimeContainer } from './hooks/use_monitoring_time';
import { BreadcrumbContainer } from './hooks/use_breadcrumbs';
Expand Down Expand Up @@ -84,6 +86,21 @@ const MonitoringApp: React.FC<{
/>

{/* ElasticSearch Views */}

<RouteInit
path="/elasticsearch/indices/:index/advanced"
component={ElasticsearchIndexAdvancedPage}
codePaths={[CODE_PATH_ELASTICSEARCH]}
fetchAllClusters={false}
/>

<RouteInit
path="/elasticsearch/indices/:index"
component={ElasticsearchIndexPage}
codePaths={[CODE_PATH_ELASTICSEARCH]}
fetchAllClusters={false}
/>

<RouteInit
path="/elasticsearch/indices"
component={ElasticsearchIndicesPage}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useContext, useState, useCallback } from 'react';
import { i18n } from '@kbn/i18n';
import { useParams } from 'react-router-dom';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
import { GlobalStateContext } from '../../global_state_context';
import { ComponentProps } from '../../route_init';
import { SetupModeRenderer } from '../../setup_mode/setup_mode_renderer';
import { SetupModeContext } from '../../../components/setup_mode/setup_mode_context';
import { useCharts } from '../../hooks/use_charts';
import { ItemTemplate } from './item_template';
// @ts-ignore
import { AdvancedIndex } from '../../../components/elasticsearch/index/advanced';

interface SetupModeProps {
setupMode: any;
flyoutComponent: any;
bottomBarComponent: any;
}

export const ElasticsearchIndexAdvancedPage: React.FC<ComponentProps> = ({ clusters }) => {
const globalState = useContext(GlobalStateContext);
const { services } = useKibana<{ data: any }>();
const { index }: { index: string } = useParams();
const { zoomInfo, onBrush } = useCharts();
const clusterUuid = globalState.cluster_uuid;
const [data, setData] = useState({} as any);

const title = i18n.translate('xpack.monitoring.elasticsearch.index.advanced.title', {
defaultMessage: 'Elasticsearch - Indices - {indexName} - Advanced',
values: {
indexName: index,
},
});

const getPageData = useCallback(async () => {
const bounds = services.data?.query.timefilter.timefilter.getBounds();
const url = `../api/monitoring/v1/clusters/${clusterUuid}/elasticsearch/indices/${index}`;
const response = await services.http?.fetch(url, {
method: 'POST',
body: JSON.stringify({
timeRange: {
min: bounds.min.toISOString(),
max: bounds.max.toISOString(),
},
is_advanced: true,
}),
});
setData(response);
}, [clusterUuid, services.data?.query.timefilter.timefilter, services.http, index]);

return (
<ItemTemplate title={title} getPageData={getPageData} id={index} pageType="indices">
<SetupModeRenderer
render={({ setupMode, flyoutComponent, bottomBarComponent }: SetupModeProps) => (
<SetupModeContext.Provider value={{ setupModeSupported: true }}>
{flyoutComponent}
<AdvancedIndex
setupMode={setupMode}
alerts={{}}
indexSummary={data.indexSummary}
metrics={data.metrics}
onBrush={onBrush}
zoomInfo={zoomInfo}
/>
{bottomBarComponent}
</SetupModeContext.Provider>
)}
/>
</ItemTemplate>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useContext, useState, useCallback } from 'react';
import { i18n } from '@kbn/i18n';
import { useParams } from 'react-router-dom';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
import { GlobalStateContext } from '../../global_state_context';
// @ts-ignore
import { IndexReact } from '../../../components/elasticsearch/index/index_react';
import { ComponentProps } from '../../route_init';
import { SetupModeRenderer } from '../../setup_mode/setup_mode_renderer';
import { SetupModeContext } from '../../../components/setup_mode/setup_mode_context';
import { useCharts } from '../../hooks/use_charts';
import { ItemTemplate } from './item_template';
// @ts-ignore
import { indicesByNodes } from '../../../components/elasticsearch/shard_allocation/transformers/indices_by_nodes';
// @ts-ignore
import { labels } from '../../../components/elasticsearch/shard_allocation/lib/labels';

interface SetupModeProps {
setupMode: any;
flyoutComponent: any;
bottomBarComponent: any;
}

export const ElasticsearchIndexPage: React.FC<ComponentProps> = ({ clusters }) => {
const globalState = useContext(GlobalStateContext);
const { services } = useKibana<{ data: any }>();
const { index }: { index: string } = useParams();
const { zoomInfo, onBrush } = useCharts();
const clusterUuid = globalState.cluster_uuid;
const [data, setData] = useState({} as any);
const [indexLabel, setIndexLabel] = useState(labels.index as any);
const [nodesByIndicesData, setNodesByIndicesData] = useState([]);

const title = i18n.translate('xpack.monitoring.elasticsearch.index.overview.title', {
defaultMessage: 'Elasticsearch - Indices - {indexName} - Overview',
values: {
indexName: index,
},
});

const pageTitle = i18n.translate('xpack.monitoring.elasticsearch.index.overview.pageTitle', {
defaultMessage: 'Index: {indexName}',
values: {
indexName: index,
},
});

const getPageData = useCallback(async () => {
const bounds = services.data?.query.timefilter.timefilter.getBounds();
const url = `../api/monitoring/v1/clusters/${clusterUuid}/elasticsearch/indices/${index}`;
const response = await services.http?.fetch(url, {
method: 'POST',
body: JSON.stringify({
timeRange: {
min: bounds.min.toISOString(),
max: bounds.max.toISOString(),
},
is_advanced: false,
}),
});
setData(response);
const transformer = indicesByNodes();
setNodesByIndicesData(transformer(response.shards, response.nodes));

const shards = response.shards;
if (shards.some((shard: any) => shard.state === 'UNASSIGNED')) {
setIndexLabel(labels.indexWithUnassigned);
}
}, [clusterUuid, services.data?.query.timefilter.timefilter, services.http, index]);

return (
<ItemTemplate
title={title}
pageTitle={pageTitle}
getPageData={getPageData}
id={index}
pageType="indices"
>
<SetupModeRenderer
render={({ setupMode, flyoutComponent, bottomBarComponent }: SetupModeProps) => (
<SetupModeContext.Provider value={{ setupModeSupported: true }}>
{flyoutComponent}
<IndexReact
setupMode={setupMode}
labels={indexLabel}
alerts={{}}
onBrush={onBrush}
indexUuid={index}
clusterUuid={clusterUuid}
zoomInfo={zoomInfo}
nodesByIndices={nodesByIndicesData}
{...data}
/>
{bottomBarComponent}
</SetupModeContext.Provider>
)}
/>
</ItemTemplate>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { i18n } from '@kbn/i18n';
import { PageTemplate } from '../page_template';
import { TabMenuItem, PageTemplateProps } from '../page_template';

interface ItemTemplateProps extends PageTemplateProps {
id: string;
pageType: string;
}
export const ItemTemplate: React.FC<ItemTemplateProps> = (props) => {
const { pageType, id, ...rest } = props;
const tabs: TabMenuItem[] = [
{
id: 'overview',
label: i18n.translate('xpack.monitoring.esItemNavigation.overviewLinkText', {
defaultMessage: 'Overview',
}),
route: `/elasticsearch/${pageType}/${id}`,
},
{
id: 'advanced',
label: i18n.translate('xpack.monitoring.esItemNavigation.advancedLinkText', {
defaultMessage: 'Advanced',
}),
route: `/elasticsearch/${pageType}/${id}/advanced`,
},
];

return <PageTemplate {...rest} tabs={tabs} product="elasticsearch" />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
import React, { useContext, useState, useCallback } from 'react';
import { useParams } from 'react-router-dom';
import { i18n } from '@kbn/i18n';
import { find } from 'lodash';
import { ElasticsearchTemplate } from './elasticsearch_template';
import { ItemTemplate } from './item_template';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
import { GlobalStateContext } from '../../global_state_context';
import { NodeReact } from '../../../components/elasticsearch';
Expand All @@ -18,6 +17,8 @@ import { SetupModeContext } from '../../../components/setup_mode/setup_mode_cont
import { useLocalStorage } from '../../hooks/use_local_storage';
import { useCharts } from '../../hooks/use_charts';
import { nodesByIndices } from '../../../components/elasticsearch/shard_allocation/transformers/nodes_by_indices';
// @ts-ignore
import { labels } from '../../../components/elasticsearch/shard_allocation/lib/labels';

interface SetupModeProps {
setupMode: any;
Expand All @@ -38,9 +39,6 @@ export const ElasticsearchNodePage: React.FC<ComponentProps> = ({ clusters }) =>

const clusterUuid = globalState.cluster_uuid;
const ccs = globalState.ccs;
const cluster = find(clusters, {
cluster_uuid: clusterUuid,
});
const [data, setData] = useState({} as any);
const [nodesByIndicesData, setNodesByIndicesData] = useState([]);

Expand Down Expand Up @@ -92,33 +90,33 @@ export const ElasticsearchNodePage: React.FC<ComponentProps> = ({ clusters }) =>
}, [showSystemIndices, setShowSystemIndices]);

return (
<ElasticsearchTemplate
<ItemTemplate
title={title}
pageTitle={pageTitle}
getPageData={getPageData}
cluster={cluster}
id={node}
pageType="nodes"
>
<div data-test-subj="elasticsearchNodeListingPage">
<SetupModeRenderer
render={({ setupMode, flyoutComponent, bottomBarComponent }: SetupModeProps) => (
<SetupModeContext.Provider value={{ setupModeSupported: true }}>
{flyoutComponent}
<NodeReact
alerts={{}}
nodeId={node}
clusterUuid={clusterUuid}
onBrush={onBrush}
zoomInfo={zoomInfo}
toggleShowSystemIndices={toggleShowSystemIndices}
showSystemIndices={showSystemIndices}
nodesByIndices={nodesByIndicesData}
{...data}
/>
{bottomBarComponent}
</SetupModeContext.Provider>
)}
/>
</div>
</ElasticsearchTemplate>
<SetupModeRenderer
render={({ setupMode, flyoutComponent, bottomBarComponent }: SetupModeProps) => (
<SetupModeContext.Provider value={{ setupModeSupported: true }}>
{flyoutComponent}
<NodeReact
alerts={{}}
labels={labels.node}
nodeId={node}
clusterUuid={clusterUuid}
onBrush={onBrush}
zoomInfo={zoomInfo}
toggleShowSystemIndices={toggleShowSystemIndices}
showSystemIndices={showSystemIndices}
nodesByIndices={nodesByIndicesData}
{...data}
/>
{bottomBarComponent}
</SetupModeContext.Provider>
)}
/>
</ItemTemplate>
);
};
Loading

0 comments on commit 9f685ef

Please sign in to comment.