UNPKG

@elastic/eui

Version:

Elastic UI Component Library

545 lines (533 loc) 24.1 kB
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", "noItemsMessage", "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'; } /** * Extracts and formats a query from search props based on the search format * @param search - The search configuration * @param defaultQuery - Whether to use the defaultQuery property as fallback * @param searchFormat - The search format: 'eql' for parsed queries, 'text' for plain text * @returns Formatted query string or Query object */ var getQueryFromSearch = function getQueryFromSearch(search, defaultQuery, searchFormat) { var _ref, _searchProps$defaultQ, _searchProps$query; if (!search) { return searchFormat === 'text' ? '""' : ''; } var searchProps = search; var queryString = defaultQuery ? (_ref = (_searchProps$defaultQ = searchProps.defaultQuery) !== null && _searchProps$defaultQ !== void 0 ? _searchProps$defaultQ : searchProps.query) !== null && _ref !== void 0 ? _ref : '' : (_searchProps$query = searchProps.query) !== null && _searchProps$query !== void 0 ? _searchProps$query : ''; if (searchFormat === 'text') { return "\"".concat(queryString, "\""); } return isString(queryString) ? EuiSearchBar.Query.parse(queryString) : queryString; }; var getInitialPagination = function getInitialPagination(pagination, consumerDefaults) { var _ref3, _pagination$pageIndex, _ref4, _pagination$pageSize; if (!pagination) { return { pageIndex: undefined, pageSize: undefined }; } var defaults = _objectSpread(_objectSpread({}, euiTablePaginationDefaults), consumerDefaults); var _ref2 = pagination, _ref2$pageSizeOptions = _ref2.pageSizeOptions, pageSizeOptions = _ref2$pageSizeOptions === void 0 ? defaults.itemsPerPageOptions : _ref2$pageSizeOptions, _ref2$showPerPageOpti = _ref2.showPerPageOptions, showPerPageOptions = _ref2$showPerPageOpti === void 0 ? defaults.showPerPageOptions : _ref2$showPerPageOpti; var defaultPageSize = pageSizeOptions !== null && pageSizeOptions !== void 0 && pageSizeOptions.includes(defaults.itemsPerPage) ? defaults.itemsPerPage : pageSizeOptions[0]; var initialPageIndex = pagination === true ? 0 : (_ref3 = (_pagination$pageIndex = pagination.pageIndex) !== null && _pagination$pageIndex !== void 0 ? _pagination$pageIndex : pagination.initialPageIndex) !== null && _ref3 !== void 0 ? _ref3 : 0; var initialPageSize = pagination === true ? defaultPageSize : (_ref4 = (_pagination$pageSize = pagination.pageSize) !== null && _pagination$pageSize !== void 0 ? _pagination$pageSize : pagination.initialPageSize) !== null && _ref4 !== void 0 ? _ref4 : 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 _props$searchFormat; var _this; _classCallCheck(this, EuiInMemoryTable); _this = _callSuper(this, EuiInMemoryTable, [props]); _defineProperty(_this, "onTableChange", function (_ref5) { var page = _ref5.page, sort = _ref5.sort; var _ref6 = page || {}, pageIndex = _ref6.index, pageSize = _ref6.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 _ref7 = sort || {}, sortName = _ref7.field, sortDirection = _ref7.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 (_ref8) { var query = _ref8.query, queryText = _ref8.queryText, error = _ref8.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 search = _this.props.search; if (isEuiSearchBarProps(search)) { if (search.onChange) { var shouldQueryInMemory = search.onChange({ query: null, queryText: escapedQueryText, error: null }); if (!shouldQueryInMemory) { return; } } } _this.setState({ query: "\"".concat(escapedQueryText, "\"") }); }); 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, (_props$searchFormat = props.searchFormat) !== null && _props$searchFormat !== void 0 ? _props$searchFormat : 'eql'), 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 _ref9 = search, _ref9$box = _ref9.box, box = _ref9$box === void 0 ? {} : _ref9$box, query = _ref9.query, defaultQuery = _ref9.defaultQuery; var schema = box.schema, searchBoxProps = _objectWithoutProperties(box, _excluded); // in the unexpected case a Query object is passed with searchFormat=text if (process.env.NODE_ENV === 'development') { if (query != null && !isString(query)) { console.warn('EuiInMemoryTable: `query` should be a string when using searchFormat="text". Query objects are only supported with searchFormat="eql".'); } if (defaultQuery != null && !isString(defaultQuery)) { console.warn('EuiInMemoryTable: `defaultQuery` should be a string when using searchFormat="text". Query objects are only supported with searchFormat="eql".'); } } // use only string values, ignore Query objects var displayQuery = isString(query) ? query : isString(defaultQuery) ? defaultQuery : ''; searchBar = ___EmotionJSX(EuiSearchBox, _extends({}, searchBoxProps, { query: displayQuery, 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 _ref10 = column, field = _ref10.field, dataType = _ref10.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 (_ref11) { var name = _ref11.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, noItemsMessage = _this$props2.noItemsMessage, 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: noItemsMessage, 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) { var _nextProps$searchForm; updatedPrevState = _objectSpread(_objectSpread({}, updatedPrevState), {}, { prevProps: _objectSpread(_objectSpread({}, updatedPrevState.prevProps), {}, { search: nextProps.search }), query: getQueryFromSearch(nextProps.search, false, (_nextProps$searchForm = nextProps.searchFormat) !== null && _nextProps$searchForm !== void 0 ? _nextProps$searchForm : 'eql') }); } if (updatedPrevState !== prevState) { return updatedPrevState; } return null; } }]); }(Component); _defineProperty(EuiInMemoryTable, "contextType", EuiComponentDefaultsContext); _defineProperty(EuiInMemoryTable, "defaultProps", { tableLayout: 'fixed', searchFormat: 'eql' });