Compare commits

..
Author SHA1 Message Date
kaloster 5b48c7aecf debug 2024-09-12 21:43:38 -04:00
Ronen ca8435de10 Merge branch 'main' into kaloster/various-fixes 2024-09-12 21:40:57 -04:00
kaloster 0bff55201a fix: update markdown images 2024-09-12 21:40:19 -04:00
26 changed files with 727 additions and 833 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ Whether you need to visualize one thousand cells or one million, CELLxGENE Annot
### Quick start ### Quick start
To install CELLxGENE Annotate you need Python 3.10+. We recommend [installing Annotate into a conda or virtual environment.](https://github.com/chanzuckerberg/cellxgene-documentation/blob/main/desktop/install.md) _To install CELLxGENE Annotate you need Python 3.10+_. We recommend [installing Annotate into a conda or virtual environment.](https://github.com/chanzuckerberg/cellxgene-documentation/blob/main/desktop/install.md)
Install the package. Install the package.
+1 -1
View File
@@ -1,4 +1,4 @@
import * as ENV_DEFAULT from "Code/cellxgene/environment.default.json"; import * as ENV_DEFAULT from "../../../environment.default.json";
export const jestEnv = process.env.JEST_ENV || ENV_DEFAULT.JEST_ENV; export const jestEnv = process.env.JEST_ENV || ENV_DEFAULT.JEST_ENV;
export const appUrlBase = export const appUrlBase =
+1 -1
View File
@@ -5,8 +5,8 @@
*/ */
import { setDefaultOptions } from "expect-puppeteer"; import { setDefaultOptions } from "expect-puppeteer";
import * as ENV_DEFAULT from "Code/cellxgene/environment.default.json";
import { isDebug, isDev } from "./config"; import { isDebug, isDev } from "./config";
import * as ENV_DEFAULT from "../../../environment.default.json";
// (thuang): This is the max time a test can take to run. // (thuang): This is the max time a test can take to run.
// Since when debugging, we run slowMo and !headless, this means // Since when debugging, we run slowMo and !headless, this means
+6 -6
View File
@@ -76,7 +76,7 @@ describe("PromiseLimit", () => {
const plimit = new PromiseLimit(1); const plimit = new PromiseLimit(1);
let finishOrder = 0; let finishOrder = 0;
const callback = async () => { const callback = () => async () => {
await delay(100); await delay(100);
const result = finishOrder; const result = finishOrder;
finishOrder += 1; finishOrder += 1;
@@ -84,11 +84,11 @@ describe("PromiseLimit", () => {
}; };
const result = await Promise.all([ const result = await Promise.all([
plimit.add(callback), plimit.add(callback()),
plimit.priorityAdd(4, callback), plimit.priorityAdd(4, callback()),
plimit.priorityAdd(0, callback), plimit.priorityAdd(0, callback()),
plimit.priorityAdd(1, callback), plimit.priorityAdd(1, callback()),
plimit.priorityAdd(-1, callback), plimit.priorityAdd(-1, callback()),
]); ]);
expect(result).toEqual([0, 4, 2, 3, 1]); expect(result).toEqual([0, 4, 2, 3, 1]);
+1 -2
View File
@@ -82,14 +82,13 @@ module.exports = {
}, },
// Can't extend in overrides: https://github.com/eslint/eslint/issues/8813 // Can't extend in overrides: https://github.com/eslint/eslint/issues/8813
// "extends": ["plugin:jest/recommended"] // "extends": ["plugin:jest/recommended"]
plugins: ["jest", "no-floating-promise"], plugins: ["jest"],
rules: { rules: {
"jest/no-disabled-tests": "warn", "jest/no-disabled-tests": "warn",
"jest/no-focused-tests": "error", "jest/no-focused-tests": "error",
"jest/no-identical-title": "error", "jest/no-identical-title": "error",
"jest/prefer-to-have-length": "warn", "jest/prefer-to-have-length": "warn",
"jest/valid-expect": "error", "jest/valid-expect": "error",
"no-floating-promise/no-floating-promise": 2,
}, },
}, },
], ],
+647 -776
View File
File diff suppressed because it is too large Load Diff
+6 -7
View File
@@ -10,8 +10,8 @@
"dev": "npm run build -- configuration/webpack/webpack.config.dev.js", "dev": "npm run build -- configuration/webpack/webpack.config.dev.js",
"e2e": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2e.test.js", "e2e": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2e.test.js",
"e2e-annotations": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2eAnnotations.test.js", "e2e-annotations": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2eAnnotations.test.js",
"fmt": "eslint --fix __tests__", "fmt": "eslint --fix src __tests__",
"lint": "eslint --fix __tests__", "lint": "eslint --fix src __tests__",
"prod": "npm run build -- configuration/webpack/webpack.config.prod.js", "prod": "npm run build -- configuration/webpack/webpack.config.prod.js",
"test": "jest --testPathIgnorePatterns e2e", "test": "jest --testPathIgnorePatterns e2e",
"prepare": "cd .. && husky install client/.husky" "prepare": "cd .. && husky install client/.husky"
@@ -92,7 +92,7 @@
"@babel/preset-react": "^7.13.13", "@babel/preset-react": "^7.13.13",
"@babel/register": "^7.13.16", "@babel/register": "^7.13.16",
"@babel/runtime": "^7.13.16", "@babel/runtime": "^7.13.16",
"@blueprintjs/eslint-plugin": "^6.1.4", "@blueprintjs/eslint-plugin": "^0.3.0",
"@sentry/webpack-plugin": "^1.15.0", "@sentry/webpack-plugin": "^1.15.0",
"babel-jest": "^26.1.0", "babel-jest": "^26.1.0",
"babel-loader": "^8.1.0", "babel-loader": "^8.1.0",
@@ -104,16 +104,15 @@
"codecov": "^3.7.1", "codecov": "^3.7.1",
"css-loader": "^5.2.4", "css-loader": "^5.2.4",
"css-minimizer-webpack-plugin": "^4.0.0", "css-minimizer-webpack-plugin": "^4.0.0",
"eslint": "^8.56.0", "eslint": "^7.24.0",
"eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb": "^18.2.0",
"eslint-config-prettier": "^8.2.0", "eslint-config-prettier": "^8.2.0",
"eslint-plugin-compat": "^4.2.0", "eslint-plugin-compat": "^4.2.0",
"eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-filenames": "^1.3.2", "eslint-plugin-filenames": "^1.3.2",
"eslint-plugin-import": "^2.24.2", "eslint-plugin-import": "^2.24.2",
"eslint-plugin-jest": "^28.8.3", "eslint-plugin-jest": "^24.3.5",
"eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-no-floating-promise": "^2.0.0",
"eslint-plugin-react": "^7.23.2", "eslint-plugin-react": "^7.23.2",
"eslint-plugin-react-hooks": "^4.0.8", "eslint-plugin-react-hooks": "^4.0.8",
"expect-puppeteer": "^5.0.0", "expect-puppeteer": "^5.0.0",
@@ -1,8 +1,8 @@
import React from "react"; import React from "react";
import * as globals from "../../globals"; import * as globals from "../../globals";
function ErrorLoading({ displayName, zebra }) { const ErrorLoading = ({ displayName, zebra }) => (
return <div <div
style={{ style={{
backgroundColor: zebra ? globals.lightestGrey : "white", backgroundColor: zebra ? globals.lightestGrey : "white",
fontStyle: "italic", fontStyle: "italic",
@@ -10,6 +10,6 @@ function ErrorLoading({ displayName, zebra }) {
> >
<span>{`Failure loading ${displayName}`}</span> <span>{`Failure loading ${displayName}`}</span>
</div> </div>
} );
export default ErrorLoading; export default ErrorLoading;
@@ -5,7 +5,7 @@ import * as d3 from "d3";
import maybeScientific from "../../util/maybeScientific"; import maybeScientific from "../../util/maybeScientific";
import clamp from "../../util/clamp"; import clamp from "../../util/clamp";
function Histogram({ const Histogram = ({
field, field,
fieldForId, fieldForId,
display, display,
@@ -18,7 +18,7 @@ function Histogram({
isColorBy, isColorBy,
selectionRange, selectionRange,
mini, mini,
}) { }) => {
const svgRef = useRef(null); const svgRef = useRef(null);
const [brush, setBrush] = useState(null); const [brush, setBrush] = useState(null);
@@ -186,6 +186,6 @@ function Histogram({
ref={svgRef} ref={svgRef}
/> />
); );
} };
export default Histogram; export default Histogram;
@@ -3,8 +3,12 @@ import { Button } from "@blueprintjs/core";
import * as globals from "../../globals"; import * as globals from "../../globals";
function StillLoading({ zebra, displayName }) { const StillLoading = ({ zebra, displayName }) =>
return <div /*
Render a loading indicator for the field.
*/
(
<div
data-testclass="gene-loading-spinner" data-testclass="gene-loading-spinner"
style={{ style={{
padding: globals.leftSidebarSectionPadding, padding: globals.leftSidebarSectionPadding,
@@ -33,6 +37,7 @@ function StillLoading({ zebra, displayName }) {
</div> </div>
</div> </div>
</div> </div>
} )
;
export default StillLoading; export default StillLoading;
@@ -71,7 +71,8 @@ class Category extends React.PureComponent {
const { metadataField, annotations, obsCrossfilter } = this.props; const { metadataField, annotations, obsCrossfilter } = this.props;
return ( return (
<AnnoDialog <>
<AnnoDialog
isActive={ isActive={
annotations.isAddingNewLabel && annotations.isAddingNewLabel &&
annotations.categoryAddingNewLabel === metadataField annotations.categoryAddingNewLabel === metadataField
@@ -104,6 +105,7 @@ class Category extends React.PureComponent {
/> />
} }
/> />
</>
); );
} }
} }
@@ -105,7 +105,8 @@ class AnnoDialogEditCategoryName extends React.PureComponent {
const { metadataField, annotations } = this.props; const { metadataField, annotations } = this.props;
return ( return (
<AnnoDialog <>
<AnnoDialog
isActive={ isActive={
annotations.isEditingCategoryName && annotations.isEditingCategoryName &&
annotations.categoryBeingEdited === metadataField annotations.categoryBeingEdited === metadataField
@@ -140,6 +141,7 @@ class AnnoDialogEditCategoryName extends React.PureComponent {
/> />
} }
/> />
</>
); );
} }
} }
@@ -288,8 +288,11 @@ class Category extends React.PureComponent {
export default Category; export default Category;
function StillLoading({ metadataField, checkboxID }) { const StillLoading = ({ metadataField, checkboxID }) => (
return <div /*
We are still loading this category, so render a "busy" signal.
*/
<div
style={{ style={{
maxWidth: globals.maxControlsWidth, maxWidth: globals.maxControlsWidth,
}} }}
@@ -332,8 +335,8 @@ function StillLoading({ metadataField, checkboxID }) {
</div> </div>
</div> </div>
</div> </div>
} );
function ErrorLoading({ metadataField, error }) { const ErrorLoading = ({ metadataField, error }) => {
console.error(error); // log error to console as it is unexpected. console.error(error); // log error to console as it is unexpected.
return ( return (
<div style={{ marginBottom: 10, marginTop: 4 }}> <div style={{ marginBottom: 10, marginTop: 4 }}>
@@ -349,7 +352,7 @@ function ErrorLoading({ metadataField, error }) {
</span> </span>
</div> </div>
); );
} };
const CategoryHeader = React.memo( const CategoryHeader = React.memo(
({ ({
@@ -162,7 +162,7 @@ class CategoryValue extends React.Component {
); );
}; };
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate = (nextProps, nextState) => {
/* /*
Checks to see if at least one of the following changed: Checks to see if at least one of the following changed:
* world state * world state
+2 -2
View File
@@ -109,7 +109,7 @@ const loadAllEmbeddingCounts = async ({ annoMatrix, available }) => {
})); }));
}; };
function EmbeddingChoices({ onChange, annoMatrix, layoutChoice }) { const EmbeddingChoices = ({ onChange, annoMatrix, layoutChoice }) => {
const { available } = layoutChoice; const { available } = layoutChoice;
const { data, error, isPending } = useAsync({ const { data, error, isPending } = useAsync({
promiseFn: loadAllEmbeddingCounts, promiseFn: loadAllEmbeddingCounts,
@@ -149,4 +149,4 @@ function EmbeddingChoices({ onChange, annoMatrix, layoutChoice }) {
); );
} }
return null; return null;
} };
+2 -2
View File
@@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import icon from "../../images/icon.png"; import icon from "../../images/icon.png";
function Logo(props) { const Logo = (props) => {
const { size } = props; const { size } = props;
return ( return (
<img <img
@@ -11,6 +11,6 @@ function Logo(props) {
alt="CELLxGENE Annotate Logo" alt="CELLxGENE Annotate Logo"
/> />
); );
} };
export default Logo; export default Logo;
@@ -53,7 +53,8 @@ class AddGeneToGenesetDialogue extends React.PureComponent {
const { genesToAdd } = this.state; const { genesToAdd } = this.state;
return ( return (
<AnnoDialog <>
<AnnoDialog
isActive={genesetsUI.isAddingGenesToGeneset === geneset} isActive={genesetsUI.isAddingGenesToGeneset === geneset}
inputProps={{ "data-testid": `${geneset}:create-label-dialog` }} inputProps={{ "data-testid": `${geneset}:create-label-dialog` }}
primaryButtonProps={{ primaryButtonProps={{
@@ -80,6 +81,7 @@ class AddGeneToGenesetDialogue extends React.PureComponent {
handleSubmit={this.handleAddGeneToGeneSet} handleSubmit={this.handleAddGeneToGeneSet}
handleCancel={this.disableAddGeneMode} handleCancel={this.disableAddGeneMode}
/> />
</>
); );
} }
} }
@@ -125,7 +125,8 @@ class CreateGenesetDialogue extends React.PureComponent {
const { genesetsUI, genesets } = this.props; const { genesetsUI, genesets } = this.props;
return ( return (
<Dialog <>
<Dialog
icon="tag" icon="tag"
title="Create gene set" title="Create gene set"
isOpen={genesetsUI.createGenesetModeActive} isOpen={genesetsUI.createGenesetModeActive}
@@ -209,6 +210,7 @@ class CreateGenesetDialogue extends React.PureComponent {
</div> </div>
</form> </form>
</Dialog> </Dialog>
</>
); );
} }
} }
@@ -109,7 +109,8 @@ class RenameGeneset extends React.PureComponent {
} = this.props; } = this.props;
return ( return (
<AnnoDialog <>
<AnnoDialog
isActive={genesetsUI.isEditingGenesetName === originalGenesetName} isActive={genesetsUI.isEditingGenesetName === originalGenesetName}
inputProps={{ inputProps={{
"data-testid": `${genesetsUI.isEditingGenesetName}:rename-geneset-dialog`, "data-testid": `${genesetsUI.isEditingGenesetName}:rename-geneset-dialog`,
@@ -160,6 +161,7 @@ class RenameGeneset extends React.PureComponent {
handleSubmit={this.renameGeneset} handleSubmit={this.renameGeneset}
handleCancel={this.disableEditGenesetNameMode} handleCancel={this.disableEditGenesetNameMode}
/> />
</>
); );
} }
} }
+10 -5
View File
@@ -935,7 +935,7 @@ class Graph extends React.Component {
} }
} }
function ErrorLoading({ displayName, error, width, height }) { const ErrorLoading = ({ displayName, error, width, height }) => {
console.log(error); // log to console as this is an unepected error console.log(error); // log to console as this is an unepected error
return ( return (
<div <div
@@ -949,10 +949,14 @@ function ErrorLoading({ displayName, error, width, height }) {
<span>{`Failure loading ${displayName}`}</span> <span>{`Failure loading ${displayName}`}</span>
</div> </div>
); );
} };
function StillLoading({ displayName, width, height }) { const StillLoading = ({ displayName, width, height }) =>
return <div /*
Render a busy/loading indicator
*/
(
<div
style={{ style={{
position: "fixed", position: "fixed",
fontWeight: 500, fontWeight: 500,
@@ -972,6 +976,7 @@ function StillLoading({ displayName, width, height }) {
<span style={{ fontStyle: "italic" }}>Loading {displayName}</span> <span style={{ fontStyle: "italic" }}>Loading {displayName}</span>
</div> </div>
</div> </div>
} )
;
export default Graph; export default Graph;
@@ -167,7 +167,7 @@ class CentroidLabels extends PureComponent {
} }
} }
function Label({ const Label = ({
label, label,
dilatedValue, dilatedValue,
coords, coords,
@@ -177,7 +177,7 @@ function Label({
displayLabel, displayLabel,
onMouseEnter, onMouseEnter,
onMouseOut, onMouseOut,
}) { }) => {
/* /*
Render a label at a given coordinate. Render a label at a given coordinate.
*/ */
@@ -215,4 +215,4 @@ function Label({
</text> </text>
</g> </g>
); );
} };
+3 -1
View File
@@ -159,7 +159,8 @@ export default class LabelInput extends React.PureComponent {
}; };
const { queryResults } = this.state; const { queryResults } = this.state;
return ( return (
<Suggest <>
<Suggest
fill fill
inputValueRenderer={(i) => i.target} inputValueRenderer={(i) => i.target}
items={queryResults} items={queryResults}
@@ -171,6 +172,7 @@ export default class LabelInput extends React.PureComponent {
inputProps={inputProps} inputProps={inputProps}
onKeyDown={this.handleKeyDown} onKeyDown={this.handleKeyDown}
/> />
</>
); );
} }
} }
+2 -2
View File
@@ -35,11 +35,11 @@ export default class MiniHistogram extends React.PureComponent {
} }
}; };
componentDidMount() { componentDidMount = () => {
this.drawHistogram(); this.drawHistogram();
}; };
componentDidUpdate(prevProps) { componentDidUpdate = (prevProps) => {
const { obsOrVarContinuousFieldDisplayName, bins } = this.props; const { obsOrVarContinuousFieldDisplayName, bins } = this.props;
if ( if (
prevProps.obsOrVarContinuousFieldDisplayName !== prevProps.obsOrVarContinuousFieldDisplayName !==
@@ -42,12 +42,12 @@ export default class MiniStackedBar extends React.PureComponent {
} }
}; };
componentDidUpdate(prevProps) { componentDidUpdate = (prevProps) => {
const { occupancy } = this.props; const { occupancy } = this.props;
if (occupancy !== prevProps.occupancy) this.drawStacks(); if (occupancy !== prevProps.occupancy) this.drawStacks();
}; };
componentDidMount() { componentDidMount = () => {
this.drawStacks(); this.drawStacks();
}; };
+1 -1
View File
@@ -32,7 +32,7 @@ const SECOND_HALF_INNER_STYLE = {
right: 0, right: 0,
}; };
export default function(props) { export default (props) => {
const { children, isGenesetDescription, tooltipAddendum = "" } = props; const { children, isGenesetDescription, tooltipAddendum = "" } = props;
// Truncate only support a single child with a text child // Truncate only support a single child with a text child
+1 -1
View File
@@ -1,6 +1,6 @@
import { Colors } from "@blueprintjs/core"; import { Colors } from "@blueprintjs/core";
import ENV_DEFAULT from "Code/cellxgene/environment.default.json";
import { dispatchNetworkErrorMessageToUser } from "./util/actionHelpers"; import { dispatchNetworkErrorMessageToUser } from "./util/actionHelpers";
import ENV_DEFAULT from "../../environment.default.json";
/* overflow category values are created using this string */ /* overflow category values are created using this string */
export const overflowCategoryLabel = ": all other labels"; export const overflowCategoryLabel = ": all other labels";