client/helpers/utils.js

"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ISODateStringToObject = ISODateStringToObject;
exports.RelationshipTypeEditorIcon = exports.IdentifierTypeEditorIcon = void 0;
exports.convertMapToObject = convertMapToObject;
exports.countWords = countWords;
exports.dateObjectToISOString = dateObjectToISOString;
exports.formatDate = formatDate;
exports.getEntityKey = getEntityKey;
exports.getEntityTable = getEntityTable;
exports.getTodayDate = getTodayDate;
exports.injectDefaultAliasName = injectDefaultAliasName;
exports.isNullDate = isNullDate;
exports.labelsForAuthor = labelsForAuthor;
exports.stringToHTMLWithLinks = stringToHTMLWithLinks;
require("core-js/modules/es.function.name.js");
require("core-js/modules/es.object.assign.js");
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.regexp.to-string.js");
require("core-js/modules/es.regexp.exec.js");
require("core-js/modules/es.string.split.js");
require("core-js/modules/es.parse-int.js");
require("core-js/modules/es.number.is-integer.js");
require("core-js/modules/es.number.constructor.js");
require("core-js/modules/es.math.sign.js");
require("core-js/modules/es.array.concat.js");
require("core-js/modules/es.string.replace.js");
require("core-js/modules/es.string.starts-with.js");
require("core-js/modules/es.string.match.js");
var _padStart2 = _interopRequireDefault(require("lodash/padStart"));
var _isNil2 = _interopRequireDefault(require("lodash/isNil"));
var _has2 = _interopRequireDefault(require("lodash/has"));
var _isPlainObject2 = _interopRequireDefault(require("lodash/isPlainObject"));
var _isString2 = _interopRequireDefault(require("lodash/isString"));
var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
var _authorTable = _interopRequireDefault(require("../components/pages/entities/author-table"));
var _isomorphicDompurify = _interopRequireDefault(require("isomorphic-dompurify"));
var _editionGroupTable = _interopRequireDefault(require("../components/pages/entities/editionGroup-table"));
var _editionTable = _interopRequireDefault(require("../components/pages/entities/edition-table"));
var _reactFontawesome = require("@fortawesome/react-fontawesome");
var _publisherTable = _interopRequireDefault(require("../components/pages/entities/publisher-table"));
var _react = _interopRequireDefault(require("react"));
var _seriesTable = _interopRequireDefault(require("../components/pages/entities/series-table"));
var _workTable = _interopRequireDefault(require("../components/pages/entities/work-table"));
var _dateFns = require("date-fns");
var _types = require("../../types");
/*
 * Copyright (C) 2016  Daniel Hsing
 *               2021  Akash Gupta
 * 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.
 */

/**
 * Injects entity model object with a default alias name property.
 *
 * @param {object} instance - Entity object.
 * @returns {object} - New object with injected properties.
 */
function injectDefaultAliasName(instance) {
  if (instance && instance.name) {
    return Object.assign({}, instance, {
      defaultAlias: {
        name: instance.name
      }
    });
  }
  return instance;
}
function formatDate(date, includeTime) {
  if (!date) {
    return null;
  }
  if (includeTime) {
    return (0, _dateFns.format)(date, 'yyyy-MM-dd HH:mm:ss');
  }
  return (0, _dateFns.format)(date, 'yyyy-MM-dd');
}
function labelsForAuthor(isGroup) {
  return {
    beginAreaLabel: isGroup ? 'Place founded' : 'Place of birth',
    beginDateLabel: isGroup ? 'Date founded' : 'Date of birth',
    endAreaLabel: isGroup ? 'Place of dissolution' : 'Place of death',
    endDateLabel: isGroup ? 'Date of dissolution' : 'Date of death',
    endedLabel: isGroup ? 'Dissolved?' : 'Died?'
  };
}
function convertMapToObject(value) {
  return (0, _types.isIterable)(value) ? value.toJS() : value;
}

/**
 * Returns today's date as a {day, month, year} object
 * Used to check if a date is in the future
 * @function getTodayDate
 * @returns {object} today's date as a {day, month, year} object
 */
function getTodayDate() {
  var date = new Date();
  var year = date.getFullYear().toString();
  var month = (date.getMonth() + 1).toString();
  var day = date.getDate().toString();
  return {
    day: day,
    month: month,
    year: year
  };
}

/**
 * Parse an ISO 8601-2004 string and return an object with separate day, month and year, if they exist.
 * If any of the values don't exist, the default is an empty string.
 * @function ISODateStringToObject
 * @param {string} value - relationshipId number for initaial relationship
 * @returns {object} a {day, month, year} object
 */
function ISODateStringToObject(value) {
  if (!(0, _isString2.default)(value)) {
    if ((0, _isPlainObject2.default)(value) && (0, _has2.default)(value, 'year')) {
      return value;
    }
    return {
      day: '',
      month: '',
      year: ''
    };
  }
  var date = value ? value.split('-') : [];
  // A leading minus sign denotes a BC date
  // This creates an empty first array item that needs to be removed,
  // and requires us to add the negative sign back for the year
  if (date.length && date[0] === '') {
    date.shift();
    date[0] = (-parseInt(date[0], 10)).toString();
  }
  return {
    day: date.length > 2 ? date[2] : '',
    month: date.length > 1 ? date[1] : '',
    year: date.length > 0 ? date[0] : ''
  };
}

/**
 * Determines wether a given date is empty or null, meaning no year month or day has been specified.
 * Accepts a {day, month, year} object or an ISO 8601-2004 string (±YYYYYY-MM-DD)
 * @function isNullDate
 * @param {object|string} date - a {day, month, year} object or ISO 8601-2004 string (±YYYYYY-MM-DD)
 * @returns {boolean} true if the date is empty/null
 */
