"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.EditAssigneesSelectable = void 0;
var _react = _interopRequireWildcard(require("react"));
var _lodash = require("lodash");
var _eui = require("@elastic/eui");
var _userProfileComponents = require("@kbn/user-profile-components");
var _use_bulk_get_user_profiles = require("../../../containers/user_profiles/use_bulk_get_user_profiles");
var _use_is_user_typing = require("../../../common/use_is_user_typing");
var _use_suggest_user_profiles = require("../../../containers/user_profiles/use_suggest_user_profiles");
var i18n = _interopRequireWildcard(require("./translations"));
var _use_items_state = require("../use_items_state");
var _use_cases_context = require("../../cases_context/use_cases_context");
var _empty_message = require("../../user_profiles/empty_message");
var _no_matches = require("../../user_profiles/no_matches");
var _small_user_avatar = require("../../user_profiles/small_user_avatar");
var _no_selected_assignees = require("./no_selected_assignees");
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.
 */

const getUnknownUsers = (assignees, userProfiles) => {
  const unknownUsers = [];
  if (!userProfiles) {
    return unknownUsers;
  }
  for (const assignee of assignees) {
    if (!userProfiles.has(assignee)) {
      unknownUsers.push(assignee);
    }
  }
  return unknownUsers;
};
const EditAssigneesSelectableComponent = ({
  selectedCases,
  onChangeAssignees
}) => {
  const {
    owner: owners
  } = (0, _use_cases_context.useCasesContext)();
  const {
    euiTheme
  } = (0, _eui.useEuiTheme)();
  const {
    isUserTyping,
    onContentChange,
    onDebounce
  } = (0, _use_is_user_typing.useIsUserTyping)();
  const hasDataBeenSetToStateAfterFetched = (0, _react.useRef)(false);
  const assignees = (0, _react.useMemo)(() => new Set(selectedCases.map(theCase => theCase.assignees.map(({
    uid
  }) => uid)).flat()), [selectedCases]);
  const {
    data,
    isLoading: isLoadingUserProfiles
  } = (0, _use_bulk_get_user_profiles.useBulkGetUserProfiles)({
    uids: Array.from(assignees.values())
  });
  const userProfiles = (0, _react.useMemo)(() => data !== null && data !== void 0 ? data : new Map(), [data]);
  const unknownUsers = getUnknownUsers(assignees, userProfiles);
  const userProfileIds = [...userProfiles.keys(), ...unknownUsers];
  const [searchValue, setSearchValue] = (0, _react.useState)('');
  const {
    data: searchResultUserProfiles,
    isLoading: isLoadingSuggest
  } = (0, _use_suggest_user_profiles.useSuggestUserProfiles)({
    name: searchValue,
    owners,
    onDebounce
  });
  const itemToSelectableOption = (0, _react.useCallback)(item => {
    const userProfileFromData = item.data;
    const userProfile = (0, _lodash.isEmpty)(userProfileFromData) ? userProfiles.get(item.key) : userProfileFromData;
    if (isUserProfile(userProfile)) {
      return toSelectableOption(userProfile);
    }
    const profileInSuggestedUsers = searchResultUserProfiles === null || searchResultUserProfiles === void 0 ? void 0 : searchResultUserProfiles.find(profile => profile.uid === item.data.uid);
    if (profileInSuggestedUsers) {
      return toSelectableOption(profileInSuggestedUsers);
    }
    return {
      key: item.key,
      label: i18n.UNKNOWN,
      data: {
        unknownUser: true
      },
      'data-test-subj': `cases-actions-assignees-edit-selectable-assignee-${item.key}`
    };
  }, [searchResultUserProfiles, userProfiles]);
  const {
    options,
    totalSelectedItems,
    onChange,
    onSelectNone,
    resetItems
  } = (0, _use_items_state.useItemsState)({
    items: userProfileIds,
    selectedCases,
    fieldSelector: theCase => theCase.assignees.map(({
      uid
    }) => uid),
    onChangeItems: onChangeAssignees,
    itemToSelectableOption
  });
  if (data && !hasDataBeenSetToStateAfterFetched.current) {
    hasDataBeenSetToStateAfterFetched.current = true;
    resetItems(userProfileIds);
  }
  const finalOptions = getDisplayOptions({
    searchResultUserProfiles: searchResultUserProfiles !== null && searchResultUserProfiles !== void 0 ? searchResultUserProfiles : [],
    options,
    searchValue,
    initialUserProfiles: userProfiles
  });
  const isLoadingData = isLoadingUserProfiles || isLoadingSuggest || isUserTyping;
  const renderOption = (0, _react.useCallback)((option, search) => {
    var _option$itemIcon, _option$user, _option$user2;
    const icon = (_option$itemIcon = option.itemIcon) !== null && _option$itemIcon !== void 0 ? _option$itemIcon : 'empty';
    const dataTestSubj = `cases-actions-assignees-edit-selectable-assignee-${option.key}-icon-${icon}`;
    const userInfo = option.user ? {
      user: option.user,
      data: option.data
    } : undefined;
    return /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
      grow: false
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, {
      gutterSize: "s",
      alignItems: "center",
      justifyContent: "center",
      responsive: false
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
      grow: false
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiIcon, {
      type: icon,
      "data-test-subj": dataTestSubj
    })), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
      grow: false
    }, /*#__PURE__*/_react.default.createElement(_small_user_avatar.SmallUserAvatar, {
      userInfo: userInfo
    })))), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, {
      alignItems: "center",
      justifyContent: "spaceBetween",
      gutterSize: "s",
      responsive: false
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, null, /*#__PURE__*/_react.default.createElement(_eui.EuiHighlight, {
      search: searchValue
    }, option.label)), (_option$user = option.user) !== null && _option$user !== void 0 && _option$user.email && ((_option$user2 = option.user) === null || _option$user2 === void 0 ? void 0 : _option$user2.email) !== option.label ? /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
      grow: false
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiTextColor, {
      color: option.disabled ? 'disabled' : 'subdued'
    }, searchValue ? /*#__PURE__*/_react.default.createElement(_eui.EuiHighlight, {
      search: searchValue
    }, option.user.email) : option.user.email)) : undefined));
  }, [searchValue]);
  const onSearchChange = (0, _react.useCallback)(value => {
    setSearchValue(value);
    onContentChange(value);
  }, [onContentChange]);
  if (isLoadingUserProfiles) {
    return /*#__PURE__*/_react.default.createElement(_eui.EuiLoadingSpinner, null);
  }
  return /*#__PURE__*/_react.default.createElement(_eui.EuiSelectable, {
    options: finalOptions,
    searchable: true,
    searchProps: {
      placeholder: i18n.SEARCH_ASSIGNEES_PLACEHOLDER,
      isLoading: isLoadingData,
      isClearable: !isLoadingData,
      onChange: onSearchChange,
      value: searchValue,
      'data-test-subj': 'cases-actions-assignees-edit-selectable-search-input'
    },
    renderOption: renderOption,
    listProps: {
      showIcons: false
    },
    onChange: onChange,
    noMatchesMessage: !isLoadingData ? /*#__PURE__*/_react.default.createElement(_no_matches.NoMatches, null) : /*#__PURE__*/_react.default.createElement(_empty_message.EmptyMessage, null),
    emptyMessage: /*#__PURE__*/_react.default.createElement(_no_selected_assignees.NoSelectedAssignees, {
      totalSelectedCases: selectedCases.length
    }),
    "data-test-subj": "cases-actions-assignees-edit-selectable",
    height: "full"
  }, (list, search) => {
    return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, search, /*#__PURE__*/_react.default.createElement(_eui.EuiSpacer, {
      size: "s"
    }), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, {
      alignItems: "center",
      justifyContent: "spaceBetween",
      responsive: false,
      direction: "row",
      css: {
        flexGrow: 0
      },
      gutterSize: "none"
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
      grow: false,
      css: {
        paddingLeft: euiTheme.size.s
      }
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiText, {
      size: "xs",
      color: "subdued"
    }, i18n.SELECTED_ASSIGNEES(totalSelectedItems))), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
      grow: false,
      css: {
        marginLeft: 'auto'
      }
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, {
      responsive: false,
      direction: "row",
      alignItems: "center",
      justifyContent: "flexEnd",
      gutterSize: "xs"
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
      grow: false
    }, /*#__PURE__*/_react.default.createElement(_eui.EuiButtonEmpty, {
      size: "xs",
      flush: "right",
      onClick: onSelectNone
    }, i18n.REMOVE_ASSIGNEES))))), /*#__PURE__*/_react.default.createElement(_eui.EuiHorizontalRule, {
      margin: "m"
    }), list);
  });
};
EditAssigneesSelectableComponent.displayName = 'EditAssigneesSelectable';
const EditAssigneesSelectable = /*#__PURE__*/_react.default.memo(EditAssigneesSelectableComponent);
exports.EditAssigneesSelectable = EditAssigneesSelectable;
const getDisplayOptions = ({
  searchResultUserProfiles,
  options,
  searchValue,
  initialUserProfiles
}) => {
  var _searchResultUserProf, _searchResultUserProf2;
  /**
   * If the user does not perform any search we do not want to show
   * the results of an empty search to the initial list of users.
   * We also filter out users that appears both in the initial list
   * and the search results
   */
  const searchResultsOptions = (0, _lodash.isEmpty)(searchValue) ? [] : (_searchResultUserProf = searchResultUserProfiles === null || searchResultUserProfiles === void 0 ? void 0 : (_searchResultUserProf2 = searchResultUserProfiles.filter(profile => !options.find(option => isMatchingOption(option, profile)))) === null || _searchResultUserProf2 === void 0 ? void 0 : _searchResultUserProf2.map(profile => toSelectableOption(profile))) !== null && _searchResultUserProf !== void 0 ? _searchResultUserProf : [];
  /**
   * In the initial view, when the user does not perform any search,
   * we want to filter out options that are not in the initial user profile
   * mapping or profiles returned by the search result that are not selected.
   * We want to keep unknown users as they can only be available from the
   * selected cases and not from search results
   */
  const filteredOptions = (0, _lodash.isEmpty)(searchValue) ? options.filter(option => {
    var _option$data, _option$data2, _option$data3;
    return initialUserProfiles.has(option === null || option === void 0 ? void 0 : (_option$data = option.data) === null || _option$data === void 0 ? void 0 : _option$data.uid) || (option === null || option === void 0 ? void 0 : (_option$data2 = option.data) === null || _option$data2 === void 0 ? void 0 : _option$data2.itemIcon) !== 'empty' || ((_option$data3 = option.data) === null || _option$data3 === void 0 ? void 0 : _option$data3.unknownUser);
  }) : [...options];
  const finalOptions = sortOptionsAlphabetically([...searchResultsOptions, ...filteredOptions]);
  return finalOptions;
};
const sortOptionsAlphabetically = options =>
/**
 * sortBy will not mutate the original array.
 * It will return a new sorted array
 *  */
(0, _lodash.sortBy)(options, option => option.label);
const toSelectableOption = userProfile => {
  return {
    key: userProfile.uid,
    label: (0, _userProfileComponents.getUserDisplayName)(userProfile.user),
    data: userProfile,
    'data-test-subj': `cases-actions-assignees-edit-selectable-assignee-${userProfile.uid}`
  };
};
const isMatchingOption = (option, profile) => {
  return option.key === profile.uid;
};
const isUserProfile = userProfile => !!userProfile && !!userProfile.uid && !!userProfile.user;