wire up geneset reducer (#2082)

* first cut at GET /genesets route

* update existing tests to match code changes

* more GET /genesets and initial tests

* add missing test fixture

* geneset validation accepts OTA format

* genesets route: better error handling, more tests

* lint

* genesets reducer and initial load

* fix lint

* add autosave support for genesets

* remove debug logging

* fix typo

* fix another typo

* update smoke test config for genesets

* smoke test fixes

* more fiddling with smoke tests
This commit is contained in:
Bruce Martin
2021-03-02 12:12:58 -08:00
committed by GitHub
parent b3aadf6632
commit b00496198d
8 changed files with 1082 additions and 19 deletions
+93
View File
@@ -387,3 +387,96 @@ export const saveObsAnnotationsAction = () => async (dispatch, getState) => {
});
}
};
export const saveGenesetsAction = () => async (dispatch, getState) => {
const state = getState();
// bail if gene sets not available, or in readonly mode.
const { config } = state;
const genesetsAreAvailable =
config?.parameters?.["annotations_genesets"] ?? false;
const genesetsReadonly =
config?.parameters?.["annotations_genesets_readonly"] ?? true;
if (!genesetsAreAvailable || genesetsReadonly) {
// our non-save was completed!
return dispatch({
type: "autosave: genesets complete",
lastSavedGenesets: state.genesets,
});
}
const { lastTid, genesets: lastGenesets } = state.genesets;
/* Create the JSON OTA data structure */
const tid = (lastTid ?? 0) + 1;
const genesets = [];
for (const [name, gs] of lastGenesets) {
// const genes = Array.from(gs.genes.values());
const genes = [];
for (const g of gs.genes.values()) {
genes.push({
gene_symbol: g.geneSymbol,
gene_description: g.geneDescription,
});
}
genesets.push({
geneset_name: name,
geneset_description: gs.genesetDescription,
genes,
});
}
const ota = {
tid,
genesets,
};
/* Save to server */
try {
const {
dataCollectionNameIsReadOnly,
dataCollectionName,
} = state.annotations;
const queryString =
!dataCollectionNameIsReadOnly && !!dataCollectionName
? `?annotation-collection-name=${encodeURIComponent(
dataCollectionName
)}`
: "";
const res = await fetch(
`${globals.API.prefix}${globals.API.version}genesets${queryString}`,
{
method: "PUT",
headers: new Headers({
Accept: "application/json",
"Content-Type": "application/json",
}),
body: JSON.stringify(ota),
credentials: "include",
}
);
if (!res.ok) {
return dispatch({
type: "autosave: genesets error",
message: `HTTP error ${res.status} - ${res.statusText}`,
res,
});
}
return Promise.all([
dispatch({
type: "autosave: genesets complete",
lastSavedGenesets: genesets,
}),
dispatch({
type: "geneset: set tid",
tid,
}),
]);
} catch (error) {
return dispatch({
type: "autosave: genesets error",
message: error.toString(),
error,
});
}
};
+24
View File
@@ -52,6 +52,27 @@ async function userInfoFetch(dispatch) {
});
}
async function genesetsFetch(dispatch, config) {
/* request genesets ONLY if the backend supports the feature */
const defaultResponse = {
genesets: [],
tid: 0,
};
if (config?.parameters?.["annotations_genesets"] ?? false) {
fetchJson("genesets").then((response) => {
dispatch({
type: "geneset: initial load",
data: response ?? defaultResponse,
});
});
} else {
dispatch({
type: "geneset: initial load",
data: defaultResponse,
});
}
}
function prefetchEmbeddings(annoMatrix) {
/*
prefetch requests for all embeddings
@@ -76,6 +97,8 @@ const doInitialDataLoad = () =>
userInfoFetch(dispatch),
]);
genesetsFetch(dispatch, config);
const baseDataUrl = `${globals.API.prefix}${globals.API.version}`;
const annoMatrix = new AnnoMatrixLoader(baseDataUrl, schema.schema);
const obsCrossfilter = new AnnoMatrixObsCrossfilter(annoMatrix);
@@ -242,6 +265,7 @@ export default {
annotationRenameLabelInCategory: annoActions.annotationRenameLabelInCategory,
annotationLabelCurrentSelection: annoActions.annotationLabelCurrentSelection,
saveObsAnnotationsAction: annoActions.saveObsAnnotationsAction,
saveGenesetsAction: annoActions.saveGenesetsAction,
needToSaveObsAnnotations: annoActions.needToSaveObsAnnotations,
layoutChoiceAction: embActions.layoutChoiceAction,
setCellSetFromSelection: selnActions.setCellSetFromSelection,