synapse-react-client
Version:
[](https://travis-ci.com/Sage-Bionetworks/Synapse-React-Client) [](https://badge.fury.io/js/synaps
369 lines • 23.5 kB
JavaScript
"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