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

283 lines 13.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QUERY_FILTERS_COLLAPSED_CSS = exports.QUERY_FILTERS_EXPANDED_CSS = void 0; var tslib_1 = require("tslib"); var React = (0, tslib_1.__importStar)(require("react")); var utils_1 = require("../utils/"); var queryUtils_1 = require("../utils/functions/queryUtils"); var DeepLinkingUtils = (0, tslib_1.__importStar)(require("../utils/functions/deepLinkingUtils")); var lodash_es_1 = require("lodash-es"); var SynapseConstants_1 = require("../utils/SynapseConstants"); exports.QUERY_FILTERS_EXPANDED_CSS = 'isShowingFacetFilters'; exports.QUERY_FILTERS_COLLAPSED_CSS = 'isHidingFacetFilters'; /** * Class wraps around any Synapse views that are dependent on a query bundle * Those classes then take in as props: * * @class QueryWrapper * @extends {React.Component} */ var QueryWrapper = /** @class */ (function (_super) { (0, tslib_1.__extends)(QueryWrapper, _super); function QueryWrapper(props) { var _a; var _this = _super.call(this, props) || this; _this.executeInitialQueryRequest = _this.executeInitialQueryRequest.bind(_this); _this.executeQueryRequest = _this.executeQueryRequest.bind(_this); _this.getLastQueryRequest = _this.getLastQueryRequest.bind(_this); _this.getNextPageOfData = _this.getNextPageOfData.bind(_this); _this.updateParentState = _this.updateParentState.bind(_this); _this.getInitQueryRequest = _this.getInitQueryRequest.bind(_this); var showFacetVisualization = (_a = props.defaultShowFacetVisualization) !== null && _a !== void 0 ? _a : true; _this.state = { data: undefined, isLoading: true, isLoadingNewData: true, hasMoreData: true, lastFacetSelection: { columnName: '', facetValue: '', selector: '', }, chartSelectionIndex: 0, isAllFilterSelectedForFacet: {}, loadNowStarted: false, lastQueryRequest: (0, lodash_es_1.cloneDeep)(_this.props.initQueryRequest), topLevelControlsState: { showColumnFilter: true, showFacetFilter: true, showFacetVisualization: showFacetVisualization, showSearchBar: false, showDownloadConfirmation: false, showColumnSelectDropdown: false, }, isColumnSelected: [], selectedRowIndices: [], error: undefined, }; _this.componentIndex = props.componentIndex || 0; return _this; } /** * Compute default query request * * @memberof QueryWrapper */ QueryWrapper.prototype.componentDidMount = function () { var _a = this.props.loadNow, loadNow = _a === void 0 ? true : _a; var query = DeepLinkingUtils.getQueryRequestFromLink('QueryWrapper', this.componentIndex); if (loadNow) { this.executeInitialQueryRequest(query); } }; /** * @memberof QueryWrapper */ QueryWrapper.prototype.componentDidUpdate = function (prevProps) { /** * If component updates and the token has changed (they signed in) then the data should be pulled in. Or if the * sql query has changed of the component then perform an update. */ var _a = this.props.loadNow, loadNow = _a === void 0 ? true : _a; if (loadNow && !this.state.loadNowStarted) { this.executeInitialQueryRequest(); } else if (loadNow && this.props.token !== prevProps.token) { // if loadNow is true and they've logged in with a token that is not undefined, null, or an empty string when it was before this.executeQueryRequest(this.getLastQueryRequest()); } else if (prevProps.initQueryRequest.query.sql !== this.props.initQueryRequest.query.sql) { this.executeInitialQueryRequest(); } }; /** * Pass down a deep clone (so no side affects on the child's part) of the * last query request made * * @returns * @memberof QueryWrapper */ QueryWrapper.prototype.getLastQueryRequest = function () { return (0, lodash_es_1.cloneDeep)(this.state.lastQueryRequest); }; /** * Pass down a deep clone (so no side affects on the child's part) of the * first query request made * * @returns * @memberof QueryWrapper */ QueryWrapper.prototype.getInitQueryRequest = function () { return (0, lodash_es_1.cloneDeep)(this.props.initQueryRequest); }; /** * Execute the given query * * @param {*} queryRequest Query request as specified by * https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/table/Query.html * @memberof QueryWrapper */ QueryWrapper.prototype.executeQueryRequest = function (queryRequest) { var _this = this; var clonedQueryRequest = (0, lodash_es_1.cloneDeep)(queryRequest); this.setState({ isLoading: true, lastQueryRequest: clonedQueryRequest, selectedRowIndices: [], // reset selected row indices any time the query is re-run }); if (clonedQueryRequest.query) { var stringifiedQuery = encodeURIComponent(JSON.stringify(clonedQueryRequest.query)); if (this.props.shouldDeepLink) { DeepLinkingUtils.updateUrlWithNewSearchParam('QueryWrapper', this.componentIndex, stringifiedQuery); } } return utils_1.SynapseClient.getQueryTableResults(clonedQueryRequest, this.props.token, this.updateParentState) .then(function (data) { var hasMoreData = data.queryResult.queryResults.rows.length === clonedQueryRequest.query.limit; var newState = { hasMoreData: hasMoreData, data: data, asyncJobStatus: undefined, }; _this.setState(newState); }) .catch(function (error) { console.error('Failed to get data ', error); _this.setState(error); }) .finally(function () { _this.setState({ isLoading: false, isLoadingNewData: false }); }); }; /** * Grab the next page of data, pulling in 25 more rows. * * @param {*} queryRequest Query request as specified by * https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/table/Query.html * @memberof QueryWrapper */ QueryWrapper.prototype.getNextPageOfData = function (queryRequest) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { var _this = this; return (0, tslib_1.__generator)(this, function (_a) { switch (_a.label) { case 0: this.setState({ isLoading: true, }); return [4 /*yield*/, (0, queryUtils_1.getNextPageOfData)(queryRequest, this.state.data, this.props.token).then(function (newState) { _this.setState((0, tslib_1.__assign)((0, tslib_1.__assign)({}, newState), { isLoading: false, lastQueryRequest: (0, lodash_es_1.cloneDeep)(queryRequest) })); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Execute the initial query passed into the component * * @param {*} queryRequest Query request as specified by * https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/table/Query.html * @memberof QueryWrapper */ QueryWrapper.prototype.executeInitialQueryRequest = function (initQueryRequest) { var _this = this; if (initQueryRequest === void 0) { initQueryRequest = this.props.initQueryRequest; } var lastQueryRequest = (0, lodash_es_1.cloneDeep)(initQueryRequest); this.setState({ isLoading: true, chartSelectionIndex: 0, loadNowStarted: true, lastQueryRequest: lastQueryRequest, }); utils_1.SynapseClient.getQueryTableResults(initQueryRequest, this.props.token, this.updateParentState) .then(function (data) { var _a, _b, _c, _d; var hasMoreData = (_a = data.queryResult.queryResults.rows.length === initQueryRequest.query.limit) !== null && _a !== void 0 ? _a : SynapseConstants_1.DEFAULT_PAGE_SIZE; var isAllFilterSelectedForFacet = (0, lodash_es_1.cloneDeep)(_this.state.isAllFilterSelectedForFacet); var chartSelectionIndex = _this.state.chartSelectionIndex; if (_this.props.facet) { if (!data.facets) { throw Error('Error on query request, must include facets in partmask to show facets'); } var enumFacets = data.facets.filter(function (el) { return el.facetType === 'enumeration'; }); enumFacets.forEach(function (el) { // isAll is only true iff there are no facets selected or all elements are selected var facetValues = el.facetValues; var isAllFalse = facetValues.every(function (facet) { return !facet.isSelected; }); var isAllTrue = facetValues.every(function (facet) { return facet.isSelected; }); var isByDefaultSelected = isAllFalse || isAllTrue; isAllFilterSelectedForFacet[el.columnName] = isByDefaultSelected; if (el.columnName === _this.props.facet && !isAllFalse) { // Note - this picks the first selected facet chartSelectionIndex = facetValues .sort(function (a, b) { return b.count - a.count; }) .findIndex(function (facet) { return facet.isSelected; }); } }); } var newState = { isAllFilterSelectedForFacet: isAllFilterSelectedForFacet, hasMoreData: hasMoreData, data: data, chartSelectionIndex: chartSelectionIndex, asyncJobStatus: undefined, isColumnSelected: (_d = (_b = data === null || data === void 0 ? void 0 : data.selectColumns) === null || _b === void 0 ? void 0 : _b.slice(0, (_c = _this.props.visibleColumnCount) !== null && _c !== void 0 ? _c : Infinity).map(function (el) { return el.name; })) !== null && _d !== void 0 ? _d : [], }; _this.setState(newState); }) .catch(function (error) { console.error('Failed to get data ', error); _this.setState({ error: error, }); }) .finally(function () { _this.setState({ isLoading: false, isLoadingNewData: false, }); }); }; QueryWrapper.prototype.updateParentState = function (update) { this.setState(update); }; /** * remove a particular facet name (e.g. study) and its all possible values based on the parameter specified in the url * this is to remove the facet from the charts, search and filter. * @return data: QueryResultBundle */ QueryWrapper.prototype.removeLockedFacetData = function () { var _a, _b; var lockedFacet = (_a = this.props.lockedFacet) === null || _a === void 0 ? void 0 : _a.facet; if (lockedFacet && this.state.data) { // for details page, return data without the "locked" facet var data = (0, lodash_es_1.cloneDeep)(this.state.data); var facets = (_b = data.facets) === null || _b === void 0 ? void 0 : _b.filter(function (item) { return item.columnName.toLowerCase() !== lockedFacet.toLowerCase(); }); data.facets = facets; return data; } else { // for other pages, just return the data return this.state.data; } }; /** * Render the children without any formatting */ QueryWrapper.prototype.render = function () { var isLoading = this.state.isLoading; var _a = this.props, children = _a.children, rest = (0, tslib_1.__rest)(_a, ["children"]); var queryWrapperChildProps = (0, tslib_1.__assign)({ isAllFilterSelectedForFacet: this.state.isAllFilterSelectedForFacet, data: this.removeLockedFacetData(), hasMoreData: this.state.hasMoreData, lastFacetSelection: this.state.lastFacetSelection, chartSelectionIndex: this.state.chartSelectionIndex, isLoading: this.state.isLoading, isLoadingNewData: this.state.isLoadingNewData, asyncJobStatus: this.state.asyncJobStatus, topLevelControlsState: this.state.topLevelControlsState, isColumnSelected: this.state.isColumnSelected, selectedRowIndices: this.state.selectedRowIndices, error: this.state.error, executeInitialQueryRequest: this.executeInitialQueryRequest, executeQueryRequest: this.executeQueryRequest, getLastQueryRequest: this.getLastQueryRequest, getNextPageOfData: this.getNextPageOfData, updateParentState: this.updateParentState, getInitQueryRequest: this.getInitQueryRequest }, rest); var loadingCusrorClass = isLoading ? 'SRC-logo-cursor' : ''; return (React.createElement("div", { className: "SRC-wrapper " + loadingCusrorClass }, children && children(queryWrapperChildProps))); }; return QueryWrapper; }(React.Component)); exports.default = QueryWrapper; //# sourceMappingURL=QueryWrapper.js.map