client/entity-editor/name-section/name-section.js

"use strict";

require("core-js/modules/es.reflect.construct.js");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
require("core-js/modules/es.array.map.js");
require("core-js/modules/es.array.concat.js");
require("core-js/modules/es.function.name.js");
require("core-js/modules/es.array.filter.js");
require("core-js/modules/es.object.to-string.js");
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _debounce2 = _interopRequireDefault(require("lodash/debounce"));
var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty"));
var _kebabCase2 = _interopRequireDefault(require("lodash/kebabCase"));
var _startCase2 = _interopRequireDefault(require("lodash/startCase"));
var _toLower2 = _interopRequireDefault(require("lodash/toLower"));
var _isNil2 = _interopRequireDefault(require("lodash/isNil"));
var _reactBootstrap = require("react-bootstrap");
var _actions = require("../edition-section/actions");
var _actions2 = require("./actions");
var _helpers = require("../helpers");
var _common = require("../validators/common");
var _disambiguationField = _interopRequireDefault(require("./disambiguation-field"));
var _immutable = _interopRequireDefault(require("immutable"));
var _languageField = _interopRequireDefault(require("../common/language-field"));
var _nameField = _interopRequireDefault(require("../common/name-field"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _react = _interopRequireDefault(require("react"));
var _searchResults = _interopRequireDefault(require("../../components/pages/parts/search-results"));
var _sortNameField = _interopRequireDefault(require("../common/sort-name-field"));
var _reactRedux = require("react-redux");
var _utils = require("../../helpers/utils");
var _reactValidators = require("../../helpers/react-validators");
var _entity = require("../../helpers/entity");
var _makeImmutable = _interopRequireDefault(require("../common/make-immutable"));
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /*
                                                                                                                                                                                                                                                                                                                                           * Copyright (C) 2016  Ben Ockmore
                                                                                                                                                                                                                                                                                                                                           *
                                                                                                                                                                                                                                                                                                                                           * This program is free software; you can redistribute it and/or modify
                                                                                                                                                                                                                                                                                                                                           * it under the terms of the GNU General Public License as published by
                                                                                                                                                                                                                                                                                                                                           * the Free Software Foundation; either version 2 of the License, or
                                                                                                                                                                                                                                                                                                                                           * (at your option) any later version.
                                                                                                                                                                                                                                                                                                                                           *
                                                                                                                                                                                                                                                                                                                                           * This program is distributed in the hope that it will be useful,
                                                                                                                                                                                                                                                                                                                                           * but WITHOUT ANY WARRANTY; without even the implied warranty of
                                                                                                                                                                                                                                                                                                                                           * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                                                                                                                                                                                                                                                                                                                                           * GNU General Public License for more details.
                                                                                                                                                                                                                                                                                                                                           *
                                                                                                                                                                                                                                                                                                                                           * You should have received a copy of the GNU General Public License along
                                                                                                                                                                                                                                                                                                                                           * with this program; if not, write to the Free Software Foundation, Inc.,
                                                                                                                                                                                                                                                                                                                                           * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
                                                                                                                                                                                                                                                                                                                                           */
var ImmutableLanguageField = (0, _makeImmutable.default)(_languageField.default);

/**
 * Container component. The NameSection component contains input fields for
 * setting the name of an entity. It also allows setting of the entity's
 * disambiguation. The intention is that this component is rendered as a
 * modular section within the entity editor.
 *
 * @param {Object} props - The properties passed to the component.
 * @param {string} props.disambiguationDefaultValue - The default value for the
 *        disambiguation field.
 * @param {Array} props.languageOptions - The list of possible languages for the
 *        entity name.
 * @param {string} props.languageValue - The ID of the language currently
 *        selected for the entity name.
 * @param {string} props.nameValue - The name currently set for this entity.
 * @param {string} props.sortNameValue - The sort name currently set for this
 *        entity.
 * @param {Function} props.onLanguageChange - A function to be called when a
 *        different language type is selected.
 * @param {Function} props.onNameChange - A function to be called when the name
 *        is changed.
 * @param {Function} props.onSortNameChange - A function to be called when the
 *        sort name is changed.
 * @param {Function} props.onDisambiguationChange - A function to be called when
 *        the disambiguation is changed.
 * @returns {ReactElement} React element containing the rendered NameSection.
 */
var NameSection = /*#__PURE__*/function (_React$Component) {
  (0, _inherits2.default)(NameSection, _React$Component);
  var _super = _createSuper(NameSection);
  function NameSection(props) {
    var _this;
    (0, _classCallCheck2.default)(this, NameSection);
    _this = _super.call(this, props);
    _this.updateNameFieldInputRef = _this.updateNameFieldInputRef.bind((0, _assertThisInitialized2.default)(_this));
    _this.handleNameChange = _this.handleNameChange.bind((0, _assertThisInitialized2.default)(_this));
    _this.searchForMatchingEditionGroups = _this.searchForMatchingEditionGroups.bind((0, _assertThisInitialized2.default)(_this));
    return _this;
  }

  /*
  	Fix issue with user typing in input before js is fully loaded,
  	not triggering the name search.
  	Also an issue if passing a nameSection with a name that might be a duplicate
  	(e.g. creating an Edition from a Work, the Work's nameSection will be pre-filled)
  	When Component is first loaded, manually trigger "handleNameChange" mechanism.
  */
  (0, _createClass2.default)(NameSection, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      if (this.props.action !== 'edit' && !(0, _isNil2.default)(this.nameInputRef)) {
        this.handleNameChange({
          target: {
            value: this.nameInputRef.value
          }
        });
      }
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps) {
      var _this$props = this.props,
        nameValue = _this$props.nameValue,
        searchForExistingEditionGroup = _this$props.searchForExistingEditionGroup;
      if (prevProps.searchForExistingEditionGroup === searchForExistingEditionGroup || searchForExistingEditionGroup === false) {
        return;
      }
      this.searchForMatchingEditionGroups(nameValue);
    }
  }, {
    key: "handleNameChange",
    value: function handleNameChange(event) {
      this.props.onNameChange(event.target.value);
      this.props.onNameChangeCheckIfExists(event.target.value);
      this.props.onNameChangeSearchName(event.target.value);
      this.searchForMatchingEditionGroups(event.target.value);
    }
  }, {
    key: "searchForMatchingEditionGroups",
    value: function searchForMatchingEditionGroups(nameValue) {
      var _this$props2 = this.props,
        entityType = _this$props2.entityType,
        onNameChangeCheckIfEditionGroupExists = _this$props2.onNameChangeCheckIfEditionGroupExists,
        searchForExistingEditionGroup = _this$props2.searchForExistingEditionGroup;
      // Search for Edition Groups that match the name, if the entity is an Edition
      // Will react to name changes and searchForExistingEditionGroup (which reacts to editionGroupBBID field)
      if ((0, _toLower2.default)(entityType) === 'edition' && searchForExistingEditionGroup && !(0, _isNil2.default)(nameValue)) {
        onNameChangeCheckIfEditionGroupExists(nameValue);
      }
    }
  }, {
    key: "updateNameFieldInputRef",
    value: function updateNameFieldInputRef(inputRef) {
      this.nameInputRef = inputRef;
    }
  }, {
    key: "renderDuplicateAlert",
    value: function renderDuplicateAlert(warnIfExists, disambiguationDefaultValue, exactMatches, entityType, lgCol) {
      return /*#__PURE__*/_react.default.createElement(_reactBootstrap.Col, {
        lg: lgCol
      }, (0, _helpers.isRequiredDisambiguationEmpty)(warnIfExists, disambiguationDefaultValue) ? /*#__PURE__*/_react.default.createElement(_reactBootstrap.Alert, {
        variant: "warning"
      }, "We found the following\xA0", (0, _startCase2.default)(entityType), exactMatches.length > 1 ? 's' : '', " with exactly the same name or alias:", /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("small", {
        className: "text-muted"
      }, "Click on a name to open it (Ctrl/Cmd + click to open in a new tab)"), /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup, {
        activeKey: null,
        className: "margin-top-1 margin-bottom-1"
      }, exactMatches.map(function (match) {
        return /*#__PURE__*/_react.default.createElement(_reactBootstrap.ListGroup.Item, {
          action: true,
          href: "/".concat((0, _kebabCase2.default)(entityType), "/").concat(match.bbid),
          key: "".concat(match.bbid),
          rel: "noopener noreferrer",
          target: "_blank",
          variant: "warning"
        }, match.defaultAlias.name, " ", (0, _entity.getEntityDisambiguation)(match));
      })), "If you are sure your entry is different, please fill the disambiguation field below to help us differentiate between them.") : null);
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props3 = this.props,
        disambiguationDefaultValue = _this$props3.disambiguationDefaultValue,
        entityType = _this$props3.entityType,
        immutableExactMatches = _this$props3.exactMatches,
        languageOptions = _this$props3.languageOptions,
        languageValue = _this$props3.languageValue,
        nameValue = _this$props3.nameValue,
        sortNameValue = _this$props3.sortNameValue,
        onLanguageChange = _this$props3.onLanguageChange,
        onSortNameChange = _this$props3.onSortNameChange,
        onDisambiguationChange = _this$props3.onDisambiguationChange,
        immutableSearchResults = _this$props3.searchResults,
        isUnifiedForm = _this$props3.isUnifiedForm,
        isModal = _this$props3.isModal;
      var exactMatches = (0, _utils.convertMapToObject)(immutableExactMatches);
      var searchResults = (0, _utils.convertMapToObject)(immutableSearchResults);
      var languageOptionsForDisplay = languageOptions.map(function (language) {
        return {
          frequency: language.frequency,
          label: language.name,
          value: language.id
        };
      });
      var warnIfExists = !(0, _isEmpty2.default)(exactMatches);
      var languageOption = languageOptionsForDisplay.filter(function (el) {
        return el.value === languageValue;
      });
      var lgCol = {
        offset: 3,
        span: 6
      };
      if (isUnifiedForm) {
        lgCol.offset = 0;
      }
      var duplicateSuggestions = !warnIfExists && !(0, _isEmpty2.default)(searchResults) && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Row, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Col, {
        lg: lgCol
      }, "If the ", (0, _startCase2.default)(entityType), " you want to add appears in the results below, click on it to inspect it before adding a possible duplicate.", /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("small", null, "Ctrl/Cmd + click to open in a new tab"), /*#__PURE__*/_react.default.createElement(_searchResults.default, {
        condensed: true,
        results: searchResults
      })));
      var duplicateAlert = this.renderDuplicateAlert(warnIfExists, disambiguationDefaultValue, exactMatches, entityType, lgCol);
      var heading = /*#__PURE__*/_react.default.createElement("h2", null, "What is the ".concat((0, _startCase2.default)(entityType), " called?"));
      return /*#__PURE__*/_react.default.createElement("div", null, !isUnifiedForm && heading, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Row, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Col, {
        lg: lgCol
      }, /*#__PURE__*/_react.default.createElement(_nameField.default, {
        defaultValue: nameValue,
        empty: (0, _helpers.isAliasEmpty)(nameValue, sortNameValue, languageValue),
        error: !(0, _common.validateNameSectionName)(nameValue),
        inputRef: this.updateNameFieldInputRef,
        tooltipText: "Official name of the ".concat((0, _startCase2.default)(entityType), " in its original language.\n\t\t\t\t\t\t\t\tNames in other languages should be added as aliases."),
        warn: (0, _helpers.isRequiredDisambiguationEmpty)(warnIfExists, disambiguationDefaultValue),
        onChange: this.handleNameChange
      })), !isModal && duplicateAlert), !isModal && duplicateSuggestions, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Row, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Col, {
        lg: lgCol
      }, /*#__PURE__*/_react.default.createElement(_sortNameField.default, {
        defaultValue: sortNameValue,
        empty: (0, _helpers.isAliasEmpty)(nameValue, sortNameValue, languageValue),
        error: !(0, _common.validateNameSectionSortName)(sortNameValue),
        storedNameValue: nameValue,
        onChange: onSortNameChange
      }))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Row, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Col, {
        lg: lgCol
      }, /*#__PURE__*/_react.default.createElement(ImmutableLanguageField, {
        empty: (0, _helpers.isAliasEmpty)(nameValue, sortNameValue, languageValue),
        error: !(0, _common.validateNameSectionLanguage)(languageValue),
        instanceId: "language",
        options: languageOptionsForDisplay,
        tooltipText: "Language used for the above name",
        value: languageOption,
        onChange: onLanguageChange
      }))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Row, null, /*#__PURE__*/_react.default.createElement(_reactBootstrap.Col, {
        lg: lgCol
      }, /*#__PURE__*/_react.default.createElement(_disambiguationField.default, {
        defaultValue: disambiguationDefaultValue,
        error: (0, _helpers.isRequiredDisambiguationEmpty)(warnIfExists, disambiguationDefaultValue) || !(0, _common.validateNameSectionDisambiguation)(disambiguationDefaultValue),
        required: warnIfExists,
        onChange: onDisambiguationChange
      }))), isModal && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Row, null, duplicateAlert), isModal && duplicateSuggestions);
    }
  }]);
  return NameSection;
}(_react.default.Component);
NameSection.displayName = 'NameSection';
NameSection.propTypes = {
  action: _propTypes.default.string,
  disambiguationDefaultValue: _propTypes.default.string,
  entityType: _reactValidators.entityTypeProperty.isRequired,
  exactMatches: _propTypes.default.object,
  isModal: _propTypes.default.bool,
  isUnifiedForm: _propTypes.default.bool,
  languageOptions: _propTypes.default.array.isRequired,
  languageValue: _propTypes.default.number,
  nameValue: _propTypes.default.string.isRequired,
  onDisambiguationChange: _propTypes.default.func.isRequired,
  onLanguageChange: _propTypes.default.func.isRequired,
  onNameChange: _propTypes.default.func.isRequired,
  onNameChangeCheckIfEditionGroupExists: _propTypes.default.func.isRequired,
  onNameChangeCheckIfExists: _propTypes.default.func.isRequired,
  onNameChangeSearchName: _propTypes.default.func.isRequired,
  onSortNameChange: _propTypes.default.func.isRequired,
  searchForExistingEditionGroup: _propTypes.default.bool,
  searchResults: _propTypes.default.object,
  sortNameValue: _propTypes.default.string.isRequired
};
NameSection.defaultProps = {
  action: 'create',
  disambiguationDefaultValue: null,
  exactMatches: [],
  isModal: false,
  isUnifiedForm: false,
  languageValue: null,
  searchForExistingEditionGroup: true,
  searchResults: []
};
function mapStateToProps(rootState, _ref) {
  var isUnifiedForm = _ref.isUnifiedForm,
    setDefault = _ref.setDefault;
  var state = rootState.get('nameSection');
  var editionSectionState = rootState.get('editionSection');
  var searchForExistingEditionGroup = Boolean(editionSectionState) && (!editionSectionState.get('editionGroup') || editionSectionState.get('editionGroupRequired'));
  // to prevent double double state updates on action caused by modal
  if (isUnifiedForm && setDefault) {
    return {
      disambiguationDefaultValue: '',
      exactMatches: _immutable.default.Map([]),
      languageValue: null,
      nameValue: '',
      searchResults: _immutable.default.Map([]),
      sortNameValue: ''
    };
  }
  return {
    disambiguationDefaultValue: state.get('disambiguation'),
    exactMatches: state.get('exactMatches'),
    languageValue: state.get('language'),
    nameValue: state.get('name'),
    searchForExistingEditionGroup: searchForExistingEditionGroup,
    searchResults: state.get('searchResults'),
    sortNameValue: state.get('sortName')
  };
}
function mapDispatchToProps(dispatch, _ref2) {
  var entity = _ref2.entity,
    entityType = _ref2.entityType,
    copyLanguages = _ref2.copyLanguages;
  var entityBBID = entity && entity.bbid;
  return {
    onDisambiguationChange: function onDisambiguationChange(event) {
      return dispatch((0, _actions2.debouncedUpdateDisambiguationField)(event.target.value));
    },
    onLanguageChange: function onLanguageChange(value) {
      return dispatch((0, _actions2.updateLanguageField)(value && value.value)) && copyLanguages && dispatch((0, _actions.addLanguage)(value));
    },
    onNameChange: function onNameChange(value) {
      return dispatch((0, _actions2.debouncedUpdateNameField)(value));
    },
    onNameChangeCheckIfEditionGroupExists: (0, _debounce2.default)(function (value) {
      dispatch((0, _actions2.checkIfNameExists)(value, entityBBID, 'EditionGroup', _actions.UPDATE_WARN_IF_EDITION_GROUP_EXISTS));
    }, 1500),
    onNameChangeCheckIfExists: (0, _debounce2.default)(function (value) {
      dispatch((0, _actions2.checkIfNameExists)(value, entityBBID, entityType));
    }, 500),
    onNameChangeSearchName: (0, _debounce2.default)(function (value) {
      dispatch((0, _actions2.searchName)(value, entityBBID, entityType));
    }, 500),
    onSortNameChange: function onSortNameChange(event) {
      return dispatch((0, _actions2.debouncedUpdateSortNameField)(event.target.value));
    }
  };
}
var _default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(NameSection);
exports.default = _default;
//# sourceMappingURL=name-section.js.map