"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof3 = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.usePopoverArrowNavigation = exports.useHasColumnActions = exports.isColumnActionEnabled = exports.getSortColumnActions = exports.getHideColumnAction = exports.getColumnActions = exports.getColumnActionConfig = exports.ColumnActions = void 0;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireWildcard(require("react"));
var _tabbable = require("tabbable");
var _services = require("../../../../services");
var _i18n = require("../../../i18n");
var _popover = require("../../../popover");
var _list_group = require("../../../list_group");
var _button = require("../../../button");
var _focus = require("../../utils/focus");
var _data_grid_schema = require("../../utils/data_grid_schema");
var _column_sorting_draggable = require("../../controls/column_sorting_draggable");
var _data_grid_header_cell = require("./data_grid_header_cell.styles");
var _react2 = require("@emotion/react");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
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) { (0, _defineProperty2.default)(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.
 */ // Keep the i18n scope the same as EuiDataGridHeaderCell
/* eslint-disable local/i18n */
var useHasColumnActions = exports.useHasColumnActions = function useHasColumnActions(columnActions) {
  return (0, _react.useMemo)(function () {
    // By default, all column actions are enabled
    if (columnActions === undefined) return true;
    if (columnActions === false) return false;
    if (columnActions.additional && columnActions.additional.length) return true;
    // Check if all (currently 5) default column actions have been manually disabled
    var disabledActions = Object.values(columnActions).filter(function (action) {
      return action === false;
    });
    return disabledActions.length < 5;
  }, [columnActions]);
};

// Props to pass back to EuiDataGridHeaderCell and set on EuiDataGridHeaderCellWrapper

var ColumnActions = exports.ColumnActions = /*#__PURE__*/(0, _react.memo)(function (_ref) {
  var index = _ref.index,
    id = _ref.id,
    title = _ref.title,
    column = _ref.column,
    columns = _ref.columns,
    schema = _ref.schema,
    schemaDetectors = _ref.schemaDetectors,
    setVisibleColumns = _ref.setVisibleColumns,
    switchColumnPos = _ref.switchColumnPos,
    sorting = _ref.sorting,
    hasFocusTrap = _ref.hasFocusTrap,
    setPropsFromColumnActions = _ref.setPropsFromColumnActions,
    actionsButtonRef = _ref.actionsButtonRef;
  /**
   * Popover logic and accessibility
   */
  var _useState = (0, _react.useState)(false),
    _useState2 = (0, _slicedToArray2.default)(_useState, 2),
    isPopoverOpen = _useState2[0],
    setIsPopoverOpen = _useState2[1];
  var togglePopover = (0, _react.useCallback)(function () {
    setIsPopoverOpen(function (isOpen) {
      return !isOpen;
    });
  }, []);
  var closePopover = (0, _react.useCallback)(function () {
    setIsPopoverOpen(false);
  }, []);
  var actionsButtonAriaLabel = (0, _i18n.useEuiI18n)('euiDataGridHeaderCell.actionsButtonAriaLabel', '{title}. Click to view column header actions.', {
    title: title
  });
  var actionsEnterKeyInstructions = (0, _i18n.useEuiI18n)('euiDataGridHeaderCell.actionsEnterKeyInstructions', "Press the Enter key to view this column's actions");
  var openActionsPopoverOnEnter = (0, _react.useCallback)(function (e) {
    if (e.key === _services.keys.ENTER) {
      setIsPopoverOpen(true);
    }
  }, []);
  var popoverArrowNavigationProps = usePopoverArrowNavigation();

  /**
   * Props to set on parent EuiDataGridHeaderCell
   */
  var _useState3 = (0, _react.useState)(false),
    _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
    isColumnMoving = _useState4[0],
    setIsColumnMoving = _useState4[1];
  (0, _react.useEffect)(function () {
    setPropsFromColumnActions({
      className: isPopoverOpen ? 'euiDataGridHeaderCell--isActionsPopoverOpen' : '',
      onKeyDown: openActionsPopoverOnEnter,
      'data-column-moving': isColumnMoving || undefined
    });
  }, [setPropsFromColumnActions, isPopoverOpen, openActionsPopoverOnEnter, isColumnMoving]);

  /**
   * Get column actions as an array of EuiListGroup items
   */
  var _useContext = (0, _react.useContext)(_focus.DataGridFocusContext),
    setFocusedCell = _useContext.setFocusedCell,
    focusFirstVisibleInteractiveCell = _useContext.focusFirstVisibleInteractiveCell;
  var columnActions = (0, _react.useMemo)(function () {
    return getColumnActions({
      column: column,
      columns: columns,
      schema: schema,
      schemaDetectors: schemaDetectors,
      setVisibleColumns: setVisibleColumns,
      focusFirstVisibleInteractiveCell: focusFirstVisibleInteractiveCell,
      sorting: sorting,
      switchColumnPos: switchColumnPos,
      setIsPopoverOpen: setIsPopoverOpen,
      setIsColumnMoving: setIsColumnMoving,
      setFocusedCell: setFocusedCell,
      columnFocusIndex: index
    });
  }, [column, columns, schema, schemaDetectors, setVisibleColumns, focusFirstVisibleInteractiveCell, sorting, switchColumnPos, setFocusedCell, index]);

  /**
   * Rendering
   */
  var styles = (0, _services.useEuiMemoizedStyles)(_data_grid_header_cell.euiDataGridHeaderCellStyles);
  return (0, _react2.jsx)(_popover.EuiPopover, (0, _extends2.default)({
    display: "block",
    panelPaddingSize: "s",
    offset: 7,
    anchorPosition: "downRight",
    css: styles.euiDataGridHeaderCell__popover,
    button: (0, _react2.jsx)(_button.EuiButtonIcon, {
      iconType: "boxesVertical",
      iconSize: "s",
      color: "text",
      className: "euiDataGridHeaderCell__button",
      onClick: togglePopover,
      buttonRef: actionsButtonRef,
      "aria-label": hasFocusTrap ? actionsButtonAriaLabel : actionsEnterKeyInstructions,
      css: [styles.euiDataGridHeaderCell__actions.action, styles.euiDataGridHeaderCell__actions.end, ";label:ColumnActions;"],
      "data-test-subj": "dataGridHeaderCellActionButton-".concat(id)
    }),
    isOpen: isPopoverOpen,
    closePopover: closePopover
  }, popoverArrowNavigationProps), (0, _react2.jsx)(_list_group.EuiListGroup, {
    listItems: columnActions,
    "data-test-subj": "dataGridHeaderCellActionGroup-".concat(id)
  }));
});
ColumnActions.displayName = 'EuiDataGridHeaderCellColumnActions';

/**
 * Add keyboard arrow navigation to the cell actions popover
 * to match the UX of the rest of EuiDataGrid
 */
var usePopoverArrowNavigation = exports.usePopoverArrowNavigation = function usePopoverArrowNavigation() {
  var popoverPanelRef = (0, _react.useRef)(null);
  var actionsRef = (0, _react.useRef)(undefined);
  var panelRef = (0, _react.useCallback)(function (ref) {
    popoverPanelRef.current = ref;
    actionsRef.current = ref ? (0, _tabbable.tabbable)(ref) : undefined;
  }, []);
  var onKeyDown = (0, _react.useCallback)(function (e) {
    var _actionsRef$current;
    if (e.key !== _services.keys.ARROW_DOWN && e.key !== _services.keys.ARROW_UP) return;
    if (!((_actionsRef$current = actionsRef.current) !== null && _actionsRef$current !== void 0 && _actionsRef$current.length)) return;
    e.preventDefault();
    var initialState = document.activeElement === popoverPanelRef.current;
    var currentIndex = !initialState ? actionsRef.current.findIndex(function (el) {
      return document.activeElement === el;
    }) : -1;
    var lastIndex = actionsRef.current.length - 1;
    var indexToFocus;
    if (initialState) {
      if (e.key === _services.keys.ARROW_DOWN) {
        indexToFocus = 0;
      } else if (e.key === _services.keys.ARROW_UP) {
        indexToFocus = lastIndex;
      }
    } else {
      if (e.key === _services.keys.ARROW_DOWN) {
        indexToFocus = currentIndex + 1;
        if (indexToFocus > lastIndex) {
          indexToFocus = 0;
        }
      } else if (e.key === _services.keys.ARROW_UP) {
        indexToFocus = currentIndex - 1;
        if (indexToFocus < 0) {
          indexToFocus = lastIndex;
        }
      }
    }
    actionsRef.current[indexToFocus].focus();
  }, []);
  return {
    panelRef: panelRef,
    panelProps: {
      onKeyDown: onKeyDown
    },
    popoverScreenReaderText: (0, _react2.jsx)(_i18n.EuiI18n, {
      token: "euiDataGridHeaderCell.actionsPopoverScreenReaderText",
      default: "To navigate through the list of column actions, press the Tab or Up and Down arrow keys."
    })
  };
};

/**
 * Logic for returning an array of actions/items to pass to EuiListGroup
 */

var getColumnActions = exports.getColumnActions = function getColumnActions(_ref2) {
  var _column$actions;
  var column = _ref2.column,
    columns = _ref2.columns,
    schema = _ref2.schema,
    schemaDetectors = _ref2.schemaDetectors,
    setVisibleColumns = _ref2.setVisibleColumns,
    focusFirstVisibleInteractiveCell = _ref2.focusFirstVisibleInteractiveCell,
    setIsPopoverOpen = _ref2.setIsPopoverOpen,
    sorting = _ref2.sorting,
    switchColumnPos = _ref2.switchColumnPos,
    setIsColumnMoving = _ref2.setIsColumnMoving,
    setFocusedCell = _ref2.setFocusedCell,
    columnFocusIndex = _ref2.columnFocusIndex;
  if (column.actions === false) {
    return [];
  }
  var actions = [].concat((0, _toConsumableArray2.default)(getHideColumnAction({
    column: column,
    columns: columns,
    setVisibleColumns: setVisibleColumns,
    focusFirstVisibleInteractiveCell: focusFirstVisibleInteractiveCell
  })), (0, _toConsumableArray2.default)(getSortColumnActions({
    column: column,
    sorting: sorting,
    schema: schema,
    schemaDetectors: schemaDetectors
  })), (0, _toConsumableArray2.default)(getMoveColumnActions({
    column: column,
    columns: columns,
    switchColumnPos: switchColumnPos,
    setIsColumnMoving: setIsColumnMoving,
    setFocusedCell: setFocusedCell,
    columnFocusIndex: columnFocusIndex
  })), (0, _toConsumableArray2.default)(((_column$actions = column.actions) === null || _column$actions === void 0 ? void 0 : _column$actions.additional) || []));
  return actions.map(function (action) {
    return _objectSpread(_objectSpread({}, action), {}, {
      // Wrap EuiListGroupItem onClick function to close the popover and prevent bubbling up
      onClick: function onClick(e) {
        e.stopPropagation();
        setIsPopoverOpen(false);
        if (action !== null && action !== void 0 && action.onClick) {
          action.onClick(e);
        }
      }
    });
  });
};

/**
 * Hide column action
 */

var getHideColumnAction = exports.getHideColumnAction = function getHideColumnAction(_ref3) {
  var column = _ref3.column,
    columns = _ref3.columns,
    setVisibleColumns = _ref3.setVisibleColumns,
    focusFirstVisibleInteractiveCell = _ref3.focusFirstVisibleInteractiveCell;
  var items = [];
  var onClickHideColumn = function onClickHideColumn() {
    setVisibleColumns(columns.filter(function (col) {
      return col.id !== column.id;
    }).map(function (col) {
      return col.id;
    }));
    // Since we hid the current column, we need to manually set focus back onto the grid
    focusFirstVisibleInteractiveCell();
  };
  var action = {
    label: (0, _react2.jsx)(_i18n.EuiI18n, {
      token: "euiColumnActions.hideColumn",
      default: "Hide column"
    }),
    onClick: onClickHideColumn,
    iconType: 'eyeSlash',
    size: 'xs',
    color: 'text'
  };
  if (isColumnActionEnabled('showHide', column.actions)) {
    items.push(getColumnActionConfig(action, 'showHide', column.actions));
  }
  return items;
};

/**
 * Move column actions
 */

var getMoveColumnActions = function getMoveColumnActions(_ref4) {
  var column = _ref4.column,
    columns = _ref4.columns,
    switchColumnPos = _ref4.switchColumnPos,
    setIsColumnMoving = _ref4.setIsColumnMoving,
    setFocusedCell = _ref4.setFocusedCell,
    columnFocusIndex = _ref4.columnFocusIndex;
  var items = [];
  var colIdx = columns.findIndex(function (col) {
    return col.id === column.id;
  });

  // UX polish: prevent the column actions hover animation from flashing after column move
  var handleAnimationFlash = function handleAnimationFlash() {
    setIsColumnMoving(true);
    requestAnimationFrame(function () {
      return setIsColumnMoving(false);
    });
  };
  var moveFocus = function moveFocus(direction) {
    var newIndex = direction === 'left' ? -1 : 1;
    // Wait a beat to move focus, otherwise the EuiPopover's EuiFocusTrap's
    // returnFocus logic sometimes steals it (depending on rerenders)
    setTimeout(function () {
      setFocusedCell([columnFocusIndex + newIndex, -1]); // -1 is the static y-index of the header
    });
  };
  if (isColumnActionEnabled('showMoveLeft', column.actions)) {
    var onClickMoveLeft = function onClickMoveLeft() {
      var targetCol = columns[colIdx - 1];
      if (targetCol) {
        switchColumnPos(column.id, targetCol.id);
        handleAnimationFlash();
        moveFocus('left');
      }
    };
    var action = {
      label: (0, _react2.jsx)(_i18n.EuiI18n, {
        token: "euiColumnActions.moveLeft",
        default: "Move left"
      }),
      iconType: 'sortLeft',
      size: 'xs',
      color: 'text',
      onClick: onClickMoveLeft,
      isDisabled: colIdx === 0
    };
    items.push(getColumnActionConfig(action, 'showMoveLeft', column.actions));
  }
  if (isColumnActionEnabled('showMoveRight', column.actions)) {
    var onClickMoveRight = function onClickMoveRight() {
      var targetCol = columns[colIdx + 1];
      if (targetCol) {
        switchColumnPos(column.id, targetCol.id);
        handleAnimationFlash();
        moveFocus('right');
      }
    };
    var _action = {
      label: (0, _react2.jsx)(_i18n.EuiI18n, {
        token: "euiColumnActions.moveRight",
        default: "Move right"
      }),
      iconType: 'sortRight',
      size: 'xs',
      color: 'text',
      onClick: onClickMoveRight,
      isDisabled: colIdx === columns.length - 1
    };
    items.push(getColumnActionConfig(_action, 'showMoveRight', column.actions));
  }
  return items;
};

/**
 * Sort column actions
 */

var getSortColumnActions = exports.getSortColumnActions = function getSortColumnActions(_ref5) {
  var column = _ref5.column,
    sorting = _ref5.sorting,
    schema = _ref5.schema,
    schemaDetectors = _ref5.schemaDetectors;
  if (!sorting) return [];
  var items = [];
  var sortingIdx = sorting.columns.findIndex(function (col) {
    return col.id === column.id;
  });
  var schemaDetails = schema.hasOwnProperty(column.id) && schema[column.id].columnType != null ? (0, _data_grid_schema.getDetailsForSchema)(schemaDetectors, schema[column.id].columnType) : null;
  var sortBy = function sortBy(direction) {
    var _sorting$columns$sort;
    if (sortingIdx >= 0 && ((_sorting$columns$sort = sorting.columns[sortingIdx]) === null || _sorting$columns$sort === void 0 ? void 0 : _sorting$columns$sort.direction) === direction) {
      // unsort if the same current and new direction are same
      var newColumns = sorting.columns.filter(function (_, idx) {
        return idx !== sortingIdx;
      });
      sorting.onSort(newColumns);
    } else if (sortingIdx >= 0) {
      // replace existing sort
      var _newColumns = Object.values(_objectSpread(_objectSpread({}, sorting.columns), {}, (0, _defineProperty2.default)({}, sortingIdx, {
        id: column.id,
        direction: direction
      })));
      sorting.onSort(_newColumns);
    } else {
      // add new sort
      var _newColumns2 = [].concat((0, _toConsumableArray2.default)(sorting.columns), [{
        id: column.id,
        direction: direction
      }]);
      sorting.onSort(_newColumns2);
    }
  };
  if (isColumnActionEnabled('showSortAsc', column.actions)) {
    var label = schemaDetails ? schemaDetails.sortTextAsc : _column_sorting_draggable.defaultSortAscLabel;
    var onClickSortAsc = function onClickSortAsc() {
      sortBy('asc');
    };
    var isSorted = sortingIdx >= 0 && sorting.columns[sortingIdx].direction === 'asc';
    var action = {
      label: isSorted ? (0, _react2.jsx)(_i18n.EuiI18n, {
        token: "euiColumnActions.unsort",
        default: "Unsort {schemaLabel}",
        values: {
          schemaLabel: label
        }
      }) : (0, _react2.jsx)(_i18n.EuiI18n, {
        token: "euiColumnActions.sort",
        default: "Sort {schemaLabel}",
        values: {
          schemaLabel: label
        }
      }),
      onClick: onClickSortAsc,
      isDisabled: column.isSortable === false,
      iconType: 'sortUp',
      size: 'xs',
      color: 'text'
    };
    items.push(getColumnActionConfig(action, 'showSortAsc', column.actions));
  }
  if (isColumnActionEnabled('showSortDesc', column.actions)) {
    var _label = schemaDetails ? schemaDetails.sortTextDesc : _column_sorting_draggable.defaultSortDescLabel;
    var onClickSortDesc = function onClickSortDesc() {
      sortBy('desc');
    };
    var _isSorted = sortingIdx >= 0 && sorting.columns[sortingIdx].direction === 'desc';
    var _action2 = {
      label: _isSorted ? (0, _react2.jsx)(_i18n.EuiI18n, {
        token: "euiColumnActions.unsort",
        default: "Unsort {schemaLabel}",
        values: {
          schemaLabel: _label
        }
      }) : (0, _react2.jsx)(_i18n.EuiI18n, {
        token: "euiColumnActions.sort",
        default: "Sort {schemaLabel}",
        values: {
          schemaLabel: _label
        }
      }),
      onClick: onClickSortDesc,
      isDisabled: column.isSortable === false,
      iconType: 'sortDown',
      size: 'xs',
      color: 'text'
    };
    items.push(getColumnActionConfig(_action2, 'showSortDesc', column.actions));
  }
  return items;
};

/**
 * Column action utility helpers - mostly syntactical sugar for adding an extra
 * actions !== false checks, which we make an early return for in the main fn,
 * but that the individual utils don't know about and Typescript complains about
 */

// Check whether an action is enabled/should be appended to the actions array
var isColumnActionEnabled = exports.isColumnActionEnabled = function isColumnActionEnabled(actionKey, actions) {
  if (actions === false) return false;
  if ((actions === null || actions === void 0 ? void 0 : actions[actionKey]) === false) return false;
  return true;
};

// Utility helper for appending any custom EuiDataGridColumnActions configuration to its action
var getColumnActionConfig = exports.getColumnActionConfig = function getColumnActionConfig(action, actionKey, actions) {
  var configuration = actions !== false && (actions === null || actions === void 0 ? void 0 : actions[actionKey]);
  return (0, _typeof2.default)(configuration) === 'object' ? _objectSpread(_objectSpread({}, action), configuration) : action;
};