Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ML] Show better file structure finder explanations #62316

1 change: 1 addition & 0 deletions x-pack/plugins/ml/common/types/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface ErrorResponse {
statusCode: number;
error: string;
message: string;
attributes?: any;
};
name: string;
}
Expand Down
65 changes: 65 additions & 0 deletions x-pack/plugins/ml/common/types/file_datavisualizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@
* you may not use this file except in compliance with the Elastic License.
*/

export interface InputOverrides {
[key: string]: string;
}

export type FormattedOverrides = InputOverrides & {
column_names: string[];
has_header_row: boolean;
should_trim_fields: boolean;
};

export interface AnalysisResult {
results: FindFileStructureResponse;
overrides?: FormattedOverrides;
}

export interface FindFileStructureResponse {
charset: string;
has_header_row: boolean;
Expand All @@ -28,4 +43,54 @@ export interface FindFileStructureResponse {
need_client_timezone: boolean;
num_lines_analyzed: number;
column_names: string[];
explanation?: string[];
grok_pattern?: string;
multiline_start_pattern?: string;
exclude_lines_pattern?: string;
java_timestamp_formats?: string[];
joda_timestamp_formats?: string[];
timestamp_field?: string;
should_trim_fields?: boolean;
}

export interface ImportResponse {
success: boolean;
id: string;
index?: string;
pipelineId?: string;
docCount: number;
failures: ImportFailure[];
error?: any;
ingestError?: boolean;
}

export interface ImportFailure {
item: number;
reason: string;
doc: Doc;
}

export interface Doc {
message: string;
}

export interface Settings {
pipeline?: string;
index: string;
body: any[];
[key: string]: any;
}

export interface Mappings {
[key: string]: any;
}

export interface IngestPipelineWrapper {
id: string;
pipeline: IngestPipeline;
}

export interface IngestPipeline {
description: string;
processors: any[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import React, { FC } from 'react';

import {
EuiFlexGroup,
Expand All @@ -23,7 +23,11 @@ import {

import { WelcomeContent } from './welcome_content';

export function AboutPanel({ onFilePickerChange }) {
interface Props {
onFilePickerChange(files: FileList | null): void;
}

export const AboutPanel: FC<Props> = ({ onFilePickerChange }) => {
return (
<EuiPage restrictWidth={1000} data-test-subj="mlPageFileDataVisualizerUpload">
<EuiPageBody>
Expand Down Expand Up @@ -54,9 +58,9 @@ export function AboutPanel({ onFilePickerChange }) {
</EuiPageBody>
</EuiPage>
);
}
};

export function LoadingPanel() {
export const LoadingPanel: FC = () => {
return (
<EuiPage restrictWidth={400} data-test-subj="mlPageFileDataVisLoading">
<EuiPageBody>
Expand All @@ -79,4 +83,4 @@ export function LoadingPanel() {
</EuiPageBody>
</EuiPage>
);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
*/

import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import React, { FC } from 'react';
import { i18n } from '@kbn/i18n';

import {
EuiFlexGroup,
Expand All @@ -19,7 +20,14 @@ import {

import { ExperimentalBadge } from '../experimental_badge';

export function WelcomeContent() {
export const WelcomeContent: FC = () => {
const toolTipContent = i18n.translate(
'xpack.ml.fileDatavisualizer.welcomeContent.experimentalFeatureTooltip',
{
defaultMessage: "Experimental feature. We'd love to hear your feedback.",
}
);

return (
<EuiFlexGroup gutterSize="xl" alignItems="center">
<EuiFlexItem grow={false}>
Expand All @@ -32,16 +40,7 @@ export function WelcomeContent() {
id="xpack.ml.fileDatavisualizer.welcomeContent.visualizeDataFromLogFileTitle"
defaultMessage="Visualize data from a log file&nbsp;{experimentalBadge}"
values={{
experimentalBadge: (
<ExperimentalBadge
tooltipContent={
<FormattedMessage
id="xpack.ml.fileDatavisualizer.welcomeContent.experimentalFeatureTooltip"
defaultMessage="Experimental feature. We'd love to hear your feedback."
/>
}
/>
),
experimentalBadge: <ExperimentalBadge tooltipContent={toolTipContent} />,
}}
/>
</h1>
Expand Down Expand Up @@ -144,4 +143,4 @@ export function WelcomeContent() {
</EuiFlexItem>
</EuiFlexGroup>
);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
*/

import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import React, { FC } from 'react';

import { EuiTitle, EuiSpacer, EuiDescriptionList } from '@elastic/eui';
import { FindFileStructureResponse } from '../../../../../../common/types/file_datavisualizer';

export function AnalysisSummary({ results }) {
export const AnalysisSummary: FC<{ results: FindFileStructureResponse }> = ({ results }) => {
const items = createDisplayItems(results);

return (
Expand All @@ -28,10 +29,10 @@ export function AnalysisSummary({ results }) {
<EuiDescriptionList type="column" listItems={items} className="analysis-summary-list" />
</React.Fragment>
);
}
};

function createDisplayItems(results) {
const items = [
function createDisplayItems(results: FindFileStructureResponse) {
const items: Array<{ title: any; description: string | number }> = [
{
title: (
<FormattedMessage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
*/

import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import React, { FC } from 'react';

import { EuiBetaBadge } from '@elastic/eui';

export function ExperimentalBadge({ tooltipContent }) {
export const ExperimentalBadge: FC<{ tooltipContent: string }> = ({ tooltipContent }) => {
return (
<span>
<EuiBetaBadge
Expand All @@ -24,4 +24,4 @@ export function ExperimentalBadge({ tooltipContent }) {
/>
</span>
);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* 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.
*/
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit - double copyright comments at the top of this file.

* 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, { FC } from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiFlyout,
EuiFlyoutFooter,
EuiFlexGroup,
EuiFlexItem,
EuiFlyoutHeader,
EuiButtonEmpty,
EuiTitle,
EuiFlyoutBody,
EuiSpacer,
EuiText,
EuiSubSteps,
} from '@elastic/eui';
import { FindFileStructureResponse } from '../../../../../../common/types/file_datavisualizer';

interface Props {
results: FindFileStructureResponse;
closeFlyout(): void;
}
export const ExplanationFlyout: FC<Props> = ({ results, closeFlyout }) => {
const explanation = results.explanation!;
return (
<EuiFlyout onClose={closeFlyout} hideCloseButton size={'m'}>
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<h2>
<FormattedMessage
id="xpack.ml.fileDatavisualizer.explanationFlyout.title"
defaultMessage="Analysis explanation"
/>
</h2>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>
<Content explanation={explanation} />
</EuiFlyoutBody>
<EuiFlyoutFooter>
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiButtonEmpty iconType="cross" onClick={closeFlyout} flush="left">
<FormattedMessage
id="xpack.ml.fileDatavisualizer.explanationFlyout.closeButton"
defaultMessage="Close"
/>
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlyoutFooter>
</EuiFlyout>
);
};

const Content: FC<{ explanation: string[] }> = ({ explanation }) => (
<>
<EuiText size={'s'}>
The logical steps that have produced the analysis results.
peteharverson marked this conversation as resolved.
Show resolved Hide resolved
<EuiSpacer size="l" />
<EuiSubSteps>
<ul style={{ wordBreak: 'break-word' }}>
{explanation.map((e, i) => (
<li key={i}>
{e}
<EuiSpacer size="s" />
</li>
))}
</ul>
</EuiSubSteps>
</EuiText>
</>
);
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/

export { ImportProgress, IMPORT_STATUS } from './import_progress';
export { ExplanationFlyout } from './explanation_flyout';
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@
*/

import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import React, { FC } from 'react';

import { EuiTitle, EuiSpacer } from '@elastic/eui';

import { MLJobEditor, ML_EDITOR_MODE } from '../../../../jobs/jobs_list/components/ml_job_editor';

export function FileContents({ data, format, numberOfLines }) {
interface Props {
data: string;
format: string;
numberOfLines: number;
}

export const FileContents: FC<Props> = ({ data, format, numberOfLines }) => {
let mode = ML_EDITOR_MODE.TEXT;
if (format === ML_EDITOR_MODE.JSON) {
mode = ML_EDITOR_MODE.JSON;
Expand All @@ -35,7 +41,7 @@ export function FileContents({ data, format, numberOfLines }) {
id="xpack.ml.fileDatavisualizer.fileContents.firstLinesDescription"
defaultMessage="First {numberOfLines, plural, zero {# line} one {# line} other {# lines}}"
values={{
numberOfLines: numberOfLines,
numberOfLines,
}}
/>
</div>
Expand All @@ -51,9 +57,9 @@ export function FileContents({ data, format, numberOfLines }) {
/>
</React.Fragment>
);
}
};

function limitByNumberOfLines(data, numberOfLines) {
function limitByNumberOfLines(data: string, numberOfLines: number) {
return data
.split('\n')
.slice(0, numberOfLines)
Expand Down
Loading