"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.FieldPicker = FieldPicker; var _react = _interopRequireWildcard(require("react")); var _eui = require("@elastic/eui"); var _i18n = require("@kbn/i18n"); var _classnames = _interopRequireDefault(require("classnames")); var _reactField = require("@kbn/react-field"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * 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; you may not use this file except in compliance with the Elastic License * 2.0. */ function FieldPicker({ fieldMap, selectField, deselectField, open, setOpen }) { const allFields = Object.values(fieldMap); const hasFields = allFields.length > 0; const [fieldOptions, setFieldOptions] = (0, _react.useState)(toOptions(allFields)); (0, _react.useEffect)(() => { if (!open) { // only update the field options if the popover is not open currently. // This is necessary because EuiSelectable assumes options don't change // on their own. setFieldOptions(toOptions(Object.values(fieldMap))); } }, [fieldMap, open]); const badgeDescription = _i18n.i18n.translate('xpack.graph.bar.pickFieldsLabel', { defaultMessage: 'Add fields' }); return /*#__PURE__*/_react.default.createElement(_eui.EuiPopover, { id: "graphFieldPicker", anchorPosition: "downCenter", ownFocus: true, panelPaddingSize: "none", button: /*#__PURE__*/_react.default.createElement(_eui.EuiBadge, { "data-test-subj": "graph-add-field-button", className: (0, _classnames.default)('gphFieldPicker__button', { 'gphFieldPicker__button--disabled': !hasFields }), color: "hollow", iconType: "plusInCircleFilled", "aria-disabled": !hasFields, onClick: () => { if (hasFields) { setOpen(!open); } }, onClickAriaLabel: badgeDescription }, badgeDescription), isOpen: open, closePopover: () => setOpen(false), panelClassName: "gphFieldPicker__popoverPanel" }, open && /*#__PURE__*/_react.default.createElement(_eui.EuiSelectable, { searchProps: { placeholder: _i18n.i18n.translate('xpack.graph.fieldManager.fieldSearchPlaceholder', { defaultMessage: 'Filter by' }), compressed: true, 'data-test-subj': 'graph-field-search' }, listProps: { className: 'gphFieldPicker__selectableList' }, searchable: true, options: fieldOptions, onChange: newOptions => { newOptions.forEach(option => { if (option.checked === 'on' && !fieldMap[option.label].selected) { selectField(option.label); } else if (option.checked !== 'on' && fieldMap[option.label].selected) { deselectField(option.label); } }); setFieldOptions(newOptions); } }, (list, search) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, search, list))); } function toOptions(fields) { return fields // don't show non-aggregatable fields, except for the case when they are already selected. // this is necessary to ensure backwards compatibility with existing workspaces that might // contain non-aggregatable fields. .filter(field => isExplorable(field) || field.selected).map(field => ({ label: field.name, prepend: /*#__PURE__*/_react.default.createElement(_reactField.FieldIcon, { className: "eui-alignMiddle", type: field.type, fill: "none" }), checked: field.selected ? 'on' : undefined })); } const explorableTypes = ['string', 'number', 'date', 'ip', 'boolean']; function isExplorable(field) { if (!field.aggregatable) { return false; } return explorableTypes.includes(field.type); }