mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* Add empty analysis tab * Add ml capabilities check * Add job status checking functionality * Add a loading page for the job status check * Change types / change method for deriving space ID / change setup requirement filtering check * Use new structure * Change tab syntax * i18n translate message prop * Fix import
This commit is contained in:
parent
9f0b7ce998
commit
015116980d
15 changed files with 468 additions and 88 deletions
|
@ -6,5 +6,8 @@
|
|||
|
||||
import { JobType } from './log_analysis';
|
||||
|
||||
export const getJobIdPrefix = (spaceId: string, sourceId: string) =>
|
||||
`kibana-logs-ui-${spaceId}-${sourceId}-`;
|
||||
|
||||
export const getJobId = (spaceId: string, sourceId: string, jobType: JobType) =>
|
||||
`kibana-logs-ui-${spaceId}-${sourceId}-${jobType}`;
|
||||
`${getJobIdPrefix(spaceId, sourceId)}${jobType}`;
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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 rt from 'io-ts';
|
||||
import { kfetch } from 'ui/kfetch';
|
||||
import { getJobId } from '../../../../../common/log_analysis';
|
||||
import { throwErrors, createPlainError } from '../../../../../common/runtime_types';
|
||||
|
||||
export const callJobsSummaryAPI = async (spaceId: string, sourceId: string) => {
|
||||
const response = await kfetch({
|
||||
method: 'POST',
|
||||
pathname: '/api/ml/jobs/jobs_summary',
|
||||
body: JSON.stringify(
|
||||
fetchJobStatusRequestPayloadRT.encode({
|
||||
jobIds: [getJobId(spaceId, sourceId, 'log-entry-rate')],
|
||||
})
|
||||
),
|
||||
});
|
||||
return fetchJobStatusResponsePayloadRT.decode(response).getOrElseL(throwErrors(createPlainError));
|
||||
};
|
||||
|
||||
export const fetchJobStatusRequestPayloadRT = rt.type({
|
||||
jobIds: rt.array(rt.string),
|
||||
});
|
||||
|
||||
export type FetchJobStatusRequestPayload = rt.TypeOf<typeof fetchJobStatusRequestPayloadRT>;
|
||||
|
||||
// TODO: Get this to align with the payload - something is tripping it up somewhere
|
||||
// export const fetchJobStatusResponsePayloadRT = rt.array(rt.type({
|
||||
// datafeedId: rt.string,
|
||||
// datafeedIndices: rt.array(rt.string),
|
||||
// datafeedState: rt.string,
|
||||
// description: rt.string,
|
||||
// earliestTimestampMs: rt.number,
|
||||
// groups: rt.array(rt.string),
|
||||
// hasDatafeed: rt.boolean,
|
||||
// id: rt.string,
|
||||
// isSingleMetricViewerJob: rt.boolean,
|
||||
// jobState: rt.string,
|
||||
// latestResultsTimestampMs: rt.number,
|
||||
// latestTimestampMs: rt.number,
|
||||
// memory_status: rt.string,
|
||||
// nodeName: rt.union([rt.string, rt.undefined]),
|
||||
// processed_record_count: rt.number,
|
||||
// fullJob: rt.any,
|
||||
// auditMessage: rt.any,
|
||||
// deleting: rt.union([rt.boolean, rt.undefined]),
|
||||
// }));
|
||||
|
||||
export const fetchJobStatusResponsePayloadRT = rt.any;
|
||||
|
||||
export type FetchJobStatusResponsePayload = rt.TypeOf<typeof fetchJobStatusResponsePayloadRT>;
|
|
@ -4,4 +4,6 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export * from './log_analysis_capabilities';
|
||||
export * from './log_analysis_jobs';
|
||||
export * from './log_analysis_results';
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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 { useMemo, useState, useEffect } from 'react';
|
||||
import { kfetch } from 'ui/kfetch';
|
||||
|
||||
import { useTrackedPromise } from '../../../utils/use_tracked_promise';
|
||||
import {
|
||||
getMlCapabilitiesResponsePayloadRT,
|
||||
GetMlCapabilitiesResponsePayload,
|
||||
} from './ml_api_types';
|
||||
import { throwErrors, createPlainError } from '../../../../common/runtime_types';
|
||||
|
||||
export const useLogAnalysisCapabilities = () => {
|
||||
const [mlCapabilities, setMlCapabilities] = useState<GetMlCapabilitiesResponsePayload>(
|
||||
initialMlCapabilities
|
||||
);
|
||||
|
||||
const [fetchMlCapabilitiesRequest, fetchMlCapabilities] = useTrackedPromise(
|
||||
{
|
||||
cancelPreviousOn: 'resolution',
|
||||
createPromise: async () => {
|
||||
const rawResponse = await kfetch({
|
||||
method: 'GET',
|
||||
pathname: '/api/ml/ml_capabilities',
|
||||
});
|
||||
|
||||
return getMlCapabilitiesResponsePayloadRT
|
||||
.decode(rawResponse)
|
||||
.getOrElseL(throwErrors(createPlainError));
|
||||
},
|
||||
onResolve: response => {
|
||||
setMlCapabilities(response);
|
||||
},
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetchMlCapabilities();
|
||||
}, []);
|
||||
|
||||
const isLoading = useMemo(() => fetchMlCapabilitiesRequest.state === 'pending', [
|
||||
fetchMlCapabilitiesRequest.state,
|
||||
]);
|
||||
|
||||
return {
|
||||
hasLogAnalysisCapabilites: mlCapabilities.capabilities.canCreateJob,
|
||||
isLoading,
|
||||
};
|
||||
};
|
||||
|
||||
const initialMlCapabilities = {
|
||||
capabilities: {
|
||||
canGetJobs: false,
|
||||
canCreateJob: false,
|
||||
canDeleteJob: false,
|
||||
canOpenJob: false,
|
||||
canCloseJob: false,
|
||||
canForecastJob: false,
|
||||
canGetDatafeeds: false,
|
||||
canStartStopDatafeed: false,
|
||||
canUpdateJob: false,
|
||||
canUpdateDatafeed: false,
|
||||
canPreviewDatafeed: false,
|
||||
canGetCalendars: false,
|
||||
canCreateCalendar: false,
|
||||
canDeleteCalendar: false,
|
||||
canGetFilters: false,
|
||||
canCreateFilter: false,
|
||||
canDeleteFilter: false,
|
||||
canFindFileStructure: false,
|
||||
canGetDataFrameJobs: false,
|
||||
canDeleteDataFrameJob: false,
|
||||
canPreviewDataFrameJob: false,
|
||||
canCreateDataFrameJob: false,
|
||||
canStartStopDataFrameJob: false,
|
||||
},
|
||||
isPlatinumOrTrialLicense: false,
|
||||
mlFeatureEnabledInSpace: false,
|
||||
upgradeInProgress: false,
|
||||
};
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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 createContainer from 'constate-latest';
|
||||
import { useMemo, useEffect, useState } from 'react';
|
||||
import { values } from 'lodash';
|
||||
import { getJobId } from '../../../../common/log_analysis';
|
||||
import { useTrackedPromise } from '../../../utils/use_tracked_promise';
|
||||
import { callJobsSummaryAPI } from './api/ml_get_jobs_summary_api';
|
||||
|
||||
type JobStatus = 'unknown' | 'closed' | 'closing' | 'failed' | 'opened' | 'opening' | 'deleted';
|
||||
// type DatafeedStatus = 'unknown' | 'started' | 'starting' | 'stopped' | 'stopping' | 'deleted';
|
||||
|
||||
export const useLogAnalysisJobs = ({
|
||||
indexPattern,
|
||||
sourceId,
|
||||
spaceId,
|
||||
}: {
|
||||
indexPattern: string;
|
||||
sourceId: string;
|
||||
spaceId: string;
|
||||
}) => {
|
||||
const [jobStatus, setJobStatus] = useState<{
|
||||
logEntryRate: JobStatus;
|
||||
}>({
|
||||
logEntryRate: 'unknown',
|
||||
});
|
||||
|
||||
// const [setupMlModuleRequest, setupMlModule] = useTrackedPromise(
|
||||
// {
|
||||
// cancelPreviousOn: 'resolution',
|
||||
// createPromise: async () => {
|
||||
// kfetch({
|
||||
// method: 'POST',
|
||||
// pathname: '/api/ml/modules/setup',
|
||||
// body: JSON.stringify(
|
||||
// setupMlModuleRequestPayloadRT.encode({
|
||||
// indexPatternName: indexPattern,
|
||||
// prefix: getJobIdPrefix(spaceId, sourceId),
|
||||
// startDatafeed: true,
|
||||
// })
|
||||
// ),
|
||||
// });
|
||||
// },
|
||||
// },
|
||||
// [indexPattern, spaceId, sourceId]
|
||||
// );
|
||||
|
||||
const [fetchJobStatusRequest, fetchJobStatus] = useTrackedPromise(
|
||||
{
|
||||
cancelPreviousOn: 'resolution',
|
||||
createPromise: async () => {
|
||||
return callJobsSummaryAPI(spaceId, sourceId);
|
||||
},
|
||||
onResolve: response => {
|
||||
if (response && response.length) {
|
||||
const logEntryRate = response.find(
|
||||
(job: any) => job.id === getJobId(spaceId, sourceId, 'log-entry-rate')
|
||||
);
|
||||
setJobStatus({
|
||||
logEntryRate: logEntryRate ? logEntryRate.jobState : 'unknown',
|
||||
});
|
||||
}
|
||||
},
|
||||
onReject: error => {
|
||||
// TODO: Handle errors
|
||||
},
|
||||
},
|
||||
[indexPattern, spaceId, sourceId]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetchJobStatus();
|
||||
}, []);
|
||||
|
||||
const isSetupRequired = useMemo(() => {
|
||||
const jobStates = values(jobStatus);
|
||||
return (
|
||||
jobStates.filter(state => state === 'opened' || state === 'opening').length < jobStates.length
|
||||
);
|
||||
}, [jobStatus]);
|
||||
|
||||
const isLoadingSetupStatus = useMemo(() => fetchJobStatusRequest.state === 'pending', [
|
||||
fetchJobStatusRequest.state,
|
||||
]);
|
||||
|
||||
return {
|
||||
jobStatus,
|
||||
isSetupRequired,
|
||||
isLoadingSetupStatus,
|
||||
};
|
||||
};
|
||||
|
||||
export const LogAnalysisJobs = createContainer(useLogAnalysisJobs);
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import createContainer from 'constate-latest/dist/ts/src';
|
||||
import createContainer from 'constate-latest';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useLogEntryRate } from './log_entry_rate';
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 rt from 'io-ts';
|
||||
|
||||
export const getMlCapabilitiesResponsePayloadRT = rt.type({
|
||||
capabilities: rt.type({
|
||||
canGetJobs: rt.boolean,
|
||||
canCreateJob: rt.boolean,
|
||||
canDeleteJob: rt.boolean,
|
||||
canOpenJob: rt.boolean,
|
||||
canCloseJob: rt.boolean,
|
||||
canForecastJob: rt.boolean,
|
||||
canGetDatafeeds: rt.boolean,
|
||||
canStartStopDatafeed: rt.boolean,
|
||||
canUpdateJob: rt.boolean,
|
||||
canUpdateDatafeed: rt.boolean,
|
||||
canPreviewDatafeed: rt.boolean,
|
||||
}),
|
||||
isPlatinumOrTrialLicense: rt.boolean,
|
||||
mlFeatureEnabledInSpace: rt.boolean,
|
||||
upgradeInProgress: rt.boolean,
|
||||
});
|
||||
|
||||
export type GetMlCapabilitiesResponsePayload = rt.TypeOf<typeof getMlCapabilitiesResponsePayloadRT>;
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export * from './page';
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 React, { useContext } from 'react';
|
||||
import chrome from 'ui/chrome';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ColumnarPage } from '../../../components/page';
|
||||
import { LoadingPage } from '../../../components/loading_page';
|
||||
import { AnalysisPageProviders } from './page_providers';
|
||||
import { AnalysisResultsContent } from './page_results_content';
|
||||
import { AnalysisSetupContent } from './page_setup_content';
|
||||
import { useLogAnalysisJobs } from '../../../containers/logs/log_analysis/log_analysis_jobs';
|
||||
import { Source } from '../../../containers/source';
|
||||
|
||||
export const AnalysisPage = () => {
|
||||
const { sourceId, source } = useContext(Source.Context);
|
||||
const spaceId = chrome.getInjected('activeSpace').space.id;
|
||||
const { isSetupRequired, isLoadingSetupStatus } = useLogAnalysisJobs({
|
||||
indexPattern: source ? source.configuration.logAlias : '',
|
||||
sourceId,
|
||||
spaceId,
|
||||
});
|
||||
|
||||
return (
|
||||
<AnalysisPageProviders>
|
||||
<ColumnarPage data-test-subj="infraLogsAnalysisPage">
|
||||
{isLoadingSetupStatus ? (
|
||||
<LoadingPage
|
||||
message={i18n.translate('xpack.infra.logs.analysisPage.loadingMessage', {
|
||||
defaultMessage: 'Checking status of analysis jobs...',
|
||||
})}
|
||||
/>
|
||||
) : isSetupRequired ? (
|
||||
<AnalysisSetupContent />
|
||||
) : (
|
||||
<AnalysisResultsContent />
|
||||
)}
|
||||
</ColumnarPage>
|
||||
</AnalysisPageProviders>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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 React from 'react';
|
||||
|
||||
import { Source, useSource } from '../../../containers/source';
|
||||
import { useSourceId } from '../../../containers/source_id';
|
||||
|
||||
export const AnalysisPageProviders: React.FunctionComponent = ({ children }) => {
|
||||
const [sourceId] = useSourceId();
|
||||
const source = useSource({ sourceId });
|
||||
|
||||
return <Source.Context.Provider value={source}>{children}</Source.Context.Provider>;
|
||||
};
|
|
@ -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;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { useTrackPageview } from '../../../hooks/use_track_metric';
|
||||
|
||||
export const AnalysisResultsContent = () => {
|
||||
useTrackPageview({ app: 'infra_logs', path: 'analysis_results' });
|
||||
useTrackPageview({ app: 'infra_logs', path: 'analysis_results', delay: 15000 });
|
||||
|
||||
return <div>Results</div>;
|
||||
};
|
|
@ -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;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { useTrackPageview } from '../../../hooks/use_track_metric';
|
||||
|
||||
export const AnalysisSetupContent = () => {
|
||||
useTrackPageview({ app: 'infra_logs', path: 'analysis_setup' });
|
||||
useTrackPageview({ app: 'infra_logs', path: 'analysis_setup', delay: 15000 });
|
||||
|
||||
return <div>Setup</div>;
|
||||
};
|
|
@ -16,10 +16,15 @@ import { HelpCenterContent } from '../../components/help_center_content';
|
|||
import { Header } from '../../components/header';
|
||||
import { RoutedTabs } from '../../components/navigation/routed_tabs';
|
||||
import { ColumnarPage } from '../../components/page';
|
||||
import { Source } from '../../containers/source';
|
||||
import { SourceLoadingPage } from '../../components/source_loading_page';
|
||||
import { SourceErrorPage } from '../../components/source_error_page';
|
||||
import { Source, useSource } from '../../containers/source';
|
||||
import { StreamPage } from './stream';
|
||||
import { SettingsPage } from '../shared/settings';
|
||||
import { AppNavigation } from '../../components/navigation/app_navigation';
|
||||
import { AnalysisPage } from './analysis';
|
||||
import { useLogAnalysisCapabilities } from '../../containers/logs/log_analysis';
|
||||
import { useSourceId } from '../../containers/source_id';
|
||||
|
||||
interface LogsPageProps extends RouteComponentProps {
|
||||
intl: InjectedIntl;
|
||||
|
@ -27,61 +32,90 @@ interface LogsPageProps extends RouteComponentProps {
|
|||
}
|
||||
|
||||
export const LogsPage = injectUICapabilities(
|
||||
injectI18n(({ match, intl, uiCapabilities }: LogsPageProps) => (
|
||||
<Source.Provider sourceId="default">
|
||||
<ColumnarPage>
|
||||
<DocumentTitle
|
||||
title={intl.formatMessage({
|
||||
id: 'xpack.infra.logs.index.documentTitle',
|
||||
defaultMessage: 'Logs',
|
||||
})}
|
||||
/>
|
||||
injectI18n(({ match, intl, uiCapabilities }: LogsPageProps) => {
|
||||
const [sourceId] = useSourceId();
|
||||
const source = useSource({ sourceId });
|
||||
const { hasLogAnalysisCapabilites } = useLogAnalysisCapabilities();
|
||||
const streamTab = {
|
||||
title: intl.formatMessage({
|
||||
id: 'xpack.infra.logs.index.streamTabTitle',
|
||||
defaultMessage: 'Stream',
|
||||
}),
|
||||
path: `${match.path}/stream`,
|
||||
};
|
||||
const analysisTab = {
|
||||
title: intl.formatMessage({
|
||||
id: 'xpack.infra.logs.index.analysisTabTitle',
|
||||
defaultMessage: 'Analysis',
|
||||
}),
|
||||
path: `${match.path}/analysis`,
|
||||
};
|
||||
const settingsTab = {
|
||||
title: intl.formatMessage({
|
||||
id: 'xpack.infra.logs.index.settingsTabTitle',
|
||||
defaultMessage: 'Settings',
|
||||
}),
|
||||
path: `${match.path}/settings`,
|
||||
};
|
||||
return (
|
||||
<Source.Context.Provider value={source}>
|
||||
<ColumnarPage>
|
||||
<DocumentTitle
|
||||
title={intl.formatMessage({
|
||||
id: 'xpack.infra.logs.index.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',
|
||||
})}
|
||||
/>
|
||||
<HelpCenterContent
|
||||
feedbackLink="https://discuss.elastic.co/c/logs"
|
||||
feedbackLinkText={intl.formatMessage({
|
||||
id: 'xpack.infra.logsPage.logsHelpContent.feedbackLinkText',
|
||||
defaultMessage: 'Provide feedback for Logs',
|
||||
})}
|
||||
/>
|
||||
|
||||
<Header
|
||||
breadcrumbs={[
|
||||
{
|
||||
text: i18n.translate('xpack.infra.header.logsTitle', {
|
||||
defaultMessage: 'Logs',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
readOnlyBadge={!uiCapabilities.logs.save}
|
||||
/>
|
||||
|
||||
<AppNavigation>
|
||||
<RoutedTabs
|
||||
tabs={[
|
||||
<Header
|
||||
breadcrumbs={[
|
||||
{
|
||||
title: intl.formatMessage({
|
||||
id: 'xpack.infra.logs.index.streamTabTitle',
|
||||
defaultMessage: 'Stream',
|
||||
text: i18n.translate('xpack.infra.header.logsTitle', {
|
||||
defaultMessage: 'Logs',
|
||||
}),
|
||||
path: `${match.path}/stream`,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({
|
||||
id: 'xpack.infra.logs.index.settingsTabTitle',
|
||||
defaultMessage: 'Settings',
|
||||
}),
|
||||
path: `${match.path}/settings`,
|
||||
},
|
||||
]}
|
||||
readOnlyBadge={!uiCapabilities.logs.save}
|
||||
/>
|
||||
</AppNavigation>
|
||||
{source.isLoadingSource ||
|
||||
(!source.isLoadingSource &&
|
||||
!source.hasFailedLoadingSource &&
|
||||
source.source === undefined) ? (
|
||||
<SourceLoadingPage />
|
||||
) : source.hasFailedLoadingSource ? (
|
||||
<SourceErrorPage
|
||||
errorMessage={source.loadSourceFailureMessage || ''}
|
||||
retry={source.loadSource}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<AppNavigation>
|
||||
<RoutedTabs
|
||||
tabs={
|
||||
hasLogAnalysisCapabilites
|
||||
? [streamTab, analysisTab, settingsTab]
|
||||
: [streamTab, settingsTab]
|
||||
}
|
||||
/>
|
||||
</AppNavigation>
|
||||
|
||||
<Switch>
|
||||
<Route path={`${match.path}/stream`} component={StreamPage} />
|
||||
<Route path={`${match.path}/settings`} component={SettingsPage} />
|
||||
</Switch>
|
||||
</ColumnarPage>
|
||||
</Source.Provider>
|
||||
))
|
||||
<Switch>
|
||||
<Route path={`${match.path}/stream`} component={StreamPage} />
|
||||
<Route path={`${match.path}/analysis`} component={AnalysisPage} />
|
||||
<Route path={`${match.path}/settings`} component={SettingsPage} />
|
||||
</Switch>
|
||||
</>
|
||||
)}
|
||||
</ColumnarPage>
|
||||
</Source.Context.Provider>
|
||||
);
|
||||
})
|
||||
);
|
||||
|
|
|
@ -6,32 +6,12 @@
|
|||
|
||||
import React, { useContext } from 'react';
|
||||
|
||||
import { SourceErrorPage } from '../../../components/source_error_page';
|
||||
import { SourceLoadingPage } from '../../../components/source_loading_page';
|
||||
import { Source } from '../../../containers/source';
|
||||
import { LogsPageLogsContent } from './page_logs_content';
|
||||
import { LogsPageNoIndicesContent } from './page_no_indices_content';
|
||||
|
||||
export const StreamPageContent: React.FunctionComponent = () => {
|
||||
const {
|
||||
hasFailedLoadingSource,
|
||||
isLoadingSource,
|
||||
logIndicesExist,
|
||||
loadSource,
|
||||
loadSourceFailureMessage,
|
||||
} = useContext(Source.Context);
|
||||
const { logIndicesExist } = useContext(Source.Context);
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoadingSource ? (
|
||||
<SourceLoadingPage />
|
||||
) : logIndicesExist ? (
|
||||
<LogsPageLogsContent />
|
||||
) : hasFailedLoadingSource ? (
|
||||
<SourceErrorPage errorMessage={loadSourceFailureMessage || ''} retry={loadSource} />
|
||||
) : (
|
||||
<LogsPageNoIndicesContent />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
return <>{logIndicesExist ? <LogsPageLogsContent /> : <LogsPageNoIndicesContent />}</>;
|
||||
};
|
||||
|
|
|
@ -4,27 +4,23 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
|
||||
import { LogFlyout } from '../../../containers/logs/log_flyout';
|
||||
import { LogViewConfiguration } from '../../../containers/logs/log_view_configuration';
|
||||
import { LogHighlightsState } from '../../../containers/logs/log_highlights/log_highlights';
|
||||
import { Source, useSource } from '../../../containers/source';
|
||||
import { useSourceId } from '../../../containers/source_id';
|
||||
import { Source } from '../../../containers/source';
|
||||
|
||||
export const LogsPageProviders: React.FunctionComponent = ({ children }) => {
|
||||
const [sourceId] = useSourceId();
|
||||
const source = useSource({ sourceId });
|
||||
const { sourceId, version } = useContext(Source.Context);
|
||||
|
||||
return (
|
||||
<Source.Context.Provider value={source}>
|
||||
<LogViewConfiguration.Provider>
|
||||
<LogFlyout.Provider>
|
||||
<LogHighlightsState.Provider sourceId={sourceId} sourceVersion={source.version}>
|
||||
{children}
|
||||
</LogHighlightsState.Provider>
|
||||
</LogFlyout.Provider>
|
||||
</LogViewConfiguration.Provider>
|
||||
</Source.Context.Provider>
|
||||
<LogViewConfiguration.Provider>
|
||||
<LogFlyout.Provider>
|
||||
<LogHighlightsState.Provider sourceId={sourceId} sourceVersion={version}>
|
||||
{children}
|
||||
</LogHighlightsState.Provider>
|
||||
</LogFlyout.Provider>
|
||||
</LogViewConfiguration.Provider>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue