Skip to content

Commit

Permalink
[ML] Show better file structure finder explanations (elastic#62316)
Browse files Browse the repository at this point in the history
* [ML] Show better file structure finder explanations

* more typescript changes

* changing function format

* fixing some types

* fixing translation id

* fix boom error reporting

* changes based on review

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
jgowdyelastic and elasticmachine committed Apr 7, 2020
1 parent d44699e commit 6c6e812
Show file tree
Hide file tree
Showing 43 changed files with 609 additions and 268 deletions.
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,82 @@
/*
* 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, { 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'}>
<FormattedMessage
id="xpack.ml.fileDatavisualizer.explanationFlyout.content"
defaultMessage="The logical steps that have produced the analysis results."
/>

<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

0 comments on commit 6c6e812

Please sign in to comment.