mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Logs UI] Slim down local view configuration state (#31723)
This commit is contained in:
parent
748c18b8f4
commit
a9d75988bd
23 changed files with 584 additions and 600 deletions
|
@ -172,6 +172,7 @@
|
|||
"classnames": "2.2.5",
|
||||
"concat-stream": "1.5.1",
|
||||
"constate": "^0.9.0",
|
||||
"constate-latest": "npm:constate@^1.0.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"copy-to-clipboard": "^3.0.8",
|
||||
"core-js": "2.5.3",
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { mountHook } from 'test_utils/enzyme_helpers';
|
||||
|
||||
import { useLogViewConfiguration } from './log_view_configuration';
|
||||
|
||||
describe('useLogViewConfiguration hook', () => {
|
||||
describe('textScale state', () => {
|
||||
it('has a default value', () => {
|
||||
const { getLastHookValue } = mountHook(() => useLogViewConfiguration().textScale);
|
||||
|
||||
expect(getLastHookValue()).toEqual('medium');
|
||||
});
|
||||
|
||||
it('can be updated', () => {
|
||||
const { act, getLastHookValue } = mountHook(() => useLogViewConfiguration());
|
||||
|
||||
act(({ setTextScale }) => {
|
||||
setTextScale('small');
|
||||
});
|
||||
|
||||
expect(getLastHookValue().textScale).toEqual('small');
|
||||
});
|
||||
});
|
||||
|
||||
describe('textWrap state', () => {
|
||||
it('has a default value', () => {
|
||||
const { getLastHookValue } = mountHook(() => useLogViewConfiguration().textWrap);
|
||||
|
||||
expect(getLastHookValue()).toEqual(true);
|
||||
});
|
||||
|
||||
it('can be updated', () => {
|
||||
const { act, getLastHookValue } = mountHook(() => useLogViewConfiguration());
|
||||
|
||||
act(({ setTextWrap }) => {
|
||||
setTextWrap(false);
|
||||
});
|
||||
|
||||
expect(getLastHookValue().textWrap).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('intervalSize state', () => {
|
||||
it('has a default value', () => {
|
||||
const { getLastHookValue } = mountHook(() => useLogViewConfiguration().intervalSize);
|
||||
|
||||
expect(getLastHookValue()).toEqual(86400000);
|
||||
});
|
||||
|
||||
it('can be updated', () => {
|
||||
const { act, getLastHookValue } = mountHook(() => useLogViewConfiguration());
|
||||
|
||||
act(({ setIntervalSize }) => {
|
||||
setIntervalSize(90000000);
|
||||
});
|
||||
|
||||
expect(getLastHookValue().intervalSize).toEqual(90000000);
|
||||
});
|
||||
});
|
||||
|
||||
it('provides the available text scales', () => {
|
||||
const { getLastHookValue } = mountHook(() => useLogViewConfiguration().availableTextScales);
|
||||
|
||||
expect(getLastHookValue()).toEqual(expect.any(Array));
|
||||
expect(getLastHookValue().length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('provides the available interval sizes', () => {
|
||||
const { getLastHookValue } = mountHook(() => useLogViewConfiguration().availableIntervalSizes);
|
||||
|
||||
expect(getLastHookValue()).toEqual(expect.any(Array));
|
||||
expect(getLastHookValue().length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import createContainer from 'constate-latest';
|
||||
import { useState } from 'react';
|
||||
|
||||
export type TextScale = 'small' | 'medium' | 'large';
|
||||
|
||||
export const useLogViewConfiguration = () => {
|
||||
// text scale
|
||||
const [textScale, setTextScale] = useState<TextScale>('medium');
|
||||
|
||||
// text wrap
|
||||
const [textWrap, setTextWrap] = useState<boolean>(true);
|
||||
|
||||
// minimap interval
|
||||
const [intervalSize, setIntervalSize] = useState<number>(1000 * 60 * 60 * 24);
|
||||
|
||||
return {
|
||||
availableIntervalSizes,
|
||||
availableTextScales,
|
||||
setTextScale,
|
||||
setTextWrap,
|
||||
textScale,
|
||||
textWrap,
|
||||
intervalSize,
|
||||
setIntervalSize,
|
||||
};
|
||||
};
|
||||
|
||||
export const LogViewConfiguration = createContainer(useLogViewConfiguration);
|
||||
|
||||
/**
|
||||
* constants
|
||||
*/
|
||||
|
||||
export const availableTextScales: TextScale[] = ['large', 'medium', 'small'];
|
||||
|
||||
export const availableIntervalSizes = [
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneYearLabel', {
|
||||
defaultMessage: '1 Year',
|
||||
}),
|
||||
intervalSize: 1000 * 60 * 60 * 24 * 365,
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneMonthLabel', {
|
||||
defaultMessage: '1 Month',
|
||||
}),
|
||||
intervalSize: 1000 * 60 * 60 * 24 * 30,
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneWeekLabel', {
|
||||
defaultMessage: '1 Week',
|
||||
}),
|
||||
intervalSize: 1000 * 60 * 60 * 24 * 7,
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneDayLabel', {
|
||||
defaultMessage: '1 Day',
|
||||
}),
|
||||
intervalSize: 1000 * 60 * 60 * 24,
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneHourLabel', {
|
||||
defaultMessage: '1 Hour',
|
||||
}),
|
||||
intervalSize: 1000 * 60 * 60,
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneMinuteLabel', {
|
||||
defaultMessage: '1 Minute',
|
||||
}),
|
||||
intervalSize: 1000 * 60,
|
||||
},
|
||||
];
|
|
@ -4,97 +4,42 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import React, { useContext, useMemo } from 'react';
|
||||
|
||||
import { logMinimapActions, logMinimapSelectors, State } from '../../store';
|
||||
import { asChildFunctionRenderer } from '../../utils/typed_react';
|
||||
import { bindPlainActionCreators } from '../../utils/typed_redux';
|
||||
import { UrlStateContainer } from '../../utils/url_state';
|
||||
|
||||
export const withLogMinimap = connect(
|
||||
(state: State) => ({
|
||||
availableIntervalSizes,
|
||||
intervalSize: logMinimapSelectors.selectMinimapIntervalSize(state),
|
||||
urlState: selectMinimapUrlState(state),
|
||||
}),
|
||||
bindPlainActionCreators({
|
||||
setIntervalSize: logMinimapActions.setMinimapIntervalSize,
|
||||
})
|
||||
);
|
||||
|
||||
export const WithLogMinimap = asChildFunctionRenderer(withLogMinimap);
|
||||
|
||||
export const availableIntervalSizes = [
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneYearLabel', {
|
||||
defaultMessage: '1 Year',
|
||||
}),
|
||||
intervalSize: 1000 * 60 * 60 * 24 * 365,
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneMonthLabel', {
|
||||
defaultMessage: '1 Month',
|
||||
}),
|
||||
intervalSize: 1000 * 60 * 60 * 24 * 30,
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneWeekLabel', {
|
||||
defaultMessage: '1 Week',
|
||||
}),
|
||||
intervalSize: 1000 * 60 * 60 * 24 * 7,
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneDayLabel', {
|
||||
defaultMessage: '1 Day',
|
||||
}),
|
||||
intervalSize: 1000 * 60 * 60 * 24,
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneHourLabel', {
|
||||
defaultMessage: '1 Hour',
|
||||
}),
|
||||
intervalSize: 1000 * 60 * 60,
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.infra.mapLogs.oneMinuteLabel', {
|
||||
defaultMessage: '1 Minute',
|
||||
}),
|
||||
intervalSize: 1000 * 60,
|
||||
},
|
||||
];
|
||||
import { LogViewConfiguration } from './log_view_configuration';
|
||||
|
||||
/**
|
||||
* Url State
|
||||
*/
|
||||
|
||||
interface LogMinimapUrlState {
|
||||
intervalSize?: ReturnType<typeof logMinimapSelectors.selectMinimapIntervalSize>;
|
||||
intervalSize?: number;
|
||||
}
|
||||
|
||||
export const WithLogMinimapUrlState = () => (
|
||||
<WithLogMinimap>
|
||||
{({ urlState, setIntervalSize }) => (
|
||||
<UrlStateContainer
|
||||
urlState={urlState}
|
||||
urlStateKey="logMinimap"
|
||||
mapToUrlState={mapToUrlState}
|
||||
onChange={newUrlState => {
|
||||
if (newUrlState && newUrlState.intervalSize) {
|
||||
setIntervalSize(newUrlState.intervalSize);
|
||||
}
|
||||
}}
|
||||
onInitialize={newUrlState => {
|
||||
if (newUrlState && newUrlState.intervalSize) {
|
||||
setIntervalSize(newUrlState.intervalSize);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</WithLogMinimap>
|
||||
);
|
||||
export const WithLogMinimapUrlState = () => {
|
||||
const { intervalSize, setIntervalSize } = useContext(LogViewConfiguration.Context);
|
||||
|
||||
const urlState = useMemo(() => ({ intervalSize }), [intervalSize]);
|
||||
|
||||
return (
|
||||
<UrlStateContainer
|
||||
urlState={urlState}
|
||||
urlStateKey="logMinimap"
|
||||
mapToUrlState={mapToUrlState}
|
||||
onChange={newUrlState => {
|
||||
if (newUrlState && newUrlState.intervalSize) {
|
||||
setIntervalSize(newUrlState.intervalSize);
|
||||
}
|
||||
}}
|
||||
onInitialize={newUrlState => {
|
||||
if (newUrlState && newUrlState.intervalSize) {
|
||||
setIntervalSize(newUrlState.intervalSize);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const mapToUrlState = (value: any): LogMinimapUrlState | undefined =>
|
||||
value
|
||||
|
@ -105,10 +50,3 @@ const mapToUrlState = (value: any): LogMinimapUrlState | undefined =>
|
|||
|
||||
const mapToIntervalSizeUrlState = (value: any) =>
|
||||
value && typeof value === 'number' ? value : undefined;
|
||||
|
||||
const selectMinimapUrlState = createSelector(
|
||||
logMinimapSelectors.selectMinimapIntervalSize,
|
||||
intervalSize => ({
|
||||
intervalSize,
|
||||
})
|
||||
);
|
||||
|
|
|
@ -4,69 +4,47 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import React, { useContext, useMemo } from 'react';
|
||||
|
||||
import { TextScale } from '../../../common/log_text_scale';
|
||||
import { logTextviewActions, logTextviewSelectors, State } from '../../store';
|
||||
import { asChildFunctionRenderer } from '../../utils/typed_react';
|
||||
import { bindPlainActionCreators } from '../../utils/typed_redux';
|
||||
import { UrlStateContainer } from '../../utils/url_state';
|
||||
|
||||
const availableTextScales = ['large', 'medium', 'small'] as TextScale[];
|
||||
|
||||
export const withLogTextview = connect(
|
||||
(state: State) => ({
|
||||
availableTextScales,
|
||||
textScale: logTextviewSelectors.selectTextviewScale(state),
|
||||
urlState: selectTextviewUrlState(state),
|
||||
wrap: logTextviewSelectors.selectTextviewWrap(state),
|
||||
}),
|
||||
bindPlainActionCreators({
|
||||
setTextScale: logTextviewActions.setTextviewScale,
|
||||
setTextWrap: logTextviewActions.setTextviewWrap,
|
||||
})
|
||||
);
|
||||
|
||||
export const WithLogTextview = asChildFunctionRenderer(withLogTextview);
|
||||
|
||||
/**
|
||||
* Url State
|
||||
*/
|
||||
import { availableTextScales, LogViewConfiguration, TextScale } from './log_view_configuration';
|
||||
|
||||
interface LogTextviewUrlState {
|
||||
textScale?: ReturnType<typeof logTextviewSelectors.selectTextviewScale>;
|
||||
wrap?: ReturnType<typeof logTextviewSelectors.selectTextviewWrap>;
|
||||
textScale?: TextScale;
|
||||
wrap?: boolean;
|
||||
}
|
||||
|
||||
export const WithLogTextviewUrlState = () => (
|
||||
<WithLogTextview>
|
||||
{({ urlState, setTextScale, setTextWrap }) => (
|
||||
<UrlStateContainer
|
||||
urlState={urlState}
|
||||
urlStateKey="logTextview"
|
||||
mapToUrlState={mapToUrlState}
|
||||
onChange={newUrlState => {
|
||||
if (newUrlState && newUrlState.textScale) {
|
||||
setTextScale(newUrlState.textScale);
|
||||
}
|
||||
if (newUrlState && typeof newUrlState.wrap !== 'undefined') {
|
||||
setTextWrap(newUrlState.wrap);
|
||||
}
|
||||
}}
|
||||
onInitialize={newUrlState => {
|
||||
if (newUrlState && newUrlState.textScale) {
|
||||
setTextScale(newUrlState.textScale);
|
||||
}
|
||||
if (newUrlState && typeof newUrlState.wrap !== 'undefined') {
|
||||
setTextWrap(newUrlState.wrap);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</WithLogTextview>
|
||||
);
|
||||
export const WithLogTextviewUrlState = () => {
|
||||
const { textScale, textWrap, setTextScale, setTextWrap } = useContext(
|
||||
LogViewConfiguration.Context
|
||||
);
|
||||
|
||||
const urlState = useMemo(() => ({ textScale, wrap: textWrap }), [textScale, textWrap]);
|
||||
|
||||
return (
|
||||
<UrlStateContainer
|
||||
urlState={urlState}
|
||||
urlStateKey="logTextview"
|
||||
mapToUrlState={mapToUrlState}
|
||||
onChange={newUrlState => {
|
||||
if (newUrlState && newUrlState.textScale) {
|
||||
setTextScale(newUrlState.textScale);
|
||||
}
|
||||
if (newUrlState && typeof newUrlState.wrap !== 'undefined') {
|
||||
setTextWrap(newUrlState.wrap);
|
||||
}
|
||||
}}
|
||||
onInitialize={newUrlState => {
|
||||
if (newUrlState && newUrlState.textScale) {
|
||||
setTextScale(newUrlState.textScale);
|
||||
}
|
||||
if (newUrlState && typeof newUrlState.wrap !== 'undefined') {
|
||||
setTextWrap(newUrlState.wrap);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const mapToUrlState = (value: any): LogTextviewUrlState | undefined =>
|
||||
value
|
||||
|
@ -80,12 +58,3 @@ const mapToTextScaleUrlState = (value: any) =>
|
|||
availableTextScales.includes(value) ? (value as TextScale) : undefined;
|
||||
|
||||
const mapToWrapUrlState = (value: any) => (typeof value === 'boolean' ? value : undefined);
|
||||
|
||||
const selectTextviewUrlState = createSelector(
|
||||
logTextviewSelectors.selectTextviewScale,
|
||||
logTextviewSelectors.selectTextviewWrap,
|
||||
(textScale, wrap) => ({
|
||||
textScale,
|
||||
wrap,
|
||||
})
|
||||
);
|
||||
|
|
|
@ -21,6 +21,7 @@ import { ColumnarPage } from '../../components/page';
|
|||
|
||||
import { SourceConfigurationFlyout } from '../../components/source_configuration';
|
||||
import { WithSourceConfigurationFlyoutState } from '../../components/source_configuration/source_configuration_flyout_state';
|
||||
import { LogViewConfiguration } from '../../containers/logs/log_view_configuration';
|
||||
import { WithLogFilter, WithLogFilterUrlState } from '../../containers/logs/with_log_filter';
|
||||
import { WithLogFlyout } from '../../containers/logs/with_log_flyout';
|
||||
import { WithFlyoutOptions } from '../../containers/logs/with_log_flyout_options';
|
||||
|
@ -43,128 +44,130 @@ export const LogsPage = injectI18n(
|
|||
const { intl } = this.props;
|
||||
|
||||
return (
|
||||
<ColumnarPage>
|
||||
<Header
|
||||
breadcrumbs={[
|
||||
{
|
||||
text: intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.logsBreadcrumbsText',
|
||||
defaultMessage: 'Logs',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<WithSource>
|
||||
{({
|
||||
derivedIndexPattern,
|
||||
hasFailed,
|
||||
isLoading,
|
||||
lastFailureMessage,
|
||||
load,
|
||||
logIndicesExist,
|
||||
sourceId,
|
||||
}) => (
|
||||
<>
|
||||
<DocumentTitle
|
||||
title={intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.documentTitle',
|
||||
<LogViewConfiguration.Provider>
|
||||
<ColumnarPage>
|
||||
<Header
|
||||
breadcrumbs={[
|
||||
{
|
||||
text: intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.logsBreadcrumbsText',
|
||||
defaultMessage: 'Logs',
|
||||
})}
|
||||
/>
|
||||
<HelpCenterContent
|
||||
feedbackLink="https://discuss.elastic.co/c/logs"
|
||||
feedbackLinkText={intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.logsHelpContent.feedbackLinkText',
|
||||
defaultMessage: 'Provide feedback for Logs',
|
||||
})}
|
||||
/>
|
||||
<SourceConfigurationFlyout />
|
||||
{isLoading ? (
|
||||
<SourceLoadingPage />
|
||||
) : logIndicesExist ? (
|
||||
<>
|
||||
<WithLogFilterUrlState indexPattern={derivedIndexPattern} />
|
||||
<WithLogPositionUrlState />
|
||||
<WithLogMinimapUrlState />
|
||||
<WithLogTextviewUrlState />
|
||||
<WithFlyoutOptionsUrlState />
|
||||
<LogsToolbar />
|
||||
<WithLogFilter indexPattern={derivedIndexPattern}>
|
||||
{({ applyFilterQueryFromKueryExpression }) => (
|
||||
<React.Fragment>
|
||||
<WithFlyoutOptions>
|
||||
{({ showFlyout, setFlyoutItem }) => (
|
||||
<LogsPageContent
|
||||
showFlyout={showFlyout}
|
||||
setFlyoutItem={setFlyoutItem}
|
||||
/>
|
||||
)}
|
||||
</WithFlyoutOptions>
|
||||
<WithLogFlyout sourceId={sourceId}>
|
||||
{({ flyoutItem, hideFlyout, loading }) => (
|
||||
<LogFlyout
|
||||
setFilter={applyFilterQueryFromKueryExpression}
|
||||
flyoutItem={flyoutItem}
|
||||
hideFlyout={hideFlyout}
|
||||
loading={loading}
|
||||
/>
|
||||
)}
|
||||
</WithLogFlyout>
|
||||
</React.Fragment>
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<WithSource>
|
||||
{({
|
||||
derivedIndexPattern,
|
||||
hasFailed,
|
||||
isLoading,
|
||||
lastFailureMessage,
|
||||
load,
|
||||
logIndicesExist,
|
||||
sourceId,
|
||||
}) => (
|
||||
<>
|
||||
<DocumentTitle
|
||||
title={intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.documentTitle',
|
||||
defaultMessage: 'Logs',
|
||||
})}
|
||||
/>
|
||||
<HelpCenterContent
|
||||
feedbackLink="https://discuss.elastic.co/c/logs"
|
||||
feedbackLinkText={intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.logsHelpContent.feedbackLinkText',
|
||||
defaultMessage: 'Provide feedback for Logs',
|
||||
})}
|
||||
/>
|
||||
<SourceConfigurationFlyout />
|
||||
{isLoading ? (
|
||||
<SourceLoadingPage />
|
||||
) : logIndicesExist ? (
|
||||
<>
|
||||
<WithLogFilterUrlState indexPattern={derivedIndexPattern} />
|
||||
<WithLogPositionUrlState />
|
||||
<WithLogMinimapUrlState />
|
||||
<WithLogTextviewUrlState />
|
||||
<WithFlyoutOptionsUrlState />
|
||||
<LogsToolbar />
|
||||
<WithLogFilter indexPattern={derivedIndexPattern}>
|
||||
{({ applyFilterQueryFromKueryExpression }) => (
|
||||
<React.Fragment>
|
||||
<WithFlyoutOptions>
|
||||
{({ showFlyout, setFlyoutItem }) => (
|
||||
<LogsPageContent
|
||||
showFlyout={showFlyout}
|
||||
setFlyoutItem={setFlyoutItem}
|
||||
/>
|
||||
)}
|
||||
</WithFlyoutOptions>
|
||||
<WithLogFlyout sourceId={sourceId}>
|
||||
{({ flyoutItem, hideFlyout, loading }) => (
|
||||
<LogFlyout
|
||||
setFilter={applyFilterQueryFromKueryExpression}
|
||||
flyoutItem={flyoutItem}
|
||||
hideFlyout={hideFlyout}
|
||||
loading={loading}
|
||||
/>
|
||||
)}
|
||||
</WithLogFlyout>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</WithLogFilter>
|
||||
</>
|
||||
) : hasFailed ? (
|
||||
<SourceErrorPage errorMessage={lastFailureMessage || ''} retry={load} />
|
||||
) : (
|
||||
<WithKibanaChrome>
|
||||
{({ basePath }) => (
|
||||
<NoIndices
|
||||
title={intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.noLoggingIndicesTitle',
|
||||
defaultMessage: "Looks like you don't have any logging indices.",
|
||||
})}
|
||||
message={intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.noLoggingIndicesDescription',
|
||||
defaultMessage: "Let's add some!",
|
||||
})}
|
||||
actions={
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiButton
|
||||
href={`${basePath}/app/kibana#/home/tutorial_directory/logging`}
|
||||
color="primary"
|
||||
fill
|
||||
>
|
||||
{intl.formatMessage({
|
||||
id:
|
||||
'xpack.infra.logsPage.noLoggingIndicesInstructionsActionLabel',
|
||||
defaultMessage: 'View setup instructions',
|
||||
})}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<WithSourceConfigurationFlyoutState>
|
||||
{({ enable }) => (
|
||||
<EuiButton color="primary" onClick={enable}>
|
||||
{intl.formatMessage({
|
||||
id: 'xpack.infra.configureSourceActionLabel',
|
||||
defaultMessage: 'Change source configuration',
|
||||
})}
|
||||
</EuiButton>
|
||||
)}
|
||||
</WithSourceConfigurationFlyoutState>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</WithLogFilter>
|
||||
</>
|
||||
) : hasFailed ? (
|
||||
<SourceErrorPage errorMessage={lastFailureMessage || ''} retry={load} />
|
||||
) : (
|
||||
<WithKibanaChrome>
|
||||
{({ basePath }) => (
|
||||
<NoIndices
|
||||
title={intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.noLoggingIndicesTitle',
|
||||
defaultMessage: "Looks like you don't have any logging indices.",
|
||||
})}
|
||||
message={intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.noLoggingIndicesDescription',
|
||||
defaultMessage: "Let's add some!",
|
||||
})}
|
||||
actions={
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiButton
|
||||
href={`${basePath}/app/kibana#/home/tutorial_directory/logging`}
|
||||
color="primary"
|
||||
fill
|
||||
>
|
||||
{intl.formatMessage({
|
||||
id:
|
||||
'xpack.infra.logsPage.noLoggingIndicesInstructionsActionLabel',
|
||||
defaultMessage: 'View setup instructions',
|
||||
})}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<WithSourceConfigurationFlyoutState>
|
||||
{({ enable }) => (
|
||||
<EuiButton color="primary" onClick={enable}>
|
||||
{intl.formatMessage({
|
||||
id: 'xpack.infra.configureSourceActionLabel',
|
||||
defaultMessage: 'Change source configuration',
|
||||
})}
|
||||
</EuiButton>
|
||||
)}
|
||||
</WithSourceConfigurationFlyoutState>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</WithKibanaChrome>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</WithSource>
|
||||
</ColumnarPage>
|
||||
</WithKibanaChrome>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</WithSource>
|
||||
</ColumnarPage>
|
||||
</LogViewConfiguration.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,16 +4,15 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { AutoSizer } from '../../components/auto_sizer';
|
||||
import { LogMinimap } from '../../components/logging/log_minimap';
|
||||
import { ScrollableLogTextStreamView } from '../../components/logging/log_text_stream';
|
||||
import { PageContent } from '../../components/page';
|
||||
import { WithLogMinimap } from '../../containers/logs/with_log_minimap';
|
||||
import { LogViewConfiguration } from '../../containers/logs/log_view_configuration';
|
||||
import { WithLogPosition } from '../../containers/logs/with_log_position';
|
||||
import { WithLogTextview } from '../../containers/logs/with_log_textview';
|
||||
import { WithStreamItems } from '../../containers/logs/with_stream_items';
|
||||
import { WithSummary } from '../../containers/logs/with_summary';
|
||||
|
||||
|
@ -22,95 +21,91 @@ interface Props {
|
|||
showFlyout: () => void;
|
||||
}
|
||||
|
||||
export const LogsPageContent: React.SFC<Props> = ({ showFlyout, setFlyoutItem }) => (
|
||||
<PageContent>
|
||||
<AutoSizer content>
|
||||
{({ measureRef, content: { width = 0, height = 0 } }) => (
|
||||
<LogPageEventStreamColumn innerRef={measureRef}>
|
||||
<WithLogTextview>
|
||||
{({ textScale, wrap }) => (
|
||||
<WithLogPosition>
|
||||
{({
|
||||
isAutoReloading,
|
||||
jumpToTargetPosition,
|
||||
reportVisiblePositions,
|
||||
targetPosition,
|
||||
}) => (
|
||||
<WithStreamItems>
|
||||
export const LogsPageContent: React.FunctionComponent<Props> = ({ showFlyout, setFlyoutItem }) => {
|
||||
const { intervalSize, textScale, textWrap } = useContext(LogViewConfiguration.Context);
|
||||
|
||||
return (
|
||||
<PageContent>
|
||||
<AutoSizer content>
|
||||
{({ measureRef, content: { width = 0, height = 0 } }) => (
|
||||
<LogPageEventStreamColumn innerRef={measureRef}>
|
||||
<WithLogPosition>
|
||||
{({
|
||||
isAutoReloading,
|
||||
jumpToTargetPosition,
|
||||
reportVisiblePositions,
|
||||
targetPosition,
|
||||
}) => (
|
||||
<WithStreamItems>
|
||||
{({
|
||||
hasMoreAfterEnd,
|
||||
hasMoreBeforeStart,
|
||||
isLoadingMore,
|
||||
isReloading,
|
||||
items,
|
||||
lastLoadedTime,
|
||||
loadNewerEntries,
|
||||
}) => (
|
||||
<ScrollableLogTextStreamView
|
||||
hasMoreAfterEnd={hasMoreAfterEnd}
|
||||
hasMoreBeforeStart={hasMoreBeforeStart}
|
||||
height={height}
|
||||
isLoadingMore={isLoadingMore}
|
||||
isReloading={isReloading}
|
||||
isStreaming={isAutoReloading}
|
||||
items={items}
|
||||
jumpToTarget={jumpToTargetPosition}
|
||||
lastLoadedTime={lastLoadedTime}
|
||||
loadNewerItems={loadNewerEntries}
|
||||
reportVisibleInterval={reportVisiblePositions}
|
||||
scale={textScale}
|
||||
target={targetPosition}
|
||||
width={width}
|
||||
wrap={textWrap}
|
||||
setFlyoutItem={setFlyoutItem}
|
||||
showFlyout={showFlyout}
|
||||
/>
|
||||
)}
|
||||
</WithStreamItems>
|
||||
)}
|
||||
</WithLogPosition>
|
||||
</LogPageEventStreamColumn>
|
||||
)}
|
||||
</AutoSizer>
|
||||
<AutoSizer content>
|
||||
{({ measureRef, content: { width = 0, height = 0 } }) => {
|
||||
return (
|
||||
<LogPageMinimapColumn innerRef={measureRef}>
|
||||
<WithSummary>
|
||||
{({ buckets }) => (
|
||||
<WithLogPosition>
|
||||
{({
|
||||
hasMoreAfterEnd,
|
||||
hasMoreBeforeStart,
|
||||
isLoadingMore,
|
||||
isReloading,
|
||||
items,
|
||||
lastLoadedTime,
|
||||
loadNewerEntries,
|
||||
jumpToTargetPosition,
|
||||
reportVisibleSummary,
|
||||
visibleMidpointTime,
|
||||
visibleTimeInterval,
|
||||
}) => (
|
||||
<ScrollableLogTextStreamView
|
||||
hasMoreAfterEnd={hasMoreAfterEnd}
|
||||
hasMoreBeforeStart={hasMoreBeforeStart}
|
||||
<LogMinimap
|
||||
height={height}
|
||||
isLoadingMore={isLoadingMore}
|
||||
isReloading={isReloading}
|
||||
isStreaming={isAutoReloading}
|
||||
items={items}
|
||||
jumpToTarget={jumpToTargetPosition}
|
||||
lastLoadedTime={lastLoadedTime}
|
||||
loadNewerItems={loadNewerEntries}
|
||||
reportVisibleInterval={reportVisiblePositions}
|
||||
scale={textScale}
|
||||
target={targetPosition}
|
||||
width={width}
|
||||
wrap={wrap}
|
||||
setFlyoutItem={setFlyoutItem}
|
||||
showFlyout={showFlyout}
|
||||
highlightedInterval={visibleTimeInterval}
|
||||
intervalSize={intervalSize}
|
||||
jumpToTarget={jumpToTargetPosition}
|
||||
reportVisibleInterval={reportVisibleSummary}
|
||||
summaryBuckets={buckets}
|
||||
target={visibleMidpointTime}
|
||||
/>
|
||||
)}
|
||||
</WithStreamItems>
|
||||
</WithLogPosition>
|
||||
)}
|
||||
</WithLogPosition>
|
||||
)}
|
||||
</WithLogTextview>
|
||||
</LogPageEventStreamColumn>
|
||||
)}
|
||||
</AutoSizer>
|
||||
<AutoSizer content>
|
||||
{({ measureRef, content: { width = 0, height = 0 } }) => {
|
||||
return (
|
||||
<LogPageMinimapColumn innerRef={measureRef}>
|
||||
<WithLogMinimap>
|
||||
{({ intervalSize }) => (
|
||||
<WithSummary>
|
||||
{({ buckets }) => (
|
||||
<WithLogPosition>
|
||||
{({
|
||||
jumpToTargetPosition,
|
||||
reportVisibleSummary,
|
||||
visibleMidpointTime,
|
||||
visibleTimeInterval,
|
||||
}) => (
|
||||
<LogMinimap
|
||||
height={height}
|
||||
width={width}
|
||||
highlightedInterval={visibleTimeInterval}
|
||||
intervalSize={intervalSize}
|
||||
jumpToTarget={jumpToTargetPosition}
|
||||
reportVisibleInterval={reportVisibleSummary}
|
||||
summaryBuckets={buckets}
|
||||
target={visibleMidpointTime}
|
||||
/>
|
||||
)}
|
||||
</WithLogPosition>
|
||||
)}
|
||||
</WithSummary>
|
||||
)}
|
||||
</WithLogMinimap>
|
||||
</LogPageMinimapColumn>
|
||||
);
|
||||
}}
|
||||
</AutoSizer>
|
||||
</PageContent>
|
||||
);
|
||||
</WithSummary>
|
||||
</LogPageMinimapColumn>
|
||||
);
|
||||
}}
|
||||
</AutoSizer>
|
||||
</PageContent>
|
||||
);
|
||||
};
|
||||
|
||||
const LogPageEventStreamColumn = styled.div`
|
||||
flex: 1 0 0%;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { injectI18n } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
|
||||
import { AutocompleteField } from '../../components/autocomplete_field';
|
||||
import { Toolbar } from '../../components/eui';
|
||||
|
@ -16,95 +16,97 @@ import { LogTextScaleControls } from '../../components/logging/log_text_scale_co
|
|||
import { LogTextWrapControls } from '../../components/logging/log_text_wrap_controls';
|
||||
import { LogTimeControls } from '../../components/logging/log_time_controls';
|
||||
import { SourceConfigurationButton } from '../../components/source_configuration';
|
||||
import { LogViewConfiguration } from '../../containers/logs/log_view_configuration';
|
||||
import { WithLogFilter } from '../../containers/logs/with_log_filter';
|
||||
import { WithLogMinimap } from '../../containers/logs/with_log_minimap';
|
||||
import { WithLogPosition } from '../../containers/logs/with_log_position';
|
||||
import { WithLogTextview } from '../../containers/logs/with_log_textview';
|
||||
import { WithKueryAutocompletion } from '../../containers/with_kuery_autocompletion';
|
||||
import { WithSource } from '../../containers/with_source';
|
||||
|
||||
export const LogsToolbar = injectI18n(({ intl }) => (
|
||||
<Toolbar>
|
||||
<WithSource>
|
||||
{({ configuration, derivedIndexPattern }) => (
|
||||
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween" gutterSize="s">
|
||||
<EuiFlexItem>
|
||||
<WithKueryAutocompletion indexPattern={derivedIndexPattern}>
|
||||
{({ isLoadingSuggestions, loadSuggestions, suggestions }) => (
|
||||
<WithLogFilter indexPattern={derivedIndexPattern}>
|
||||
{({
|
||||
applyFilterQueryFromKueryExpression,
|
||||
filterQueryDraft,
|
||||
isFilterQueryDraftValid,
|
||||
setFilterQueryDraftFromKueryExpression,
|
||||
}) => (
|
||||
<AutocompleteField
|
||||
isLoadingSuggestions={isLoadingSuggestions}
|
||||
isValid={isFilterQueryDraftValid}
|
||||
loadSuggestions={loadSuggestions}
|
||||
onChange={setFilterQueryDraftFromKueryExpression}
|
||||
onSubmit={applyFilterQueryFromKueryExpression}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.toolbar.kqlSearchFieldPlaceholder',
|
||||
defaultMessage: 'Search for log entries… (e.g. host.name:host-1)',
|
||||
})}
|
||||
suggestions={suggestions}
|
||||
value={filterQueryDraft ? filterQueryDraft.expression : ''}
|
||||
/>
|
||||
)}
|
||||
</WithLogFilter>
|
||||
)}
|
||||
</WithKueryAutocompletion>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<SourceConfigurationButton />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<LogCustomizationMenu>
|
||||
<WithLogMinimap>
|
||||
{({ availableIntervalSizes, intervalSize, setIntervalSize }) => (
|
||||
<LogMinimapScaleControls
|
||||
availableIntervalSizes={availableIntervalSizes}
|
||||
setIntervalSize={setIntervalSize}
|
||||
intervalSize={intervalSize}
|
||||
export const LogsToolbar = injectI18n(({ intl }) => {
|
||||
const {
|
||||
availableIntervalSizes,
|
||||
availableTextScales,
|
||||
intervalSize,
|
||||
setIntervalSize,
|
||||
setTextScale,
|
||||
setTextWrap,
|
||||
textScale,
|
||||
textWrap,
|
||||
} = useContext(LogViewConfiguration.Context);
|
||||
|
||||
return (
|
||||
<Toolbar>
|
||||
<WithSource>
|
||||
{({ derivedIndexPattern }) => (
|
||||
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween" gutterSize="s">
|
||||
<EuiFlexItem>
|
||||
<WithKueryAutocompletion indexPattern={derivedIndexPattern}>
|
||||
{({ isLoadingSuggestions, loadSuggestions, suggestions }) => (
|
||||
<WithLogFilter indexPattern={derivedIndexPattern}>
|
||||
{({
|
||||
applyFilterQueryFromKueryExpression,
|
||||
filterQueryDraft,
|
||||
isFilterQueryDraftValid,
|
||||
setFilterQueryDraftFromKueryExpression,
|
||||
}) => (
|
||||
<AutocompleteField
|
||||
isLoadingSuggestions={isLoadingSuggestions}
|
||||
isValid={isFilterQueryDraftValid}
|
||||
loadSuggestions={loadSuggestions}
|
||||
onChange={setFilterQueryDraftFromKueryExpression}
|
||||
onSubmit={applyFilterQueryFromKueryExpression}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.toolbar.kqlSearchFieldPlaceholder',
|
||||
defaultMessage: 'Search for log entries… (e.g. host.name:host-1)',
|
||||
})}
|
||||
suggestions={suggestions}
|
||||
value={filterQueryDraft ? filterQueryDraft.expression : ''}
|
||||
/>
|
||||
)}
|
||||
</WithLogFilter>
|
||||
)}
|
||||
</WithKueryAutocompletion>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<SourceConfigurationButton />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<LogCustomizationMenu>
|
||||
<LogMinimapScaleControls
|
||||
availableIntervalSizes={availableIntervalSizes}
|
||||
setIntervalSize={setIntervalSize}
|
||||
intervalSize={intervalSize}
|
||||
/>
|
||||
<LogTextWrapControls wrap={textWrap} setTextWrap={setTextWrap} />
|
||||
<LogTextScaleControls
|
||||
availableTextScales={availableTextScales}
|
||||
textScale={textScale}
|
||||
setTextScale={setTextScale}
|
||||
/>
|
||||
</LogCustomizationMenu>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<WithLogPosition resetOnUnmount>
|
||||
{({
|
||||
visibleMidpointTime,
|
||||
isAutoReloading,
|
||||
jumpToTargetPositionTime,
|
||||
startLiveStreaming,
|
||||
stopLiveStreaming,
|
||||
}) => (
|
||||
<LogTimeControls
|
||||
currentTime={visibleMidpointTime}
|
||||
isLiveStreaming={isAutoReloading}
|
||||
jumpToTime={jumpToTargetPositionTime}
|
||||
startLiveStreaming={startLiveStreaming}
|
||||
stopLiveStreaming={stopLiveStreaming}
|
||||
/>
|
||||
)}
|
||||
</WithLogMinimap>
|
||||
<WithLogTextview>
|
||||
{({ availableTextScales, textScale, setTextScale, setTextWrap, wrap }) => (
|
||||
<>
|
||||
<LogTextWrapControls wrap={wrap} setTextWrap={setTextWrap} />
|
||||
<LogTextScaleControls
|
||||
availableTextScales={availableTextScales}
|
||||
textScale={textScale}
|
||||
setTextScale={setTextScale}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</WithLogTextview>
|
||||
</LogCustomizationMenu>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<WithLogPosition resetOnUnmount>
|
||||
{({
|
||||
visibleMidpointTime,
|
||||
isAutoReloading,
|
||||
jumpToTargetPositionTime,
|
||||
startLiveStreaming,
|
||||
stopLiveStreaming,
|
||||
}) => (
|
||||
<LogTimeControls
|
||||
currentTime={visibleMidpointTime}
|
||||
isLiveStreaming={isAutoReloading}
|
||||
jumpToTime={jumpToTargetPositionTime}
|
||||
startLiveStreaming={startLiveStreaming}
|
||||
stopLiveStreaming={stopLiveStreaming}
|
||||
/>
|
||||
)}
|
||||
</WithLogPosition>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
</WithSource>
|
||||
</Toolbar>
|
||||
));
|
||||
</WithLogPosition>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
</WithSource>
|
||||
</Toolbar>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
|
||||
export {
|
||||
logFilterActions,
|
||||
logMinimapActions,
|
||||
logPositionActions,
|
||||
logTextviewActions,
|
||||
metricTimeActions,
|
||||
waffleFilterActions,
|
||||
waffleTimeActions,
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
*/
|
||||
|
||||
export { logFilterActions } from './log_filter';
|
||||
export { logMinimapActions } from './log_minimap';
|
||||
export { logPositionActions } from './log_position';
|
||||
export { logTextviewActions } from './log_textview';
|
||||
export { metricTimeActions } from './metric_time';
|
||||
export { waffleFilterActions } from './waffle_filter';
|
||||
export { waffleTimeActions } from './waffle_time';
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import actionCreatorFactory from 'typescript-fsa';
|
||||
|
||||
const actionCreator = actionCreatorFactory('x-pack/infra/local/log_minimap');
|
||||
|
||||
export const setMinimapIntervalSize = actionCreator<number>('SET_MINIMAP_INTERVAL_SIZE');
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import * as logMinimapActions from './actions';
|
||||
import * as logMinimapSelectors from './selectors';
|
||||
|
||||
export { logMinimapActions, logMinimapSelectors };
|
||||
export * from './reducer';
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { reducerWithInitialState } from 'typescript-fsa-reducers/dist';
|
||||
|
||||
import { setMinimapIntervalSize } from './actions';
|
||||
|
||||
export interface LogMinimapState {
|
||||
intervalSize: number;
|
||||
}
|
||||
|
||||
export const initialLogMinimapState: LogMinimapState = {
|
||||
intervalSize: 1000 * 60 * 60 * 24,
|
||||
};
|
||||
|
||||
export const logMinimapReducer = reducerWithInitialState(initialLogMinimapState)
|
||||
.case(setMinimapIntervalSize, (state, intervalSize) => ({
|
||||
intervalSize,
|
||||
}))
|
||||
.build();
|
|
@ -1,9 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { LogMinimapState } from './reducer';
|
||||
|
||||
export const selectMinimapIntervalSize = (state: LogMinimapState) => state.intervalSize;
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import actionCreatorFactory from 'typescript-fsa';
|
||||
|
||||
import { TextScale } from '../../../../common/log_text_scale';
|
||||
|
||||
const actionCreator = actionCreatorFactory('x-pack/infra/local/log_textview');
|
||||
|
||||
export const setTextviewScale = actionCreator<TextScale>('SET_TEXTVIEW_SCALE');
|
||||
|
||||
export const setTextviewWrap = actionCreator<boolean>('SET_TEXTVIEW_WRAP');
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import * as logTextviewActions from './actions';
|
||||
import * as logTextviewSelectors from './selectors';
|
||||
|
||||
export { logTextviewActions, logTextviewSelectors };
|
||||
export * from './reducer';
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { combineReducers } from 'redux';
|
||||
import { reducerWithInitialState } from 'typescript-fsa-reducers/dist';
|
||||
|
||||
import { TextScale } from '../../../../common/log_text_scale';
|
||||
import { setTextviewScale, setTextviewWrap } from './actions';
|
||||
|
||||
export interface LogTextviewState {
|
||||
scale: TextScale;
|
||||
wrap: boolean;
|
||||
}
|
||||
|
||||
export const initialLogTextviewState: LogTextviewState = {
|
||||
scale: 'medium',
|
||||
wrap: true,
|
||||
};
|
||||
|
||||
const textviewScaleReducer = reducerWithInitialState(initialLogTextviewState.scale).case(
|
||||
setTextviewScale,
|
||||
(state, scale) => scale
|
||||
);
|
||||
|
||||
const textviewWrapReducer = reducerWithInitialState(initialLogTextviewState.wrap).case(
|
||||
setTextviewWrap,
|
||||
(state, wrap) => wrap
|
||||
);
|
||||
|
||||
export const logTextviewReducer = combineReducers<LogTextviewState>({
|
||||
scale: textviewScaleReducer,
|
||||
wrap: textviewWrapReducer,
|
||||
});
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { LogTextviewState } from './reducer';
|
||||
|
||||
export const selectTextviewScale = (state: LogTextviewState) => state.scale;
|
||||
|
||||
export const selectTextviewWrap = (state: LogTextviewState) => state.wrap;
|
|
@ -8,9 +8,7 @@ import { combineReducers } from 'redux';
|
|||
|
||||
import { initialLogFilterState, logFilterReducer, LogFilterState } from './log_filter';
|
||||
import { flyoutOptionsReducer, FlyoutOptionsState, initialFlyoutOptionsState } from './log_flyout';
|
||||
import { initialLogMinimapState, logMinimapReducer, LogMinimapState } from './log_minimap';
|
||||
import { initialLogPositionState, logPositionReducer, LogPositionState } from './log_position';
|
||||
import { initialLogTextviewState, logTextviewReducer, LogTextviewState } from './log_textview';
|
||||
import { initialMetricTimeState, metricTimeReducer, MetricTimeState } from './metric_time';
|
||||
import { initialWaffleFilterState, waffleFilterReducer, WaffleFilterState } from './waffle_filter';
|
||||
import {
|
||||
|
@ -22,9 +20,7 @@ import { initialWaffleTimeState, waffleTimeReducer, WaffleTimeState } from './wa
|
|||
|
||||
export interface LocalState {
|
||||
logFilter: LogFilterState;
|
||||
logMinimap: LogMinimapState;
|
||||
logPosition: LogPositionState;
|
||||
logTextview: LogTextviewState;
|
||||
metricTime: MetricTimeState;
|
||||
waffleFilter: WaffleFilterState;
|
||||
waffleTime: WaffleTimeState;
|
||||
|
@ -34,9 +30,7 @@ export interface LocalState {
|
|||
|
||||
export const initialLocalState: LocalState = {
|
||||
logFilter: initialLogFilterState,
|
||||
logMinimap: initialLogMinimapState,
|
||||
logPosition: initialLogPositionState,
|
||||
logTextview: initialLogTextviewState,
|
||||
metricTime: initialMetricTimeState,
|
||||
waffleFilter: initialWaffleFilterState,
|
||||
waffleTime: initialWaffleTimeState,
|
||||
|
@ -46,9 +40,7 @@ export const initialLocalState: LocalState = {
|
|||
|
||||
export const localReducer = combineReducers<LocalState>({
|
||||
logFilter: logFilterReducer,
|
||||
logMinimap: logMinimapReducer,
|
||||
logPosition: logPositionReducer,
|
||||
logTextview: logTextviewReducer,
|
||||
metricTime: metricTimeReducer,
|
||||
waffleFilter: waffleFilterReducer,
|
||||
waffleTime: waffleTimeReducer,
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
import { globalizeSelectors } from '../../utils/typed_redux';
|
||||
import { logFilterSelectors as innerLogFilterSelectors } from './log_filter';
|
||||
import { flyoutOptionsSelectors as innerFlyoutOptionsSelectors } from './log_flyout';
|
||||
import { logMinimapSelectors as innerLogMinimapSelectors } from './log_minimap';
|
||||
import { logPositionSelectors as innerLogPositionSelectors } from './log_position';
|
||||
import { logTextviewSelectors as innerLogTextviewSelectors } from './log_textview';
|
||||
import { metricTimeSelectors as innerMetricTimeSelectors } from './metric_time';
|
||||
import { LocalState } from './reducer';
|
||||
import { waffleFilterSelectors as innerWaffleFilterSelectors } from './waffle_filter';
|
||||
|
@ -21,21 +19,11 @@ export const logFilterSelectors = globalizeSelectors(
|
|||
innerLogFilterSelectors
|
||||
);
|
||||
|
||||
export const logMinimapSelectors = globalizeSelectors(
|
||||
(state: LocalState) => state.logMinimap,
|
||||
innerLogMinimapSelectors
|
||||
);
|
||||
|
||||
export const logPositionSelectors = globalizeSelectors(
|
||||
(state: LocalState) => state.logPosition,
|
||||
innerLogPositionSelectors
|
||||
);
|
||||
|
||||
export const logTextviewSelectors = globalizeSelectors(
|
||||
(state: LocalState) => state.logTextview,
|
||||
innerLogTextviewSelectors
|
||||
);
|
||||
|
||||
export const metricTimeSelectors = globalizeSelectors(
|
||||
(state: LocalState) => state.metricTime,
|
||||
innerMetricTimeSelectors
|
||||
|
|
|
@ -11,9 +11,7 @@ import { globalizeSelectors } from '../utils/typed_redux';
|
|||
import {
|
||||
flyoutOptionsSelectors as localFlyoutOptionsSelectors,
|
||||
logFilterSelectors as localLogFilterSelectors,
|
||||
logMinimapSelectors as localLogMinimapSelectors,
|
||||
logPositionSelectors as localLogPositionSelectors,
|
||||
logTextviewSelectors as localLogTextviewSelectors,
|
||||
metricTimeSelectors as localMetricTimeSelectors,
|
||||
waffleFilterSelectors as localWaffleFilterSelectors,
|
||||
waffleOptionsSelectors as localWaffleOptionsSelectors,
|
||||
|
@ -32,9 +30,7 @@ import {
|
|||
const selectLocal = (state: State) => state.local;
|
||||
|
||||
export const logFilterSelectors = globalizeSelectors(selectLocal, localLogFilterSelectors);
|
||||
export const logMinimapSelectors = globalizeSelectors(selectLocal, localLogMinimapSelectors);
|
||||
export const logPositionSelectors = globalizeSelectors(selectLocal, localLogPositionSelectors);
|
||||
export const logTextviewSelectors = globalizeSelectors(selectLocal, localLogTextviewSelectors);
|
||||
export const metricTimeSelectors = globalizeSelectors(selectLocal, localMetricTimeSelectors);
|
||||
export const waffleFilterSelectors = globalizeSelectors(selectLocal, localWaffleFilterSelectors);
|
||||
export const waffleTimeSelectors = globalizeSelectors(selectLocal, localWaffleTimeSelectors);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
import { I18nProvider, InjectedIntl, intlShape } from '@kbn/i18n/react';
|
||||
import { mount, ReactWrapper, render, shallow } from 'enzyme';
|
||||
import React, { ReactElement, ValidationMap } from 'react';
|
||||
import { act as reactAct } from 'react-dom/test-utils';
|
||||
|
||||
// Use fake component to extract `intl` property to use in tests.
|
||||
const { intl } = (mount(
|
||||
|
@ -113,3 +114,69 @@ export function renderWithIntl<T>(
|
|||
|
||||
return render(nodeWithIntlProp(node), options);
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper object to provide access to the state of a hook under test and to
|
||||
* enable interaction with that hook.
|
||||
*/
|
||||
interface ReactHookWrapper<HookValue> {
|
||||
/* Ensures that async React operations have settled before and after the
|
||||
* given actor callback is called. */
|
||||
act: (actor: (lastHookValue: HookValue) => void) => void;
|
||||
/* The enzyme wrapper around the test component. */
|
||||
component: ReactWrapper;
|
||||
/* The most recent value return the by test harness of the hook. */
|
||||
getLastHookValue: () => HookValue;
|
||||
/* The jest Mock function that receives the hook values for introspection. */
|
||||
hookValueCallback: jest.Mock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows for execution of hooks inside of a test component which records the
|
||||
* returned values.
|
||||
*
|
||||
* @param body A function that calls the hook and returns data derived from it
|
||||
* @param WrapperComponent A component that, if provided, will be wrapped
|
||||
* around the test component. This can be useful to provide context values.
|
||||
* @return {ReactHookWrapper} An object providing access to the hook state and
|
||||
* functions to interact with it.
|
||||
*/
|
||||
export const mountHook = <HookValue extends any>(
|
||||
body: () => HookValue,
|
||||
WrapperComponent?: React.ComponentType
|
||||
): ReactHookWrapper<HookValue> => {
|
||||
const hookValueCallback = jest.fn();
|
||||
|
||||
const act = (actor: (lastHookValue: HookValue) => void) => {
|
||||
reactAct(() => actor(getLastHookValue()));
|
||||
component.update();
|
||||
};
|
||||
|
||||
const getLastHookValue = () => {
|
||||
const calls = hookValueCallback.mock.calls;
|
||||
if (calls.length <= 0) {
|
||||
throw Error('No recent hook value present.');
|
||||
}
|
||||
return calls[calls.length - 1][0];
|
||||
};
|
||||
|
||||
const TestComponent = () => {
|
||||
hookValueCallback(body());
|
||||
return null;
|
||||
};
|
||||
|
||||
const component = WrapperComponent
|
||||
? mount(
|
||||
<WrapperComponent>
|
||||
<TestComponent />
|
||||
</WrapperComponent>
|
||||
)
|
||||
: mount(<TestComponent />);
|
||||
|
||||
return {
|
||||
act,
|
||||
component,
|
||||
getLastHookValue,
|
||||
hookValueCallback,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6947,6 +6947,11 @@ constants-browserify@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
|
||||
integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
|
||||
|
||||
"constate-latest@npm:constate@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/constate/-/constate-1.0.0.tgz#93fa87108e364a05e93b3597e22d53adaf86776d"
|
||||
integrity sha512-b1Pip712fAQ1el4pndiYeVMXAzlbrD8+Z8ik79TOQc3ZJNjxKGawT0gCPpANsNbT4eHszDZ/8472hvL1rowUhQ==
|
||||
|
||||
constate@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/constate/-/constate-0.9.0.tgz#877197ef8fbcacee95672a7e98f7b21dec818891"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue