Skip to content

Commit

Permalink
[ML] Replace EuiBasicTable with EuiInMemoryTable (#83057)
Browse files Browse the repository at this point in the history
  • Loading branch information
qn895 authored Nov 11, 2020
1 parent 88312d8 commit af51394
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 366 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { Dispatch, SetStateAction, FC, Fragment, useState } from 'react';
import {
EuiSearchBar,
EuiSearchBarProps,
EuiFlexGroup,
EuiFlexItem,
EuiFormRow,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { stringMatch } from '../../../../../util/string_utils';
import { stringMatch } from '../../util/string_utils';
import {
TermClause,
FieldClause,
Value,
DataFrameAnalyticsListRow,
} from '../analytics_list/common';
import { ModelItem } from '../models_management/models_list';
} from '../pages/analytics_management/components/analytics_list/common';
import { ModelItem } from '../pages/analytics_management/components/models_management/models_list';

export function filterAnalyticsModels(
items: ModelItem[],
Expand Down Expand Up @@ -151,69 +142,3 @@ export function filterAnalytics(

return filtered;
}

function getError(errorMessage: string | null) {
if (errorMessage) {
return i18n.translate('xpack.ml.analyticList.searchBar.invalidSearchErrorMessage', {
defaultMessage: 'Invalid search: {errorMessage}',
values: { errorMessage },
});
}

return '';
}

interface Props {
filters: EuiSearchBarProps['filters'];
searchQueryText: string;
setSearchQueryText: Dispatch<SetStateAction<string>>;
}

export const AnalyticsSearchBar: FC<Props> = ({ filters, searchQueryText, setSearchQueryText }) => {
const [errorMessage, setErrorMessage] = useState<null | string>(null);

const onChange: EuiSearchBarProps['onChange'] = ({ query, error }) => {
if (error) {
setErrorMessage(error.message);
} else if (query !== null && query.text !== undefined) {
setSearchQueryText(query.text);
setErrorMessage(null);
}
};

return (
<EuiFlexGroup direction="column">
<EuiFlexItem data-test-subj="mlAnalyticsSearchBar" grow={false}>
{searchQueryText === undefined && (
<EuiSearchBar
box={{
incremental: true,
}}
filters={filters}
onChange={onChange}
className="mlAnalyitcsSearchBar"
/>
)}
{searchQueryText !== undefined && (
<EuiSearchBar
box={{
incremental: true,
}}
defaultQuery={searchQueryText}
filters={filters}
onChange={onChange}
className="mlAnalyitcsSearchBar"
/>
)}
<EuiFormRow
fullWidth
isInvalid={errorMessage !== null}
error={getError(errorMessage)}
style={{ maxHeight: '0px' }}
>
<Fragment />
</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
EuiCallOut,
EuiFlexGroup,
EuiFlexItem,
EuiBasicTable,
EuiInMemoryTable,
EuiSearchBar,
EuiSearchBarProps,
EuiSpacer,
Expand All @@ -35,7 +35,7 @@ import {
getGroupQueryText,
} from '../../../../../jobs/jobs_list/components/utils';
import { SourceSelection } from '../source_selection';
import { filterAnalytics, AnalyticsSearchBar } from '../analytics_search_bar';
import { filterAnalytics } from '../../../../common/search_bar_filters';
import { AnalyticsEmptyPrompt } from './empty_prompt';
import { useTableSettings } from './use_table_settings';
import { RefreshAnalyticsListButton } from '../refresh_analytics_list_button';
Expand Down Expand Up @@ -97,6 +97,7 @@ export const DataFrameAnalyticsList: FC<Props> = ({
const [isLoading, setIsLoading] = useState(false);
const [filteredAnalytics, setFilteredAnalytics] = useState<DataFrameAnalyticsListRow[]>([]);
const [searchQueryText, setSearchQueryText] = useState('');
const [searchError, setSearchError] = useState<string | undefined>();
const [analytics, setAnalytics] = useState<DataFrameAnalyticsListRow[]>([]);
const [analyticsStats, setAnalyticsStats] = useState<AnalyticStatsBarStats | undefined>(
undefined
Expand Down Expand Up @@ -183,9 +184,21 @@ export const DataFrameAnalyticsList: FC<Props> = ({
isMlEnabledInSpace
);

const { onTableChange, pageOfItems, pagination, sorting } = useTableSettings<
DataFrameAnalyticsListRow
>(DataFrameAnalyticsListColumn.id, filteredAnalytics);
const { onTableChange, pagination, sorting } = useTableSettings<DataFrameAnalyticsListRow>(
DataFrameAnalyticsListColumn.id,
filteredAnalytics
);

const handleSearchOnChange: EuiSearchBarProps['onChange'] = (search) => {
if (search.error !== null) {
setSearchError(search.error.message);
return false;
}

setSearchError(undefined);
setSearchQueryText(search.queryText);
return true;
};

// Before the analytics have been loaded for the first time, display the loading indicator only.
// Otherwise a user would see 'No data frame analytics found' during the initial loading.
Expand Down Expand Up @@ -240,6 +253,14 @@ export const DataFrameAnalyticsList: FC<Props> = ({
</EuiFlexGroup>
</EuiFlexItem>
);
const search: EuiSearchBarProps = {
query: searchQueryText,
onChange: handleSearchOnChange,
box: {
incremental: true,
},
filters,
};

return (
<div data-test-subj="mlAnalyticsJobList">
Expand All @@ -263,25 +284,22 @@ export const DataFrameAnalyticsList: FC<Props> = ({
</EuiFlexGroup>
<EuiSpacer size="m" />
<div data-test-subj="mlAnalyticsTableContainer">
<AnalyticsSearchBar
filters={filters}
searchQueryText={searchQueryText}
setSearchQueryText={setSearchQueryText}
/>
<EuiSpacer size="l" />
<EuiBasicTable<DataFrameAnalyticsListRow>
className="mlAnalyticsTable"
<EuiInMemoryTable<DataFrameAnalyticsListRow>
allowNeutralSort={false}
className="mlAnalyticsInMemoryTable"
columns={columns}
error={searchError}
hasActions={false}
isExpandable={true}
isSelectable={false}
items={pageOfItems}
items={analytics}
itemId={DataFrameAnalyticsListColumn.id}
itemIdToExpandedRowMap={itemIdToExpandedRowMap}
loading={isLoading}
onChange={onTableChange}
pagination={pagination!}
onTableChange={onTableChange}
pagination={pagination}
sorting={sorting}
search={search}
data-test-subj={isLoading ? 'mlAnalyticsTable loading' : 'mlAnalyticsTable loaded'}
rowProps={(item) => ({
'data-test-subj': `mlAnalyticsTableRow row-${item.id}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,11 @@
*/

import { useState } from 'react';
import { Direction, EuiBasicTableProps, EuiTableSortingType } from '@elastic/eui';
import { sortBy, get } from 'lodash';
import { Direction, EuiBasicTableProps, Pagination, PropertySort } from '@elastic/eui';

const PAGE_SIZE = 10;
const PAGE_SIZE_OPTIONS = [10, 25, 50];

const jobPropertyMap = {
ID: 'id',
Status: 'state',
Type: 'job_type',
};

// Copying from EUI EuiBasicTable types as type is not correctly picked up for table's onChange
// Can be removed when https://github.com/elastic/eui/issues/4011 is addressed in EUI
export interface Criteria<T> {
Expand Down Expand Up @@ -47,9 +40,8 @@ interface AnalyticsBasicTableSettings<T> {

interface UseTableSettingsReturnValue<T> {
onTableChange: EuiBasicTableProps<T>['onChange'];
pageOfItems: T[];
pagination: EuiBasicTableProps<T>['pagination'];
sorting: EuiTableSortingType<any>;
pagination: Pagination;
sorting: { sort: PropertySort };
}

export function useTableSettings<TypeOfItem>(
Expand All @@ -65,33 +57,6 @@ export function useTableSettings<TypeOfItem>(
sortDirection: 'asc',
});

const getPageOfItems = (
list: TypeOfItem[],
index: number,
size: number,
sortField: keyof TypeOfItem,
sortDirection: Direction
) => {
list = sortBy(list, (item) =>
get(item, jobPropertyMap[sortField as keyof typeof jobPropertyMap] || sortField)
);
list = sortDirection === 'asc' ? list : list.reverse();
const listLength = list.length;

let pageStart = index * size;
if (pageStart >= listLength && listLength !== 0) {
// if the page start is larger than the number of items due to
// filters being applied or items being deleted, calculate a new page start
pageStart = Math.floor((listLength - 1) / size) * size;

setTableSettings({ ...tableSettings, pageIndex: pageStart / size });
}
return {
pageOfItems: list.slice(pageStart, pageStart + size),
totalItemCount: listLength,
};
};

const onTableChange: EuiBasicTableProps<TypeOfItem>['onChange'] = ({
page = { index: 0, size: PAGE_SIZE },
sort = { field: sortByField, direction: 'asc' },
Expand All @@ -110,27 +75,19 @@ export function useTableSettings<TypeOfItem>(

const { pageIndex, pageSize, sortField, sortDirection } = tableSettings;

const { pageOfItems, totalItemCount } = getPageOfItems(
items,
pageIndex,
pageSize,
sortField,
sortDirection
);

const pagination = {
pageIndex,
pageSize,
totalItemCount,
totalItemCount: items.length,
pageSizeOptions: PAGE_SIZE_OPTIONS,
};

const sorting = {
sort: {
field: sortField,
field: sortField as string,
direction: sortDirection,
},
};

return { onTableChange, pageOfItems, pagination, sorting };
return { onTableChange, pagination, sorting };
}

This file was deleted.

Loading

0 comments on commit af51394

Please sign in to comment.