Skip to content

Commit

Permalink
[ML] Data frame analytics: Exploration page bug fixes. (elastic#44496) (
Browse files Browse the repository at this point in the history
elastic#44617)

Fixes various issues with the data frame analytics outlier detection results page.

- Fixes the default sorting and sets it to descending outlier_score.
- Fixes to retain the sorting when columns are enabled/disabled via the options menu. Previously the sorting would be reset to use the left most column.
- Fixes the sorting to be applied to get the data for the table from Elasticsearch when the user changes sorting by clicking on the arrows on the table column headers. Previously only on load the data would be loaded once (1000 docs sort by outlier_score descending) and sorting would only by applied to this initially loaded data.
- Consolidates redundant TypeScript specifications in in_memory_table.ts.
  • Loading branch information
walterra committed Sep 2, 2019
1 parent 2c53304 commit 3b3eeeb
Show file tree
Hide file tree
Showing 10 changed files with 415 additions and 313 deletions.
29 changes: 20 additions & 9 deletions x-pack/legacy/plugins/ml/common/types/eui/in_memory_table.ts
Expand Up @@ -137,13 +137,27 @@ interface InitialPageOptions extends PageSizeOptions {
initialPageIndex: number;
initialPageSize: number;
}
type Pagination = boolean | PageSizeOptions | InitialPageOptions;
type PaginationProp = boolean | PageSizeOptions | InitialPageOptions;

type PropertySortType = any;
type Sorting = boolean | { sort: PropertySortType };
export enum SORT_DIRECTION {
ASC = 'asc',
DESC = 'desc',
}
export type SortDirection = SORT_DIRECTION.ASC | SORT_DIRECTION.DESC;
export interface Sorting {
sort: {
field: string;
direction: SortDirection;
};
}
export type SortingPropType = boolean | Sorting;

type SelectionType = any;

export interface OnTableChangeArg extends Sorting {
page: { index: number; size: number };
}

type ItemIdTypeFunc = (item: Item) => string;
type ItemIdType =
| string // the name of the item id property
Expand All @@ -160,8 +174,8 @@ export type EuiInMemoryTableProps = CommonProps & {
error?: string;
compressed?: boolean;
search?: SearchType;
pagination?: Pagination;
sorting?: Sorting;
pagination?: PaginationProp;
sorting?: SortingPropType;
// Set `allowNeutralSort` to false to force column sorting. Defaults to true.
allowNeutralSort?: boolean;
responsive?: boolean;
Expand All @@ -170,10 +184,7 @@ export type EuiInMemoryTableProps = CommonProps & {
itemIdToExpandedRowMap?: Record<string, Item>;
rowProps?: () => void | Record<string, any>;
cellProps?: () => void | Record<string, any>;
onTableChange?: (arg: {
page: { index: number; size: number };
sort: { field: string; direction: string };
}) => void;
onTableChange?: (arg: OnTableChangeArg) => void;
};

interface ComponentWithConstructor<T> extends Component {
Expand Down
Expand Up @@ -28,7 +28,12 @@ import {
RIGHT_ALIGNMENT,
} from '@elastic/eui';

import { ColumnType, MlInMemoryTable } from '../../../../../../common/types/eui/in_memory_table';
import {
ColumnType,
MlInMemoryTable,
SortingPropType,
SORT_DIRECTION,
} from '../../../../../../common/types/eui/in_memory_table';

import { KBN_FIELD_TYPES } from '../../../../../../common/constants/field_types';
import { Dictionary } from '../../../../../../common/types/common';
Expand All @@ -52,23 +57,6 @@ type ItemIdToExpandedRowMap = Dictionary<JSX.Element>;

const CELL_CLICK_ENABLED = false;

// Defining our own ENUM here.
// EUI's SortDirection wasn't usable as a union type
// required for the Sorting interface.
enum SORT_DIRECTON {
ASC = 'asc',
DESC = 'desc',
}

interface Sorting {
sort: {
field: string;
direction: SORT_DIRECTON.ASC | SORT_DIRECTON.DESC;
};
}

type TableSorting = Sorting | boolean;

interface SourceIndexPreviewTitle {
indexPatternTitle: string;
}
Expand Down Expand Up @@ -301,13 +289,13 @@ export const SourceIndexPreview: React.SFC<Props> = React.memo(({ cellClick, que
return column;
});

let sorting: TableSorting = false;
let sorting: SortingPropType = false;

if (columns.length > 0) {
sorting = {
sort: {
field: `_source["${selectedFields[0]}"]`,
direction: SORT_DIRECTON.ASC,
direction: SORT_DIRECTION.ASC,
},
};
}
Expand Down
Expand Up @@ -19,10 +19,13 @@ import {
EuiProgress,
EuiText,
EuiTitle,
SortDirection,
} from '@elastic/eui';

import { ColumnType, MlInMemoryTable } from '../../../../../../common/types/eui/in_memory_table';
import {
ColumnType,
MlInMemoryTable,
SORT_DIRECTION,
} from '../../../../../../common/types/eui/in_memory_table';
import { dictionaryToArray } from '../../../../../../common/types/common';
import { ES_FIELD_TYPES } from '../../../../../../common/constants/field_types';
import { formatHumanReadableDateTimeSeconds } from '../../../../../util/date_utils';
Expand Down Expand Up @@ -271,7 +274,7 @@ export const PivotPreview: SFC<PivotPreviewProps> = React.memo(({ aggs, groupBy,
const sorting = {
sort: {
field: columns[0].field,
direction: SortDirection.ASC,
direction: SORT_DIRECTION.ASC,
},
};

Expand Down
Expand Up @@ -6,7 +6,8 @@

import React, { FC, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { SortDirection } from '@elastic/eui';
import { SortDirection, SORT_DIRECTION } from '../../../../../../common/types/eui/in_memory_table';

import { ml } from '../../../../../services/ml_api_service';

import {
Expand Down Expand Up @@ -75,7 +76,7 @@ export const ExpandedRowPreviewPane: FC<Props> = ({ transformConfig }) => {
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(10);
const [sortField, setSortField] = useState<string>('');
const [sortDirection, setSortDirection] = useState<string>(SortDirection.ASC);
const [sortDirection, setSortDirection] = useState<SortDirection>(SORT_DIRECTION.ASC);
const [isLoading, setIsLoading] = useState(false);
const [errorMessage, setErrorMessage] = useState('');

Expand Down Expand Up @@ -148,10 +149,10 @@ export const ExpandedRowPreviewPane: FC<Props> = ({ transformConfig }) => {

const onTableChange = ({
page = { index: 0, size: 10 },
sort = { field: columns[0].field, direction: SortDirection.ASC },
sort = { field: columns[0].field, direction: SORT_DIRECTION.ASC },
}: {
page: { index: number; size: number };
sort: { field: string; direction: string };
sort: { field: string; direction: SortDirection };
}) => {
const { index, size } = page;
setPageIndex(index);
Expand Down
Expand Up @@ -16,9 +16,14 @@ import {
EuiEmptyPrompt,
EuiPopover,
EuiTitle,
SortDirection,
} from '@elastic/eui';

import {
OnTableChangeArg,
SortDirection,
SORT_DIRECTION,
} from '../../../../../../common/types/eui/in_memory_table';

import { DataFrameTransformId, moveToDataFrameWizard } from '../../../../common';
import { checkPermission } from '../../../../../privilege/check_privilege';
import { getTaskStateBadge } from './columns';
Expand Down Expand Up @@ -91,7 +96,7 @@ export const DataFrameTransformList: SFC<Props> = ({
const [pageSize, setPageSize] = useState(10);

const [sortField, setSortField] = useState<string>(DataFrameTransformListColumn.id);
const [sortDirection, setSortDirection] = useState<string>(SortDirection.ASC);
const [sortDirection, setSortDirection] = useState<SortDirection>(SORT_DIRECTION.ASC);

const disabled =
!checkPermission('canCreateDataFrame') ||
Expand Down Expand Up @@ -336,11 +341,8 @@ export const DataFrameTransformList: SFC<Props> = ({

const onTableChange = ({
page = { index: 0, size: 10 },
sort = { field: DataFrameTransformListColumn.id, direction: SortDirection.ASC },
}: {
page: { index: number; size: number };
sort: { field: string; direction: string };
}) => {
sort = { field: DataFrameTransformListColumn.id, direction: SORT_DIRECTION.ASC },
}: OnTableChangeArg) => {
const { index, size } = page;
setPageIndex(index);
setPageSize(size);
Expand Down
@@ -0,0 +1,33 @@
/*
* 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 { DataFrameAnalyticsConfig } from '../../../../common';

import { getOutlierScoreFieldName } from './common';

describe('Data Frame Analytics: <Exploration /> common utils', () => {
test('getOutlierScoreFieldName()', () => {
const jobConfig: DataFrameAnalyticsConfig = {
id: 'the-id',
analysis: { outlier_detection: {} },
dest: {
index: 'the-dest-index',
results_field: 'the-results-field',
},
source: {
index: 'the-source-index',
},
analyzed_fields: { includes: [], excludes: [] },
model_memory_limit: '50mb',
create_time: 1234,
version: '1.0.0',
};

const outlierScoreFieldName = getOutlierScoreFieldName(jobConfig);

expect(outlierScoreFieldName).toMatch('the-results-field.outlier_score');
});
});
@@ -0,0 +1,12 @@
/*
* 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 { DataFrameAnalyticsConfig } from '../../../../common';

const OUTLIER_SCORE = 'outlier_score';

export const getOutlierScoreFieldName = (jobConfig: DataFrameAnalyticsConfig) =>
`${jobConfig.dest.results_field}.${OUTLIER_SCORE}`;

0 comments on commit 3b3eeeb

Please sign in to comment.