diff --git a/client/__tests__/e2e/__snapshots__/e2e.test.js.snap b/client/__tests__/e2e/__snapshots__/e2e.test.js.snap
index fce4a085..e7207fb7 100644
--- a/client/__tests__/e2e/__snapshots__/e2e.test.js.snap
+++ b/client/__tests__/e2e/__snapshots__/e2e.test.js.snap
@@ -1,5 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`did launch page launched 1`] = `"pbmc3kc3k"`;
+exports[`did launch page launched 1`] = `"pbmc3kc3k"`;
exports[`metadata loads categories and values from dataset appear 1`] = `"
"`;
diff --git a/client/src/components/categorical/category/index.js b/client/src/components/categorical/category/index.js
index 90999deb..6fc628f1 100644
--- a/client/src/components/categorical/category/index.js
+++ b/client/src/components/categorical/category/index.js
@@ -491,19 +491,7 @@ const CategoryRender = React.memo(
/*
Entire category has a single value, special case.
*/
- const theOneValue = categorySummary.categoryValues[0];
- return (
-
-
-
- {metadataField}
-
-
-
- {`: ${theOneValue}`}
-
-
- );
+ return null;
}
/*
diff --git a/client/src/components/infoDrawer/infoDrawer.js b/client/src/components/infoDrawer/infoDrawer.js
new file mode 100644
index 00000000..047e5017
--- /dev/null
+++ b/client/src/components/infoDrawer/infoDrawer.js
@@ -0,0 +1,152 @@
+import React, { PureComponent } from "react";
+import { connect, shallowEqual } from "react-redux";
+import { Drawer, H3, H1, UL, Classes } from "@blueprintjs/core";
+import Async from "react-async";
+import {
+ selectableCategoryNames,
+ createCategorySummaryFromDfCol,
+} from "../../util/stateManager/controlsHelpers";
+
+@connect((state) => {
+ return {
+ annoMatrix: state.annoMatrix,
+ schema: state.annoMatrix.schema,
+ datasetTitle: state.config?.displayNames?.dataset ?? "",
+ aboutURL: state.config?.links?.["about-dataset"],
+ isOpen: state.controls.datasetDrawer,
+ };
+})
+class InfoDrawer extends PureComponent {
+ static watchAsync(props, prevProps) {
+ return !shallowEqual(props.watchProps, prevProps.watchProps);
+ }
+
+ fetchAsyncProps = async (props) => {
+ const { schema } = props.watchProps;
+ const { annoMatrix } = this.props;
+
+ const allCategoryNames = selectableCategoryNames(schema).sort();
+
+ const nonUserAnnoCategories = allCategoryNames.map((catName) => {
+ const isUserAnno = schema?.annotations?.obsByName[catName]?.writable;
+ if (!isUserAnno) return annoMatrix.fetch("obs", catName);
+ return null;
+ });
+ const singleValueCategories = (
+ await Promise.all(nonUserAnnoCategories)
+ ).reduce((acc, categoryData, i) => {
+ const catName = allCategoryNames[i];
+
+ const column = categoryData.icol(0);
+ const colSchema = schema.annotations.obsByName[catName];
+
+ const categorySummary = createCategorySummaryFromDfCol(column, colSchema);
+
+ const { numCategoryValues } = categorySummary;
+ // Add to the array if the category has only one value
+ if (numCategoryValues === 1) {
+ acc.set(catName, categorySummary.allCategoryValues[0]);
+ }
+ return acc;
+ }, new Map());
+
+ return { singleValueCategories };
+ };
+
+ handleClose = () => {
+ const { dispatch } = this.props;
+
+ dispatch({ type: "toggle dataset drawer" });
+ };
+
+ render() {
+ const { position, aboutURL, datasetTitle, schema, isOpen } = this.props;
+
+ return (
+
+
+
+
+
+
+ {(error) => {
+ console.error(error);
+ return Failed to load info;
+ }}
+
+
+ {(asyncProps) => {
+ const { singleValueCategories } = asyncProps;
+ return (
+
+ );
+ }}
+
+
+
+ );
+ }
+}
+
+const NUM_CATEGORIES = 8;
+
+const singleValueCategoriesPlaceholder = Array.from(Array(NUM_CATEGORIES)).map(
+ (_, index) => {
+ return [index, index];
+ }
+);
+
+const InfoFormat = ({
+ datasetTitle,
+ singleValueCategories = new Map(singleValueCategoriesPlaceholder),
+ aboutURL = "thisisabouthtelengthofaurl",
+ skeleton = false,
+}) => {
+ return (
+
+
{datasetTitle}
+ {singleValueCategories.size > 0 && (
+ <>
+
+ Dataset Metadata
+
+
+ {Array.from(singleValueCategories).map((pair) => {
+ if (!pair[1] || pair[1] === "") return null;
+ return (
+ - {`${pair[0]}: ${pair[1]}`}
+ );
+ })}
+
+ >
+ )}
+ {aboutURL && (
+ <>
+
More Info
+
+ {aboutURL}
+
+ >
+ )}
+
+ );
+};
+export default InfoDrawer;
diff --git a/client/src/components/leftSidebar/topLeftLogoAndTitle.js b/client/src/components/leftSidebar/topLeftLogoAndTitle.js
index ee274b6f..f2346593 100644
--- a/client/src/components/leftSidebar/topLeftLogoAndTitle.js
+++ b/client/src/components/leftSidebar/topLeftLogoAndTitle.js
@@ -1,22 +1,27 @@
// jshint esversion: 6
import React from "react";
import { connect } from "react-redux";
+import { Button } from "@blueprintjs/core";
+import { IconNames } from "@blueprintjs/icons";
+
import * as globals from "../../globals";
import Logo from "../framework/logo";
import Truncate from "../util/truncate";
+import InfoDrawer from "../infoDrawer/infoDrawer";
-const DATASET_TITLE_WIDTH = 190;
const DATASET_TITLE_FONT_SIZE = 14;
@connect((state) => ({
datasetTitle: state.config?.displayNames?.dataset ?? "",
- aboutURL: state.config?.links?.["about-dataset"],
- scatterplotXXaccessor: state.controls.scatterplotXXaccessor,
- scatterplotYYaccessor: state.controls.scatterplotYYaccessor,
}))
class LeftSideBar extends React.Component {
+ handleClick = () => {
+ const { dispatch } = this.props;
+ dispatch({ type: "toggle dataset drawer" });
+ };
+
render() {
- const { datasetTitle, aboutURL } = this.props;
+ const { datasetTitle } = this.props;
return (
gene
-
+
+
+ {datasetTitle}
+
+
+
+
);
}
diff --git a/client/src/components/menubar/index.js b/client/src/components/menubar/index.js
index c06ece70..3fd840c0 100644
--- a/client/src/components/menubar/index.js
+++ b/client/src/components/menubar/index.js
@@ -250,10 +250,7 @@ class MenuBar extends React.PureComponent {
>
{
+ dispatch({ type: "toggle dataset drawer" });
+};
+
const InformationMenu = React.memo((props) => {
- const { libraryVersions, aboutLink, tosURL, privacyURL } = props;
+ const { libraryVersions, tosURL, privacyURL, dispatch } = props;
return (
- {aboutLink ? (
-
- ) : (
- ""
- )}
+