mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Stack Monitoring] Add setup mode to react app (#110670)
* Show setup mode button and setup bottom bar * Adapt setup mode in react components to work without angular * Add setup mode data update to react app * Add missing functions from setup mode * Revert setup mode changes from react components * remove some empty lines * Add setup button to monitoring toolbar * Fix types Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
6f357e0433
commit
75486ecd12
10 changed files with 514 additions and 48 deletions
|
@ -13,9 +13,11 @@ interface GlobalStateProviderProps {
|
|||
toasts: MonitoringStartPluginDependencies['core']['notifications']['toasts'];
|
||||
}
|
||||
|
||||
interface State {
|
||||
export interface State {
|
||||
cluster_uuid?: string;
|
||||
ccs?: any;
|
||||
inSetupMode?: boolean;
|
||||
save?: () => void;
|
||||
}
|
||||
|
||||
export const GlobalStateContext = createContext({} as State);
|
||||
|
|
|
@ -15,8 +15,15 @@ import { TabMenuItem } from '../page_template';
|
|||
import { PageLoading } from '../../../components';
|
||||
import { Overview } from '../../../components/cluster/overview';
|
||||
import { ExternalConfigContext } from '../../external_config_context';
|
||||
import { SetupModeRenderer } from '../../setup_mode/setup_mode_renderer';
|
||||
import { SetupModeContext } from '../../../components/setup_mode/setup_mode_context';
|
||||
|
||||
const CODE_PATHS = [CODE_PATH_ALL];
|
||||
interface SetupModeProps {
|
||||
setupMode: any;
|
||||
flyoutComponent: any;
|
||||
bottomBarComponent: any;
|
||||
}
|
||||
|
||||
export const ClusterOverview: React.FC<{}> = () => {
|
||||
// TODO: check how many requests with useClusters
|
||||
|
@ -49,11 +56,20 @@ export const ClusterOverview: React.FC<{}> = () => {
|
|||
return (
|
||||
<PageTemplate title={title} pageTitle={pageTitle} tabs={tabs}>
|
||||
{loaded ? (
|
||||
<Overview
|
||||
cluster={clusters[0]}
|
||||
alerts={[]}
|
||||
setupMode={{}}
|
||||
showLicenseExpiration={externalConfig.showLicenseExpiration}
|
||||
<SetupModeRenderer
|
||||
render={({ setupMode, flyoutComponent, bottomBarComponent }: SetupModeProps) => (
|
||||
<SetupModeContext.Provider value={{ setupModeSupported: true }}>
|
||||
{flyoutComponent}
|
||||
<Overview
|
||||
cluster={clusters[0]}
|
||||
alerts={[]}
|
||||
setupMode={setupMode}
|
||||
showLicenseExpiration={externalConfig.showLicenseExpiration}
|
||||
/>
|
||||
{/* <EnableAlertsModal alerts={this.alerts} /> */}
|
||||
{bottomBarComponent}
|
||||
</SetupModeContext.Provider>
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<PageLoading />
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiTab, EuiTabs, EuiTitle } from '@elastic/eui';
|
||||
import { EuiTab, EuiTabs } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { useTitle } from '../hooks/use_title';
|
||||
import { MonitoringToolbar } from '../../components/shared/toolbar';
|
||||
|
@ -29,34 +29,7 @@ export const PageTemplate: React.FC<PageTemplateProps> = ({ title, pageTitle, ta
|
|||
|
||||
return (
|
||||
<div className="app-container">
|
||||
<EuiFlexGroup gutterSize="l" justifyContent="spaceBetween" responsive>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup
|
||||
gutterSize="none"
|
||||
justifyContent="spaceEvenly"
|
||||
direction="column"
|
||||
responsive
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<div id="setupModeNav">{/* HERE GOES THE SETUP BUTTON */}</div>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem className="monTopNavSecondItem">
|
||||
{pageTitle && (
|
||||
<div data-test-subj="monitoringPageTitle">
|
||||
<EuiTitle size="xs">
|
||||
<h1>{pageTitle}</h1>
|
||||
</EuiTitle>
|
||||
</div>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem>
|
||||
<MonitoringToolbar />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<MonitoringToolbar pageTitle={pageTitle} />
|
||||
{tabs && (
|
||||
<EuiTabs>
|
||||
{tabs.map((item, idx) => {
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* 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 { render } from 'react-dom';
|
||||
import { get, includes } from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { HttpStart } from 'kibana/public';
|
||||
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import { Legacy } from '../../legacy_shims';
|
||||
import { SetupModeEnterButton } from '../../components/setup_mode/enter_button';
|
||||
import { SetupModeFeature } from '../../../common/enums';
|
||||
import { ISetupModeContext } from '../../components/setup_mode/setup_mode_context';
|
||||
import { State as GlobalState } from '../../application/global_state_context';
|
||||
|
||||
function isOnPage(hash: string) {
|
||||
return includes(window.location.hash, hash);
|
||||
}
|
||||
|
||||
let globalState: GlobalState;
|
||||
let httpService: HttpStart;
|
||||
|
||||
interface ISetupModeState {
|
||||
enabled: boolean;
|
||||
data: any;
|
||||
callback?: (() => void) | null;
|
||||
hideBottomBar: boolean;
|
||||
}
|
||||
const setupModeState: ISetupModeState = {
|
||||
enabled: false,
|
||||
data: null,
|
||||
callback: null,
|
||||
hideBottomBar: false,
|
||||
};
|
||||
|
||||
export const getSetupModeState = () => setupModeState;
|
||||
|
||||
export const setNewlyDiscoveredClusterUuid = (clusterUuid: string) => {
|
||||
globalState.cluster_uuid = clusterUuid;
|
||||
globalState.save?.();
|
||||
};
|
||||
|
||||
export const fetchCollectionData = async (uuid?: string, fetchWithoutClusterUuid = false) => {
|
||||
const clusterUuid = globalState.cluster_uuid;
|
||||
const ccs = globalState.ccs;
|
||||
|
||||
let url = '../api/monitoring/v1/setup/collection';
|
||||
if (uuid) {
|
||||
url += `/node/${uuid}`;
|
||||
} else if (!fetchWithoutClusterUuid && clusterUuid) {
|
||||
url += `/cluster/${clusterUuid}`;
|
||||
} else {
|
||||
url += '/cluster';
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await httpService.post(url, {
|
||||
body: JSON.stringify({
|
||||
ccs,
|
||||
}),
|
||||
});
|
||||
return response;
|
||||
} catch (err) {
|
||||
// TODO: handle errors
|
||||
throw new Error(err);
|
||||
}
|
||||
};
|
||||
|
||||
const notifySetupModeDataChange = () => setupModeState.callback && setupModeState.callback();
|
||||
|
||||
export const updateSetupModeData = async (uuid?: string, fetchWithoutClusterUuid = false) => {
|
||||
const data = await fetchCollectionData(uuid, fetchWithoutClusterUuid);
|
||||
setupModeState.data = data;
|
||||
const hasPermissions = get(data, '_meta.hasPermissions', false);
|
||||
if (!hasPermissions) {
|
||||
let text: string = '';
|
||||
if (!hasPermissions) {
|
||||
text = i18n.translate('xpack.monitoring.setupMode.notAvailablePermissions', {
|
||||
defaultMessage: 'You do not have the necessary permissions to do this.',
|
||||
});
|
||||
}
|
||||
|
||||
Legacy.shims.toastNotifications.addDanger({
|
||||
title: i18n.translate('xpack.monitoring.setupMode.notAvailableTitle', {
|
||||
defaultMessage: 'Setup mode is not available',
|
||||
}),
|
||||
text,
|
||||
});
|
||||
return toggleSetupMode(false);
|
||||
}
|
||||
notifySetupModeDataChange();
|
||||
|
||||
const clusterUuid = globalState.cluster_uuid;
|
||||
if (!clusterUuid) {
|
||||
const liveClusterUuid: string = get(data, '_meta.liveClusterUuid');
|
||||
const migratedEsNodes = Object.values(get(data, 'elasticsearch.byUuid', {})).filter(
|
||||
(node: any) => node.isPartiallyMigrated || node.isFullyMigrated
|
||||
);
|
||||
if (liveClusterUuid && migratedEsNodes.length > 0) {
|
||||
setNewlyDiscoveredClusterUuid(liveClusterUuid);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const hideBottomBar = () => {
|
||||
setupModeState.hideBottomBar = true;
|
||||
notifySetupModeDataChange();
|
||||
};
|
||||
export const showBottomBar = () => {
|
||||
setupModeState.hideBottomBar = false;
|
||||
notifySetupModeDataChange();
|
||||
};
|
||||
|
||||
export const disableElasticsearchInternalCollection = async () => {
|
||||
const clusterUuid = globalState.cluster_uuid;
|
||||
const url = `../api/monitoring/v1/setup/collection/${clusterUuid}/disable_internal_collection`;
|
||||
try {
|
||||
const response = await httpService.post(url);
|
||||
return response;
|
||||
} catch (err) {
|
||||
// TODO: handle errors
|
||||
throw new Error(err);
|
||||
}
|
||||
};
|
||||
|
||||
export const toggleSetupMode = (inSetupMode: boolean) => {
|
||||
setupModeState.enabled = inSetupMode;
|
||||
globalState.inSetupMode = inSetupMode;
|
||||
globalState.save?.();
|
||||
setSetupModeMenuItem();
|
||||
notifySetupModeDataChange();
|
||||
|
||||
if (inSetupMode) {
|
||||
// Intentionally do not await this so we don't block UI operations
|
||||
updateSetupModeData();
|
||||
}
|
||||
};
|
||||
|
||||
export const setSetupModeMenuItem = () => {
|
||||
if (isOnPage('no-data')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const enabled = !globalState.inSetupMode;
|
||||
const I18nContext = Legacy.shims.I18nContext;
|
||||
|
||||
render(
|
||||
<KibanaContextProvider services={Legacy.shims.kibanaServices}>
|
||||
<I18nContext>
|
||||
<SetupModeEnterButton enabled={enabled} toggleSetupMode={toggleSetupMode} />
|
||||
</I18nContext>
|
||||
</KibanaContextProvider>,
|
||||
document.getElementById('setupModeNav')
|
||||
);
|
||||
};
|
||||
|
||||
export const initSetupModeState = async (
|
||||
state: GlobalState,
|
||||
http: HttpStart,
|
||||
callback?: () => void
|
||||
) => {
|
||||
globalState = state;
|
||||
httpService = http;
|
||||
if (callback) {
|
||||
setupModeState.callback = callback;
|
||||
}
|
||||
|
||||
if (globalState.inSetupMode) {
|
||||
toggleSetupMode(true);
|
||||
}
|
||||
};
|
||||
|
||||
export const isInSetupMode = (context?: ISetupModeContext) => {
|
||||
if (context?.setupModeSupported === false) {
|
||||
return false;
|
||||
}
|
||||
if (setupModeState.enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return globalState.inSetupMode;
|
||||
};
|
||||
|
||||
export const isSetupModeFeatureEnabled = (feature: SetupModeFeature) => {
|
||||
if (!setupModeState.enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (feature === SetupModeFeature.MetricbeatMigration) {
|
||||
if (Legacy.shims.isCloud) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
8
x-pack/plugins/monitoring/public/application/setup_mode/setup_mode_renderer.d.ts
vendored
Normal file
8
x-pack/plugins/monitoring/public/application/setup_mode/setup_mode_renderer.d.ts
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const SetupModeRenderer: FunctionComponent<Props>;
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* 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, { Fragment } from 'react';
|
||||
import {
|
||||
getSetupModeState,
|
||||
initSetupModeState,
|
||||
updateSetupModeData,
|
||||
disableElasticsearchInternalCollection,
|
||||
toggleSetupMode,
|
||||
setSetupModeMenuItem,
|
||||
} from './setup_mode';
|
||||
import { Flyout } from '../../components/metricbeat_migration/flyout';
|
||||
import {
|
||||
EuiBottomBar,
|
||||
EuiButton,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiTextColor,
|
||||
EuiIcon,
|
||||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
import { findNewUuid } from '../../components/renderers/lib/find_new_uuid';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { GlobalStateContext } from '../../application/global_state_context';
|
||||
import { withKibana } from '../../../../../../src/plugins/kibana_react/public';
|
||||
|
||||
class WrappedSetupModeRenderer extends React.Component {
|
||||
globalState;
|
||||
state = {
|
||||
renderState: false,
|
||||
isFlyoutOpen: false,
|
||||
instance: null,
|
||||
newProduct: null,
|
||||
isSettingUpNew: false,
|
||||
};
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
this.globalState = this.context;
|
||||
const { kibana } = this.props;
|
||||
initSetupModeState(this.globalState, kibana.services.http, (_oldData) => {
|
||||
const newState = { renderState: true };
|
||||
|
||||
const { productName } = this.props;
|
||||
if (!productName) {
|
||||
this.setState(newState);
|
||||
return;
|
||||
}
|
||||
|
||||
const setupModeState = getSetupModeState();
|
||||
if (!setupModeState.enabled || !setupModeState.data) {
|
||||
this.setState(newState);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = setupModeState.data[productName];
|
||||
const oldData = _oldData ? _oldData[productName] : null;
|
||||
if (data && oldData) {
|
||||
const newUuid = findNewUuid(Object.keys(oldData.byUuid), Object.keys(data.byUuid));
|
||||
if (newUuid) {
|
||||
newState.newProduct = data.byUuid[newUuid];
|
||||
}
|
||||
}
|
||||
|
||||
this.setState(newState);
|
||||
});
|
||||
setSetupModeMenuItem();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.setState({
|
||||
renderState: false,
|
||||
isFlyoutOpen: false,
|
||||
instance: null,
|
||||
newProduct: null,
|
||||
isSettingUpNew: false,
|
||||
});
|
||||
}
|
||||
|
||||
getFlyout(data, meta) {
|
||||
const { productName } = this.props;
|
||||
const { isFlyoutOpen, instance, isSettingUpNew, newProduct } = this.state;
|
||||
if (!data || !isFlyoutOpen) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let product = null;
|
||||
if (newProduct) {
|
||||
product = newProduct;
|
||||
}
|
||||
// For new instance discovery flow, we pass in empty instance object
|
||||
else if (instance && Object.keys(instance).length) {
|
||||
product = data.byUuid[instance.uuid];
|
||||
}
|
||||
|
||||
if (!product) {
|
||||
const uuids = Object.values(data.byUuid);
|
||||
if (uuids.length && !isSettingUpNew) {
|
||||
product = uuids[0];
|
||||
} else {
|
||||
product = {
|
||||
isNetNewUser: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Flyout
|
||||
onClose={() => this.reset()}
|
||||
productName={productName}
|
||||
product={product}
|
||||
meta={meta}
|
||||
instance={instance}
|
||||
updateProduct={updateSetupModeData}
|
||||
isSettingUpNew={isSettingUpNew}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
getBottomBar(setupModeState) {
|
||||
if (!setupModeState.enabled || setupModeState.hideBottomBar) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiSpacer size="xxl" />
|
||||
<EuiBottomBar>
|
||||
<EuiFlexGroup
|
||||
justifyContent="spaceBetween"
|
||||
alignItems="center"
|
||||
data-test-subj="monitoringSetupModeBottomBar"
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTextColor color="ghost">
|
||||
<FormattedMessage
|
||||
id="xpack.monitoring.setupMode.description"
|
||||
defaultMessage="You are in setup mode. The ({flagIcon}) icon indicates configuration options."
|
||||
values={{
|
||||
flagIcon: <EuiIcon type="flag" />,
|
||||
}}
|
||||
/>
|
||||
</EuiTextColor>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
color="danger"
|
||||
fill
|
||||
iconType="flag"
|
||||
iconSide="right"
|
||||
size="s"
|
||||
onClick={() => toggleSetupMode(false)}
|
||||
>
|
||||
{i18n.translate('xpack.monitoring.setupMode.exit', {
|
||||
defaultMessage: `Exit setup mode`,
|
||||
})}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiBottomBar>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
async shortcutToFinishMigration() {
|
||||
await disableElasticsearchInternalCollection();
|
||||
await updateSetupModeData();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { render, productName } = this.props;
|
||||
const setupModeState = getSetupModeState();
|
||||
|
||||
let data = { byUuid: {} };
|
||||
if (setupModeState.data) {
|
||||
if (productName && setupModeState.data[productName]) {
|
||||
data = setupModeState.data[productName];
|
||||
} else if (setupModeState.data) {
|
||||
data = setupModeState.data;
|
||||
}
|
||||
}
|
||||
|
||||
const meta = setupModeState.data ? setupModeState.data._meta : null;
|
||||
|
||||
return render({
|
||||
setupMode: {
|
||||
data,
|
||||
meta,
|
||||
enabled: setupModeState.enabled,
|
||||
productName,
|
||||
updateSetupModeData,
|
||||
shortcutToFinishMigration: () => this.shortcutToFinishMigration(),
|
||||
openFlyout: (instance, isSettingUpNew) =>
|
||||
this.setState({ isFlyoutOpen: true, instance, isSettingUpNew }),
|
||||
closeFlyout: () => this.setState({ isFlyoutOpen: false }),
|
||||
},
|
||||
flyoutComponent: this.getFlyout(data, meta),
|
||||
bottomBarComponent: this.getBottomBar(setupModeState),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
WrappedSetupModeRenderer.contextType = GlobalStateContext;
|
||||
export const SetupModeRenderer = withKibana(WrappedSetupModeRenderer);
|
|
@ -5,11 +5,21 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiSuperDatePicker, OnRefreshChangeProps } from '@elastic/eui';
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiSuperDatePicker,
|
||||
EuiTitle,
|
||||
OnRefreshChangeProps,
|
||||
} from '@elastic/eui';
|
||||
import React, { useContext, useCallback } from 'react';
|
||||
import { MonitoringTimeContainer } from '../../application/pages/use_monitoring_time';
|
||||
|
||||
export const MonitoringToolbar = () => {
|
||||
interface MonitoringToolbarProps {
|
||||
pageTitle?: string;
|
||||
}
|
||||
|
||||
export const MonitoringToolbar: React.FC<MonitoringToolbarProps> = ({ pageTitle }) => {
|
||||
const {
|
||||
currentTimerange,
|
||||
handleTimeChange,
|
||||
|
@ -38,18 +48,36 @@ export const MonitoringToolbar = () => {
|
|||
);
|
||||
|
||||
return (
|
||||
<EuiFlexGroup gutterSize={'xl'} justifyContent={'spaceBetween'}>
|
||||
<EuiFlexItem>Setup Button</EuiFlexItem>
|
||||
<EuiFlexGroup gutterSize="l" justifyContent="spaceBetween" responsive>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup gutterSize="none" justifyContent="spaceEvenly" direction="column" responsive>
|
||||
<EuiFlexItem>
|
||||
<div id="setupModeNav">{/* HERE GOES THE SETUP BUTTON */}</div>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem className="monTopNavSecondItem">
|
||||
{pageTitle && (
|
||||
<div data-test-subj="monitoringPageTitle">
|
||||
<EuiTitle size="xs">
|
||||
<h1>{pageTitle}</h1>
|
||||
</EuiTitle>
|
||||
</div>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiSuperDatePicker
|
||||
start={currentTimerange.from}
|
||||
end={currentTimerange.to}
|
||||
onTimeChange={onTimeChange}
|
||||
onRefresh={() => {}}
|
||||
isPaused={isPaused}
|
||||
refreshInterval={refreshInterval}
|
||||
onRefreshChange={onRefreshChange}
|
||||
/>
|
||||
<div style={{ padding: 8 }}>
|
||||
<EuiSuperDatePicker
|
||||
start={currentTimerange.from}
|
||||
end={currentTimerange.to}
|
||||
onTimeChange={onTimeChange}
|
||||
onRefresh={() => {}}
|
||||
isPaused={isPaused}
|
||||
refreshInterval={refreshInterval}
|
||||
onRefreshChange={onRefreshChange}
|
||||
/>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
|
16
x-pack/plugins/monitoring/public/external_config.ts
Normal file
16
x-pack/plugins/monitoring/public/external_config.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
let config: { [key: string]: unknown } = {};
|
||||
|
||||
export const setConfig = (externalConfig: { [key: string]: unknown }) => {
|
||||
config = externalConfig;
|
||||
};
|
||||
|
||||
export const isReactMigrationEnabled = () => {
|
||||
return config.renderReactApp;
|
||||
};
|
|
@ -15,6 +15,8 @@ import { ajaxErrorHandlersProvider } from './ajax_error_handler';
|
|||
import { SetupModeEnterButton } from '../components/setup_mode/enter_button';
|
||||
import { SetupModeFeature } from '../../common/enums';
|
||||
import { ISetupModeContext } from '../components/setup_mode/setup_mode_context';
|
||||
import * as setupModeReact from '../application/setup_mode/setup_mode';
|
||||
import { isReactMigrationEnabled } from '../external_config';
|
||||
|
||||
function isOnPage(hash: string) {
|
||||
return includes(window.location.hash, hash);
|
||||
|
@ -209,6 +211,7 @@ export const initSetupModeState = async ($scope: any, $injector: any, callback?:
|
|||
};
|
||||
|
||||
export const isInSetupMode = (context?: ISetupModeContext) => {
|
||||
if (isReactMigrationEnabled()) return setupModeReact.isInSetupMode(context);
|
||||
if (context?.setupModeSupported === false) {
|
||||
return false;
|
||||
}
|
||||
|
@ -222,6 +225,7 @@ export const isInSetupMode = (context?: ISetupModeContext) => {
|
|||
};
|
||||
|
||||
export const isSetupModeFeatureEnabled = (feature: SetupModeFeature) => {
|
||||
if (isReactMigrationEnabled()) return setupModeReact.isSetupModeFeatureEnabled(feature);
|
||||
if (!setupModeState.enabled) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import { createThreadPoolRejectionsAlertType } from './alerts/thread_pool_reject
|
|||
import { createMemoryUsageAlertType } from './alerts/memory_usage_alert';
|
||||
import { createCCRReadExceptionsAlertType } from './alerts/ccr_read_exceptions_alert';
|
||||
import { createLargeShardSizeAlertType } from './alerts/large_shard_size_alert';
|
||||
import { setConfig } from './external_config';
|
||||
|
||||
interface MonitoringSetupPluginDependencies {
|
||||
home?: HomePublicPluginSetup;
|
||||
|
@ -125,6 +126,7 @@ export class MonitoringPlugin
|
|||
});
|
||||
|
||||
const config = Object.fromEntries(externalConfig);
|
||||
setConfig(config);
|
||||
if (config.renderReactApp) {
|
||||
const { renderApp } = await import('./application');
|
||||
return renderApp(coreStart, pluginsStart, params, config);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue