Render categories with one label without checkbox (#1375)

* categories with 1 item rendered without checkbox

* break out into helper functions

* prettier
This commit is contained in:
Colin Megill
2020-04-13 23:04:23 -04:00
committed by GitHub
parent a3df1a9f4a
commit 64bd908c25
+101 -50
View File
@@ -10,11 +10,11 @@ import AnnoSelect from "./annoSelect";
import LabelInput from "./labelInput"; import LabelInput from "./labelInput";
import { labelPrompt } from "./labelUtil"; import { labelPrompt } from "./labelUtil";
@connect(state => ({ @connect((state) => ({
writableCategoriesEnabled: state.config?.parameters?.["annotations"] ?? false, writableCategoriesEnabled: state.config?.parameters?.["annotations"] ?? false,
schema: state.world?.schema, schema: state.world?.schema,
config: state.config, config: state.config,
ontology: state.ontology ontology: state.ontology,
})) }))
class Categories extends React.Component { class Categories extends React.Component {
constructor(props) { constructor(props) {
@@ -23,22 +23,22 @@ class Categories extends React.Component {
createAnnoModeActive: false, createAnnoModeActive: false,
newCategoryText: "", newCategoryText: "",
categoryToDuplicate: null, categoryToDuplicate: null,
expandedCats: new Set() expandedCats: new Set(),
}; };
} }
handleCreateUserAnno = e => { handleCreateUserAnno = (e) => {
const { dispatch } = this.props; const { dispatch } = this.props;
const { newCategoryText, categoryToDuplicate } = this.state; const { newCategoryText, categoryToDuplicate } = this.state;
dispatch({ dispatch({
type: "annotation: create category", type: "annotation: create category",
data: newCategoryText, data: newCategoryText,
categoryToDuplicate categoryToDuplicate,
}); });
this.setState({ this.setState({
createAnnoModeActive: false, createAnnoModeActive: false,
categoryToDuplicate: null, categoryToDuplicate: null,
newCategoryText: "" newCategoryText: "",
}); });
e.preventDefault(); e.preventDefault();
}; };
@@ -51,15 +51,15 @@ class Categories extends React.Component {
this.setState({ this.setState({
createAnnoModeActive: false, createAnnoModeActive: false,
categoryToDuplicate: null, categoryToDuplicate: null,
newCategoryText: "" newCategoryText: "",
}); });
}; };
handleModalDuplicateCategorySelection = d => { handleModalDuplicateCategorySelection = (d) => {
this.setState({ categoryToDuplicate: d }); this.setState({ categoryToDuplicate: d });
}; };
categoryNameError = name => { categoryNameError = (name) => {
/* /*
return false if this is a LEGAL/acceptable category name or NULL/empty string, return false if this is a LEGAL/acceptable category name or NULL/empty string,
or return an error type. or return an error type.
@@ -73,7 +73,7 @@ class Categories extends React.Component {
we render as categorical. we render as categorical.
*/ */
const { schema } = this.props; const { schema } = this.props;
const allCategoryNames = schema.annotations.obs.columns.map(c => c.name); const allCategoryNames = schema.annotations.obs.columns.map((c) => c.name);
/* check category name syntax */ /* check category name syntax */
const error = AnnotationsHelpers.annotationNameIsErroneous(name); const error = AnnotationsHelpers.annotationNameIsErroneous(name);
@@ -90,15 +90,15 @@ class Categories extends React.Component {
return false; return false;
}; };
handleChange = name => { handleChange = (name) => {
this.setState({ newCategoryText: name }); this.setState({ newCategoryText: name });
}; };
handleSelect = name => { handleSelect = (name) => {
this.setState({ newCategoryText: name }); this.setState({ newCategoryText: name });
}; };
instruction = name => { instruction = (name) => {
return labelPrompt( return labelPrompt(
this.categoryNameError(name), this.categoryNameError(name),
"New, unique category name", "New, unique category name",
@@ -106,25 +106,76 @@ class Categories extends React.Component {
); );
}; };
onExpansionChange = catName => { onExpansionChange = (catName) => {
const {expandedCats} = this.state; const { expandedCats } = this.state;
if (expandedCats.has(catName)) { if (expandedCats.has(catName)) {
const _expandedCats = new Set(expandedCats); const _expandedCats = new Set(expandedCats);
_expandedCats.delete(catName) _expandedCats.delete(catName);
this.setState({expandedCats: _expandedCats}) this.setState({ expandedCats: _expandedCats });
} else { } else {
const _expandedCats = new Set(expandedCats); const _expandedCats = new Set(expandedCats);
_expandedCats.add(catName) _expandedCats.add(catName);
this.setState({expandedCats: _expandedCats}) this.setState({ expandedCats: _expandedCats });
} }
} };
maybeRenderSingleLabel = (allCategoryNames, schema) => {
return allCategoryNames.map((catName) =>
!schema.annotations.obsByName[catName].writable &&
schema.annotations.obsByName[catName].categories.length === 1 ? (
<div style={{ marginBottom: 10 }}>
<span style={{ fontWeight: 700 }}>{catName}</span>:{" "}
{schema.annotations.obsByName[catName].categories[0]}
</div>
) : null
);
};
maybeRenderReadOnly = (
allCategoryNames,
schema,
expandedCats,
createAnnoModeActive
) => {
return allCategoryNames.map((catName) =>
!schema.annotations.obsByName[catName].writable &&
schema.annotations.obsByName[catName].categories.length > 1 ? (
<Category
key={catName}
metadataField={catName}
onExpansionChange={this.onExpansionChange}
isExpanded={expandedCats.has(catName)}
createAnnoModeActive={createAnnoModeActive}
isUserAnno={false}
/>
) : null
);
};
maybeRenderAnnotations = (
allCategoryNames,
schema,
expandedCats,
createAnnoModeActive
) => {
return allCategoryNames.map((catName) =>
schema.annotations.obsByName[catName].writable ? (
<Category
key={catName}
metadataField={catName}
onExpansionChange={this.onExpansionChange}
isExpanded={expandedCats.has(catName)}
createAnnoModeActive={createAnnoModeActive}
isUserAnno
/>
) : null
);
};
render() { render() {
const { const {
createAnnoModeActive, createAnnoModeActive,
categoryToDuplicate, categoryToDuplicate,
newCategoryText, newCategoryText,
expandedCats expandedCats,
} = this.state; } = this.state;
const { writableCategoriesEnabled, schema, config, ontology } = this.props; const { writableCategoriesEnabled, schema, config, ontology } = this.props;
const ontologyEnabled = ontology?.enabled ?? false; const ontologyEnabled = ontology?.enabled ?? false;
@@ -137,7 +188,7 @@ class Categories extends React.Component {
return ( return (
<div <div
style={{ style={{
padding: globals.leftSidebarSectionPadding padding: globals.leftSidebarSectionPadding,
}} }}
> >
<AnnoDialog <AnnoDialog
@@ -160,7 +211,7 @@ class Categories extends React.Component {
"data-testid": "new-category-name", "data-testid": "new-category-name",
leftIcon: "tag", leftIcon: "tag",
intent: "none", intent: "none",
autoFocus: true autoFocus: true,
}} }}
newLabelMessage="New category" newLabelMessage="New category"
/> />
@@ -176,33 +227,33 @@ class Categories extends React.Component {
} }
/> />
{/* READ ONLY CATEGORICAL FIELDS */} <div style={{ marginLeft: 0 }}>
{/* this is duplicative but flat, could be abstracted */} {
{allCategoryNames.map(catName => this.maybeRenderSingleLabel(
!schema.annotations.obsByName[catName].writable ? ( allCategoryNames,
<Category schema,
key={catName} expandedCats,
metadataField={catName} createAnnoModeActive
onExpansionChange={this.onExpansionChange} ) /* Categories with only one label */
isExpanded={expandedCats.has(catName)} }
createAnnoModeActive={createAnnoModeActive} </div>
isUserAnno={false} {
/> this.maybeRenderReadOnly(
) : null allCategoryNames,
)} schema,
{/* WRITEABLE FIELDS */} expandedCats,
{allCategoryNames.map(catName => createAnnoModeActive
schema.annotations.obsByName[catName].writable ? ( ) /* Read only categorical fields, ostensibly 'normal' mode */
<Category }
key={catName} {
metadataField={catName} this.maybeRenderAnnotations(
onExpansionChange={this.onExpansionChange} allCategoryNames,
isExpanded={expandedCats.has(catName)} schema,
createAnnoModeActive={createAnnoModeActive} expandedCats,
isUserAnno createAnnoModeActive
/> ) /* Writable fields, ie., anno */
) : null }
)}
{writableCategoriesEnabled ? ( {writableCategoriesEnabled ? (
<div> <div>
<Button <Button