UNPKG

synapse-react-client

Version:

[![Build Status](https://travis-ci.com/Sage-Bionetworks/Synapse-React-Client.svg?branch=main)](https://travis-ci.com/Sage-Bionetworks/Synapse-React-Client) [![npm version](https://badge.fury.io/js/synapse-react-client.svg)](https://badge.fury.io/js/synaps

369 lines 23.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SynapseCardLabel = exports.getValueOrMultiValue = exports.getCutoff = exports.CARD_LONG_DESCRIPTION_CSS = exports.CARD_SHORT_DESCRIPTION_CSS = void 0; var tslib_1 = require("tslib"); var lodash_es_1 = require("lodash-es"); var react_1 = (0, tslib_1.__importDefault)(require("react")); var utils_1 = require("../utils"); var getEndpoint_1 = require("../utils/functions/getEndpoint"); var RegularExpressions_1 = require("../utils/functions/RegularExpressions"); var unCamelCase_1 = require("../utils/functions/unCamelCase"); var SynapseConstants_1 = require("../utils/SynapseConstants"); var SynapseContext_1 = require("../utils/SynapseContext"); var synapseTypes_1 = require("../utils/synapseTypes"); var HeaderCard_1 = (0, tslib_1.__importDefault)(require("./HeaderCard")); var IconList_1 = (0, tslib_1.__importDefault)(require("./IconList")); var MarkdownSynapse_1 = (0, tslib_1.__importDefault)(require("./MarkdownSynapse")); var utils_2 = require("./row_renderers/utils"); var UserCard_1 = (0, tslib_1.__importDefault)(require("./UserCard")); var FileHandleLink_1 = require("./widgets/FileHandleLink"); var ImageFileHandle_1 = require("./widgets/ImageFileHandle"); var CHAR_COUNT_CUTOFF = 400; exports.CARD_SHORT_DESCRIPTION_CSS = 'SRC-short-description'; exports.CARD_LONG_DESCRIPTION_CSS = 'SRC-long-description'; // This function isn't in the class only for ease of testing with renderShortDescription var getCutoff = function (summary) { var previewText = ''; var summarySplit = summary.split(' '); // find num words to join such that its >= char_count_cutoff var i = 0; while (previewText.length < CHAR_COUNT_CUTOFF && i < summarySplit.length) { previewText += summarySplit[i] + " "; i += 1; } previewText = previewText.trim(); return { previewText: previewText }; }; exports.getCutoff = getCutoff; var getValueOrMultiValue = function (_a) { var columnName = _a.columnName, value = _a.value, selectColumns = _a.selectColumns, columnModels = _a.columnModels; if (!value) { return { str: '', strList: undefined, columnModelType: undefined, }; } var selectedColumnOrUndefined = (selectColumns === null || selectColumns === void 0 ? void 0 : selectColumns.find(function (el) { return el.name === columnName; })) || (columnModels === null || columnModels === void 0 ? void 0 : columnModels.find(function (el) { return el.name === columnName; })); var isMultiValue = selectedColumnOrUndefined === null || selectedColumnOrUndefined === void 0 ? void 0 : selectedColumnOrUndefined.columnType.endsWith('_LIST'); if (isMultiValue) { var val = value; var strList = void 0; try { strList = JSON.parse(val); val = strList.join(', '); return { strList: strList, str: val, columnModelType: selectedColumnOrUndefined === null || selectedColumnOrUndefined === void 0 ? void 0 : selectedColumnOrUndefined.columnType, }; } catch (e) { console.error('Could not parse multivalue string ', val, ' caught err ', e); } } return { str: value, columnModelType: selectedColumnOrUndefined === null || selectedColumnOrUndefined === void 0 ? void 0 : selectedColumnOrUndefined.columnType }; }; exports.getValueOrMultiValue = getValueOrMultiValue; var SynapseCardLabel = function (props) { var value = props.value, columnName = props.columnName, labelLink = props.labelLink, selectColumns = props.selectColumns, columnModels = props.columnModels, isHeader = props.isHeader, className = props.className, rowData = props.rowData; if (!value) { return react_1.default.createElement(react_1.default.Fragment, null, value); } var _a = (0, exports.getValueOrMultiValue)({ columnName: columnName, value: value, selectColumns: selectColumns, columnModels: columnModels, }), strList = _a.strList, str = _a.str, columnModelType = _a.columnModelType; if (!str) { // the array came back empty return react_1.default.createElement(react_1.default.Fragment, null, str); } var newClassName = className; var style = {}; if (isHeader) { newClassName = className === null || className === void 0 ? void 0 : className.concat(' ', 'SRC-lightLink'); } // PORTALS-1913: special rendering for user ID lists if (columnModelType === 'USERID_LIST' && strList) { return (react_1.default.createElement(react_1.default.Fragment, null, strList.map(function (val, index) { return (react_1.default.createElement("span", { key: val }, react_1.default.createElement(UserCard_1.default, { ownerId: val, size: SynapseConstants_1.SMALL_USER_CARD, className: newClassName }), index < strList.length - 1 && ',\u00a0\u00a0')); }))); } if (columnModelType === 'USERID' && str) { return (react_1.default.createElement(UserCard_1.default, { ownerId: str, size: SynapseConstants_1.SMALL_USER_CARD, className: newClassName })); } if (!labelLink) { // if this looks like a Synapse ID, then autolink. if (str.match(RegularExpressions_1.SYNAPSE_ENTITY_ID_REGEX)) { // its a synId return (react_1.default.createElement("a", { target: "_blank", rel: "noopener noreferrer", href: getEndpoint_1.PRODUCTION_ENDPOINT_CONFIG.PORTAL + "#!Synapse:" + str, className: newClassName }, str)); } else { // they don't need a link return react_1.default.createElement(react_1.default.Fragment, null, str); } } if (labelLink.isMarkdown) { if (strList) { return (react_1.default.createElement(react_1.default.Fragment, null, strList.map(function (el, index) { return (react_1.default.createElement("span", { key: el }, react_1.default.createElement(MarkdownSynapse_1.default, { key: el, renderInline: true, markdown: el }), index < strList.length - 1 && ',\u00a0\u00a0')); }))); } else { return react_1.default.createElement(MarkdownSynapse_1.default, { renderInline: true, markdown: value }); } } var split = strList ? strList : str.split(','); if ('linkColumnName' in labelLink) { var linkIndex = (selectColumns === null || selectColumns === void 0 ? void 0 : selectColumns.findIndex(function (el) { return el.name === labelLink.linkColumnName; })) || (columnModels === null || columnModels === void 0 ? void 0 : columnModels.findIndex(function (el) { return el.name === labelLink.linkColumnName; })); if (linkIndex == null) { console.warn("Could not determine column index of " + labelLink.linkColumnName); return react_1.default.createElement(react_1.default.Fragment, null, value); } else { var href_1 = rowData[linkIndex]; if ((0, lodash_es_1.isEmpty)(href_1)) { return react_1.default.createElement(react_1.default.Fragment, null, value); } return (react_1.default.createElement(react_1.default.Fragment, null, split.map(function (el, index) { return (react_1.default.createElement(react_1.default.Fragment, { key: el }, react_1.default.createElement("a", { href: href_1, target: "_blank", rel: "noopener noreferrer", key: el, className: newClassName, style: style }, el), index < split.length - 1 && (react_1.default.createElement("span", { style: { marginRight: 4 } }, ", ")))); }))); } } else { return (react_1.default.createElement(react_1.default.Fragment, null, split.map(function (el, index) { var baseURL = labelLink.baseURL, URLColumnName = labelLink.URLColumnName, wrapValueWithParens = labelLink.wrapValueWithParens; var value = wrapValueWithParens ? "(" + el + ")" : el; var href = "/" + baseURL + "?" + URLColumnName + "=" + value; return (react_1.default.createElement(react_1.default.Fragment, { key: el }, react_1.default.createElement("a", { href: href, key: el, className: newClassName, style: style }, el), index < split.length - 1 && (react_1.default.createElement("span", { style: { marginRight: 4 } }, ", ")))); }))); } }; exports.SynapseCardLabel = SynapseCardLabel; var GenericCard = /** @class */ (function (_super) { (0, tslib_1.__extends)(GenericCard, _super); function GenericCard(props) { var _this = _super.call(this, props) || this; _this.getCutoff = function (summary) { var previewText = ''; var summarySplit = summary.split(' '); // find num words to join such that its >= char_count_cutoff var i = 0; while (previewText.length < CHAR_COUNT_CUTOFF && i < summarySplit.length) { previewText += summarySplit[i] + " "; i += 1; } previewText = previewText.trim(); return { previewText: previewText }; }; _this.toggleShowMore = function () { _this.setState({ hasClickedShowMore: true, }); }; _this.renderTitle = function (_a) { var href = _a.href, target = _a.target, titleSearchHandle = _a.titleSearchHandle, title = _a.title; if (href) { return (react_1.default.createElement("a", { "data-search-handle": titleSearchHandle, target: target, href: href, className: "highlight-link" }, title)); } else { return react_1.default.createElement("span", { "data-search-handle": titleSearchHandle }, " ", title, " "); } }; _this.state = { hasClickedShowMore: false, }; _this.getLinkParams = _this.getLinkParams.bind(_this); _this.getCardLinkHref = _this.getCardLinkHref.bind(_this); _this.renderLongDescription = _this.renderLongDescription.bind(_this); _this.renderShortDescription = _this.renderShortDescription.bind(_this); return _this; } GenericCard.prototype.getLinkParams = function (link, cardLinkConfig, data, schema) { var _a; link = link.trim(); var href = link; var target = '_self'; if (link.match(RegularExpressions_1.SYNAPSE_ENTITY_ID_REGEX)) { // its a synId href = getEndpoint_1.PRODUCTION_ENDPOINT_CONFIG.PORTAL + "#!Synapse:" + link; } else if (link.match(RegularExpressions_1.DOI_REGEX)) { target = '_blank'; href = "https://dx.doi.org/" + link; } else if (!cardLinkConfig) { target = '_blank'; } else if (cardLinkConfig) { href = (_a = this.getCardLinkHref(cardLinkConfig, data, schema)) !== null && _a !== void 0 ? _a : ''; } return { href: href, target: target }; }; GenericCard.prototype.getCardLinkHref = function (cardLink, data, schema) { if (cardLink) { if (!data || !schema) { throw Error('Must specify CardLink and data for linking to work'); } var matchColumnName = cardLink.matchColumnName, URLColumnName = cardLink.URLColumnName; var indexInData = schema[matchColumnName]; if (indexInData === undefined) { console.error("Could not find match for data: " + data + " with columnName " + matchColumnName); } else { var value = data[indexInData]; return "/" + cardLink.baseURL + "?" + URLColumnName + "=" + value; } } return undefined; }; GenericCard.prototype.render = function () { var _a; var _b = this.props, schema = _b.schema, data = _b.data, genericCardSchema = _b.genericCardSchema, secondaryLabelLimit = _b.secondaryLabelLimit, selectColumns = _b.selectColumns, columnModels = _b.columnModels, iconOptions = _b.iconOptions, _c = _b.isHeader, isHeader = _c === void 0 ? false : _c, titleLinkConfig = _b.titleLinkConfig, ctaLinkConfig = _b.ctaLinkConfig, labelLinkConfig = _b.labelLinkConfig, _d = _b.facetAliases, facetAliases = _d === void 0 ? {} : _d, descriptionConfig = _b.descriptionConfig, rgbIndex = _b.rgbIndex, tableId = _b.tableId, tableEntityConcreteType = _b.tableEntityConcreteType, columnIconOptions = _b.columnIconOptions; // GenericCard inherits properties from CommonCardProps so that the properties have the same name // and type, but theres one nuance which is that we can't override if one specific property will be // defined, so we assert genericCardSchema is not null and assign to genericCardSchemaDefined var genericCardSchemaDefined = genericCardSchema; var hasClickedShowMore = this.state.hasClickedShowMore; var _e = genericCardSchemaDefined.link, link = _e === void 0 ? '' : _e, type = genericCardSchemaDefined.type; var title = data[schema[genericCardSchemaDefined.title]]; var subTitle = genericCardSchemaDefined.subTitle && data[schema[genericCardSchemaDefined.subTitle]]; subTitle = (genericCardSchemaDefined === null || genericCardSchemaDefined === void 0 ? void 0 : genericCardSchemaDefined.subTitle) && (0, exports.getValueOrMultiValue)({ value: subTitle, columnName: genericCardSchemaDefined === null || genericCardSchemaDefined === void 0 ? void 0 : genericCardSchemaDefined.subTitle, selectColumns: selectColumns, columnModels: columnModels, }).str; var description = data[schema[genericCardSchemaDefined.description || '']]; var iconValue = data[schema[genericCardSchemaDefined.icon || '']]; var dataTypeIconNames = data[schema[genericCardSchemaDefined.dataTypeIconNames || '']]; var imageFileHandleIdValue = data[schema[genericCardSchemaDefined.imageFileHandleColumnName || '']]; var titleColumnModel = columnModels === null || columnModels === void 0 ? void 0 : columnModels.find(function (el) { return genericCardSchemaDefined.link === el.name; }); var titleColumnType = titleColumnModel === null || titleColumnModel === void 0 ? void 0 : titleColumnModel.columnType; // wrap link in parens because undefined would throw an error var linkValue = data[schema[link]] || ''; var _f = this.getLinkParams(linkValue, titleLinkConfig, data, schema), href = _f.href, target = _f.target; var values = []; var _g = genericCardSchemaDefined.secondaryLabels, secondaryLabels = _g === void 0 ? [] : _g; var _loop_1 = function (i) { var columnName = secondaryLabels[i]; var value = data[schema[columnName]]; if (value) { var labelLink = labelLinkConfig === null || labelLinkConfig === void 0 ? void 0 : labelLinkConfig.find(function (el) { return el.matchColumnName === columnName; }); value = (0, exports.SynapseCardLabel)({ value: value, columnName: columnName, labelLink: labelLink, isHeader: isHeader, selectColumns: selectColumns, columnModels: columnModels, rowData: data, }); var columnDisplayName = (0, unCamelCase_1.unCamelCase)(columnName, facetAliases); var keyValue = [columnDisplayName, value, columnName]; values.push(keyValue); } }; for (var i = 0; i < secondaryLabels.length; i += 1) { _loop_1(i); } var showFooter = values.length > 0; var style = { // undefined, take default value from class marginTop: isHeader ? '0px' : undefined, marginBottom: isHeader ? '0px' : undefined, paddingBottom: showFooter || imageFileHandleIdValue ? undefined : '15px', }; var icon = (react_1.default.createElement(react_1.default.Fragment, null, imageFileHandleIdValue && (react_1.default.createElement("div", { className: "SRC-imageThumbnail", style: { padding: genericCardSchemaDefined.thumbnailRequiresPadding ? '21px' : undefined, } }, react_1.default.createElement(ImageFileHandle_1.ImageFileHandle, { fileHandleId: imageFileHandleIdValue, tableEntityConcreteType: tableEntityConcreteType, rowId: data[schema.id], tableId: tableId }))), !imageFileHandleIdValue && (react_1.default.createElement("div", { className: "SRC-cardThumbnail" }, react_1.default.createElement(utils_2.Icon, { iconOptions: iconOptions, value: iconValue, type: type }))))); if (isHeader) { return (react_1.default.createElement(HeaderCard_1.default, { descriptionConfig: descriptionConfig, title: title, subTitle: subTitle, description: description, type: type, icon: icon, values: values, href: href, target: target, isAlignToLeftNav: true, secondaryLabelLimit: secondaryLabelLimit, rgbIndex: rgbIndex })); } var titleSearchHandle = (0, unCamelCase_1.unCamelCase)(genericCardSchemaDefined.title, facetAliases); var stubTitleSearchHandle = (0, unCamelCase_1.unCamelCase)(genericCardSchemaDefined.subTitle, facetAliases); var descriptionSubTitle = (0, unCamelCase_1.unCamelCase)(genericCardSchemaDefined.description, facetAliases); var ctaHref = undefined, ctaTarget = undefined; if (ctaLinkConfig) { var ctaLinkValue = data[schema[ctaLinkConfig.link]] || ''; var _h = this.getLinkParams(ctaLinkValue, undefined, //card link config data, schema), newCtaHref = _h.href, newCtaTarget = _h.target; ctaHref = newCtaHref; ctaTarget = newCtaTarget; } return (react_1.default.createElement("div", { style: style, className: 'SRC-portalCard' }, react_1.default.createElement("div", { className: 'SRC-portalCardMain' }, icon, react_1.default.createElement("div", { className: "SRC-cardContent" }, react_1.default.createElement("div", { className: "SRC-type" }, type), // If the portal configs has columnIconOptions.columns.dataType option // and the column value is not null, display the card data type icons ((_a = columnIconOptions === null || columnIconOptions === void 0 ? void 0 : columnIconOptions.columns) === null || _a === void 0 ? void 0 : _a.dataType) && (dataTypeIconNames === null || dataTypeIconNames === void 0 ? void 0 : dataTypeIconNames.length) && (react_1.default.createElement("div", { style: { marginTop: '20px' } }, react_1.default.createElement(IconList_1.default, { iconConfigs: columnIconOptions.columns.dataType, iconNames: JSON.parse(dataTypeIconNames), useBackground: true, useTheme: true }))), react_1.default.createElement("div", null, react_1.default.createElement("h3", { className: "SRC-boldText SRC-blackText", style: { margin: 'none' } }, !titleLinkConfig && titleColumnType === synapseTypes_1.ColumnType.FILEHANDLEID ? (react_1.default.createElement(FileHandleLink_1.FileHandleLink, { fileHandleId: linkValue, tableEntityConcreteType: tableEntityConcreteType, showDownloadIcon: type !== utils_1.SynapseConstants.EXPERIMENTAL, rowId: data[schema.id], tableId: tableId, displayValue: title })) : (this.renderTitle({ href: href, target: target, titleSearchHandle: titleSearchHandle, title: title, })))), subTitle && (react_1.default.createElement("div", { "data-search-handle": stubTitleSearchHandle, className: "SRC-author" }, subTitle)), description && this.renderShortDescription(description, hasClickedShowMore, descriptionSubTitle, descriptionConfig), description && this.renderLongDescription(description, hasClickedShowMore, descriptionSubTitle, descriptionConfig), ctaLinkConfig && ctaHref && ctaTarget && (react_1.default.createElement("div", { className: "SRC-portalCardCTALink bootstrap-4-backport" }, react_1.default.createElement("a", { target: ctaTarget, rel: "noopener noreferrer", href: ctaHref }, ctaLinkConfig.text))))), showFooter && (react_1.default.createElement(utils_2.CardFooter, { isHeader: false, secondaryLabelLimit: secondaryLabelLimit, values: values, columnIconOptions: columnIconOptions, className: "" + (imageFileHandleIdValue ? 'hasImage' : 'hasIcon') })))); }; GenericCard.prototype.renderLongDescription = function (description, hasClickedShowMore, descriptionSubTitle, descriptionConfig) { var content = description; if (descriptionConfig === null || descriptionConfig === void 0 ? void 0 : descriptionConfig.isMarkdown) { content = react_1.default.createElement(MarkdownSynapse_1.default, { markdown: content }); } var show = hasClickedShowMore || (descriptionConfig === null || descriptionConfig === void 0 ? void 0 : descriptionConfig.showFullDescriptionByDefault); return (react_1.default.createElement("div", { className: show ? '' : 'SRC-hidden' }, react_1.default.createElement("span", { "data-search-handle": descriptionSubTitle, className: "SRC-font-size-base " + exports.CARD_LONG_DESCRIPTION_CSS }, content))); }; GenericCard.prototype.renderShortDescription = function (description, hasClickedShowMore, descriptionSubTitle, descriptionConfig) { if (descriptionConfig === null || descriptionConfig === void 0 ? void 0 : descriptionConfig.showFullDescriptionByDefault) { return react_1.default.createElement(react_1.default.Fragment, null); } return (react_1.default.createElement("div", { className: hasClickedShowMore ? 'SRC-hidden' : '' }, react_1.default.createElement("span", { "data-search-handle": descriptionSubTitle, className: "SRC-font-size-base " + exports.CARD_SHORT_DESCRIPTION_CSS + " SRC-short-description" }, (0, exports.getCutoff)(description).previewText), description.length >= CHAR_COUNT_CUTOFF && (react_1.default.createElement("a", { style: { fontSize: '14px', cursor: 'pointer', marginLeft: '5px', }, className: "highlight-link", onClick: this.toggleShowMore }, "...Show More")))); }; GenericCard.contextType = SynapseContext_1.SynapseContext; return GenericCard; }(react_1.default.Component)); exports.default = GenericCard; //# sourceMappingURL=GenericCard.js.map