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

291 lines 15.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TreeView = exports.FinderScope = void 0; var tslib_1 = require("tslib"); var react_1 = (0, tslib_1.__importStar)(require("react")); var react_bootstrap_1 = require("react-bootstrap"); var react_error_boundary_1 = require("react-error-boundary"); var react_intersection_observer_1 = require("react-intersection-observer"); var utils_1 = require("../../../utils"); var EntityTypeUtils_1 = require("../../../utils/functions/EntityTypeUtils"); var RegularExpressions_1 = require("../../../utils/functions/RegularExpressions"); var useEntityBundle_1 = (0, tslib_1.__importDefault)(require("../../../utils/hooks/SynapseAPI/useEntityBundle")); var useProjects_1 = require("../../../utils/hooks/SynapseAPI/useProjects"); var SynapseContext_1 = require("../../../utils/SynapseContext"); var synapseTypes_1 = require("../../../utils/synapseTypes"); var LoadingScreen_1 = require("../../LoadingScreen"); var EntityDetailsList_1 = require("../details/EntityDetailsList"); var TreeNode_1 = require("./TreeNode"); var isEntityIdInPath = function (entityId, path) { for (var _i = 0, _a = path.path; _i < _a.length; _i++) { var eh = _a[_i]; if (entityId === eh.id) { return true; } } return false; }; var FinderScope; (function (FinderScope) { FinderScope["CURRENT_PROJECT"] = "Current Project"; FinderScope["ALL_PROJECTS"] = "All Projects"; FinderScope["CREATED_BY_ME"] = "Projects Created By Me"; FinderScope["FAVORITES"] = "My Favorites"; })(FinderScope = exports.FinderScope || (exports.FinderScope = {})); function getScopeOptionNodeName(scope) { switch (scope) { case FinderScope.CURRENT_PROJECT: case FinderScope.ALL_PROJECTS: case FinderScope.CREATED_BY_ME: return 'Projects'; case FinderScope.FAVORITES: return 'Favorites'; } } /** * The TreeView displays a user's entities hierarchically, allowing a user to quickly dive into an entity tree. * * The tree view currently can only be used to drive a DetailsView using the `setDetailsViewConfiguration` property. */ var TreeView = function (_a) { var _b = _a.initialScope, initialScope = _b === void 0 ? FinderScope.CURRENT_PROJECT : _b, projectId = _a.projectId, _c = _a.initialContainer, initialContainer = _c === void 0 ? null : _c, _d = _a.visibleTypes, visibleTypes = _d === void 0 ? [synapseTypes_1.EntityType.PROJECT, synapseTypes_1.EntityType.FOLDER] : _d, toggleSelection = _a.toggleSelection, selectedEntities = _a.selectedEntities, setDetailsViewConfiguration = _a.setDetailsViewConfiguration, setBreadcrumbItems = _a.setBreadcrumbItems, _e = _a.showScopeAsRootNode, showScopeAsRootNode = _e === void 0 ? true : _e, nodeAppearance = _a.nodeAppearance, selectableTypes = _a.selectableTypes; var DEFAULT_CONFIGURATION = { type: EntityDetailsList_1.EntityDetailsListDataConfigurationType.PROMPT, }; var accessToken = (0, SynapseContext_1.useSynapseContext)().accessToken; var _f = (0, react_1.useState)(false), isLoading = _f[0], setIsLoading = _f[1]; var _g = (0, react_1.useState)([]), topLevelEntities = _g[0], setTopLevelEntities = _g[1]; var _h = (0, react_1.useState)(initialScope), scope = _h[0], setScope = _h[1]; var _j = (0, react_1.useState)(), initialContainerPath = _j[0], setInitialContainerPath = _j[1]; var _k = (0, react_1.useState)(nodeAppearance === TreeNode_1.NodeAppearance.BROWSE ? initialContainer : initialContainer), currentContainer = _k[0], setCurrentContainer = _k[1]; var handleError = (0, react_error_boundary_1.useErrorHandler)(); (0, react_1.useEffect)(function () { if (setDetailsViewConfiguration) { setDetailsViewConfiguration(DEFAULT_CONFIGURATION); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); var setSelectedId = (0, react_1.useCallback)(function (entityId) { if (toggleSelection) { toggleSelection({ targetId: entityId }); } setCurrentContainer(entityId); }, [toggleSelection]); // For these scopes, use the `useGetProjectsInfinite` hook var useProjectData = scope === FinderScope.ALL_PROJECTS || scope === FinderScope.CREATED_BY_ME; var _l = (0, useProjects_1.useGetProjectsInfinite)(scope === FinderScope.CREATED_BY_ME ? { filter: 'CREATED', sort: 'PROJECT_NAME', sortDirection: 'ASC' } : { sort: 'PROJECT_NAME', sortDirection: 'ASC' }, { enabled: useProjectData, }), projectData = _l.data, isSuccessProjects = _l.isSuccess, fetchNextPageProjects = _l.fetchNextPage, hasNextPageProjects = _l.hasNextPage, isLoadingProjects = _l.isLoading; var _m = (0, useEntityBundle_1.default)(currentContainer, undefined, undefined, { enabled: !!currentContainer && currentContainer !== 'root', }), currentContainerBundle = _m.data, isSuccessBundle = _m.isSuccess; var _o = (0, react_intersection_observer_1.useInView)({ rootMargin: '500px' }), ref = _o.ref, inView = _o.inView; (0, react_1.useEffect)(function () { if (useProjectData && isSuccessProjects) { if (projectData === null || projectData === void 0 ? void 0 : projectData.pages) { setTopLevelEntities(projectData.pages.flatMap(function (page) { return page.results; })); } } }, [useProjectData, isSuccessProjects, projectData]); (0, react_1.useEffect)(function () { if (useProjectData && inView && hasNextPageProjects && !isLoadingProjects) { fetchNextPageProjects(); } }, [ useProjectData, inView, hasNextPageProjects, fetchNextPageProjects, scope, isLoadingProjects, ]); // Populates the first level of entities in the tree view (0, react_1.useEffect)(function () { setIsLoading(true); switch (scope) { case FinderScope.ALL_PROJECTS: case FinderScope.CREATED_BY_ME: setIsLoading(isLoadingProjects); // See the useGetProjectsInfinite hook break; case FinderScope.FAVORITES: { utils_1.SynapseClient.getUserFavorites(accessToken).then(function (_a) { var results = _a.results; // TODO: https://sagebionetworks.jira.com/browse/PLFM-6652 results = results.filter(function (result) { return visibleTypes.includes((0, EntityTypeUtils_1.convertToEntityType)(result.type)); }); setTopLevelEntities(results); setIsLoading(false); }); break; } case FinderScope.CURRENT_PROJECT: if (projectId) { if (initialContainer === null || initialContainer === void 0 ? void 0 : initialContainer.match(RegularExpressions_1.SYNAPSE_ENTITY_ID_REGEX)) { utils_1.SynapseClient.getEntityPath(initialContainer, accessToken) .then(function (path) { if (!path.path.map(function (entity) { return entity.id; }).includes(projectId)) { handleError(new Error("An initial container (" + initialContainer + ") was provided but is not within or the same as the provided project (" + projectId + ")")); } setInitialContainerPath(path); setTopLevelEntities([path.path[1]]); setIsLoading(false); }) .catch(function (e) { return handleError(e); }); } else { utils_1.SynapseClient.getEntityHeader(projectId, accessToken) .then(function (header) { setTopLevelEntities([header]); setIsLoading(false); }) .catch(function (e) { return handleError(e); }); } } else { handleError(new Error('Cannot open current project because the current project is unknown')); } break; default: handleError(new Error('No scope selected')); } }, [ accessToken, scope, initialContainer, handleError, visibleTypes, isLoadingProjects, projectId, ]); // Creates the configuration for the details view and invokes the callback (0, react_1.useEffect)(function () { if (setDetailsViewConfiguration || setBreadcrumbItems) { var detailsViewConfig = void 0; var breadcrumbItems = []; if (currentContainer === null) { detailsViewConfig = { type: EntityDetailsList_1.EntityDetailsListDataConfigurationType.PROMPT, }; breadcrumbItems = []; } else if (currentContainer === 'root') { switch (scope) { case FinderScope.ALL_PROJECTS: detailsViewConfig = { type: EntityDetailsList_1.EntityDetailsListDataConfigurationType.USER_PROJECTS, }; break; case FinderScope.CREATED_BY_ME: detailsViewConfig = { type: EntityDetailsList_1.EntityDetailsListDataConfigurationType.USER_PROJECTS, getProjectParams: { filter: 'CREATED', }, }; break; case FinderScope.CURRENT_PROJECT: detailsViewConfig = { type: EntityDetailsList_1.EntityDetailsListDataConfigurationType.HEADER_LIST, headerList: topLevelEntities, }; break; case FinderScope.FAVORITES: detailsViewConfig = { type: EntityDetailsList_1.EntityDetailsListDataConfigurationType.USER_FAVORITES, }; break; } breadcrumbItems = [ { name: scope, isCurrent: true, action: function () { setCurrentContainer('root'); }, }, ]; } else { detailsViewConfig = { type: EntityDetailsList_1.EntityDetailsListDataConfigurationType.PARENT_CONTAINER, parentContainerId: currentContainer, }; if (isSuccessBundle) { breadcrumbItems = (0, tslib_1.__spreadArray)([ { name: scope, isCurrent: false, action: function () { setCurrentContainer('root'); }, } ], currentContainerBundle .path.path.slice(1) // Remove the root entity, syn4489 .map(function (entity) { return { name: entity.name, isCurrent: entity.id === currentContainer, action: function () { setCurrentContainer(entity.id); }, }; }), true); } } if (setDetailsViewConfiguration) { setDetailsViewConfiguration(detailsViewConfig); } if (setBreadcrumbItems) { setBreadcrumbItems(breadcrumbItems); } } }, [ scope, currentContainer, topLevelEntities, setDetailsViewConfiguration, setBreadcrumbItems, currentContainerBundle, isSuccessBundle, ]); var rootNodeConfiguration = { nodeText: getScopeOptionNodeName(scope), children: topLevelEntities, }; var shouldAutoExpand = (0, react_1.useCallback)(function (entityId) { return !!(scope === FinderScope.CURRENT_PROJECT && initialContainerPath && isEntityIdInPath(entityId, initialContainerPath)); }, [scope, initialContainerPath]); return (react_1.default.createElement("div", { className: "TreeView " + (nodeAppearance === TreeNode_1.NodeAppearance.SELECT ? 'SelectTree' : 'BrowseTree') }, react_1.default.createElement("div", { className: "Header" }, react_1.default.createElement("div", { className: "Browse" }, "Browse:"), react_1.default.createElement("div", { onClick: function (e) { return e.stopPropagation(); } }, react_1.default.createElement(react_bootstrap_1.Dropdown, null, react_1.default.createElement(react_bootstrap_1.Dropdown.Toggle, { variant: "gray-primary-500", id: "dropdown-basic" }, scope), react_1.default.createElement(react_bootstrap_1.Dropdown.Menu, { role: "menu" }, Object.values(FinderScope).map(function (scopeOption) { if (scopeOption === FinderScope.CURRENT_PROJECT && projectId == null) { return react_1.default.createElement(react_1.default.Fragment, { key: scopeOption }); } return (react_1.default.createElement(react_bootstrap_1.Dropdown.Item, { role: "menuitem", key: scopeOption, onClick: function (e) { e.stopPropagation(); if (scope !== scopeOption) { setScope(scopeOption); setCurrentContainer(null); } } }, scopeOption)); }))))), isLoading ? (react_1.default.createElement("div", { className: "Placeholder" }, react_1.default.createElement(LoadingScreen_1.SynapseSpinner, { size: 30 }))) : (react_1.default.createElement("div", { className: "Tree", role: "tree" }, showScopeAsRootNode ? (react_1.default.createElement(TreeNode_1.TreeNode, { level: 0, selected: selectedEntities, setSelectedId: setSelectedId, visibleTypes: visibleTypes, autoExpand: shouldAutoExpand, rootNodeConfiguration: rootNodeConfiguration, appearance: nodeAppearance, selectableTypes: selectableTypes })) : (topLevelEntities.map(function (entity) { return (react_1.default.createElement(TreeNode_1.TreeNode, { key: entity.id, level: 0, selected: selectedEntities, setSelectedId: setSelectedId, visibleTypes: visibleTypes, autoExpand: shouldAutoExpand, entityHeader: entity, appearance: nodeAppearance, selectableTypes: selectableTypes })); })), react_1.default.createElement("div", { ref: ref, style: { height: '5px', width: '100%' } }))))); }; exports.TreeView = TreeView; //# sourceMappingURL=TreeView.js.map