@elastic/eui
Version:
Elastic UI Component Library
506 lines (495 loc) • 21.9 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
var _excluded = ["schema"],
_excluded2 = ["onChange"],
_excluded3 = ["columns", "loading", "message", "error", "selection", "compressed", "pagination", "sorting", "itemIdToExpandedRowMap", "itemId", "rowProps", "cellProps", "tableLayout", "items", "search", "searchFormat", "onTableChange", "executeQueryOptions", "allowNeutralSort", "childrenBetween"];
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, { Component } from 'react';
import { EuiBasicTable } from './basic_table';
import { isString } from '../../services/predicate';
import { Comparators } from '../../services/sort';
import { EuiSearchBar } from '../search_bar/search_bar';
import { EuiSearchBox } from '../search_bar/search_box';
import { EuiSpacer } from '../spacer';
import { euiTablePaginationDefaults } from '../table/table_pagination';
import { EuiComponentDefaultsContext } from '../provider/component_defaults';
import { jsx as ___EmotionJSX } from "@emotion/react";
function isEuiSearchBarProps(x) {
return typeof x !== 'boolean';
}
var getQueryFromSearch = function getQueryFromSearch(search, defaultQuery) {
var query;
if (!search) {
query = '';
} else {
query = (defaultQuery ? search.defaultQuery || search.query || '' : search.query) || '';
}
return isString(query) ? EuiSearchBar.Query.parse(query) : query;
};
var getInitialPagination = function getInitialPagination(pagination, consumerDefaults) {
var _ref2, _pagination$pageIndex, _ref3, _pagination$pageSize;
if (!pagination) {
return {
pageIndex: undefined,
pageSize: undefined
};
}
var defaults = _objectSpread(_objectSpread({}, euiTablePaginationDefaults), consumerDefaults);
var _ref = pagination,
_ref$pageSizeOptions = _ref.pageSizeOptions,
pageSizeOptions = _ref$pageSizeOptions === void 0 ? defaults.itemsPerPageOptions : _ref$pageSizeOptions,
_ref$showPerPageOptio = _ref.showPerPageOptions,
showPerPageOptions = _ref$showPerPageOptio === void 0 ? defaults.showPerPageOptions : _ref$showPerPageOptio;
var defaultPageSize = pageSizeOptions !== null && pageSizeOptions !== void 0 && pageSizeOptions.includes(defaults.itemsPerPage) ? defaults.itemsPerPage : pageSizeOptions[0];
var initialPageIndex = pagination === true ? 0 : (_ref2 = (_pagination$pageIndex = pagination.pageIndex) !== null && _pagination$pageIndex !== void 0 ? _pagination$pageIndex : pagination.initialPageIndex) !== null && _ref2 !== void 0 ? _ref2 : 0;
var initialPageSize = pagination === true ? defaultPageSize : (_ref3 = (_pagination$pageSize = pagination.pageSize) !== null && _pagination$pageSize !== void 0 ? _pagination$pageSize : pagination.initialPageSize) !== null && _ref3 !== void 0 ? _ref3 : defaultPageSize;
if (showPerPageOptions && initialPageSize != null && !(pageSizeOptions !== null && pageSizeOptions !== void 0 && pageSizeOptions.includes(initialPageSize))) {
throw new Error("EuiInMemoryTable received initialPageSize ".concat(initialPageSize, ", which wasn't provided within pageSizeOptions."));
}
return {
pageIndex: initialPageIndex,
pageSize: initialPageSize,
pageSizeOptions: pageSizeOptions,
showPerPageOptions: showPerPageOptions
};
};
function findColumnByProp(columns, prop, value) {
for (var i = 0; i < columns.length; i++) {
var column = columns[i];
if (column[prop] === value) {
return column;
}
}
}
function findColumnByFieldOrName(columns, value) {
// The passed value can be a column's `field` or its `name`
// for backwards compatibility `field` must be checked first
var column = findColumnByProp(columns, 'field', value);
if (column == null) {
column = findColumnByProp(columns, 'name', value);
}
return column;
}
function getInitialSorting(columns, sorting) {
if (!sorting || !sorting.sort) {
return {
sortName: undefined,
sortDirection: undefined
};
}
var _sort = sorting.sort,
sortable = _sort.field,
sortDirection = _sort.direction;
var sortColumn = findColumnByFieldOrName(columns, sortable);
if (sortColumn == null) {
return {
sortName: undefined,
sortDirection: undefined
};
}
var sortName = sortColumn.name;
return {
sortName: sortName,
sortDirection: sortDirection
};
}
export var EuiInMemoryTable = /*#__PURE__*/function (_Component) {
function EuiInMemoryTable(props, context) {
var _this;
_classCallCheck(this, EuiInMemoryTable);
_this = _callSuper(this, EuiInMemoryTable, [props]);
_defineProperty(_this, "onTableChange", function (_ref4) {
var page = _ref4.page,
sort = _ref4.sort;
var _ref5 = page || {},
pageIndex = _ref5.index,
pageSize = _ref5.size;
// don't apply pagination changes that are otherwise controlled
// `page` is left unchanged as it goes to the consumer's `onTableChange` callback, allowing the app to respond
var pagination = _this.props.pagination;
if (pagination != null && typeof pagination !== 'boolean') {
if (pagination.pageSize != null) pageSize = pagination.pageSize;
if (pagination.pageIndex != null) pageIndex = pagination.pageIndex;
}
var _ref6 = sort || {},
sortName = _ref6.field,
sortDirection = _ref6.direction;
// To keep backwards compatibility reportedSortName needs to be tracked separately
// from sortName; sortName gets stored internally while reportedSortName is sent to the callback
var reportedSortName = sortName;
// EuiBasicTable returns the column's `field` instead of `name` on sort
// and the column's `name` instead of `field` on pagination
if (sortName) {
var sortColumn = findColumnByFieldOrName(_this.props.columns, sortName);
if (sortColumn) {
// Ensure sortName uses `name`
sortName = sortColumn.name;
// Ensure reportedSortName uses `field` if it exists
var sortField = sortColumn.field;
if (sortField) reportedSortName = sortField;
}
}
// Allow going back to 'neutral' sorting
if (_this.state.allowNeutralSort && _this.state.sortName === sortName && _this.state.sortDirection === 'desc' && sortDirection === 'asc') {
sortName = '';
reportedSortName = '';
sortDirection = 'asc'; // Default sort direction.
}
if (_this.props.onTableChange) {
_this.props.onTableChange({
// @ts-ignore complex relationship between pagination's existence and criteria, the code logic ensures this is correctly maintained
page: page,
sort: {
field: reportedSortName,
direction: sortDirection
}
});
}
_this.setState({
pageIndex: pageIndex,
pageSize: pageSize,
sortName: sortName,
sortDirection: sortDirection
});
});
_defineProperty(_this, "onQueryChange", function (_ref7) {
var query = _ref7.query,
queryText = _ref7.queryText,
error = _ref7.error;
var search = _this.props.search;
if (isEuiSearchBarProps(search)) {
if (search.onChange) {
var shouldQueryInMemory = error == null ? search.onChange({
query: query,
queryText: queryText,
error: null
}) : search.onChange({
query: null,
queryText: queryText,
error: error
});
if (!shouldQueryInMemory) {
return;
}
}
}
// Reset pagination state.
_this.setState(function (state) {
return {
prevProps: _objectSpread(_objectSpread({}, state.prevProps), {}, {
search: search
}),
query: query,
pageIndex: 0
};
});
});
// Alternative to onQueryChange - allows consumers to specify they want the
// search bar to ignore EQL syntax and only use the searchbar for plain text
_defineProperty(_this, "onPlainTextSearch", function (searchValue) {
var escapedQueryText = searchValue.replace(/["\\]/g, '\\$&');
var finalQuery = "\"".concat(escapedQueryText, "\"");
_this.setState({
query: EuiSearchBar.Query.parse(finalQuery)
});
});
var columns = props.columns,
_search = props.search,
_pagination = props.pagination,
sorting = props.sorting,
allowNeutralSort = props.allowNeutralSort;
var _getInitialPagination = getInitialPagination(_pagination, context.EuiTablePagination),
_pageIndex = _getInitialPagination.pageIndex,
_pageSize = _getInitialPagination.pageSize,
pageSizeOptions = _getInitialPagination.pageSizeOptions,
showPerPageOptions = _getInitialPagination.showPerPageOptions;
var _getInitialSorting = getInitialSorting(columns, sorting),
_sortName = _getInitialSorting.sortName,
_sortDirection = _getInitialSorting.sortDirection;
_this.state = {
prevProps: {
items: props.items,
sortName: _sortName,
sortDirection: _sortDirection,
search: _search
},
search: _search,
query: getQueryFromSearch(_search, true),
pageIndex: _pageIndex || 0,
pageSize: _pageSize,
pageSizeOptions: pageSizeOptions,
sortName: _sortName,
sortDirection: _sortDirection,
allowNeutralSort: allowNeutralSort !== false,
showPerPageOptions: showPerPageOptions
};
return _this;
}
_inherits(EuiInMemoryTable, _Component);
return _createClass(EuiInMemoryTable, [{
key: "renderSearchBar",
value: function renderSearchBar() {
var _this$props = this.props,
search = _this$props.search,
searchFormat = _this$props.searchFormat;
if (!search) return;
var searchBar;
if (searchFormat === 'text') {
var _searchBoxProps = (search === null || search === void 0 ? void 0 : search.box) || {}; // Work around | boolean type
var schema = _searchBoxProps.schema,
searchBoxProps = _objectWithoutProperties(_searchBoxProps, _excluded); // Destructure `schema` so it doesn't get rendered to DOM
searchBar = ___EmotionJSX(EuiSearchBox, _extends({
query: "" // Unused, passed to satisfy Typescript
}, searchBoxProps, {
onSearch: this.onPlainTextSearch
}));
} else {
var searchBarProps = {};
if (isEuiSearchBarProps(search)) {
var onChange = search.onChange,
_searchBarProps = _objectWithoutProperties(search, _excluded2);
searchBarProps = _searchBarProps;
if (searchBarProps.box && searchBarProps.box.schema === true) {
searchBarProps.box = _objectSpread(_objectSpread({}, searchBarProps.box), {}, {
schema: this.resolveSearchSchema()
});
}
}
searchBar = ___EmotionJSX(EuiSearchBar, _extends({
onChange: this.onQueryChange
}, searchBarProps));
}
return ___EmotionJSX(React.Fragment, null, searchBar, ___EmotionJSX(EuiSpacer, {
size: "l"
}));
}
}, {
key: "resolveSearchSchema",
value: function resolveSearchSchema() {
var columns = this.props.columns;
return columns.reduce(function (schema, column) {
var _ref8 = column,
field = _ref8.field,
dataType = _ref8.dataType;
if (field) {
var type = dataType || 'string';
schema.fields[field] = {
type: type
};
}
return schema;
}, {
strict: true,
fields: {}
});
}
}, {
key: "getItemSorter",
value: function getItemSorter() {
var _this$state = this.state,
sortName = _this$state.sortName,
sortDirection = _this$state.sortDirection;
var columns = this.props.columns;
var sortColumn = columns.find(function (_ref9) {
var name = _ref9.name;
return name === sortName;
});
if (sortColumn == null) {
// can't return a non-function so return a function that says everything is the same
return function () {
return 0;
};
}
var sortable = sortColumn.sortable;
if (typeof sortable === 'function') {
return Comparators.value(sortable, Comparators.default(sortDirection));
}
return Comparators.property(sortColumn.field, Comparators.default(sortDirection));
}
}, {
key: "getItems",
value: function getItems() {
var executeQueryOptions = this.props.executeQueryOptions;
var items = this.state.prevProps.items;
if (!items.length) {
return {
items: [],
totalItemCount: 0
};
}
var _this$state2 = this.state,
query = _this$state2.query,
sortName = _this$state2.sortName,
pageIndex = _this$state2.pageIndex,
pageSize = _this$state2.pageSize;
var matchingItems = query !== null && (executeQueryOptions === null || executeQueryOptions === void 0 ? void 0 : executeQueryOptions.enabled) !== false ? EuiSearchBar.Query.execute(query, items, executeQueryOptions) : items;
var sortedItems = sortName ? matchingItems.slice(0) // avoid mutating the source array
.sort(this.getItemSorter()) // sort, causes mutation
: matchingItems;
var visibleItems = pageSize && this.props.pagination ? function () {
var startIndex = pageIndex * pageSize;
return sortedItems.slice(startIndex, Math.min(startIndex + pageSize, sortedItems.length));
}() : sortedItems;
return {
items: visibleItems,
totalItemCount: matchingItems.length
};
}
}, {
key: "render",
value: function render() {
var _this$props2 = this.props,
columns = _this$props2.columns,
loading = _this$props2.loading,
message = _this$props2.message,
error = _this$props2.error,
selection = _this$props2.selection,
compressed = _this$props2.compressed,
hasPagination = _this$props2.pagination,
hasSorting = _this$props2.sorting,
itemIdToExpandedRowMap = _this$props2.itemIdToExpandedRowMap,
itemId = _this$props2.itemId,
rowProps = _this$props2.rowProps,
cellProps = _this$props2.cellProps,
tableLayout = _this$props2.tableLayout,
_unuseditems = _this$props2.items,
search = _this$props2.search,
searchFormat = _this$props2.searchFormat,
onTableChange = _this$props2.onTableChange,
executeQueryOptions = _this$props2.executeQueryOptions,
allowNeutralSort = _this$props2.allowNeutralSort,
childrenBetween = _this$props2.childrenBetween,
rest = _objectWithoutProperties(_this$props2, _excluded3);
var _this$state3 = this.state,
pageIndex = _this$state3.pageIndex,
pageSize = _this$state3.pageSize,
pageSizeOptions = _this$state3.pageSizeOptions,
sortName = _this$state3.sortName,
sortDirection = _this$state3.sortDirection,
showPerPageOptions = _this$state3.showPerPageOptions;
var _this$getItems = this.getItems(),
items = _this$getItems.items,
totalItemCount = _this$getItems.totalItemCount;
var pagination = !hasPagination ? undefined : {
pageIndex: pageIndex,
pageSize: pageSize !== null && pageSize !== void 0 ? pageSize : 1,
pageSizeOptions: pageSizeOptions,
totalItemCount: totalItemCount,
showPerPageOptions: showPerPageOptions
};
// Data loaded from a server can have a default sort order which is meaningful to the
// user, but can't be reproduced with client-side sort logic. So we allow the table to display
// rows in the order in which they're initially loaded by providing an undefined sorting prop.
var sorting = !hasSorting ? undefined : {
sort: !sortName && !sortDirection ? undefined : {
field: sortName,
direction: sortDirection
},
allowNeutralSort: this.state.allowNeutralSort
};
var searchBar = this.renderSearchBar();
var table =
// @ts-ignore complex relationship between pagination's existence and criteria, the code logic ensures this is correctly maintained
___EmotionJSX(EuiBasicTable, _extends({
items: items,
itemId: itemId,
rowProps: rowProps,
cellProps: cellProps,
columns: columns,
pagination: pagination,
sorting: sorting,
selection: selection,
onChange: this.onTableChange,
error: error,
loading: loading,
noItemsMessage: message,
tableLayout: tableLayout,
compressed: compressed,
itemIdToExpandedRowMap: itemIdToExpandedRowMap
}, rest));
if (!searchBar) {
return table;
}
return ___EmotionJSX("div", null, searchBar, childrenBetween, table);
}
}], [{
key: "getDerivedStateFromProps",
value: function getDerivedStateFromProps(nextProps, prevState) {
var updatedPrevState = prevState;
if (nextProps.items !== prevState.prevProps.items) {
// We have new items because an external search has completed, so reset pagination state.
var nextPageIndex = 0;
if (nextProps.pagination != null && typeof nextProps.pagination !== 'boolean') {
nextPageIndex = nextProps.pagination.pageIndex || 0;
}
updatedPrevState = _objectSpread(_objectSpread({}, updatedPrevState), {}, {
prevProps: _objectSpread(_objectSpread({}, updatedPrevState.prevProps), {}, {
items: nextProps.items
}),
pageIndex: nextPageIndex
});
}
// apply changes to controlled pagination
if (nextProps.pagination != null && typeof nextProps.pagination !== 'boolean') {
if (nextProps.pagination.pageSize != null && nextProps.pagination.pageSize !== updatedPrevState.pageIndex) {
updatedPrevState = _objectSpread(_objectSpread({}, updatedPrevState), {}, {
pageSize: nextProps.pagination.pageSize
});
}
if (nextProps.pagination.pageIndex != null && nextProps.pagination.pageIndex !== updatedPrevState.pageIndex) {
updatedPrevState = _objectSpread(_objectSpread({}, updatedPrevState), {}, {
pageIndex: nextProps.pagination.pageIndex
});
}
}
var _getInitialSorting2 = getInitialSorting(nextProps.columns, nextProps.sorting),
sortName = _getInitialSorting2.sortName,
sortDirection = _getInitialSorting2.sortDirection;
if (sortName !== prevState.prevProps.sortName || sortDirection !== prevState.prevProps.sortDirection) {
updatedPrevState = _objectSpread(_objectSpread({}, updatedPrevState), {}, {
prevProps: _objectSpread(_objectSpread({}, updatedPrevState.prevProps), {}, {
sortName: sortName,
sortDirection: sortDirection
}),
sortName: sortName,
sortDirection: sortDirection
});
}
var nextQuery = nextProps.search ? nextProps.search.query : '';
var prevQuery = prevState.prevProps.search ? prevState.prevProps.search.query : '';
if (nextQuery !== prevQuery) {
updatedPrevState = _objectSpread(_objectSpread({}, updatedPrevState), {}, {
prevProps: _objectSpread(_objectSpread({}, updatedPrevState.prevProps), {}, {
search: nextProps.search
}),
query: getQueryFromSearch(nextProps.search, false)
});
}
if (updatedPrevState !== prevState) {
return updatedPrevState;
}
return null;
}
}]);
}(Component);
_defineProperty(EuiInMemoryTable, "contextType", EuiComponentDefaultsContext);
_defineProperty(EuiInMemoryTable, "defaultProps", {
tableLayout: 'fixed',
searchFormat: 'eql'
});