mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-29 12:08:13 +08:00
Improve label picking (#1179)
* add simple error message helper * port all label name pickers to use the new LabelInput component * use pure components where possible * cleanup * more cleanup * lint * change new label prompt
This commit is contained in:
@@ -1,20 +1,17 @@
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import AnnoDialog from "./annoDialog";
|
||||
import AnnoInputs from "./annoInputs";
|
||||
|
||||
import { labelErrorMessage, isLabelErroneous } from "./labelUtil";
|
||||
import LabelInput from "./labelInput";
|
||||
import { labelPrompt, isLabelErroneous } from "./labelUtil";
|
||||
|
||||
@connect(state => ({
|
||||
colorAccessor: state.colors.colorAccessor,
|
||||
categoricalSelection: state.categoricalSelection,
|
||||
annotations: state.annotations,
|
||||
universe: state.universe,
|
||||
ontology: state.ontology,
|
||||
ontologyLoading: state.ontology?.loading,
|
||||
ontologyEnabled: state.ontology?.enabled
|
||||
ontology: state.ontology
|
||||
}))
|
||||
class Category extends React.Component {
|
||||
class Category extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@@ -22,14 +19,15 @@ class Category extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
disableAddNewLabelMode = () => {
|
||||
disableAddNewLabelMode = e => {
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: "annotation: disable add new label mode"
|
||||
});
|
||||
this.setState({
|
||||
newLabelText: ""
|
||||
});
|
||||
dispatch({
|
||||
type: "annotation: disable add new label mode"
|
||||
});
|
||||
if (e) e.preventDefault();
|
||||
};
|
||||
|
||||
handleAddNewLabelToCategory = e => {
|
||||
@@ -46,7 +44,7 @@ class Category extends React.Component {
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
addLabelAndAssignCells = () => {
|
||||
addLabelAndAssignCells = e => {
|
||||
const { dispatch, metadataField } = this.props;
|
||||
const { newLabelText } = this.state;
|
||||
|
||||
@@ -57,18 +55,7 @@ class Category extends React.Component {
|
||||
newLabelText,
|
||||
assignSelectedCells: true
|
||||
});
|
||||
};
|
||||
|
||||
handleCreateArbitraryLabel = newLabelTextNotInOntology => {
|
||||
const { dispatch, metadataField } = this.props;
|
||||
|
||||
this.disableAddNewLabelMode();
|
||||
dispatch({
|
||||
type: "annotation: add new label to category",
|
||||
metadataField,
|
||||
newLabelText: newLabelTextNotInOntology,
|
||||
assignSelectedCells: false
|
||||
});
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
labelNameError = name => {
|
||||
@@ -76,23 +63,18 @@ class Category extends React.Component {
|
||||
return isLabelErroneous(name, metadataField, ontology, universe.schema);
|
||||
};
|
||||
|
||||
labelNameErrorMessage = name => {
|
||||
const { metadataField, ontology, universe } = this.props;
|
||||
return labelErrorMessage(name, metadataField, ontology, universe.schema);
|
||||
instruction = label => {
|
||||
return labelPrompt(this.labelNameError(label), "New, unique label", ":");
|
||||
};
|
||||
|
||||
/* leaky to have both of these in multiple components */
|
||||
handleChoice = e => {
|
||||
this.setState({ newLabelText: e.target });
|
||||
};
|
||||
|
||||
handleTextChange = text => {
|
||||
this.setState({ newLabelText: text });
|
||||
handleChangeOrSelect = label => {
|
||||
this.setState({ newLabelText: label });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { newLabelText } = this.state;
|
||||
const { metadataField, annotations, ontologyEnabled } = this.props;
|
||||
const { metadataField, annotations, ontology } = this.props;
|
||||
const ontologyEnabled = ontology?.enabled ?? false;
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -106,27 +88,26 @@ class Category extends React.Component {
|
||||
"data-testid": `${metadataField}:submit-label`
|
||||
}}
|
||||
title="Add new label to category"
|
||||
instruction="New, unique label name:"
|
||||
instruction={this.instruction(newLabelText)}
|
||||
cancelTooltipContent="Close this dialog without adding a label."
|
||||
primaryButtonText="Add label"
|
||||
secondaryButtonText="Add label and assign currently selected cells"
|
||||
handleSecondaryButtonSubmit={this.addLabelAndAssignCells}
|
||||
text={newLabelText}
|
||||
validationError={this.labelNameError(newLabelText)}
|
||||
errorMessage={this.labelNameErrorMessage(newLabelText)}
|
||||
handleSubmit={this.handleAddNewLabelToCategory}
|
||||
handleCancel={this.disableAddNewLabelMode}
|
||||
annoInput={
|
||||
<AnnoInputs
|
||||
useSuggest={ontologyEnabled}
|
||||
text={newLabelText}
|
||||
inputProps={{ "data-testid": `${metadataField}:new-label-name` }}
|
||||
handleCreateArbitraryLabel={this.handleCreateArbitraryLabel}
|
||||
handleItemChange={this.handleSuggestActiveItemChange}
|
||||
handleChoice={this.handleChoice}
|
||||
handleTextChange={this.handleTextChange}
|
||||
isTextInvalid={this.labelNameError}
|
||||
isTextInvalidErrorMessage={this.labelNameErrorMessage}
|
||||
<LabelInput
|
||||
labelSuggestions={ontologyEnabled ? ontology.terms : null}
|
||||
onChange={this.handleChangeOrSelect}
|
||||
onSelect={this.handleChangeOrSelect}
|
||||
inputProps={{
|
||||
"data-testid": `${metadataField}:new-label-name`,
|
||||
leftIcon: "tag",
|
||||
intent: "none",
|
||||
autoFocus: true
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user