function isNullDate(date) {
  var dateObject = ISODateStringToObject(date);
  var isNullYear = (0, _isNil2.default)(dateObject.year) || dateObject.year === '';
  var isNullMonth = (0, _isNil2.default)(dateObject.month) || dateObject.month === '';
  var isNullDay = (0, _isNil2.default)(dateObject.day) || dateObject.day === '';
  return isNullYear && isNullMonth && isNullDay;
}

/**
 * Format a {day, month, year} object into an ISO 8601-2004 string (±YYYYYY-MM-DD)
 * @function dateObjectToISOString
 * @param {string} value - a {day, month, year} object
 * @returns {string} ISO 8601-2004 string (±YYYYYY-MM-DD)
 */
function dateObjectToISOString(value) {
  if ((0, _isNil2.default)(value) || isNullDate(value)) {
    return null;
  }
  // if year is missing or not a number, return invalid date
  if (!isNullDate(value) && ((0, _isNil2.default)(value.year) || value.year === '') || !Number.isInteger(Number(value.year))) {
    return '+XXXXXX';
  }
  var numericYear = parseInt(value.year, 10);
  var isCommonEraDate = Math.sign(numericYear) > -1;
  // Convert to ISO 8601:2004 extended for BCE years (±YYYYYY)
  var date = "".concat(isCommonEraDate ? '+' : '-').concat((0, _padStart2.default)(Math.abs(numericYear).toString(), 6, '0'));
  if (value.month) {
    date += "-".concat(value.month);
    if (value.day) {
      date += "-".concat(value.day);
    }
  } else if (value.day) {
    date += "-XX-".concat(value.day);
  }
  return date;
}

/**
 * Find the first index of an unbalanced paranthesis in a url string.
 * @function firstIndexOfUnbalancedParanthesis
 * @param {string} url - URL string.
 * @returns {number} idx - index of the first unbalanced parathesis. If no unbalanced paranthesis found, returns -1
 */
function firstIndexOfUnbalancedParanthesis(url) {
  var cnt = 0;
  for (var i = 0; i <= url.length; i++) {
    if (url[i] === '(') {
      cnt += 1;
    } else if (url[i] === ')') {
      cnt -= 1;
    }
    if (cnt < 0) {
      return i;
    }
  }
  return -1;
}

/**
 * Convert any string url that has a prefix http|https|ftp|ftps to a clickable link
 * and then rendered the HTML string as real HTML.
 * @function stringToHTMLWithLinks
 * @param {string} content - Can be either revision notes or annotation content etc...
 * @returns {JSX} returns a JSX Element
 */
function stringToHTMLWithLinks(content) {
  // eslint-disable-next-line max-len, no-useless-escape
  var urlRegex = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/g;
  var replacedContent = content.replace(urlRegex, function (url) {
    var cleanUrl = url;
    var suffix = '';
    var firstUnbalancedParanthesis = firstIndexOfUnbalancedParanthesis(url);
    if (firstUnbalancedParanthesis !== -1) {
      cleanUrl = url.substring(0, firstUnbalancedParanthesis);
      suffix = url.substring(firstUnbalancedParanthesis);
    }
    var link = "<a href=\"".concat(cleanUrl.startsWith('www.') ? "https://".concat(cleanUrl) : cleanUrl, "\" target=\"_blank\">").concat(cleanUrl, "</a>");
    return link + suffix;
  });
  var sanitizedHtml = _isomorphicDompurify.default.sanitize(replacedContent, {
    ADD_ATTR: ['target']
  });
  // eslint-disable-next-line react/no-danger
  return /*#__PURE__*/_react.default.createElement("span", {
    dangerouslySetInnerHTML: {
      __html: sanitizedHtml
    }
  });
}

/**
 * Returns EntityTable associated with the entity type.
 * @function getEntityTable
 * @param {string} entityType - Entity Type (author, work, series etc ...)
 * @returns {JSX} returns EntityTable Component
 */
function getEntityTable(entityType) {
  var tables = {
    Author: _authorTable.default,
    Edition: _editionTable.default,
    EditionGroup: _editionGroupTable.default,
    Publisher: _publisherTable.default,
    Series: _seriesTable.default,
    Work: _workTable.default
  };
  return tables[entityType];
}
function getEntityKey(entityType) {
  var keys = {
    Author: 'authors',
    Edition: 'editions',
    EditionGroup: 'editionGroups',
    Publisher: 'publishers',
    Series: 'series',
    Work: 'works'
  };
  return keys[entityType];
}
function countWords(text) {
  // Credit goes to iamwhitebox https://stackoverflow.com/a/39125279/14911205
  var words = text.match(/\w+/g);
  if (words === null) {
    return 0;
  }
  return words.length;
}
var RelationshipTypeEditorIcon = /*#__PURE__*/_react.default.createElement("span", {
  className: "fa-layers fa-fw margin-right-0-3"
}, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
  icon: _freeSolidSvgIcons.faLink,
  transform: "left-3"
}), /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
  icon: _freeSolidSvgIcons.faPlus,
  transform: "shrink-8 right-5 down-5"
}));
exports.RelationshipTypeEditorIcon = RelationshipTypeEditorIcon;
var IdentifierTypeEditorIcon = /*#__PURE__*/_react.default.createElement("span", {
  className: "fa-layers fa-fw margin-right-0-3"
}, /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
  icon: _freeSolidSvgIcons.faBarcode,
  transform: "shrink-3 left-5"
}), /*#__PURE__*/_react.default.createElement(_reactFontawesome.FontAwesomeIcon, {
  icon: _freeSolidSvgIcons.faPlus,
  transform: "shrink-8 right-5 down-2"
}));
exports.IdentifierTypeEditorIcon = IdentifierTypeEditorIcon;
//# sourceMappingURL=utils.js.map